@tushar-br/editing-pack 1.0.188 → 1.0.190
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/staging_area/Blender/blender.pdb.ts_part_0 +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/__init__.py +0 -173
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/__pycache__/camera.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/__pycache__/engine.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/__pycache__/operators.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/__pycache__/presets.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/__pycache__/properties.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/__pycache__/ui.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/__pycache__/version_update.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/geom/shader_data.h +0 -452
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/geom/triangle.h +0 -278
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/geom/triangle_intersect.h +0 -166
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/geom/volume.h +0 -104
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/globals.h +0 -13
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/image.h +0 -12
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/displacement_shader.h +0 -43
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/guiding.h +0 -641
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/init_from_bake.h +0 -344
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/init_from_camera.h +0 -110
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/intersect_closest.h +0 -443
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/intersect_dedicated_light.h +0 -232
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/intersect_shadow.h +0 -183
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/intersect_subsurface.h +0 -24
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/intersect_volume_stack.h +0 -250
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/megakernel.h +0 -114
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/mnee.h +0 -1123
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/path_state.h +0 -425
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shade_background.h +0 -210
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shade_dedicated_light.h +0 -243
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shade_light.h +0 -95
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shade_shadow.h +0 -192
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shade_surface.h +0 -885
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shade_volume.h +0 -2947
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shadow_catcher.h +0 -79
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shadow_linking.h +0 -69
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shadow_state_template.h +0 -99
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/state.h +0 -276
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/state_flow.h +0 -255
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/state_template.h +0 -152
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/state_util.h +0 -602
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/subsurface.h +0 -251
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/subsurface_disk.h +0 -220
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/subsurface_random_walk.h +0 -462
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/surface_shader.h +0 -1198
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/volume_shader.h +0 -539
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/volume_stack.h +0 -258
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/area.h +0 -537
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/background.h +0 -500
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/common.h +0 -86
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/distant.h +0 -167
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/distribution.h +0 -60
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/light.h +0 -499
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/point.h +0 -240
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/sample.h +0 -545
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/spot.h +0 -347
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/tree.h +0 -951
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/triangle.h +0 -339
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/osl/camera.h +0 -81
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/osl/closures_setup.h +0 -1259
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/osl/closures_template.h +0 -277
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/osl/osl.h +0 -287
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/osl/services_gpu.h +0 -1327
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/osl/types.h +0 -157
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/sample/lcg.h +0 -53
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/sample/mapping.h +0 -251
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/sample/mis.h +0 -41
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/sample/pattern.h +0 -188
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/sample/sobol_burley.h +0 -203
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/sample/tabulated_sobol.h +0 -178
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/sample/util.h +0 -79
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/ao.h +0 -148
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/aov.h +0 -49
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/attribute.h +0 -326
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/bevel.h +0 -334
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/blackbody.h +0 -35
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/brick.h +0 -147
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/brightness.h +0 -32
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/bump.h +0 -72
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/camera.h +0 -42
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/checker.h +0 -54
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/clamp.h +0 -40
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/closure.h +0 -1559
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/color_util.h +0 -409
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/convert.h +0 -66
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/displace.h +0 -240
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/fractal_noise.h +0 -550
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/fresnel.h +0 -80
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/gabor.h +0 -392
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/gamma.h +0 -27
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/geometry.h +0 -280
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/gradient.h +0 -80
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/hsv.h +0 -54
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/ies.h +0 -38
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/image.h +0 -273
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/invert.h +0 -33
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/light_path.h +0 -150
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/magic.h +0 -132
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/map_range.h +0 -164
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/mapping.h +0 -74
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/mapping_util.h +0 -37
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/math.h +0 -73
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/math_util.h +0 -278
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/mix.h +0 -125
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/node_types_template.h +0 -115
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/noise.h +0 -761
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/noisetex.h +0 -370
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/normal.h +0 -38
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/radial_tiling.h +0 -81
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/radial_tiling_shared.h +0 -1179
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/ramp.h +0 -185
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/ramp_util.h +0 -80
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/sepcomb_color.h +0 -62
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/sepcomb_vector.h +0 -45
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/sky.h +0 -309
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/svm.h +0 -492
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/tex_coord.h +0 -506
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/types.h +0 -530
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/util.h +0 -160
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/value.h +0 -34
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/vector_rotate.h +0 -79
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/vector_transform.h +0 -130
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/vertex_color.h +0 -107
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/voronoi.h +0 -1248
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/wave.h +0 -137
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/wavelength.h +0 -36
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/white_noise.h +0 -74
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/wireframe.h +0 -116
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/tables.h +0 -124
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/types.h +0 -1923
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/util/colorspace.h +0 -54
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/util/differential.h +0 -169
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/util/ies.h +0 -145
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/util/lookup_table.h +0 -74
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/util/nanovdb.h +0 -436
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/util/profiler.h +0 -28
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/util/texture_3d.h +0 -232
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/atomic.h +0 -315
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/color.h +0 -439
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/defines.h +0 -131
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/guiding.h +0 -40
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/half.h +0 -178
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/hash.h +0 -650
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math.h +0 -24
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_base.h +0 -953
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_dual.h +0 -59
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_fast.h +0 -650
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_float2.h +0 -274
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_float3.h +0 -847
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_float4.h +0 -666
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_float8.h +0 -471
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_int2.h +0 -59
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_int3.h +0 -117
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_int4.h +0 -296
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_int8.h +0 -353
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_intersect.h +0 -452
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/projection.h +0 -308
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/projection_inverse.h +0 -95
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/rect.h +0 -61
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/static_assert.h +0 -21
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/texture.h +0 -100
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/transform.h +0 -650
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types.h +0 -32
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_base.h +0 -94
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_dual.h +0 -134
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_float2.h +0 -71
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_float3.h +0 -200
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_float4.h +0 -134
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_float8.h +0 -134
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_int2.h +0 -44
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_int3.h +0 -158
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_int4.h +0 -91
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_int8.h +0 -94
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_rgbe.h +0 -109
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_spectrum.h +0 -28
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_uchar2.h +0 -39
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_uchar3.h +0 -39
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_uchar4.h +0 -45
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_uint2.h +0 -37
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_uint3.h +0 -91
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_uint4.h +0 -37
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_ushort4.h +0 -19
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/ui.py +0 -2645
- package/staging_area/Blender/5.0/scripts/addons_core/cycles/version_update.py +0 -330
- package/staging_area/Blender/5.0/scripts/addons_core/hydra_storm/__init__.py +0 -33
- package/staging_area/Blender/5.0/scripts/addons_core/hydra_storm/engine.py +0 -47
- package/staging_area/Blender/5.0/scripts/addons_core/hydra_storm/properties.py +0 -62
- package/staging_area/Blender/5.0/scripts/addons_core/hydra_storm/ui.py +0 -280
- package/staging_area/Blender/5.0/scripts/addons_core/io_anim_bvh/__init__.py +0 -397
- package/staging_area/Blender/5.0/scripts/addons_core/io_anim_bvh/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_anim_bvh/export_bvh.py +0 -294
- package/staging_area/Blender/5.0/scripts/addons_core/io_anim_bvh/import_bvh.py +0 -795
- package/staging_area/Blender/5.0/scripts/addons_core/io_curve_svg/__init__.py +0 -115
- package/staging_area/Blender/5.0/scripts/addons_core/io_curve_svg/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_curve_svg/import_svg.py +0 -1911
- package/staging_area/Blender/5.0/scripts/addons_core/io_curve_svg/svg_colors.py +0 -153
- package/staging_area/Blender/5.0/scripts/addons_core/io_curve_svg/svg_util.py +0 -107
- package/staging_area/Blender/5.0/scripts/addons_core/io_curve_svg/svg_util_test.py +0 -166
- package/staging_area/Blender/5.0/scripts/addons_core/io_mesh_uv_layout/__init__.py +0 -302
- package/staging_area/Blender/5.0/scripts/addons_core/io_mesh_uv_layout/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_mesh_uv_layout/export_uv_eps.py +0 -82
- package/staging_area/Blender/5.0/scripts/addons_core/io_mesh_uv_layout/export_uv_png.py +0 -119
- package/staging_area/Blender/5.0/scripts/addons_core/io_mesh_uv_layout/export_uv_svg.py +0 -54
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/__init__.py +0 -740
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/data_types.py +0 -62
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/encode_bin.py +0 -434
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/export_fbx_bin.py +0 -3819
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/fbx2json.py +0 -341
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/fbx_utils.py +0 -1931
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/fbx_utils_threading.py +0 -194
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/import_fbx.py +0 -4045
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/json2fbx.py +0 -165
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/parse_fbx.py +0 -274
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/__init__.py +0 -2250
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/__init__.py +0 -3
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/blender_default.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/conversion.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/data_path.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/extras.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/gltf2_blender_math.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/gltf2_blender_ui.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/gltf2_blender_utils.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/json_util.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/material_helpers.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/blender_default.py +0 -15
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/conversion.py +0 -229
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/data_path.py +0 -110
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/extras.py +0 -89
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/gltf2_blender_math.py +0 -209
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/gltf2_blender_ui.py +0 -751
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/gltf2_blender_utils.py +0 -70
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/json_util.py +0 -27
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/material_helpers.py +0 -32
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/__pycache__/cache.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/__pycache__/sampler.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/accessors.py +0 -189
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/action.py +0 -1062
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/anim_utils.py +0 -321
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/animations.py +0 -22
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/drivers.py +0 -83
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/fcurves/animation.py +0 -35
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/fcurves/channel_target.py +0 -53
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/fcurves/channels.py +0 -378
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/fcurves/keyframes.py +0 -207
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/fcurves/sampler.py +0 -231
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/keyframes.py +0 -127
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/armature/action_sampled.py +0 -55
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/armature/channel_target.py +0 -54
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/armature/channels.py +0 -236
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/armature/keyframes.py +0 -95
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/armature/sampler.py +0 -230
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/data/channel_target.py +0 -48
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/data/channels.py +0 -118
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/data/keyframes.py +0 -152
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/data/sampler.py +0 -135
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/object/action_sampled.py +0 -58
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/object/channel_target.py +0 -51
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/object/channels.py +0 -136
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/object/keyframes.py +0 -88
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/object/sampler.py +0 -171
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/sampling_cache.py +0 -754
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/shapekeys/action_sampled.py +0 -43
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/shapekeys/channel_target.py +0 -38
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/shapekeys/channels.py +0 -79
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/shapekeys/keyframes.py +0 -145
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/shapekeys/sampler.py +0 -111
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/scene_animation.py +0 -244
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/tracks.py +0 -846
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/cache.py +0 -182
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/cameras.py +0 -152
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/export.py +0 -412
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/exporter.py +0 -536
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/gather.py +0 -157
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/joints.py +0 -110
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/light_spots.py +0 -47
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/lights.py +0 -212
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/__pycache__/encode_image.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/__pycache__/image.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/__pycache__/search_node_tree.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/__pycache__/texture.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/__pycache__/texture_info.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/__pycache__/unlit.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/encode_image.py +0 -491
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/anisotropy.py +0 -259
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/clearcoat.py +0 -156
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/emission.py +0 -115
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/ior.py +0 -45
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/sheen.py +0 -129
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/specular.py +0 -140
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/transmission.py +0 -76
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/variants.py +0 -19
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/volume.py +0 -118
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/image.py +0 -514
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/material_utils.py +0 -13
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/material_viewport.py +0 -32
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/materials.py +0 -714
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/pbr_metallic_roughness.py +0 -257
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/search_node_tree.py +0 -1120
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/texture.py +0 -248
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/texture_info.py +0 -291
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/unlit.py +0 -191
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/mesh.py +0 -160
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/nodes.py +0 -577
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/primitive_attributes.py +0 -252
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/primitive_extract.py +0 -1662
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/primitives.py +0 -366
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/sampler.py +0 -187
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/skins.py +0 -148
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/tree.py +0 -976
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/KHR_materials_anisotropy.py +0 -116
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/KHR_materials_pbrSpecularGlossiness.py +0 -203
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/KHR_materials_unlit.py +0 -56
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/KHR_materials_anisotropy.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/KHR_materials_pbrSpecularGlossiness.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/KHR_materials_unlit.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/animation.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/animation_node.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/animation_pointer.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/animation_utils.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/animation_weight.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/blender_gltf.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/camera.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/draco_compression_extension.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/image.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/light.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/material.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/material_utils.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/mesh.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/node.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/pbrMetallicRoughness.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/scene.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/texture.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/vnode.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/animation.py +0 -170
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/animation_node.py +0 -170
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/animation_pointer.py +0 -787
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/animation_utils.py +0 -174
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/animation_weight.py +0 -95
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/blender_gltf.py +0 -633
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/camera.py +0 -75
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/draco_compression_extension.py +0 -138
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/image.py +0 -102
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/light.py +0 -143
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/material.py +0 -113
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/material_utils.py +0 -196
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/mesh.py +0 -920
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/node.py +0 -348
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/pbrMetallicRoughness.py +0 -903
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/scene.py +0 -133
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/texture.py +0 -233
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/vnode.py +0 -661
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/extern_draco.dll +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/__init__.py +0 -5
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/__pycache__/constants.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/__pycache__/debug.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/__pycache__/draco.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/__pycache__/gltf2_io.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/__pycache__/gltf2_io_extensions.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/__pycache__/path.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/constants.py +0 -159
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/debug.py +0 -129
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/draco.py +0 -46
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/gltf2_io.py +0 -1217
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/gltf2_io_extensions.py +0 -30
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/lights_punctual.py +0 -68
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/path.py +0 -19
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/variants.py +0 -32
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/__pycache__/binary_data.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/__pycache__/image_data.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/__pycache__/user_extensions.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/binary_data.py +0 -35
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/buffer.py +0 -54
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/draco.py +0 -174
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/export.py +0 -122
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/image_data.py +0 -80
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/user_extensions.py +0 -17
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/imp/__init__.py +0 -5
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/imp/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/imp/__pycache__/gltf2_io_binary.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/imp/__pycache__/gltf2_io_gltf.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/imp/__pycache__/user_extensions.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/imp/gltf2_io_binary.py +0 -215
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/imp/gltf2_io_gltf.py +0 -198
- package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/imp/user_extensions.py +0 -13
- package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/README.md +0 -5
- package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/__init__.py +0 -64
- package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/interface.py +0 -526
- package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/operators.py +0 -2421
- package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/preferences.py +0 -398
- package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/utils/constants.py +0 -192
- package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/utils/draw.py +0 -219
- package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/utils/nodes.py +0 -299
- package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/utils/paths.py +0 -169
- package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/utils/paths_test.py +0 -290
- package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__init__.py +0 -56
- package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__pycache__/asset_browser.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__pycache__/functions.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__pycache__/gui.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__pycache__/keymaps.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__pycache__/operators.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__pycache__/pose_creation.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__pycache__/pose_usage.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/pose_library/asset_browser.py +0 -99
- package/staging_area/Blender/5.0/scripts/addons_core/pose_library/functions.py +0 -57
- package/staging_area/Blender/5.0/scripts/addons_core/pose_library/gui.py +0 -229
- package/staging_area/Blender/5.0/scripts/addons_core/pose_library/keymaps.py +0 -29
- package/staging_area/Blender/5.0/scripts/addons_core/pose_library/operators.py +0 -299
- package/staging_area/Blender/5.0/scripts/addons_core/pose_library/pose_creation.py +0 -413
- package/staging_area/Blender/5.0/scripts/addons_core/pose_library/pose_usage.py +0 -85
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/__init__.py +0 -907
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/base_generate.py +0 -536
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/base_rig.py +0 -351
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/feature_set_list.py +0 -357
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/feature_sets/__init__.py +0 -16
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/generate.py +0 -762
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarig_menu.py +0 -271
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/Animals/__init__.py +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/Animals/bird.py +0 -1397
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/Animals/cat.py +0 -2854
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/Animals/horse.py +0 -1401
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/Animals/shark.py +0 -692
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/Animals/wolf.py +0 -3088
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/Basic/basic_human.py +0 -618
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/Basic/basic_quadruped.py +0 -715
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/__init__.py +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/human.py +0 -2625
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/operators/__init__.py +0 -34
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/operators/action_layers.py +0 -658
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/operators/copy_mirror_parameters.py +0 -316
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/operators/generic_ui_list.py +0 -191
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/operators/upgrade_face.py +0 -457
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rig_lists.py +0 -116
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rig_ui_template.py +0 -1445
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/__init__.py +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/basic/__init__.py +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/basic/copy_chain.py +0 -167
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/basic/pivot.py +0 -242
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/basic/raw_copy.py +0 -228
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/basic/super_copy.py +0 -191
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/chain_rigs.py +0 -388
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/experimental/__init__.py +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/experimental/super_chain.py +0 -853
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/face/basic_tongue.py +0 -195
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/face/skin_eye.py +0 -843
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/face/skin_jaw.py +0 -880
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/faces/__init__.py +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/faces/super_face.py +0 -2378
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/__init__.py +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/arm.py +0 -209
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/front_paw.py +0 -270
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/leg.py +0 -746
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/limb_rigs.py +0 -1287
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/limb_utils.py +0 -78
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/paw.py +0 -360
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/rear_paw.py +0 -172
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/simple_tentacle.py +0 -169
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/spline_tentacle.py +0 -1486
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/super_finger.py +0 -699
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/super_limb.py +0 -46
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/super_palm.py +0 -426
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/skin/anchor.py +0 -142
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/skin/basic_chain.py +0 -565
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/skin/glue.py +0 -325
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/skin/skin_nodes.py +0 -604
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/skin/skin_parents.py +0 -505
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/skin/skin_rigs.py +0 -250
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/skin/stretchy_chain.py +0 -422
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/skin/transform/basic.py +0 -141
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/spines/__init__.py +0 -0
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/spines/basic_spine.py +0 -387
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/spines/basic_tail.py +0 -242
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/spines/spine_rigs.py +0 -295
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/spines/super_head.py +0 -424
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/spines/super_spine.py +0 -150
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/utils.py +0 -175
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/widgets.py +0 -483
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/rot_mode.py +0 -311
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/ui.py +0 -1834
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/__init__.py +0 -40
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/action_layers.py +0 -454
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/animation.py +0 -1024
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/bones.py +0 -742
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/collections.py +0 -83
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/components.py +0 -102
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/errors.py +0 -28
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/layers.py +0 -396
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/mechanism.py +0 -669
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/metaclass.py +0 -170
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/misc.py +0 -533
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/naming.py +0 -366
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/node_merger.py +0 -345
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/objects.py +0 -206
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/rig.py +0 -747
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/switch_parent.py +0 -533
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/widgets.py +0 -531
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/widgets_basic.py +0 -305
- package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/widgets_special.py +0 -226
- package/staging_area/Blender/5.0/scripts/addons_core/ui_translate/__init__.py +0 -60
- package/staging_area/Blender/5.0/scripts/addons_core/ui_translate/settings.py +0 -194
- package/staging_area/Blender/5.0/scripts/addons_core/ui_translate/update_addon.py +0 -378
- package/staging_area/Blender/5.0/scripts/addons_core/ui_translate/update_repo.py +0 -248
- package/staging_area/Blender/5.0/scripts/addons_core/ui_translate/update_ui.py +0 -267
- package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/__init__.py +0 -55
- package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/action_map.py +0 -177
- package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/action_map_io.py +0 -346
- package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/configs/default.py +0 -434
- package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/defaults.py +0 -1587
- package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/gui.py +0 -295
- package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/operators.py +0 -540
- package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/preferences.py +0 -67
- package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/properties.py +0 -228
- package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/versioning.py +0 -38
- package/staging_area/Blender/5.0/scripts/freestyle/modules/freestyle/__init__.py +0 -14
- package/staging_area/Blender/5.0/scripts/freestyle/modules/freestyle/chainingiterators.py +0 -644
- package/staging_area/Blender/5.0/scripts/freestyle/modules/freestyle/functions.py +0 -313
- package/staging_area/Blender/5.0/scripts/freestyle/modules/freestyle/predicates.py +0 -670
- package/staging_area/Blender/5.0/scripts/freestyle/modules/freestyle/shaders.py +0 -1248
- package/staging_area/Blender/5.0/scripts/freestyle/modules/freestyle/types.py +0 -159
- package/staging_area/Blender/5.0/scripts/freestyle/modules/freestyle/utils.py +0 -541
- package/staging_area/Blender/5.0/scripts/freestyle/modules/parameter_editor.py +0 -1589
- package/staging_area/Blender/5.0/scripts/freestyle/styles/anisotropic_diffusion.py +0 -41
- package/staging_area/Blender/5.0/scripts/freestyle/styles/apriori_and_causal_density.py +0 -34
- package/staging_area/Blender/5.0/scripts/freestyle/styles/apriori_density.py +0 -33
- package/staging_area/Blender/5.0/scripts/freestyle/styles/backbone_stretcher.py +0 -28
- package/staging_area/Blender/5.0/scripts/freestyle/styles/blueprint_circles.py +0 -39
- package/staging_area/Blender/5.0/scripts/freestyle/styles/blueprint_ellipses.py +0 -39
- package/staging_area/Blender/5.0/scripts/freestyle/styles/blueprint_squares.py +0 -40
- package/staging_area/Blender/5.0/scripts/freestyle/styles/cartoon.py +0 -32
- package/staging_area/Blender/5.0/scripts/freestyle/styles/contour.py +0 -33
- package/staging_area/Blender/5.0/scripts/freestyle/styles/curvature2d.py +0 -29
- package/staging_area/Blender/5.0/scripts/freestyle/styles/external_contour.py +0 -33
- package/staging_area/Blender/5.0/scripts/freestyle/styles/external_contour_sketchy.py +0 -39
- package/staging_area/Blender/5.0/scripts/freestyle/styles/external_contour_smooth.py +0 -37
- package/staging_area/Blender/5.0/scripts/freestyle/styles/haloing.py +0 -43
- package/staging_area/Blender/5.0/scripts/freestyle/styles/ignore_small_occlusions.py +0 -30
- package/staging_area/Blender/5.0/scripts/freestyle/styles/invisible_lines.py +0 -32
- package/staging_area/Blender/5.0/scripts/freestyle/styles/japanese_bigbrush.py +0 -53
- package/staging_area/Blender/5.0/scripts/freestyle/styles/long_anisotropically_dense.py +0 -67
- package/staging_area/Blender/5.0/scripts/freestyle/styles/multiple_parameterization.py +0 -41
- package/staging_area/Blender/5.0/scripts/freestyle/styles/nature.py +0 -32
- package/staging_area/Blender/5.0/scripts/freestyle/styles/near_lines.py +0 -32
- package/staging_area/Blender/5.0/scripts/freestyle/styles/occluded_by_specific_object.py +0 -36
- package/staging_area/Blender/5.0/scripts/freestyle/styles/polygonalize.py +0 -32
- package/staging_area/Blender/5.0/scripts/freestyle/styles/qi0.py +0 -31
- package/staging_area/Blender/5.0/scripts/freestyle/styles/qi0_not_external_contour.py +0 -38
- package/staging_area/Blender/5.0/scripts/freestyle/styles/qi1.py +0 -32
- package/staging_area/Blender/5.0/scripts/freestyle/styles/qi2.py +0 -32
- package/staging_area/Blender/5.0/scripts/freestyle/styles/sequentialsplit_sketchy.py +0 -39
- package/staging_area/Blender/5.0/scripts/freestyle/styles/sketchy_multiple_parameterization.py +0 -37
- package/staging_area/Blender/5.0/scripts/freestyle/styles/sketchy_topology_broken.py +0 -39
- package/staging_area/Blender/5.0/scripts/freestyle/styles/sketchy_topology_preserved.py +0 -36
- package/staging_area/Blender/5.0/scripts/freestyle/styles/split_at_highest_2d_curvatures.py +0 -34
- package/staging_area/Blender/5.0/scripts/freestyle/styles/split_at_tvertices.py +0 -33
- package/staging_area/Blender/5.0/scripts/freestyle/styles/suggestive.py +0 -33
- package/staging_area/Blender/5.0/scripts/freestyle/styles/thickness_fof_depth_discontinuity.py +0 -32
- package/staging_area/Blender/5.0/scripts/freestyle/styles/tipremover.py +0 -32
- package/staging_area/Blender/5.0/scripts/freestyle/styles/tvertex_remover.py +0 -32
- package/staging_area/Blender/5.0/scripts/freestyle/styles/uniformpruning_zsort.py +0 -31
- package/staging_area/Blender/5.0/scripts/modules/__pycache__/_bpy_restrict_state.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/__pycache__/_bpy_types.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/__pycache__/_console_python.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/__pycache__/_keyingsets_utils.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/__pycache__/_rna_xml.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/__pycache__/addon_utils.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/__pycache__/bl_app_template_utils.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/__pycache__/nodeitems_utils.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/__pycache__/rna_keymap_ui.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/__pycache__/rna_prop_ui.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/_animsys_refactor.py +0 -230
- package/staging_area/Blender/5.0/scripts/modules/_bl_console_utils/__init__.py +0 -7
- package/staging_area/Blender/5.0/scripts/modules/_bl_console_utils/autocomplete/__init__.py +0 -7
- package/staging_area/Blender/5.0/scripts/modules/_bl_console_utils/autocomplete/complete_calltip.py +0 -174
- package/staging_area/Blender/5.0/scripts/modules/_bl_console_utils/autocomplete/complete_import.py +0 -180
- package/staging_area/Blender/5.0/scripts/modules/_bl_console_utils/autocomplete/complete_namespace.py +0 -192
- package/staging_area/Blender/5.0/scripts/modules/_bl_console_utils/autocomplete/intellisense.py +0 -138
- package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/__init__.py +0 -5
- package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/bl_extract_messages.py +0 -1363
- package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/merge_po.py +0 -132
- package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/settings.py +0 -824
- package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/settings_user.py +0 -7
- package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/utils.py +0 -1709
- package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/utils_cli.py +0 -144
- package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/utils_languages_menu.py +0 -68
- package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/utils_rtl.py +0 -179
- package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/utils_spell_check.py +0 -955
- package/staging_area/Blender/5.0/scripts/modules/_bl_previews_utils/bl_previews_render.py +0 -537
- package/staging_area/Blender/5.0/scripts/modules/_bl_rna_utils/__init__.py +0 -0
- package/staging_area/Blender/5.0/scripts/modules/_bl_rna_utils/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/_bl_rna_utils/__pycache__/data_path.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/_bl_rna_utils/data_path.py +0 -76
- package/staging_area/Blender/5.0/scripts/modules/_bl_text_utils/__init__.py +0 -0
- package/staging_area/Blender/5.0/scripts/modules/_bl_text_utils/external_editor.py +0 -54
- package/staging_area/Blender/5.0/scripts/modules/_bl_ui_utils/__init__.py +0 -0
- package/staging_area/Blender/5.0/scripts/modules/_bl_ui_utils/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/_bl_ui_utils/__pycache__/layout.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/_bl_ui_utils/layout.py +0 -21
- package/staging_area/Blender/5.0/scripts/modules/_blendfile_header.py +0 -234
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/__init__.py +0 -3
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/addons/__init__.py +0 -3
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/addons/cli.py +0 -42
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/assets/__init__.py +0 -3
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/assets/remote_library_listing/__init__.py +0 -3
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/assets/remote_library_listing/blender_asset_library_openapi.py +0 -98
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/assets/remote_library_listing/blender_asset_library_openapi.yaml +0 -83
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/__init__.py +0 -3
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/__pycache__/junction_module.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/__pycache__/wheel_manager.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/junction_module.py +0 -165
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/permissions.py +0 -16
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/stale_file_manager.py +0 -417
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/tags.py +0 -54
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/wheel_manager.py +0 -686
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/freedesktop.py +0 -598
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/grease_pencil/__init__.py +0 -3
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/grease_pencil/stroke.py +0 -402
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/http/__init__.py +0 -3
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/http/downloader.py +0 -1348
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/system_info/text_generate_runtime.py +0 -256
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/system_info/url_prefill_runtime.py +0 -60
- package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/system_info/url_prefill_startup.py +0 -107
- package/staging_area/Blender/5.0/scripts/modules/_bpy_restrict_state.py +0 -50
- package/staging_area/Blender/5.0/scripts/modules/_bpy_types.py +0 -1563
- package/staging_area/Blender/5.0/scripts/modules/_console_python.py +0 -368
- package/staging_area/Blender/5.0/scripts/modules/_console_shell.py +0 -73
- package/staging_area/Blender/5.0/scripts/modules/_graphviz_export.py +0 -194
- package/staging_area/Blender/5.0/scripts/modules/_keyingsets_utils.py +0 -355
- package/staging_area/Blender/5.0/scripts/modules/_rna_info.py +0 -984
- package/staging_area/Blender/5.0/scripts/modules/_rna_manual_reference.py +0 -4446
- package/staging_area/Blender/5.0/scripts/modules/_rna_xml.py +0 -422
- package/staging_area/Blender/5.0/scripts/modules/addon_utils.py +0 -1992
- package/staging_area/Blender/5.0/scripts/modules/bl_app_override/__init__.py +0 -211
- package/staging_area/Blender/5.0/scripts/modules/bl_app_override/helpers.py +0 -153
- package/staging_area/Blender/5.0/scripts/modules/bl_app_template_utils.py +0 -177
- package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/__init__.py +0 -9
- package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/__pycache__/io.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/__pycache__/keymap_from_toolbar.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/__pycache__/keymap_hierarchy.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/io.py +0 -308
- package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py +0 -394
- package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/keymap_hierarchy.py +0 -247
- package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/platform_helpers.py +0 -55
- package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/versioning.py +0 -328
- package/staging_area/Blender/5.0/scripts/modules/blend_render_info.py +0 -123
- package/staging_area/Blender/5.0/scripts/modules/bpy/__init__.py +0 -75
- package/staging_area/Blender/5.0/scripts/modules/bpy/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/bpy/__pycache__/ops.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/bpy/__pycache__/path.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/bpy/ops.py +0 -184
- package/staging_area/Blender/5.0/scripts/modules/bpy/path.py +0 -459
- package/staging_area/Blender/5.0/scripts/modules/bpy/utils/__init__.py +0 -1382
- package/staging_area/Blender/5.0/scripts/modules/bpy/utils/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/bpy/utils/__pycache__/previews.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/bpy/utils/previews.py +0 -136
- package/staging_area/Blender/5.0/scripts/modules/bpy/utils/toolsystem.py +0 -11
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/__init__.py +0 -20
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/__pycache__/asset_utils.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/__pycache__/io_utils.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/__pycache__/node_utils.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/__pycache__/object_utils.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/anim_utils.py +0 -1038
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/asset_utils.py +0 -50
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/bmesh_utils.py +0 -56
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/id_map_utils.py +0 -53
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/image_utils.py +0 -194
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/io_utils.py +0 -620
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/keyconfig_utils.py +0 -141
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/mesh_utils.py +0 -464
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/node_shader_utils.py +0 -829
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/node_utils.py +0 -88
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/object_utils.py +0 -289
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/view3d_utils.py +0 -181
- package/staging_area/Blender/5.0/scripts/modules/bpy_extras/wm_utils/progress_report.py +0 -160
- package/staging_area/Blender/5.0/scripts/modules/gpu_extras/__init__.py +0 -8
- package/staging_area/Blender/5.0/scripts/modules/gpu_extras/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/gpu_extras/__pycache__/presets.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/modules/gpu_extras/batch.py +0 -80
- package/staging_area/Blender/5.0/scripts/modules/gpu_extras/presets.py +0 -102
- package/staging_area/Blender/5.0/scripts/modules/nodeitems_utils.py +0 -178
- package/staging_area/Blender/5.0/scripts/modules/rna_keymap_ui.py +0 -505
- package/staging_area/Blender/5.0/scripts/modules/rna_prop_ui.py +0 -269
- package/staging_area/Blender/5.0/scripts/presets/camera/1_inch.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/1_slash_1.8_inch.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/1_slash_2.3_inch.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/1_slash_2.5_inch.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/1_slash_2.7_inch.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/1_slash_3.2_inch.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/2_slash_3_inch.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/APS-C.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/APS-C_(Canon).py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/APS-H_(Canon).py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/Analog_16mm.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/Analog_35mm.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/Analog_65mm.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/Analog_IMAX.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/Analog_Super_16.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/Analog_Super_35.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/Arri_Alexa_65.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/Arri_Alexa_LF.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/Arri_Alexa_Mini_&_SXT.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/Blackmagic_Pocket_&_Studio.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/Blackmagic_Pocket_4K.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/Blackmagic_Pocket_6k.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/Blackmagic_URSA_4.6K.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/Foveon_(Sigma).py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/Fullframe.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/MFT.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/Medium-format_(Hasselblad).py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/RED_Dragon_5K.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/RED_Dragon_6K.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/RED_Helium_8K.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/camera/RED_Monstro_8K.py +0 -4
- package/staging_area/Blender/5.0/scripts/presets/cloth/Cotton.py +0 -25
- package/staging_area/Blender/5.0/scripts/presets/cloth/Denim.py +0 -25
- package/staging_area/Blender/5.0/scripts/presets/cloth/Leather.py +0 -25
- package/staging_area/Blender/5.0/scripts/presets/cloth/Rubber.py +0 -25
- package/staging_area/Blender/5.0/scripts/presets/cloth/Silk.py +0 -25
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_A.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_B.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_C.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_D50.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_D55.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_D65.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_D75.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_D93.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_E.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F1.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F10.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F11.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F12.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F2.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F3.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F4.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F5.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F6.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F7.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F8.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F9.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-B1.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-B2.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-B3.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-B4.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-B5.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-BH1.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-RGB1.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-V1.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-V2.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/cycles/integrator/Default.py +0 -14
- package/staging_area/Blender/5.0/scripts/presets/cycles/integrator/Direct_Light.py +0 -14
- package/staging_area/Blender/5.0/scripts/presets/cycles/integrator/Fast_Global_Illumination.py +0 -14
- package/staging_area/Blender/5.0/scripts/presets/cycles/integrator/Full_Global_Illumination.py +0 -14
- package/staging_area/Blender/5.0/scripts/presets/cycles/integrator/Limited_Global_Illumination.py +0 -14
- package/staging_area/Blender/5.0/scripts/presets/cycles/performance/Default.py +0 -11
- package/staging_area/Blender/5.0/scripts/presets/cycles/performance/Faster_Render.py +0 -11
- package/staging_area/Blender/5.0/scripts/presets/cycles/performance/Lower_Memory.py +0 -11
- package/staging_area/Blender/5.0/scripts/presets/cycles/sampling/Final.py +0 -12
- package/staging_area/Blender/5.0/scripts/presets/cycles/sampling/Preview.py +0 -12
- package/staging_area/Blender/5.0/scripts/presets/cycles/viewport_sampling/Final.py +0 -11
- package/staging_area/Blender/5.0/scripts/presets/cycles/viewport_sampling/Preview.py +0 -11
- package/staging_area/Blender/5.0/scripts/presets/eevee/raytracing/Default.py +0 -22
- package/staging_area/Blender/5.0/scripts/presets/ffmpeg/DVD_(note_colon__this_changes_render_resolution).py +0 -24
- package/staging_area/Blender/5.0/scripts/presets/ffmpeg/H264_in_MP4.py +0 -18
- package/staging_area/Blender/5.0/scripts/presets/ffmpeg/H264_in_Matroska.py +0 -17
- package/staging_area/Blender/5.0/scripts/presets/ffmpeg/H264_in_Matroska_for_scrubbing.py +0 -14
- package/staging_area/Blender/5.0/scripts/presets/ffmpeg/Ogg_Theora.py +0 -18
- package/staging_area/Blender/5.0/scripts/presets/ffmpeg/WebM_(VP9+Opus).py +0 -9
- package/staging_area/Blender/5.0/scripts/presets/ffmpeg/Xvid.py +0 -18
- package/staging_area/Blender/5.0/scripts/presets/fluid/Honey.py +0 -3
- package/staging_area/Blender/5.0/scripts/presets/fluid/Oil.py +0 -3
- package/staging_area/Blender/5.0/scripts/presets/fluid/Water.py +0 -3
- package/staging_area/Blender/5.0/scripts/presets/framerate/12.py +0 -3
- package/staging_area/Blender/5.0/scripts/presets/framerate/120.py +0 -3
- package/staging_area/Blender/5.0/scripts/presets/framerate/23.98.py +0 -3
- package/staging_area/Blender/5.0/scripts/presets/framerate/24.py +0 -3
- package/staging_area/Blender/5.0/scripts/presets/framerate/240.py +0 -3
- package/staging_area/Blender/5.0/scripts/presets/framerate/25.py +0 -3
- package/staging_area/Blender/5.0/scripts/presets/framerate/29.97.py +0 -3
- package/staging_area/Blender/5.0/scripts/presets/framerate/30.py +0 -3
- package/staging_area/Blender/5.0/scripts/presets/framerate/50.py +0 -3
- package/staging_area/Blender/5.0/scripts/presets/framerate/59.94.py +0 -3
- package/staging_area/Blender/5.0/scripts/presets/framerate/6.py +0 -3
- package/staging_area/Blender/5.0/scripts/presets/framerate/60.py +0 -3
- package/staging_area/Blender/5.0/scripts/presets/framerate/8.py +0 -3
- package/staging_area/Blender/5.0/scripts/presets/framerate/Custom.py +0 -1
- package/staging_area/Blender/5.0/scripts/presets/framerate/__pycache__/30.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/presets/gpencil_material/Fill_Only.py +0 -25
- package/staging_area/Blender/5.0/scripts/presets/gpencil_material/Stroke_Only.py +0 -25
- package/staging_area/Blender/5.0/scripts/presets/gpencil_material/Stroke_and_Fill.py +0 -25
- package/staging_area/Blender/5.0/scripts/presets/hair_dynamics/Default.py +0 -17
- package/staging_area/Blender/5.0/scripts/presets/interface_theme/Blender_Dark.xml +0 -6
- package/staging_area/Blender/5.0/scripts/presets/interface_theme/Blender_Light.xml +0 -1246
- package/staging_area/Blender/5.0/scripts/presets/keyconfig/Blender.py +0 -384
- package/staging_area/Blender/5.0/scripts/presets/keyconfig/Blender_27x.py +0 -106
- package/staging_area/Blender/5.0/scripts/presets/keyconfig/Industry_Compatible.py +0 -41
- package/staging_area/Blender/5.0/scripts/presets/keyconfig/__pycache__/Blender.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/presets/keyconfig/keymap_data/__pycache__/blender_default.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/presets/keyconfig/keymap_data/blender_default.py +0 -9083
- package/staging_area/Blender/5.0/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +0 -3896
- package/staging_area/Blender/5.0/scripts/presets/pixel_density/Custom.py +0 -1
- package/staging_area/Blender/5.0/scripts/presets/pixel_density/Pixels_slash_Centimeter.py +0 -2
- package/staging_area/Blender/5.0/scripts/presets/pixel_density/Pixels_slash_Inch.py +0 -2
- package/staging_area/Blender/5.0/scripts/presets/pixel_density/Pixels_slash_Meter.py +0 -2
- package/staging_area/Blender/5.0/scripts/presets/render/4K_DCI_2160p.py +0 -8
- package/staging_area/Blender/5.0/scripts/presets/render/4K_UHDTV_2160p.py +0 -8
- package/staging_area/Blender/5.0/scripts/presets/render/4K_UW_1600p.py +0 -8
- package/staging_area/Blender/5.0/scripts/presets/render/DVCPRO_HD_1080p.py +0 -8
- package/staging_area/Blender/5.0/scripts/presets/render/DVCPRO_HD_720p.py +0 -8
- package/staging_area/Blender/5.0/scripts/presets/render/HDTV_1080p.py +0 -8
- package/staging_area/Blender/5.0/scripts/presets/render/HDTV_720p.py +0 -8
- package/staging_area/Blender/5.0/scripts/presets/render/HDV_1080p.py +0 -8
- package/staging_area/Blender/5.0/scripts/presets/render/HDV_NTSC_1080p.py +0 -8
- package/staging_area/Blender/5.0/scripts/presets/render/HDV_PAL_1080p.py +0 -8
- package/staging_area/Blender/5.0/scripts/presets/render/TV_NTSC_16_colon_9.py +0 -8
- package/staging_area/Blender/5.0/scripts/presets/render/TV_NTSC_4_colon_3.py +0 -8
- package/staging_area/Blender/5.0/scripts/presets/render/TV_PAL_16_colon_9.py +0 -8
- package/staging_area/Blender/5.0/scripts/presets/render/TV_PAL_4_colon_3.py +0 -8
- package/staging_area/Blender/5.0/scripts/presets/safe_areas/14_colon_9_in_16_colon_9.py +0 -7
- package/staging_area/Blender/5.0/scripts/presets/safe_areas/16_colon_9.py +0 -7
- package/staging_area/Blender/5.0/scripts/presets/safe_areas/4_colon_3_in_16_colon_9.py +0 -7
- package/staging_area/Blender/5.0/scripts/presets/text_editor/Internal.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/text_editor/Visual_Studio_Code.py +0 -12
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/1_inch.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/1_slash_1.8_inch.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/1_slash_2.3_inch.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/1_slash_2.5_inch.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/1_slash_2.7_inch.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/1_slash_3.2_inch.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/2_slash_3_inch.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/APS-C.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/APS-C_(Canon).py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/APS-H_(Canon).py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Analog_16mm.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Analog_35mm.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Analog_65mm.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Analog_IMAX.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Analog_Super_16.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Analog_Super_35.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Arri_Alexa_65.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Arri_Alexa_LF.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Arri_Alexa_Mini_&_SXT.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Blackmagic_Pocket_&_Studio.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Blackmagic_Pocket_4K.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Blackmagic_Pocket_6k.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Blackmagic_URSA_4.6K.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Foveon_(Sigma).py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Fullframe.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/MFT.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Medium-format_(Hasselblad).py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/RED_Dragon_5K.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/RED_Dragon_6K.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/RED_Helium_8K.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_camera/RED_Monstro_8K.py +0 -6
- package/staging_area/Blender/5.0/scripts/presets/tracking_settings/Blurry_Footage.py +0 -18
- package/staging_area/Blender/5.0/scripts/presets/tracking_settings/Default.py +0 -18
- package/staging_area/Blender/5.0/scripts/presets/tracking_settings/Fast_Motion.py +0 -18
- package/staging_area/Blender/5.0/scripts/presets/tracking_settings/Planar.py +0 -18
- package/staging_area/Blender/5.0/scripts/presets/tracking_track_color/Default.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/tracking_track_color/Far_Plane.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/tracking_track_color/Near_Plane.py +0 -5
- package/staging_area/Blender/5.0/scripts/presets/tracking_track_color/Object.py +0 -5
- package/staging_area/Blender/5.0/scripts/startup/__pycache__/keyingsets_builtins.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/__pycache__/nodeitems_builtins.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/2D_Animation/__init__.py +0 -56
- package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/2D_Animation/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/2D_Animation/startup.blend +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/Sculpting/__init__.py +0 -30
- package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/Sculpting/startup.blend +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/Storyboarding/__init__.py +0 -51
- package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/Storyboarding/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/Storyboarding/startup.blend +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/VFX/startup.blend +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/Video_Editing/__init__.py +0 -51
- package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/Video_Editing/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/Video_Editing/startup.blend +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__init__.py +0 -88
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/add_mesh_torus.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/anim.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/assets.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/bone_selection_sets.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/clip.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/connect_to_output.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/console.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/constraint.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/copy_global_transform.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/file.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/freestyle.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/geometry_nodes.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/grease_pencil.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/image.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/image_as_planes.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/mesh.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/node.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/object.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/object_align.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/object_quick_effects.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/object_randomize_transform.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/presets.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/rigidbody.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/screen_play_rendered_anim.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/sequencer.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/spreadsheet.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/userpref.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/uvcalc_follow_active.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/uvcalc_lightmap.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/uvcalc_transform.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/vertexpaint_dirt.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/view3d.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/wm.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/world.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/add_mesh_torus.py +0 -262
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/anim.py +0 -924
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/assets.py +0 -157
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/bmesh/find_adjacent.py +0 -341
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/bone_selection_sets.py +0 -439
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/clip.py +0 -1044
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/connect_to_output.py +0 -360
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/console.py +0 -156
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/constraint.py +0 -121
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/copy_global_transform.py +0 -823
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/file.py +0 -308
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/freestyle.py +0 -226
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/geometry_nodes.py +0 -394
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/grease_pencil.py +0 -63
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/image.py +0 -322
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/image_as_planes.py +0 -1216
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/mesh.py +0 -61
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/node.py +0 -1340
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/node_editor/__pycache__/node_functions.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/node_editor/node_functions.py +0 -97
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/object.py +0 -1014
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/object_align.py +0 -407
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/object_quick_effects.py +0 -680
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/object_randomize_transform.py +0 -181
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/presets.py +0 -1057
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/rigidbody.py +0 -323
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/screen_play_rendered_anim.py +0 -219
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/sequencer.py +0 -438
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/spreadsheet.py +0 -46
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/userpref.py +0 -1324
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/uvcalc_follow_active.py +0 -313
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/uvcalc_lightmap.py +0 -688
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/uvcalc_transform.py +0 -551
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/vertexpaint_dirt.py +0 -198
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/view3d.py +0 -316
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/wm.py +0 -3722
- package/staging_area/Blender/5.0/scripts/startup/bl_operators/world.py +0 -168
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__init__.py +0 -299
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/__init__.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/anim.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/asset_shelf.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/generic_ui_list.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/node_add_menu.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/node_add_menu_compositor.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/node_add_menu_geometry.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/node_add_menu_shader.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/node_add_menu_texture.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_animviz.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_collection.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_constraint.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_armature.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_bone.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_camera.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_curve.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_curves.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_empty.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_grease_pencil.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_lattice.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_light.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_lightprobe.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_mesh.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_metaball.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_modifier.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_pointcloud.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_shaderfx.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_speaker.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_volume.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_freestyle.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_grease_pencil_common.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_mask_common.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_material.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_material_gpencil.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_object.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_output.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_paint_common.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_particle.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_cloth.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_common.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_dynamicpaint.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_field.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_fluid.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_geometry_nodes.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_rigidbody.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_rigidbody_constraint.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_softbody.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_render.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_scene.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_strip.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_strip_modifier.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_texture.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_view_layer.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_workspace.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_world.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_clip.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_console.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_dopesheet.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_filebrowser.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_graph.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_image.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_info.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_nla.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_node.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_outliner.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_properties.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_sequencer.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_spreadsheet.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_statusbar.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_text.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_time.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_toolsystem_common.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_toolsystem_toolbar.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_topbar.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_userpref.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_view3d.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_view3d_sidebar.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_view3d_toolbar.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/utils.cpython-311.pyc +0 -0
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/anim.py +0 -62
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/asset_shelf.py +0 -41
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/generic_ui_list.py +0 -262
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/node_add_menu.py +0 -505
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/node_add_menu_compositor.py +0 -437
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/node_add_menu_geometry.py +0 -1158
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/node_add_menu_shader.py +0 -511
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/node_add_menu_texture.py +0 -167
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_animviz.py +0 -123
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_collection.py +0 -146
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_constraint.py +0 -1793
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_armature.py +0 -436
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_bone.py +0 -625
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_camera.py +0 -603
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_curve.py +0 -461
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_curves.py +0 -219
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_empty.py +0 -84
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_grease_pencil.py +0 -536
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_lattice.py +0 -105
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_light.py +0 -315
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_lightprobe.py +0 -413
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_mesh.py +0 -744
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_metaball.py +0 -137
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_modifier.py +0 -323
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_pointcloud.py +0 -175
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_shaderfx.py +0 -31
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_speaker.py +0 -157
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_volume.py +0 -239
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_freestyle.py +0 -1343
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_grease_pencil_common.py +0 -607
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_mask_common.py +0 -461
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_material.py +0 -460
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_material_gpencil.py +0 -272
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_object.py +0 -656
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_output.py +0 -736
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_paint_common.py +0 -1904
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_particle.py +0 -2308
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_cloth.py +0 -524
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_common.py +0 -360
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +0 -974
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_field.py +0 -487
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_fluid.py +0 -1629
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_geometry_nodes.py +0 -64
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_rigidbody.py +0 -345
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py +0 -554
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_softbody.py +0 -471
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_render.py +0 -1180
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_scene.py +0 -495
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_strip.py +0 -1056
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_strip_modifier.py +0 -49
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_texture.py +0 -997
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_view_layer.py +0 -348
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_workspace.py +0 -195
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_world.py +0 -282
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_clip.py +0 -2112
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_console.py +0 -157
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_dopesheet.py +0 -1123
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_filebrowser.py +0 -950
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_graph.py +0 -615
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_image.py +0 -1896
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_info.py +0 -117
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_nla.py +0 -429
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_node.py +0 -1247
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_outliner.py +0 -559
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_properties.py +0 -205
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_sequencer.py +0 -2097
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_spreadsheet.py +0 -83
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_statusbar.py +0 -41
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_text.py +0 -479
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_time.py +0 -364
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_toolsystem_common.py +0 -1256
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_toolsystem_toolbar.py +0 -4123
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_topbar.py +0 -891
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_userpref.py +0 -3108
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_view3d.py +0 -9421
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_view3d_sidebar.py +0 -183
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_view3d_toolbar.py +0 -2438
- package/staging_area/Blender/5.0/scripts/startup/bl_ui/utils.py +0 -40
- package/staging_area/Blender/5.0/scripts/startup/keyingsets_builtins.py +0 -686
- package/staging_area/Blender/5.0/scripts/startup/nodeitems_builtins.py +0 -54
- package/staging_area/Blender/5.0/scripts/templates_osl/advanced_camera.osl +0 -76
- package/staging_area/Blender/5.0/scripts/templates_osl/basic_camera.osl +0 -14
- package/staging_area/Blender/5.0/scripts/templates_osl/basic_shader.osl +0 -10
- package/staging_area/Blender/5.0/scripts/templates_osl/cubemap_camera.osl +0 -42
- package/staging_area/Blender/5.0/scripts/templates_osl/empty_shader.osl +0 -6
- package/staging_area/Blender/5.0/scripts/templates_osl/gabor_noise.osl +0 -17
- package/staging_area/Blender/5.0/scripts/templates_osl/lyapunov_texture.osl +0 -141
- package/staging_area/Blender/5.0/scripts/templates_osl/noise.osl +0 -27
- package/staging_area/Blender/5.0/scripts/templates_osl/ramp_closure.osl +0 -20
- package/staging_area/Blender/5.0/scripts/templates_py/addon_add_object.py +0 -84
- package/staging_area/Blender/5.0/scripts/templates_py/background_job.py +0 -118
- package/staging_area/Blender/5.0/scripts/templates_py/batch_export.py +0 -42
- package/staging_area/Blender/5.0/scripts/templates_py/bmesh_simple.py +0 -22
- package/staging_area/Blender/5.0/scripts/templates_py/bmesh_simple_editmode.py +0 -23
- package/staging_area/Blender/5.0/scripts/templates_py/builtin_keyingset.py +0 -37
- package/staging_area/Blender/5.0/scripts/templates_py/custom_nodes.py +0 -172
- package/staging_area/Blender/5.0/scripts/templates_py/driver_functions.py +0 -35
- package/staging_area/Blender/5.0/scripts/templates_py/external_script_stub.py +0 -13
- package/staging_area/Blender/5.0/scripts/templates_py/gizmo_custom_geometry.py +0 -157
- package/staging_area/Blender/5.0/scripts/templates_py/gizmo_operator.py +0 -235
- package/staging_area/Blender/5.0/scripts/templates_py/gizmo_operator_target.py +0 -50
- package/staging_area/Blender/5.0/scripts/templates_py/gizmo_simple_2d.py +0 -59
- package/staging_area/Blender/5.0/scripts/templates_py/gizmo_simple_3d.py +0 -47
- package/staging_area/Blender/5.0/scripts/templates_py/image_processing.py +0 -35
- package/staging_area/Blender/5.0/scripts/templates_py/operator_file_export.py +0 -76
- package/staging_area/Blender/5.0/scripts/templates_py/operator_file_import.py +0 -79
- package/staging_area/Blender/5.0/scripts/templates_py/operator_mesh_add.py +0 -116
- package/staging_area/Blender/5.0/scripts/templates_py/operator_mesh_uv.py +0 -56
- package/staging_area/Blender/5.0/scripts/templates_py/operator_modal.py +0 -58
- package/staging_area/Blender/5.0/scripts/templates_py/operator_modal_draw.py +0 -83
- package/staging_area/Blender/5.0/scripts/templates_py/operator_modal_timer.py +0 -54
- package/staging_area/Blender/5.0/scripts/templates_py/operator_modal_view3d.py +0 -77
- package/staging_area/Blender/5.0/scripts/templates_py/operator_modal_view3d_raycast.py +0 -115
- package/staging_area/Blender/5.0/scripts/templates_py/operator_node.py +0 -66
- package/staging_area/Blender/5.0/scripts/templates_py/operator_simple.py +0 -42
- package/staging_area/Blender/5.0/scripts/templates_py/ui_asset_shelf.py +0 -29
- package/staging_area/Blender/5.0/scripts/templates_py/ui_list.py +0 -44
- package/staging_area/Blender/5.0/scripts/templates_py/ui_list_generic.py +0 -47
- package/staging_area/Blender/5.0/scripts/templates_py/ui_list_simple.py +0 -70
- package/staging_area/Blender/5.0/scripts/templates_py/ui_menu.py +0 -50
- package/staging_area/Blender/5.0/scripts/templates_py/ui_menu_simple.py +0 -27
- package/staging_area/Blender/5.0/scripts/templates_py/ui_panel.py +0 -73
- package/staging_area/Blender/5.0/scripts/templates_py/ui_panel_simple.py +0 -38
- package/staging_area/Blender/5.0/scripts/templates_py/ui_pie_menu.py +0 -31
- package/staging_area/Blender/5.0/scripts/templates_py/ui_previews_custom_icon.py +0 -76
- package/staging_area/Blender/5.0/scripts/templates_py/ui_previews_dynamic_enum.py +0 -141
- package/staging_area/Blender/5.0/scripts/templates_py/ui_tool_simple.py +0 -91
- package/staging_area/Blender/5.0/scripts/templates_toml/blender_manifest.toml +0 -75
- package/staging_area/Blender/blender-launcher.exe +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-console-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-console-l1-2-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-datetime-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-debug-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-errorhandling-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-fibers-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-file-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-file-l1-2-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-file-l2-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-handle-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-heap-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-interlocked-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-libraryloader-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-localization-l1-2-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-memory-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-namedpipe-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-processenvironment-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-processthreads-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-processthreads-l1-1-1.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-profile-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-rtlsupport-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-string-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-synch-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-synch-l1-2-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-sysinfo-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-timezone-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-core-util-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-crt-conio-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-crt-convert-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-crt-environment-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-crt-filesystem-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-crt-heap-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-crt-locale-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-crt-math-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-crt-multibyte-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-crt-private-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-crt-process-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-crt-runtime-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-crt-stdio-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-crt-string-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-crt-time-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/api-ms-win-crt-utility-l1-1-0.dll +0 -0
- package/staging_area/Blender/blender.crt/blender.crt.manifest +0 -54
- package/staging_area/Blender/blender.crt/concrt140.dll +0 -0
- package/staging_area/Blender/blender.crt/msvcp140.dll +0 -0
- package/staging_area/Blender/blender.crt/msvcp140_1.dll +0 -0
- package/staging_area/Blender/blender.crt/msvcp140_2.dll +0 -0
- package/staging_area/Blender/blender.crt/msvcp140_atomic_wait.dll +0 -0
- package/staging_area/Blender/blender.crt/msvcp140_codecvt_ids.dll +0 -0
- package/staging_area/Blender/blender.crt/vcruntime140.dll +0 -0
- package/staging_area/Blender/blender.crt/vcruntime140_1.dll +0 -0
|
@@ -1,3819 +0,0 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: 2013 Campbell Barton
|
|
2
|
-
# SPDX-FileCopyrightText: 2014 Bastien Montagne
|
|
3
|
-
#
|
|
4
|
-
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
5
|
-
|
|
6
|
-
import datetime
|
|
7
|
-
import math
|
|
8
|
-
import numpy as np
|
|
9
|
-
import os
|
|
10
|
-
import time
|
|
11
|
-
|
|
12
|
-
from itertools import zip_longest
|
|
13
|
-
from functools import cache
|
|
14
|
-
|
|
15
|
-
if "bpy" in locals():
|
|
16
|
-
import importlib
|
|
17
|
-
if "encode_bin" in locals():
|
|
18
|
-
importlib.reload(encode_bin)
|
|
19
|
-
if "data_types" in locals():
|
|
20
|
-
importlib.reload(data_types)
|
|
21
|
-
if "fbx_utils" in locals():
|
|
22
|
-
importlib.reload(fbx_utils)
|
|
23
|
-
|
|
24
|
-
import bpy
|
|
25
|
-
import bpy_extras
|
|
26
|
-
from bpy_extras import node_shader_utils
|
|
27
|
-
from bpy.app.translations import pgettext_tip as tip_
|
|
28
|
-
from mathutils import Vector, Matrix
|
|
29
|
-
|
|
30
|
-
from . import encode_bin, data_types, fbx_utils
|
|
31
|
-
from .fbx_utils import (
|
|
32
|
-
# Constants.
|
|
33
|
-
FBX_VERSION, FBX_HEADER_VERSION, FBX_SCENEINFO_VERSION, FBX_TEMPLATES_VERSION,
|
|
34
|
-
FBX_MODELS_VERSION,
|
|
35
|
-
FBX_GEOMETRY_VERSION, FBX_GEOMETRY_NORMAL_VERSION, FBX_GEOMETRY_BINORMAL_VERSION, FBX_GEOMETRY_TANGENT_VERSION,
|
|
36
|
-
FBX_GEOMETRY_SMOOTHING_VERSION, FBX_GEOMETRY_CREASE_VERSION, FBX_GEOMETRY_VCOLOR_VERSION, FBX_GEOMETRY_UV_VERSION,
|
|
37
|
-
FBX_GEOMETRY_MATERIAL_VERSION, FBX_GEOMETRY_LAYER_VERSION,
|
|
38
|
-
FBX_GEOMETRY_SHAPE_VERSION, FBX_DEFORMER_SHAPE_VERSION, FBX_DEFORMER_SHAPECHANNEL_VERSION,
|
|
39
|
-
FBX_POSE_BIND_VERSION, FBX_DEFORMER_SKIN_VERSION, FBX_DEFORMER_CLUSTER_VERSION,
|
|
40
|
-
FBX_MATERIAL_VERSION, FBX_TEXTURE_VERSION,
|
|
41
|
-
FBX_ANIM_KEY_VERSION,
|
|
42
|
-
FBX_ANIM_PROPSGROUP_NAME,
|
|
43
|
-
FBX_KTIME,
|
|
44
|
-
BLENDER_OTHER_OBJECT_TYPES, BLENDER_OBJECT_TYPES_MESHLIKE,
|
|
45
|
-
FBX_LIGHT_TYPES, FBX_LIGHT_DECAY_TYPES,
|
|
46
|
-
RIGHT_HAND_AXES, FBX_FRAMERATES,
|
|
47
|
-
# Miscellaneous utils.
|
|
48
|
-
PerfMon,
|
|
49
|
-
units_blender_to_fbx_factor, units_convertor, units_convertor_iter,
|
|
50
|
-
matrix4_to_array, similar_values, shape_difference_exclude_similar, astype_view_signedness, fast_first_axis_unique,
|
|
51
|
-
fast_first_axis_flat,
|
|
52
|
-
# Attribute helpers.
|
|
53
|
-
MESH_ATTRIBUTE_CORNER_EDGE, MESH_ATTRIBUTE_SHARP_EDGE, MESH_ATTRIBUTE_EDGE_VERTS, MESH_ATTRIBUTE_CORNER_VERT,
|
|
54
|
-
MESH_ATTRIBUTE_SHARP_FACE, MESH_ATTRIBUTE_POSITION, MESH_ATTRIBUTE_MATERIAL_INDEX,
|
|
55
|
-
# Mesh transform helpers.
|
|
56
|
-
vcos_transformed, nors_transformed,
|
|
57
|
-
# UUID from key.
|
|
58
|
-
get_fbx_uuid_from_key,
|
|
59
|
-
# Key generators.
|
|
60
|
-
get_blenderID_key, get_blenderID_name,
|
|
61
|
-
get_blender_mesh_shape_key, get_blender_mesh_shape_channel_key,
|
|
62
|
-
get_blender_empty_key, get_blender_bone_key,
|
|
63
|
-
get_blender_bindpose_key, get_blender_armature_skin_key, get_blender_bone_cluster_key,
|
|
64
|
-
get_blender_anim_id_base, get_blender_anim_stack_key, get_blender_anim_layer_key,
|
|
65
|
-
get_blender_anim_curve_node_key, get_blender_anim_curve_key,
|
|
66
|
-
get_blender_nodetexture_key,
|
|
67
|
-
# FBX element data.
|
|
68
|
-
elem_empty,
|
|
69
|
-
elem_data_single_char, elem_data_single_int16, elem_data_single_int32, elem_data_single_int64,
|
|
70
|
-
elem_data_single_float32, elem_data_single_float64,
|
|
71
|
-
elem_data_single_bytes, elem_data_single_string, elem_data_single_string_unicode,
|
|
72
|
-
elem_data_single_bool_array, elem_data_single_int32_array, elem_data_single_int64_array,
|
|
73
|
-
elem_data_single_float32_array, elem_data_single_float64_array, elem_data_vec_float64,
|
|
74
|
-
# FBX element properties.
|
|
75
|
-
elem_properties, elem_props_set, elem_props_compound,
|
|
76
|
-
# FBX element properties handling templates.
|
|
77
|
-
elem_props_template_init, elem_props_template_set, elem_props_template_finalize,
|
|
78
|
-
# Templates.
|
|
79
|
-
FBXTemplate, fbx_templates_generate,
|
|
80
|
-
# Animation.
|
|
81
|
-
AnimationCurveNodeWrapper,
|
|
82
|
-
# Objects.
|
|
83
|
-
ObjectWrapper, fbx_name_class, ensure_object_not_in_edit_mode,
|
|
84
|
-
# Top level.
|
|
85
|
-
FBXExportSettingsMedia, FBXExportSettings, FBXExportData,
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
# Units converters!
|
|
89
|
-
convert_sec_to_ktime = units_convertor("second", "ktime")
|
|
90
|
-
convert_sec_to_ktime_iter = units_convertor_iter("second", "ktime")
|
|
91
|
-
|
|
92
|
-
convert_mm_to_inch = units_convertor("millimeter", "inch")
|
|
93
|
-
|
|
94
|
-
convert_rad_to_deg = units_convertor("radian", "degree")
|
|
95
|
-
convert_rad_to_deg_iter = units_convertor_iter("radian", "degree")
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
# ##### Templates #####
|
|
99
|
-
# TODO: check all those "default" values, they should match Blender's default as much as possible, I guess?
|
|
100
|
-
|
|
101
|
-
def fbx_template_def_globalsettings(scene, settings, override_defaults=None, nbr_users=0):
|
|
102
|
-
props = {}
|
|
103
|
-
if override_defaults is not None:
|
|
104
|
-
props.update(override_defaults)
|
|
105
|
-
return FBXTemplate(b"GlobalSettings", b"", props, nbr_users, [False])
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def fbx_template_def_model(scene, settings, override_defaults=None, nbr_users=0):
|
|
109
|
-
gscale = settings.global_scale
|
|
110
|
-
props = {
|
|
111
|
-
# Name, Value, Type, Animatable
|
|
112
|
-
b"QuaternionInterpolate": (0, "p_enum", False), # 0 = no quat interpolation.
|
|
113
|
-
b"RotationOffset": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
114
|
-
b"RotationPivot": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
115
|
-
b"ScalingOffset": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
116
|
-
b"ScalingPivot": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
117
|
-
b"TranslationActive": (False, "p_bool", False),
|
|
118
|
-
b"TranslationMin": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
119
|
-
b"TranslationMax": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
120
|
-
b"TranslationMinX": (False, "p_bool", False),
|
|
121
|
-
b"TranslationMinY": (False, "p_bool", False),
|
|
122
|
-
b"TranslationMinZ": (False, "p_bool", False),
|
|
123
|
-
b"TranslationMaxX": (False, "p_bool", False),
|
|
124
|
-
b"TranslationMaxY": (False, "p_bool", False),
|
|
125
|
-
b"TranslationMaxZ": (False, "p_bool", False),
|
|
126
|
-
b"RotationOrder": (0, "p_enum", False), # we always use 'XYZ' order.
|
|
127
|
-
b"RotationSpaceForLimitOnly": (False, "p_bool", False),
|
|
128
|
-
b"RotationStiffnessX": (0.0, "p_double", False),
|
|
129
|
-
b"RotationStiffnessY": (0.0, "p_double", False),
|
|
130
|
-
b"RotationStiffnessZ": (0.0, "p_double", False),
|
|
131
|
-
b"AxisLen": (10.0, "p_double", False),
|
|
132
|
-
b"PreRotation": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
133
|
-
b"PostRotation": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
134
|
-
b"RotationActive": (False, "p_bool", False),
|
|
135
|
-
b"RotationMin": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
136
|
-
b"RotationMax": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
137
|
-
b"RotationMinX": (False, "p_bool", False),
|
|
138
|
-
b"RotationMinY": (False, "p_bool", False),
|
|
139
|
-
b"RotationMinZ": (False, "p_bool", False),
|
|
140
|
-
b"RotationMaxX": (False, "p_bool", False),
|
|
141
|
-
b"RotationMaxY": (False, "p_bool", False),
|
|
142
|
-
b"RotationMaxZ": (False, "p_bool", False),
|
|
143
|
-
b"InheritType": (0, "p_enum", False), # RrSs
|
|
144
|
-
b"ScalingActive": (False, "p_bool", False),
|
|
145
|
-
b"ScalingMin": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
146
|
-
b"ScalingMax": ((1.0, 1.0, 1.0), "p_vector_3d", False),
|
|
147
|
-
b"ScalingMinX": (False, "p_bool", False),
|
|
148
|
-
b"ScalingMinY": (False, "p_bool", False),
|
|
149
|
-
b"ScalingMinZ": (False, "p_bool", False),
|
|
150
|
-
b"ScalingMaxX": (False, "p_bool", False),
|
|
151
|
-
b"ScalingMaxY": (False, "p_bool", False),
|
|
152
|
-
b"ScalingMaxZ": (False, "p_bool", False),
|
|
153
|
-
b"GeometricTranslation": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
154
|
-
b"GeometricRotation": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
155
|
-
b"GeometricScaling": ((1.0, 1.0, 1.0), "p_vector_3d", False),
|
|
156
|
-
b"MinDampRangeX": (0.0, "p_double", False),
|
|
157
|
-
b"MinDampRangeY": (0.0, "p_double", False),
|
|
158
|
-
b"MinDampRangeZ": (0.0, "p_double", False),
|
|
159
|
-
b"MaxDampRangeX": (0.0, "p_double", False),
|
|
160
|
-
b"MaxDampRangeY": (0.0, "p_double", False),
|
|
161
|
-
b"MaxDampRangeZ": (0.0, "p_double", False),
|
|
162
|
-
b"MinDampStrengthX": (0.0, "p_double", False),
|
|
163
|
-
b"MinDampStrengthY": (0.0, "p_double", False),
|
|
164
|
-
b"MinDampStrengthZ": (0.0, "p_double", False),
|
|
165
|
-
b"MaxDampStrengthX": (0.0, "p_double", False),
|
|
166
|
-
b"MaxDampStrengthY": (0.0, "p_double", False),
|
|
167
|
-
b"MaxDampStrengthZ": (0.0, "p_double", False),
|
|
168
|
-
b"PreferedAngleX": (0.0, "p_double", False),
|
|
169
|
-
b"PreferedAngleY": (0.0, "p_double", False),
|
|
170
|
-
b"PreferedAngleZ": (0.0, "p_double", False),
|
|
171
|
-
b"LookAtProperty": (None, "p_object", False),
|
|
172
|
-
b"UpVectorProperty": (None, "p_object", False),
|
|
173
|
-
b"Show": (True, "p_bool", False),
|
|
174
|
-
b"NegativePercentShapeSupport": (True, "p_bool", False),
|
|
175
|
-
b"DefaultAttributeIndex": (-1, "p_integer", False),
|
|
176
|
-
b"Freeze": (False, "p_bool", False),
|
|
177
|
-
b"LODBox": (False, "p_bool", False),
|
|
178
|
-
b"Lcl Translation": ((0.0, 0.0, 0.0), "p_lcl_translation", True),
|
|
179
|
-
b"Lcl Rotation": ((0.0, 0.0, 0.0), "p_lcl_rotation", True),
|
|
180
|
-
b"Lcl Scaling": ((1.0, 1.0, 1.0), "p_lcl_scaling", True),
|
|
181
|
-
b"Visibility": (1.0, "p_visibility", True),
|
|
182
|
-
b"Visibility Inheritance": (1, "p_visibility_inheritance", False),
|
|
183
|
-
}
|
|
184
|
-
if override_defaults is not None:
|
|
185
|
-
props.update(override_defaults)
|
|
186
|
-
return FBXTemplate(b"Model", b"FbxNode", props, nbr_users, [False])
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
def fbx_template_def_null(scene, settings, override_defaults=None, nbr_users=0):
|
|
190
|
-
props = {
|
|
191
|
-
b"Color": ((0.8, 0.8, 0.8), "p_color_rgb", False),
|
|
192
|
-
b"Size": (100.0, "p_double", False),
|
|
193
|
-
b"Look": (1, "p_enum", False), # Cross (0 is None, i.e. invisible?).
|
|
194
|
-
}
|
|
195
|
-
if override_defaults is not None:
|
|
196
|
-
props.update(override_defaults)
|
|
197
|
-
return FBXTemplate(b"NodeAttribute", b"FbxNull", props, nbr_users, [False])
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
def fbx_template_def_light(scene, settings, override_defaults=None, nbr_users=0):
|
|
201
|
-
gscale = settings.global_scale
|
|
202
|
-
props = {
|
|
203
|
-
b"LightType": (0, "p_enum", False), # Point light.
|
|
204
|
-
b"CastLight": (True, "p_bool", False),
|
|
205
|
-
b"Color": ((1.0, 1.0, 1.0), "p_color", True),
|
|
206
|
-
b"Intensity": (100.0, "p_number", True), # Times 100 compared to Blender values...
|
|
207
|
-
b"Exposure" : (0.0, "p_number", True ),
|
|
208
|
-
b"DecayType": (2, "p_enum", False), # Quadratic.
|
|
209
|
-
b"DecayStart": (30.0 * gscale, "p_double", False),
|
|
210
|
-
b"CastShadows": (True, "p_bool", False),
|
|
211
|
-
b"ShadowColor": ((0.0, 0.0, 0.0), "p_color", True),
|
|
212
|
-
b"AreaLightShape": (0, "p_enum", False), # Rectangle.
|
|
213
|
-
}
|
|
214
|
-
if override_defaults is not None:
|
|
215
|
-
props.update(override_defaults)
|
|
216
|
-
return FBXTemplate(b"NodeAttribute", b"FbxLight", props, nbr_users, [False])
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
def fbx_template_def_camera(scene, settings, override_defaults=None, nbr_users=0):
|
|
220
|
-
r = scene.render
|
|
221
|
-
props = {
|
|
222
|
-
b"Color": ((0.8, 0.8, 0.8), "p_color_rgb", False),
|
|
223
|
-
b"Position": ((0.0, 0.0, -50.0), "p_vector", True),
|
|
224
|
-
b"UpVector": ((0.0, 1.0, 0.0), "p_vector", True),
|
|
225
|
-
b"InterestPosition": ((0.0, 0.0, 0.0), "p_vector", True),
|
|
226
|
-
b"Roll": (0.0, "p_roll", True),
|
|
227
|
-
b"OpticalCenterX": (0.0, "p_opticalcenterx", True),
|
|
228
|
-
b"OpticalCenterY": (0.0, "p_opticalcentery", True),
|
|
229
|
-
b"BackgroundColor": ((0.63, 0.63, 0.63), "p_color", True),
|
|
230
|
-
b"TurnTable": (0.0, "p_number", True),
|
|
231
|
-
b"DisplayTurnTableIcon": (False, "p_bool", False),
|
|
232
|
-
b"UseMotionBlur": (False, "p_bool", False),
|
|
233
|
-
b"UseRealTimeMotionBlur": (True, "p_bool", False),
|
|
234
|
-
b"Motion Blur Intensity": (1.0, "p_number", True),
|
|
235
|
-
b"AspectRatioMode": (0, "p_enum", False), # WindowSize.
|
|
236
|
-
b"AspectWidth": (320.0, "p_double", False),
|
|
237
|
-
b"AspectHeight": (200.0, "p_double", False),
|
|
238
|
-
b"PixelAspectRatio": (1.0, "p_double", False),
|
|
239
|
-
b"FilmOffsetX": (0.0, "p_number", True),
|
|
240
|
-
b"FilmOffsetY": (0.0, "p_number", True),
|
|
241
|
-
b"FilmWidth": (0.816, "p_double", False),
|
|
242
|
-
b"FilmHeight": (0.612, "p_double", False),
|
|
243
|
-
b"FilmAspectRatio": (1.3333333333333333, "p_double", False),
|
|
244
|
-
b"FilmSqueezeRatio": (1.0, "p_double", False),
|
|
245
|
-
b"FilmFormatIndex": (0, "p_enum", False), # Assuming this is ApertureFormat, 0 = custom.
|
|
246
|
-
b"PreScale": (1.0, "p_number", True),
|
|
247
|
-
b"FilmTranslateX": (0.0, "p_number", True),
|
|
248
|
-
b"FilmTranslateY": (0.0, "p_number", True),
|
|
249
|
-
b"FilmRollPivotX": (0.0, "p_number", True),
|
|
250
|
-
b"FilmRollPivotY": (0.0, "p_number", True),
|
|
251
|
-
b"FilmRollValue": (0.0, "p_number", True),
|
|
252
|
-
b"FilmRollOrder": (0, "p_enum", False), # 0 = rotate first (default).
|
|
253
|
-
b"ApertureMode": (2, "p_enum", False), # 2 = Vertical.
|
|
254
|
-
b"GateFit": (0, "p_enum", False), # 0 = no resolution gate fit.
|
|
255
|
-
b"FieldOfView": (25.114999771118164, "p_fov", True),
|
|
256
|
-
b"FieldOfViewX": (40.0, "p_fov_x", True),
|
|
257
|
-
b"FieldOfViewY": (40.0, "p_fov_y", True),
|
|
258
|
-
b"FocalLength": (34.89327621672628, "p_number", True),
|
|
259
|
-
b"CameraFormat": (0, "p_enum", False), # Custom camera format.
|
|
260
|
-
b"UseFrameColor": (False, "p_bool", False),
|
|
261
|
-
b"FrameColor": ((0.3, 0.3, 0.3), "p_color_rgb", False),
|
|
262
|
-
b"ShowName": (True, "p_bool", False),
|
|
263
|
-
b"ShowInfoOnMoving": (True, "p_bool", False),
|
|
264
|
-
b"ShowGrid": (True, "p_bool", False),
|
|
265
|
-
b"ShowOpticalCenter": (False, "p_bool", False),
|
|
266
|
-
b"ShowAzimut": (True, "p_bool", False),
|
|
267
|
-
b"ShowTimeCode": (False, "p_bool", False),
|
|
268
|
-
b"ShowAudio": (False, "p_bool", False),
|
|
269
|
-
b"AudioColor": ((0.0, 1.0, 0.0), "p_vector_3d", False), # Yep, vector3d, not corlorgb… :cry:
|
|
270
|
-
b"NearPlane": (10.0, "p_double", False),
|
|
271
|
-
b"FarPlane": (4000.0, "p_double", False),
|
|
272
|
-
b"AutoComputeClipPanes": (False, "p_bool", False),
|
|
273
|
-
b"ViewCameraToLookAt": (True, "p_bool", False),
|
|
274
|
-
b"ViewFrustumNearFarPlane": (False, "p_bool", False),
|
|
275
|
-
b"ViewFrustumBackPlaneMode": (2, "p_enum", False), # 2 = show back plane if texture added.
|
|
276
|
-
b"BackPlaneDistance": (4000.0, "p_number", True),
|
|
277
|
-
b"BackPlaneDistanceMode": (1, "p_enum", False), # 1 = relative to camera.
|
|
278
|
-
b"ViewFrustumFrontPlaneMode": (2, "p_enum", False), # 2 = show front plane if texture added.
|
|
279
|
-
b"FrontPlaneDistance": (10.0, "p_number", True),
|
|
280
|
-
b"FrontPlaneDistanceMode": (1, "p_enum", False), # 1 = relative to camera.
|
|
281
|
-
b"LockMode": (False, "p_bool", False),
|
|
282
|
-
b"LockInterestNavigation": (False, "p_bool", False),
|
|
283
|
-
# BackPlate... properties **arggggg!**
|
|
284
|
-
b"FitImage": (False, "p_bool", False),
|
|
285
|
-
b"Crop": (False, "p_bool", False),
|
|
286
|
-
b"Center": (True, "p_bool", False),
|
|
287
|
-
b"KeepRatio": (True, "p_bool", False),
|
|
288
|
-
# End of BackPlate...
|
|
289
|
-
b"BackgroundAlphaTreshold": (0.5, "p_double", False),
|
|
290
|
-
b"ShowBackplate": (True, "p_bool", False),
|
|
291
|
-
b"BackPlaneOffsetX": (0.0, "p_number", True),
|
|
292
|
-
b"BackPlaneOffsetY": (0.0, "p_number", True),
|
|
293
|
-
b"BackPlaneRotation": (0.0, "p_number", True),
|
|
294
|
-
b"BackPlaneScaleX": (1.0, "p_number", True),
|
|
295
|
-
b"BackPlaneScaleY": (1.0, "p_number", True),
|
|
296
|
-
b"Background Texture": (None, "p_object", False),
|
|
297
|
-
b"FrontPlateFitImage": (True, "p_bool", False),
|
|
298
|
-
b"FrontPlateCrop": (False, "p_bool", False),
|
|
299
|
-
b"FrontPlateCenter": (True, "p_bool", False),
|
|
300
|
-
b"FrontPlateKeepRatio": (True, "p_bool", False),
|
|
301
|
-
b"Foreground Opacity": (1.0, "p_double", False),
|
|
302
|
-
b"ShowFrontplate": (True, "p_bool", False),
|
|
303
|
-
b"FrontPlaneOffsetX": (0.0, "p_number", True),
|
|
304
|
-
b"FrontPlaneOffsetY": (0.0, "p_number", True),
|
|
305
|
-
b"FrontPlaneRotation": (0.0, "p_number", True),
|
|
306
|
-
b"FrontPlaneScaleX": (1.0, "p_number", True),
|
|
307
|
-
b"FrontPlaneScaleY": (1.0, "p_number", True),
|
|
308
|
-
b"Foreground Texture": (None, "p_object", False),
|
|
309
|
-
b"DisplaySafeArea": (False, "p_bool", False),
|
|
310
|
-
b"DisplaySafeAreaOnRender": (False, "p_bool", False),
|
|
311
|
-
b"SafeAreaDisplayStyle": (1, "p_enum", False), # 1 = rounded corners.
|
|
312
|
-
b"SafeAreaAspectRatio": (1.3333333333333333, "p_double", False),
|
|
313
|
-
b"Use2DMagnifierZoom": (False, "p_bool", False),
|
|
314
|
-
b"2D Magnifier Zoom": (100.0, "p_number", True),
|
|
315
|
-
b"2D Magnifier X": (50.0, "p_number", True),
|
|
316
|
-
b"2D Magnifier Y": (50.0, "p_number", True),
|
|
317
|
-
b"CameraProjectionType": (0, "p_enum", False), # 0 = perspective, 1 = orthogonal.
|
|
318
|
-
b"OrthoZoom": (1.0, "p_double", False),
|
|
319
|
-
b"UseRealTimeDOFAndAA": (False, "p_bool", False),
|
|
320
|
-
b"UseDepthOfField": (False, "p_bool", False),
|
|
321
|
-
b"FocusSource": (0, "p_enum", False), # 0 = camera interest, 1 = distance from camera interest.
|
|
322
|
-
b"FocusAngle": (3.5, "p_double", False), # ???
|
|
323
|
-
b"FocusDistance": (200.0, "p_double", False),
|
|
324
|
-
b"UseAntialiasing": (False, "p_bool", False),
|
|
325
|
-
b"AntialiasingIntensity": (0.77777, "p_double", False),
|
|
326
|
-
b"AntialiasingMethod": (0, "p_enum", False), # 0 = oversampling, 1 = hardware.
|
|
327
|
-
b"UseAccumulationBuffer": (False, "p_bool", False),
|
|
328
|
-
b"FrameSamplingCount": (7, "p_integer", False),
|
|
329
|
-
b"FrameSamplingType": (1, "p_enum", False), # 0 = uniform, 1 = stochastic.
|
|
330
|
-
}
|
|
331
|
-
if override_defaults is not None:
|
|
332
|
-
props.update(override_defaults)
|
|
333
|
-
return FBXTemplate(b"NodeAttribute", b"FbxCamera", props, nbr_users, [False])
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
def fbx_template_def_bone(scene, settings, override_defaults=None, nbr_users=0):
|
|
337
|
-
props = {}
|
|
338
|
-
if override_defaults is not None:
|
|
339
|
-
props.update(override_defaults)
|
|
340
|
-
return FBXTemplate(b"NodeAttribute", b"LimbNode", props, nbr_users, [False])
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
def fbx_template_def_geometry(scene, settings, override_defaults=None, nbr_users=0):
|
|
344
|
-
props = {
|
|
345
|
-
b"Color": ((0.8, 0.8, 0.8), "p_color_rgb", False),
|
|
346
|
-
b"BBoxMin": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
347
|
-
b"BBoxMax": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
348
|
-
b"Primary Visibility": (True, "p_bool", False),
|
|
349
|
-
b"Casts Shadows": (True, "p_bool", False),
|
|
350
|
-
b"Receive Shadows": (True, "p_bool", False),
|
|
351
|
-
}
|
|
352
|
-
if override_defaults is not None:
|
|
353
|
-
props.update(override_defaults)
|
|
354
|
-
return FBXTemplate(b"Geometry", b"FbxMesh", props, nbr_users, [False])
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
def fbx_template_def_material(scene, settings, override_defaults=None, nbr_users=0):
|
|
358
|
-
# WIP...
|
|
359
|
-
props = {
|
|
360
|
-
b"ShadingModel": ("Phong", "p_string", False),
|
|
361
|
-
b"MultiLayer": (False, "p_bool", False),
|
|
362
|
-
# Lambert-specific.
|
|
363
|
-
b"EmissiveColor": ((0.0, 0.0, 0.0), "p_color", True),
|
|
364
|
-
b"EmissiveFactor": (1.0, "p_number", True),
|
|
365
|
-
b"AmbientColor": ((0.2, 0.2, 0.2), "p_color", True),
|
|
366
|
-
b"AmbientFactor": (1.0, "p_number", True),
|
|
367
|
-
b"DiffuseColor": ((0.8, 0.8, 0.8), "p_color", True),
|
|
368
|
-
b"DiffuseFactor": (1.0, "p_number", True),
|
|
369
|
-
b"TransparentColor": ((0.0, 0.0, 0.0), "p_color", True),
|
|
370
|
-
b"TransparencyFactor": (0.0, "p_number", True),
|
|
371
|
-
b"Opacity": (1.0, "p_number", True),
|
|
372
|
-
b"NormalMap": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
373
|
-
b"Bump": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
374
|
-
b"BumpFactor": (1.0, "p_double", False),
|
|
375
|
-
b"DisplacementColor": ((0.0, 0.0, 0.0), "p_color_rgb", False),
|
|
376
|
-
b"DisplacementFactor": (1.0, "p_double", False),
|
|
377
|
-
b"VectorDisplacementColor": ((0.0, 0.0, 0.0), "p_color_rgb", False),
|
|
378
|
-
b"VectorDisplacementFactor": (1.0, "p_double", False),
|
|
379
|
-
# Phong-specific.
|
|
380
|
-
b"SpecularColor": ((0.2, 0.2, 0.2), "p_color", True),
|
|
381
|
-
b"SpecularFactor": (1.0, "p_number", True),
|
|
382
|
-
# Not sure about the name, importer uses this (but ShininessExponent for tex prop name!)
|
|
383
|
-
# And in fbx exported by sdk, you have one in template, the other in actual material!!! :/
|
|
384
|
-
# For now, using both.
|
|
385
|
-
b"Shininess": (20.0, "p_number", True),
|
|
386
|
-
b"ShininessExponent": (20.0, "p_number", True),
|
|
387
|
-
b"ReflectionColor": ((0.0, 0.0, 0.0), "p_color", True),
|
|
388
|
-
b"ReflectionFactor": (1.0, "p_number", True),
|
|
389
|
-
}
|
|
390
|
-
if override_defaults is not None:
|
|
391
|
-
props.update(override_defaults)
|
|
392
|
-
return FBXTemplate(b"Material", b"FbxSurfacePhong", props, nbr_users, [False])
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
def fbx_template_def_texture_file(scene, settings, override_defaults=None, nbr_users=0):
|
|
396
|
-
# WIP...
|
|
397
|
-
# XXX Not sure about all names!
|
|
398
|
-
props = {
|
|
399
|
-
b"TextureTypeUse": (0, "p_enum", False), # Standard.
|
|
400
|
-
b"AlphaSource": (2, "p_enum", False), # Black (i.e. texture's alpha), XXX name guessed!.
|
|
401
|
-
b"Texture alpha": (1.0, "p_double", False),
|
|
402
|
-
b"PremultiplyAlpha": (True, "p_bool", False),
|
|
403
|
-
b"CurrentTextureBlendMode": (1, "p_enum", False), # Additive...
|
|
404
|
-
b"CurrentMappingType": (0, "p_enum", False), # UV.
|
|
405
|
-
b"UVSet": ("default", "p_string", False), # UVMap name.
|
|
406
|
-
b"WrapModeU": (0, "p_enum", False), # Repeat.
|
|
407
|
-
b"WrapModeV": (0, "p_enum", False), # Repeat.
|
|
408
|
-
b"UVSwap": (False, "p_bool", False),
|
|
409
|
-
b"Translation": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
410
|
-
b"Rotation": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
411
|
-
b"Scaling": ((1.0, 1.0, 1.0), "p_vector_3d", False),
|
|
412
|
-
b"TextureRotationPivot": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
413
|
-
b"TextureScalingPivot": ((0.0, 0.0, 0.0), "p_vector_3d", False),
|
|
414
|
-
# Not sure about those two...
|
|
415
|
-
b"UseMaterial": (False, "p_bool", False),
|
|
416
|
-
b"UseMipMap": (False, "p_bool", False),
|
|
417
|
-
}
|
|
418
|
-
if override_defaults is not None:
|
|
419
|
-
props.update(override_defaults)
|
|
420
|
-
return FBXTemplate(b"Texture", b"FbxFileTexture", props, nbr_users, [False])
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
def fbx_template_def_video(scene, settings, override_defaults=None, nbr_users=0):
|
|
424
|
-
# WIP...
|
|
425
|
-
props = {
|
|
426
|
-
# All pictures.
|
|
427
|
-
b"Width": (0, "p_integer", False),
|
|
428
|
-
b"Height": (0, "p_integer", False),
|
|
429
|
-
b"Path": ("", "p_string_url", False),
|
|
430
|
-
b"AccessMode": (0, "p_enum", False), # Disk (0=Disk, 1=Mem, 2=DiskAsync).
|
|
431
|
-
# All videos.
|
|
432
|
-
b"StartFrame": (0, "p_integer", False),
|
|
433
|
-
b"StopFrame": (0, "p_integer", False),
|
|
434
|
-
b"Offset": (0, "p_timestamp", False),
|
|
435
|
-
b"PlaySpeed": (0.0, "p_double", False),
|
|
436
|
-
b"FreeRunning": (False, "p_bool", False),
|
|
437
|
-
b"Loop": (False, "p_bool", False),
|
|
438
|
-
b"InterlaceMode": (0, "p_enum", False), # None, i.e. progressive.
|
|
439
|
-
# Image sequences.
|
|
440
|
-
b"ImageSequence": (False, "p_bool", False),
|
|
441
|
-
b"ImageSequenceOffset": (0, "p_integer", False),
|
|
442
|
-
b"FrameRate": (0.0, "p_double", False),
|
|
443
|
-
b"LastFrame": (0, "p_integer", False),
|
|
444
|
-
}
|
|
445
|
-
if override_defaults is not None:
|
|
446
|
-
props.update(override_defaults)
|
|
447
|
-
return FBXTemplate(b"Video", b"FbxVideo", props, nbr_users, [False])
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
def fbx_template_def_pose(scene, settings, override_defaults=None, nbr_users=0):
|
|
451
|
-
props = {}
|
|
452
|
-
if override_defaults is not None:
|
|
453
|
-
props.update(override_defaults)
|
|
454
|
-
return FBXTemplate(b"Pose", b"", props, nbr_users, [False])
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
def fbx_template_def_deformer(scene, settings, override_defaults=None, nbr_users=0):
|
|
458
|
-
props = {}
|
|
459
|
-
if override_defaults is not None:
|
|
460
|
-
props.update(override_defaults)
|
|
461
|
-
return FBXTemplate(b"Deformer", b"", props, nbr_users, [False])
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
def fbx_template_def_animstack(scene, settings, override_defaults=None, nbr_users=0):
|
|
465
|
-
props = {
|
|
466
|
-
b"Description": ("", "p_string", False),
|
|
467
|
-
b"LocalStart": (0, "p_timestamp", False),
|
|
468
|
-
b"LocalStop": (0, "p_timestamp", False),
|
|
469
|
-
b"ReferenceStart": (0, "p_timestamp", False),
|
|
470
|
-
b"ReferenceStop": (0, "p_timestamp", False),
|
|
471
|
-
}
|
|
472
|
-
if override_defaults is not None:
|
|
473
|
-
props.update(override_defaults)
|
|
474
|
-
return FBXTemplate(b"AnimationStack", b"FbxAnimStack", props, nbr_users, [False])
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
def fbx_template_def_animlayer(scene, settings, override_defaults=None, nbr_users=0):
|
|
478
|
-
props = {
|
|
479
|
-
b"Weight": (100.0, "p_number", True),
|
|
480
|
-
b"Mute": (False, "p_bool", False),
|
|
481
|
-
b"Solo": (False, "p_bool", False),
|
|
482
|
-
b"Lock": (False, "p_bool", False),
|
|
483
|
-
b"Color": ((0.8, 0.8, 0.8), "p_color_rgb", False),
|
|
484
|
-
b"BlendMode": (0, "p_enum", False),
|
|
485
|
-
b"RotationAccumulationMode": (0, "p_enum", False),
|
|
486
|
-
b"ScaleAccumulationMode": (0, "p_enum", False),
|
|
487
|
-
b"BlendModeBypass": (0, "p_ulonglong", False),
|
|
488
|
-
}
|
|
489
|
-
if override_defaults is not None:
|
|
490
|
-
props.update(override_defaults)
|
|
491
|
-
return FBXTemplate(b"AnimationLayer", b"FbxAnimLayer", props, nbr_users, [False])
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
def fbx_template_def_animcurvenode(scene, settings, override_defaults=None, nbr_users=0):
|
|
495
|
-
props = {
|
|
496
|
-
FBX_ANIM_PROPSGROUP_NAME.encode(): (None, "p_compound", False),
|
|
497
|
-
}
|
|
498
|
-
if override_defaults is not None:
|
|
499
|
-
props.update(override_defaults)
|
|
500
|
-
return FBXTemplate(b"AnimationCurveNode", b"FbxAnimCurveNode", props, nbr_users, [False])
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
def fbx_template_def_animcurve(scene, settings, override_defaults=None, nbr_users=0):
|
|
504
|
-
props = {}
|
|
505
|
-
if override_defaults is not None:
|
|
506
|
-
props.update(override_defaults)
|
|
507
|
-
return FBXTemplate(b"AnimationCurve", b"", props, nbr_users, [False])
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
# ##### Generators for connection elements. #####
|
|
511
|
-
|
|
512
|
-
def elem_connection(elem, c_type, uid_src, uid_dst, prop_dst=None):
|
|
513
|
-
e = elem_data_single_string(elem, b"C", c_type)
|
|
514
|
-
e.add_int64(uid_src)
|
|
515
|
-
e.add_int64(uid_dst)
|
|
516
|
-
if prop_dst is not None:
|
|
517
|
-
e.add_string(prop_dst)
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
# ##### FBX objects generators. #####
|
|
521
|
-
|
|
522
|
-
def fbx_data_element_custom_properties(props, bid):
|
|
523
|
-
"""
|
|
524
|
-
Store custom properties of blender ID bid (any mapping-like object, in fact) into FBX properties props.
|
|
525
|
-
"""
|
|
526
|
-
items = bid.items()
|
|
527
|
-
|
|
528
|
-
if not items:
|
|
529
|
-
return
|
|
530
|
-
|
|
531
|
-
rna_properties = {prop.identifier for prop in bid.bl_rna.properties if prop.is_runtime}
|
|
532
|
-
|
|
533
|
-
for k, v in items:
|
|
534
|
-
if k in rna_properties:
|
|
535
|
-
continue
|
|
536
|
-
|
|
537
|
-
list_val = getattr(v, "to_list", lambda: None)()
|
|
538
|
-
|
|
539
|
-
if isinstance(v, str):
|
|
540
|
-
elem_props_set(props, "p_string", k.encode(), v, custom=True)
|
|
541
|
-
elif isinstance(v, int):
|
|
542
|
-
elem_props_set(props, "p_integer", k.encode(), v, custom=True)
|
|
543
|
-
elif isinstance(v, float):
|
|
544
|
-
elem_props_set(props, "p_double", k.encode(), v, custom=True)
|
|
545
|
-
elif list_val:
|
|
546
|
-
if len(list_val) == 3:
|
|
547
|
-
elem_props_set(props, "p_vector", k.encode(), list_val, custom=True)
|
|
548
|
-
else:
|
|
549
|
-
elem_props_set(props, "p_string", k.encode(), str(list_val), custom=True)
|
|
550
|
-
else:
|
|
551
|
-
elem_props_set(props, "p_string", k.encode(), str(v), custom=True)
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
def fbx_data_empty_elements(root, empty, scene_data):
|
|
555
|
-
"""
|
|
556
|
-
Write the Empty data block (you can control its FBX datatype with the 'fbx_type' string custom property) or Armature
|
|
557
|
-
NodeAttribute.
|
|
558
|
-
"""
|
|
559
|
-
empty_key = scene_data.data_empties[empty]
|
|
560
|
-
|
|
561
|
-
null = elem_data_single_int64(root, b"NodeAttribute", get_fbx_uuid_from_key(empty_key))
|
|
562
|
-
null.add_string(fbx_name_class(empty.name.encode(), b"NodeAttribute"))
|
|
563
|
-
bdata = empty.bdata
|
|
564
|
-
if bdata.type == 'EMPTY':
|
|
565
|
-
val = bdata.get('fbx_type', None)
|
|
566
|
-
fbx_type = val.encode() if val and isinstance(val, str) else b"Null"
|
|
567
|
-
else:
|
|
568
|
-
fbx_type = b"Null"
|
|
569
|
-
null.add_string(fbx_type)
|
|
570
|
-
|
|
571
|
-
elem_data_single_string(null, b"TypeFlags", b"Null")
|
|
572
|
-
|
|
573
|
-
tmpl = elem_props_template_init(scene_data.templates, b"Null")
|
|
574
|
-
props = elem_properties(null)
|
|
575
|
-
elem_props_template_finalize(tmpl, props)
|
|
576
|
-
|
|
577
|
-
# Empty/Armature Object custom properties have already been saved with the Model.
|
|
578
|
-
# Only Armature data custom properties need to be saved here with the NodeAttribute.
|
|
579
|
-
if bdata.type == 'ARMATURE':
|
|
580
|
-
fbx_data_element_custom_properties(props, bdata.data)
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
def fbx_data_light_elements(root, lamp, scene_data):
|
|
584
|
-
"""
|
|
585
|
-
Write the Lamp data block.
|
|
586
|
-
"""
|
|
587
|
-
gscale = scene_data.settings.global_scale
|
|
588
|
-
|
|
589
|
-
light_key = scene_data.data_lights[lamp]
|
|
590
|
-
do_light = True
|
|
591
|
-
do_shadow = False
|
|
592
|
-
# NOTE: this was removed from lamps, always write black.
|
|
593
|
-
shadow_color = Vector((0.0, 0.0, 0.0))
|
|
594
|
-
if lamp.type not in {'HEMI'}:
|
|
595
|
-
do_light = True
|
|
596
|
-
do_shadow = lamp.use_shadow
|
|
597
|
-
# `shadow_color = lamp.shadow_color`: now removed.
|
|
598
|
-
|
|
599
|
-
light = elem_data_single_int64(root, b"NodeAttribute", get_fbx_uuid_from_key(light_key))
|
|
600
|
-
light.add_string(fbx_name_class(lamp.name.encode(), b"NodeAttribute"))
|
|
601
|
-
light.add_string(b"Light")
|
|
602
|
-
|
|
603
|
-
elem_data_single_int32(light, b"GeometryVersion", FBX_GEOMETRY_VERSION) # Sic...
|
|
604
|
-
|
|
605
|
-
intensity = lamp.energy * 100.0 * pow(2.0, lamp.exposure)
|
|
606
|
-
color = lamp.color.copy()
|
|
607
|
-
if lamp.use_temperature:
|
|
608
|
-
temperature_color = lamp.temperature_color
|
|
609
|
-
color[0] *= temperature_color[0]
|
|
610
|
-
color[1] *= temperature_color[1]
|
|
611
|
-
color[2] *= temperature_color[2]
|
|
612
|
-
|
|
613
|
-
tmpl = elem_props_template_init(scene_data.templates, b"Light")
|
|
614
|
-
props = elem_properties(light)
|
|
615
|
-
elem_props_template_set(tmpl, props, "p_enum", b"LightType", FBX_LIGHT_TYPES[lamp.type])
|
|
616
|
-
elem_props_template_set(tmpl, props, "p_bool", b"CastLight", do_light)
|
|
617
|
-
elem_props_template_set(tmpl, props, "p_color", b"Color", color)
|
|
618
|
-
elem_props_template_set(tmpl, props, "p_number", b"Intensity", intensity)
|
|
619
|
-
elem_props_template_set(tmpl, props, "p_enum", b"DecayType", FBX_LIGHT_DECAY_TYPES['INVERSE_SQUARE'])
|
|
620
|
-
elem_props_template_set(tmpl, props, "p_double", b"DecayStart", 25.0 * gscale) # 25 is old Blender default
|
|
621
|
-
elem_props_template_set(tmpl, props, "p_bool", b"CastShadows", do_shadow)
|
|
622
|
-
elem_props_template_set(tmpl, props, "p_color", b"ShadowColor", shadow_color)
|
|
623
|
-
if lamp.type in {'SPOT'}:
|
|
624
|
-
elem_props_template_set(tmpl, props, "p_double", b"OuterAngle", math.degrees(lamp.spot_size))
|
|
625
|
-
elem_props_template_set(tmpl, props, "p_double", b"InnerAngle",
|
|
626
|
-
math.degrees(lamp.spot_size * (1.0 - lamp.spot_blend)))
|
|
627
|
-
elem_props_template_finalize(tmpl, props)
|
|
628
|
-
|
|
629
|
-
# Custom properties.
|
|
630
|
-
if scene_data.settings.use_custom_props:
|
|
631
|
-
fbx_data_element_custom_properties(props, lamp)
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
def fbx_data_camera_elements(root, cam_obj, scene_data):
|
|
635
|
-
"""
|
|
636
|
-
Write the Camera data blocks.
|
|
637
|
-
"""
|
|
638
|
-
gscale = scene_data.settings.global_scale
|
|
639
|
-
|
|
640
|
-
cam = cam_obj.bdata
|
|
641
|
-
cam_data = cam.data
|
|
642
|
-
cam_key = scene_data.data_cameras[cam_obj]
|
|
643
|
-
|
|
644
|
-
# Real data now, good old camera!
|
|
645
|
-
# Object transform info.
|
|
646
|
-
loc, rot, scale, matrix, matrix_rot = cam_obj.fbx_object_tx(scene_data)
|
|
647
|
-
up = matrix_rot @ Vector((0.0, 1.0, 0.0))
|
|
648
|
-
to = matrix_rot @ Vector((0.0, 0.0, -1.0))
|
|
649
|
-
# Render settings.
|
|
650
|
-
# TODO We could export much more...
|
|
651
|
-
render = scene_data.scene.render
|
|
652
|
-
width = render.resolution_x
|
|
653
|
-
height = render.resolution_y
|
|
654
|
-
aspect = width / height
|
|
655
|
-
# Film width & height from mm to inches
|
|
656
|
-
filmwidth = convert_mm_to_inch(cam_data.sensor_width)
|
|
657
|
-
filmheight = convert_mm_to_inch(cam_data.sensor_height)
|
|
658
|
-
filmaspect = filmwidth / filmheight
|
|
659
|
-
# Film offset
|
|
660
|
-
offsetx = filmwidth * cam_data.shift_x
|
|
661
|
-
offsety = filmaspect * filmheight * cam_data.shift_y
|
|
662
|
-
|
|
663
|
-
cam = elem_data_single_int64(root, b"NodeAttribute", get_fbx_uuid_from_key(cam_key))
|
|
664
|
-
cam.add_string(fbx_name_class(cam_data.name.encode(), b"NodeAttribute"))
|
|
665
|
-
cam.add_string(b"Camera")
|
|
666
|
-
|
|
667
|
-
tmpl = elem_props_template_init(scene_data.templates, b"Camera")
|
|
668
|
-
props = elem_properties(cam)
|
|
669
|
-
|
|
670
|
-
elem_props_template_set(tmpl, props, "p_vector", b"Position", loc)
|
|
671
|
-
elem_props_template_set(tmpl, props, "p_vector", b"UpVector", up)
|
|
672
|
-
elem_props_template_set(tmpl, props, "p_vector", b"InterestPosition", loc + to) # Point, not vector!
|
|
673
|
-
# Should we use world value?
|
|
674
|
-
elem_props_template_set(tmpl, props, "p_color", b"BackgroundColor", (0.0, 0.0, 0.0))
|
|
675
|
-
elem_props_template_set(tmpl, props, "p_bool", b"DisplayTurnTableIcon", True)
|
|
676
|
-
|
|
677
|
-
elem_props_template_set(tmpl, props, "p_enum", b"AspectRatioMode", 2) # FixedResolution
|
|
678
|
-
elem_props_template_set(tmpl, props, "p_double", b"AspectWidth", float(render.resolution_x))
|
|
679
|
-
elem_props_template_set(tmpl, props, "p_double", b"AspectHeight", float(render.resolution_y))
|
|
680
|
-
elem_props_template_set(tmpl, props, "p_double", b"PixelAspectRatio",
|
|
681
|
-
float(render.pixel_aspect_x / render.pixel_aspect_y))
|
|
682
|
-
|
|
683
|
-
elem_props_template_set(tmpl, props, "p_double", b"FilmWidth", filmwidth)
|
|
684
|
-
elem_props_template_set(tmpl, props, "p_double", b"FilmHeight", filmheight)
|
|
685
|
-
elem_props_template_set(tmpl, props, "p_double", b"FilmAspectRatio", filmaspect)
|
|
686
|
-
elem_props_template_set(tmpl, props, "p_double", b"FilmOffsetX", offsetx)
|
|
687
|
-
elem_props_template_set(tmpl, props, "p_double", b"FilmOffsetY", offsety)
|
|
688
|
-
|
|
689
|
-
elem_props_template_set(tmpl, props, "p_enum", b"ApertureMode", 3) # FocalLength.
|
|
690
|
-
elem_props_template_set(tmpl, props, "p_enum", b"GateFit", 2) # FitHorizontal.
|
|
691
|
-
elem_props_template_set(tmpl, props, "p_fov", b"FieldOfView", math.degrees(cam_data.angle_x))
|
|
692
|
-
elem_props_template_set(tmpl, props, "p_fov_x", b"FieldOfViewX", math.degrees(cam_data.angle_x))
|
|
693
|
-
elem_props_template_set(tmpl, props, "p_fov_y", b"FieldOfViewY", math.degrees(cam_data.angle_y))
|
|
694
|
-
# No need to convert to inches here...
|
|
695
|
-
elem_props_template_set(tmpl, props, "p_double", b"FocalLength", cam_data.lens)
|
|
696
|
-
elem_props_template_set(tmpl, props, "p_double", b"SafeAreaAspectRatio", aspect)
|
|
697
|
-
# Depth of field and Focus distance.
|
|
698
|
-
elem_props_template_set(tmpl, props, "p_bool", b"UseDepthOfField", cam_data.dof.use_dof)
|
|
699
|
-
elem_props_template_set(tmpl, props, "p_double", b"FocusDistance", cam_data.dof.focus_distance * gscale)
|
|
700
|
-
# Default to perspective camera.
|
|
701
|
-
elem_props_template_set(tmpl, props, "p_enum", b"CameraProjectionType", 1 if cam_data.type == 'ORTHO' else 0)
|
|
702
|
-
elem_props_template_set(tmpl, props, "p_double", b"OrthoZoom", cam_data.ortho_scale)
|
|
703
|
-
|
|
704
|
-
elem_props_template_set(tmpl, props, "p_double", b"NearPlane", cam_data.clip_start * gscale)
|
|
705
|
-
elem_props_template_set(tmpl, props, "p_double", b"FarPlane", cam_data.clip_end * gscale)
|
|
706
|
-
elem_props_template_set(tmpl, props, "p_enum", b"BackPlaneDistanceMode", 1) # RelativeToCamera.
|
|
707
|
-
elem_props_template_set(tmpl, props, "p_double", b"BackPlaneDistance", cam_data.clip_end * gscale)
|
|
708
|
-
|
|
709
|
-
elem_props_template_finalize(tmpl, props)
|
|
710
|
-
|
|
711
|
-
# Custom properties.
|
|
712
|
-
if scene_data.settings.use_custom_props:
|
|
713
|
-
fbx_data_element_custom_properties(props, cam_data)
|
|
714
|
-
|
|
715
|
-
elem_data_single_string(cam, b"TypeFlags", b"Camera")
|
|
716
|
-
elem_data_single_int32(cam, b"GeometryVersion", 124) # Sic...
|
|
717
|
-
elem_data_vec_float64(cam, b"Position", loc)
|
|
718
|
-
elem_data_vec_float64(cam, b"Up", up)
|
|
719
|
-
elem_data_vec_float64(cam, b"LookAt", to)
|
|
720
|
-
elem_data_single_int32(cam, b"ShowInfoOnMoving", 1)
|
|
721
|
-
elem_data_single_int32(cam, b"ShowAudio", 0)
|
|
722
|
-
elem_data_vec_float64(cam, b"AudioColor", (0.0, 1.0, 0.0))
|
|
723
|
-
elem_data_single_float64(cam, b"CameraOrthoZoom", 1.0)
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
def fbx_data_bindpose_element(root, me_obj, me, scene_data, arm_obj=None, mat_world_arm=None, bones=[]):
|
|
727
|
-
"""
|
|
728
|
-
Helper, since bindpose are used by both meshes shape keys and armature bones...
|
|
729
|
-
"""
|
|
730
|
-
if arm_obj is None:
|
|
731
|
-
arm_obj = me_obj
|
|
732
|
-
# We assume bind pose for our bones are their "Editmode" pose...
|
|
733
|
-
# All matrices are expected in global (world) space.
|
|
734
|
-
bindpose_key = get_blender_bindpose_key(arm_obj.bdata, me)
|
|
735
|
-
fbx_pose = elem_data_single_int64(root, b"Pose", get_fbx_uuid_from_key(bindpose_key))
|
|
736
|
-
fbx_pose.add_string(fbx_name_class(me.name.encode(), b"Pose"))
|
|
737
|
-
fbx_pose.add_string(b"BindPose")
|
|
738
|
-
|
|
739
|
-
elem_data_single_string(fbx_pose, b"Type", b"BindPose")
|
|
740
|
-
elem_data_single_int32(fbx_pose, b"Version", FBX_POSE_BIND_VERSION)
|
|
741
|
-
elem_data_single_int32(fbx_pose, b"NbPoseNodes", 1 + (1 if (arm_obj != me_obj) else 0) + len(bones))
|
|
742
|
-
|
|
743
|
-
# First node is mesh/object.
|
|
744
|
-
mat_world_obj = me_obj.fbx_object_matrix(scene_data, global_space=True)
|
|
745
|
-
fbx_posenode = elem_empty(fbx_pose, b"PoseNode")
|
|
746
|
-
elem_data_single_int64(fbx_posenode, b"Node", me_obj.fbx_uuid)
|
|
747
|
-
elem_data_single_float64_array(fbx_posenode, b"Matrix", matrix4_to_array(mat_world_obj))
|
|
748
|
-
# Second node is armature object itself.
|
|
749
|
-
if arm_obj != me_obj:
|
|
750
|
-
fbx_posenode = elem_empty(fbx_pose, b"PoseNode")
|
|
751
|
-
elem_data_single_int64(fbx_posenode, b"Node", arm_obj.fbx_uuid)
|
|
752
|
-
elem_data_single_float64_array(fbx_posenode, b"Matrix", matrix4_to_array(mat_world_arm))
|
|
753
|
-
# And all bones of armature!
|
|
754
|
-
mat_world_bones = {}
|
|
755
|
-
for bo_obj in bones:
|
|
756
|
-
bomat = bo_obj.fbx_object_matrix(scene_data, rest=True, global_space=True)
|
|
757
|
-
mat_world_bones[bo_obj] = bomat
|
|
758
|
-
fbx_posenode = elem_empty(fbx_pose, b"PoseNode")
|
|
759
|
-
elem_data_single_int64(fbx_posenode, b"Node", bo_obj.fbx_uuid)
|
|
760
|
-
elem_data_single_float64_array(fbx_posenode, b"Matrix", matrix4_to_array(bomat))
|
|
761
|
-
|
|
762
|
-
return mat_world_obj, mat_world_bones
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
def fbx_data_mesh_shapes_elements(root, me_obj, me, scene_data, fbx_me_tmpl, fbx_me_props):
|
|
766
|
-
"""
|
|
767
|
-
Write shape keys related data.
|
|
768
|
-
"""
|
|
769
|
-
if me not in scene_data.data_deformers_shape:
|
|
770
|
-
return
|
|
771
|
-
|
|
772
|
-
write_normals = True # scene_data.settings.mesh_smooth_type in {'OFF'}
|
|
773
|
-
|
|
774
|
-
# First, write the geometry data itself (i.e. shapes).
|
|
775
|
-
_me_key, shape_key, shapes = scene_data.data_deformers_shape[me]
|
|
776
|
-
|
|
777
|
-
channels = []
|
|
778
|
-
|
|
779
|
-
vertices = me.vertices
|
|
780
|
-
for shape, (channel_key, geom_key, shape_verts_co, shape_verts_idx) in shapes.items():
|
|
781
|
-
# Use vgroups as weights, if defined.
|
|
782
|
-
if shape.vertex_group and shape.vertex_group in me_obj.bdata.vertex_groups:
|
|
783
|
-
shape_verts_weights = np.zeros(len(shape_verts_idx), dtype=np.float64)
|
|
784
|
-
# It's slightly faster to iterate and index the underlying memoryview objects
|
|
785
|
-
mv_shape_verts_weights = shape_verts_weights.data
|
|
786
|
-
mv_shape_verts_idx = shape_verts_idx.data
|
|
787
|
-
vg_idx = me_obj.bdata.vertex_groups[shape.vertex_group].index
|
|
788
|
-
for sk_idx, v_idx in enumerate(mv_shape_verts_idx):
|
|
789
|
-
for vg in vertices[v_idx].groups:
|
|
790
|
-
if vg.group == vg_idx:
|
|
791
|
-
mv_shape_verts_weights[sk_idx] = vg.weight
|
|
792
|
-
break
|
|
793
|
-
shape_verts_weights *= 100.0
|
|
794
|
-
else:
|
|
795
|
-
shape_verts_weights = np.full(len(shape_verts_idx), 100.0, dtype=np.float64)
|
|
796
|
-
channels.append((channel_key, shape, shape_verts_weights))
|
|
797
|
-
|
|
798
|
-
geom = elem_data_single_int64(root, b"Geometry", get_fbx_uuid_from_key(geom_key))
|
|
799
|
-
geom.add_string(fbx_name_class(shape.name.encode(), b"Geometry"))
|
|
800
|
-
geom.add_string(b"Shape")
|
|
801
|
-
|
|
802
|
-
tmpl = elem_props_template_init(scene_data.templates, b"Geometry")
|
|
803
|
-
props = elem_properties(geom)
|
|
804
|
-
elem_props_template_finalize(tmpl, props)
|
|
805
|
-
|
|
806
|
-
elem_data_single_int32(geom, b"Version", FBX_GEOMETRY_SHAPE_VERSION)
|
|
807
|
-
|
|
808
|
-
elem_data_single_int32_array(geom, b"Indexes", shape_verts_idx)
|
|
809
|
-
elem_data_single_float64_array(geom, b"Vertices", shape_verts_co)
|
|
810
|
-
if write_normals:
|
|
811
|
-
elem_data_single_float64_array(geom, b"Normals", np.zeros(len(shape_verts_idx) * 3, dtype=np.float64))
|
|
812
|
-
|
|
813
|
-
# Yiha! BindPose for shapekeys too! Dodecasigh...
|
|
814
|
-
# XXX Not sure yet whether several bindposes on same mesh are allowed, or not... :/
|
|
815
|
-
fbx_data_bindpose_element(root, me_obj, me, scene_data)
|
|
816
|
-
|
|
817
|
-
# ...and now, the deformers stuff.
|
|
818
|
-
fbx_shape = elem_data_single_int64(root, b"Deformer", get_fbx_uuid_from_key(shape_key))
|
|
819
|
-
fbx_shape.add_string(fbx_name_class(me.name.encode(), b"Deformer"))
|
|
820
|
-
fbx_shape.add_string(b"BlendShape")
|
|
821
|
-
|
|
822
|
-
elem_data_single_int32(fbx_shape, b"Version", FBX_DEFORMER_SHAPE_VERSION)
|
|
823
|
-
|
|
824
|
-
for channel_key, shape, shape_verts_weights in channels:
|
|
825
|
-
fbx_channel = elem_data_single_int64(root, b"Deformer", get_fbx_uuid_from_key(channel_key))
|
|
826
|
-
fbx_channel.add_string(fbx_name_class(shape.name.encode(), b"SubDeformer"))
|
|
827
|
-
fbx_channel.add_string(b"BlendShapeChannel")
|
|
828
|
-
|
|
829
|
-
elem_data_single_int32(fbx_channel, b"Version", FBX_DEFORMER_SHAPECHANNEL_VERSION)
|
|
830
|
-
elem_data_single_float64(fbx_channel, b"DeformPercent", shape.value * 100.0) # Percents...
|
|
831
|
-
elem_data_single_float64_array(fbx_channel, b"FullWeights", shape_verts_weights)
|
|
832
|
-
|
|
833
|
-
# *WHY* add this in linked mesh properties too? *cry*
|
|
834
|
-
# No idea whether it’s percent here too, or more usual factor (assume percentage for now) :/
|
|
835
|
-
elem_props_template_set(fbx_me_tmpl, fbx_me_props, "p_number", shape.name.encode(), shape.value * 100.0,
|
|
836
|
-
animatable=True)
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
|
|
840
|
-
"""
|
|
841
|
-
Write the Mesh (Geometry) data block.
|
|
842
|
-
"""
|
|
843
|
-
# Ugly helper... :/
|
|
844
|
-
def _infinite_gen(val):
|
|
845
|
-
while 1:
|
|
846
|
-
yield val
|
|
847
|
-
|
|
848
|
-
me_key, me, _free = scene_data.data_meshes[me_obj]
|
|
849
|
-
|
|
850
|
-
# In case of multiple instances of same mesh, only write it once!
|
|
851
|
-
if me_key in done_meshes:
|
|
852
|
-
return
|
|
853
|
-
|
|
854
|
-
# No gscale/gmat here, all data are supposed to be in object space.
|
|
855
|
-
smooth_type = scene_data.settings.mesh_smooth_type
|
|
856
|
-
write_normals = True # smooth_type in {'OFF'}
|
|
857
|
-
|
|
858
|
-
do_bake_space_transform = me_obj.use_bake_space_transform(scene_data)
|
|
859
|
-
|
|
860
|
-
# Vertices are in object space, but we are post-multiplying all transforms with the inverse of the
|
|
861
|
-
# global matrix, so we need to apply the global matrix to the vertices to get the correct result.
|
|
862
|
-
geom_mat_co = scene_data.settings.global_matrix if do_bake_space_transform else None
|
|
863
|
-
# We need to apply the inverse transpose of the global matrix when transforming normals.
|
|
864
|
-
geom_mat_no = Matrix(scene_data.settings.global_matrix_inv_transposed) if do_bake_space_transform else None
|
|
865
|
-
if geom_mat_no is not None:
|
|
866
|
-
# Remove translation & scaling!
|
|
867
|
-
geom_mat_no.translation = Vector()
|
|
868
|
-
geom_mat_no.normalize()
|
|
869
|
-
|
|
870
|
-
geom = elem_data_single_int64(root, b"Geometry", get_fbx_uuid_from_key(me_key))
|
|
871
|
-
geom.add_string(fbx_name_class(me.name.encode(), b"Geometry"))
|
|
872
|
-
geom.add_string(b"Mesh")
|
|
873
|
-
|
|
874
|
-
tmpl = elem_props_template_init(scene_data.templates, b"Geometry")
|
|
875
|
-
props = elem_properties(geom)
|
|
876
|
-
|
|
877
|
-
# Custom properties.
|
|
878
|
-
if scene_data.settings.use_custom_props:
|
|
879
|
-
fbx_data_element_custom_properties(props, me)
|
|
880
|
-
|
|
881
|
-
# Subdivision levels. Take them from the first found subsurf modifier from the
|
|
882
|
-
# first object that has the mesh. Always write crease information if present,
|
|
883
|
-
# if the modifier explicitly uses creases ("use_creases" setting) and mesh lacks them,
|
|
884
|
-
# still provide zeros (see TODO comment below)
|
|
885
|
-
write_crease = False
|
|
886
|
-
if scene_data.settings.use_subsurf:
|
|
887
|
-
last_subsurf = None
|
|
888
|
-
for mod in me_obj.bdata.modifiers:
|
|
889
|
-
if not (mod.show_render or mod.show_viewport):
|
|
890
|
-
continue
|
|
891
|
-
if mod.type == 'SUBSURF' and mod.subdivision_type == 'CATMULL_CLARK':
|
|
892
|
-
last_subsurf = mod
|
|
893
|
-
|
|
894
|
-
if last_subsurf:
|
|
895
|
-
elem_data_single_int32(geom, b"Smoothness", 2) # Display control mesh and smoothed
|
|
896
|
-
if last_subsurf.boundary_smooth == "PRESERVE_CORNERS":
|
|
897
|
-
elem_data_single_int32(geom, b"BoundaryRule", 1) # CreaseAll
|
|
898
|
-
else:
|
|
899
|
-
elem_data_single_int32(geom, b"BoundaryRule", 2) # CreaseEdge
|
|
900
|
-
elem_data_single_int32(geom, b"PreviewDivisionLevels", last_subsurf.levels)
|
|
901
|
-
elem_data_single_int32(geom, b"RenderDivisionLevels", last_subsurf.render_levels)
|
|
902
|
-
|
|
903
|
-
elem_data_single_int32(geom, b"PreserveBorders", 0)
|
|
904
|
-
elem_data_single_int32(geom, b"PreserveHardEdges", 0)
|
|
905
|
-
elem_data_single_int32(geom, b"PropagateEdgeHardness", 0)
|
|
906
|
-
|
|
907
|
-
write_crease = last_subsurf.use_creases
|
|
908
|
-
write_crease = (write_crease or me.edge_creases)
|
|
909
|
-
|
|
910
|
-
elem_data_single_int32(geom, b"GeometryVersion", FBX_GEOMETRY_VERSION)
|
|
911
|
-
|
|
912
|
-
attributes = me.attributes
|
|
913
|
-
|
|
914
|
-
# Vertex cos.
|
|
915
|
-
pos_fbx_dtype = np.float64
|
|
916
|
-
t_pos = MESH_ATTRIBUTE_POSITION.to_ndarray(attributes)
|
|
917
|
-
elem_data_single_float64_array(geom, b"Vertices", vcos_transformed(t_pos, geom_mat_co, pos_fbx_dtype))
|
|
918
|
-
del t_pos
|
|
919
|
-
|
|
920
|
-
# Polygon indices.
|
|
921
|
-
#
|
|
922
|
-
# We do loose edges as two-vertices faces, if enabled...
|
|
923
|
-
#
|
|
924
|
-
# Note we have to process Edges in the same time, as they are based on poly's loops...
|
|
925
|
-
|
|
926
|
-
# Total number of loops, including any extra added for loose edges.
|
|
927
|
-
loop_nbr = len(me.loops)
|
|
928
|
-
|
|
929
|
-
# dtypes matching the C data. Matching the C datatype avoids iteration and casting of every element in foreach_get's
|
|
930
|
-
# C code.
|
|
931
|
-
bl_loop_index_dtype = np.uintc
|
|
932
|
-
|
|
933
|
-
# Start vertex indices of loops (corners). May contain elements for loops added for the export of loose edges.
|
|
934
|
-
t_lvi = MESH_ATTRIBUTE_CORNER_VERT.to_ndarray(attributes)
|
|
935
|
-
|
|
936
|
-
# Loop start indices of polygons. May contain elements for the polygons added for the export of loose edges.
|
|
937
|
-
t_ls = np.empty(len(me.polygons), dtype=bl_loop_index_dtype)
|
|
938
|
-
|
|
939
|
-
# Vertex indices of edges (unsorted, unlike Mesh.edge_keys), flattened into an array twice the length of the number
|
|
940
|
-
# of edges.
|
|
941
|
-
t_ev = MESH_ATTRIBUTE_EDGE_VERTS.to_ndarray(attributes)
|
|
942
|
-
# Each edge has two vertex indices, so it's useful to view the array as 2d where each element on the first axis is a
|
|
943
|
-
# pair of vertex indices
|
|
944
|
-
t_ev_pair_view = t_ev.view()
|
|
945
|
-
t_ev_pair_view.shape = (-1, 2)
|
|
946
|
-
|
|
947
|
-
# Edge indices of loops (corners). May contain elements for loops added for the export of loose edges.
|
|
948
|
-
t_lei = MESH_ATTRIBUTE_CORNER_EDGE.to_ndarray(attributes)
|
|
949
|
-
|
|
950
|
-
me.polygons.foreach_get("loop_start", t_ls)
|
|
951
|
-
|
|
952
|
-
# Add "fake" faces for loose edges. Each "fake" face consists of two loops creating a new 2-sided polygon.
|
|
953
|
-
if scene_data.settings.use_mesh_edges:
|
|
954
|
-
bl_edge_is_loose_dtype = bool
|
|
955
|
-
# Get the mask of edges that are loose
|
|
956
|
-
loose_mask = np.empty(len(me.edges), dtype=bl_edge_is_loose_dtype)
|
|
957
|
-
me.edges.foreach_get('is_loose', loose_mask)
|
|
958
|
-
|
|
959
|
-
indices_of_loose_edges = np.flatnonzero(loose_mask)
|
|
960
|
-
# Since we add two loops per loose edge, repeat the indices so that there's one for each new loop
|
|
961
|
-
new_loop_edge_indices = np.repeat(indices_of_loose_edges, 2)
|
|
962
|
-
|
|
963
|
-
# Get the loose edge vertex index pairs
|
|
964
|
-
t_le = t_ev_pair_view[loose_mask]
|
|
965
|
-
|
|
966
|
-
# append will automatically flatten the pairs in t_le
|
|
967
|
-
t_lvi = np.append(t_lvi, t_le)
|
|
968
|
-
t_lei = np.append(t_lei, new_loop_edge_indices)
|
|
969
|
-
# Two loops are added per loose edge
|
|
970
|
-
loop_nbr += 2 * len(t_le)
|
|
971
|
-
t_ls = np.append(t_ls, np.arange(len(me.loops), loop_nbr, 2, dtype=t_ls.dtype))
|
|
972
|
-
del t_le
|
|
973
|
-
del loose_mask
|
|
974
|
-
del indices_of_loose_edges
|
|
975
|
-
del new_loop_edge_indices
|
|
976
|
-
|
|
977
|
-
# Edges...
|
|
978
|
-
# Note: Edges are represented as a loop here: each edge uses a single index, which refers to the polygon array.
|
|
979
|
-
# The edge is made by the vertex indexed py this polygon's point and the next one on the same polygon.
|
|
980
|
-
# Advantage: Only one index per edge.
|
|
981
|
-
# Drawback: Only polygon's edges can be represented (that's why we have to add fake two-verts polygons
|
|
982
|
-
# for loose edges).
|
|
983
|
-
# We also have to store a mapping from real edges to their indices in this array, for edge-mapped data
|
|
984
|
-
# (like e.g. crease).
|
|
985
|
-
eli_fbx_dtype = np.int32
|
|
986
|
-
|
|
987
|
-
# Edge index of each unique edge-key, used to map per-edge data to unique edge-keys (t_pvi).
|
|
988
|
-
t_pvi_edge_indices = np.empty(0, dtype=t_lei.dtype)
|
|
989
|
-
|
|
990
|
-
pvi_fbx_dtype = np.int32
|
|
991
|
-
if t_ls.size and t_lvi.size:
|
|
992
|
-
# Get unsorted edge keys by indexing the edge->vertex-indices array by the loop->edge-index array.
|
|
993
|
-
t_pvi_edge_keys = t_ev_pair_view[t_lei]
|
|
994
|
-
|
|
995
|
-
# Sort each [edge_start_n, edge_end_n] pair to get edge keys. Heapsort seems to be the fastest for this specific
|
|
996
|
-
# use case.
|
|
997
|
-
t_pvi_edge_keys.sort(axis=1, kind='heapsort')
|
|
998
|
-
|
|
999
|
-
# Note that finding unique edge keys means that if there are multiple edges that share the same vertices (which
|
|
1000
|
-
# shouldn't normally happen), only the first edge found in loops will be exported along with its per-edge data.
|
|
1001
|
-
# To export separate edges that share the same vertices, fast_first_axis_unique can be replaced with np.unique
|
|
1002
|
-
# with t_lei as the first argument, finding unique edges rather than unique edge keys.
|
|
1003
|
-
#
|
|
1004
|
-
# Since we want the unique values in their original order, the only part we care about is the indices of the
|
|
1005
|
-
# first occurrence of the unique elements in t_pvi_edge_keys, so we can use our fast uniqueness helper function.
|
|
1006
|
-
t_eli = fast_first_axis_unique(t_pvi_edge_keys, return_unique=False, return_index=True)
|
|
1007
|
-
|
|
1008
|
-
# To get the indices of the elements in t_pvi_edge_keys that produce unique values, but in the original order of
|
|
1009
|
-
# t_pvi_edge_keys, t_eli must be sorted.
|
|
1010
|
-
# Due to loops and their edge keys tending to have a partial ordering within meshes, sorting with kind='stable'
|
|
1011
|
-
# with radix sort tends to be faster than the default of kind='quicksort' with introsort.
|
|
1012
|
-
t_eli.sort(kind='stable')
|
|
1013
|
-
|
|
1014
|
-
# Edge index of each element in unique t_pvi_edge_keys, used to map per-edge data such as sharp and creases.
|
|
1015
|
-
t_pvi_edge_indices = t_lei[t_eli]
|
|
1016
|
-
|
|
1017
|
-
# We have to ^-1 last index of each loop.
|
|
1018
|
-
# Ensure t_pvi is the correct number of bits before inverting.
|
|
1019
|
-
# t_lvi may be used again later, so always create a copy to avoid modifying it in the next step.
|
|
1020
|
-
t_pvi = t_lvi.astype(pvi_fbx_dtype)
|
|
1021
|
-
# The index of the end of each loop is one before the index of the start of the next loop.
|
|
1022
|
-
t_pvi[t_ls[1:] - 1] ^= -1
|
|
1023
|
-
# The index of the end of the last loop will be the very last index.
|
|
1024
|
-
t_pvi[-1] ^= -1
|
|
1025
|
-
del t_pvi_edge_keys
|
|
1026
|
-
else:
|
|
1027
|
-
# Should be empty, but make sure it's the correct type.
|
|
1028
|
-
t_pvi = np.empty(0, dtype=pvi_fbx_dtype)
|
|
1029
|
-
t_eli = np.empty(0, dtype=eli_fbx_dtype)
|
|
1030
|
-
|
|
1031
|
-
# And finally we can write data!
|
|
1032
|
-
t_pvi = astype_view_signedness(t_pvi, pvi_fbx_dtype)
|
|
1033
|
-
t_eli = astype_view_signedness(t_eli, eli_fbx_dtype)
|
|
1034
|
-
elem_data_single_int32_array(geom, b"PolygonVertexIndex", t_pvi)
|
|
1035
|
-
elem_data_single_int32_array(geom, b"Edges", t_eli)
|
|
1036
|
-
del t_pvi
|
|
1037
|
-
del t_eli
|
|
1038
|
-
del t_ev
|
|
1039
|
-
del t_ev_pair_view
|
|
1040
|
-
|
|
1041
|
-
# And now, layers!
|
|
1042
|
-
|
|
1043
|
-
# Smoothing.
|
|
1044
|
-
if smooth_type in {'FACE', 'EDGE', 'SMOOTH_GROUP'}:
|
|
1045
|
-
ps_fbx_dtype = np.int32
|
|
1046
|
-
_map = b""
|
|
1047
|
-
if smooth_type == 'FACE':
|
|
1048
|
-
# The FBX integer values are usually interpreted as boolean where 0 is False (sharp) and 1 is True
|
|
1049
|
-
# (smooth).
|
|
1050
|
-
# The values may also be used to represent smoothing group bitflags, but this does not seem well-supported.
|
|
1051
|
-
t_ps = MESH_ATTRIBUTE_SHARP_FACE.get_ndarray(attributes)
|
|
1052
|
-
if t_ps is not None:
|
|
1053
|
-
# FBX sharp is False, but Blender sharp is True, so invert.
|
|
1054
|
-
t_ps = np.logical_not(t_ps)
|
|
1055
|
-
else:
|
|
1056
|
-
# The mesh has no "sharp_face" attribute, so every face is smooth.
|
|
1057
|
-
t_ps = np.ones(len(me.polygons), dtype=ps_fbx_dtype)
|
|
1058
|
-
_map = b"ByPolygon"
|
|
1059
|
-
elif smooth_type == 'SMOOTH_GROUP':
|
|
1060
|
-
smoothing_groups = me.calc_smooth_groups(use_bitflags=True, use_boundary_vertices_for_bitflags=True)[0]
|
|
1061
|
-
t_ps = np.asarray(smoothing_groups, dtype=ps_fbx_dtype)
|
|
1062
|
-
_map = b"ByPolygon"
|
|
1063
|
-
else: # EDGE
|
|
1064
|
-
_map = b"ByEdge"
|
|
1065
|
-
if t_pvi_edge_indices.size:
|
|
1066
|
-
# Write Edge Smoothing.
|
|
1067
|
-
# Note edge is sharp also if it's used by more than two faces, or one of its faces is flat.
|
|
1068
|
-
mesh_poly_nbr = len(me.polygons)
|
|
1069
|
-
mesh_edge_nbr = len(me.edges)
|
|
1070
|
-
mesh_loop_nbr = len(me.loops)
|
|
1071
|
-
# t_ls and t_lei may contain extra polygons or loops added for loose edges that are not present in the
|
|
1072
|
-
# mesh data, so create views that exclude the extra data added for loose edges.
|
|
1073
|
-
mesh_t_ls_view = t_ls[:mesh_poly_nbr]
|
|
1074
|
-
mesh_t_lei_view = t_lei[:mesh_loop_nbr]
|
|
1075
|
-
|
|
1076
|
-
# - Get sharp edges from edges used by more than two loops (and therefore more than two faces)
|
|
1077
|
-
e_more_than_two_faces_mask = np.bincount(mesh_t_lei_view, minlength=mesh_edge_nbr) > 2
|
|
1078
|
-
|
|
1079
|
-
# - Get sharp edges from the "sharp_edge" attribute. The attribute may not exist, in which case, there
|
|
1080
|
-
# are no edges marked as sharp.
|
|
1081
|
-
e_use_sharp_mask = MESH_ATTRIBUTE_SHARP_EDGE.get_ndarray(attributes)
|
|
1082
|
-
if e_use_sharp_mask is not None:
|
|
1083
|
-
# - Combine with edges that are sharp because they're in more than two faces
|
|
1084
|
-
e_use_sharp_mask = np.logical_or(e_use_sharp_mask, e_more_than_two_faces_mask, out=e_use_sharp_mask)
|
|
1085
|
-
else:
|
|
1086
|
-
e_use_sharp_mask = e_more_than_two_faces_mask
|
|
1087
|
-
|
|
1088
|
-
# - Get sharp edges from flat shaded faces
|
|
1089
|
-
p_flat_mask = MESH_ATTRIBUTE_SHARP_FACE.get_ndarray(attributes)
|
|
1090
|
-
if p_flat_mask is not None:
|
|
1091
|
-
# Convert flat shaded polygons to flat shaded loops by repeating each element by the number of sides
|
|
1092
|
-
# of that polygon.
|
|
1093
|
-
# Polygon sides can be calculated from the element-wise difference of loop starts appended by the
|
|
1094
|
-
# number of loops. Alternatively, polygon sides can be retrieved directly from the 'loop_total'
|
|
1095
|
-
# attribute of polygons, but since we already have t_ls, it tends to be quicker to calculate from
|
|
1096
|
-
# t_ls.
|
|
1097
|
-
polygon_sides = np.diff(mesh_t_ls_view, append=mesh_loop_nbr)
|
|
1098
|
-
p_flat_loop_mask = np.repeat(p_flat_mask, polygon_sides)
|
|
1099
|
-
# Convert flat shaded loops to flat shaded (sharp) edge indices.
|
|
1100
|
-
# Note that if an edge is in multiple loops that are part of flat shaded faces, its edge index will
|
|
1101
|
-
# end up in sharp_edge_indices_from_polygons multiple times.
|
|
1102
|
-
sharp_edge_indices_from_polygons = mesh_t_lei_view[p_flat_loop_mask]
|
|
1103
|
-
|
|
1104
|
-
# - Combine with edges that are sharp because a polygon they're in has flat shading
|
|
1105
|
-
e_use_sharp_mask[sharp_edge_indices_from_polygons] = True
|
|
1106
|
-
del sharp_edge_indices_from_polygons
|
|
1107
|
-
del p_flat_loop_mask
|
|
1108
|
-
del polygon_sides
|
|
1109
|
-
del p_flat_mask
|
|
1110
|
-
|
|
1111
|
-
# - Convert sharp edges to sharp edge keys (t_pvi)
|
|
1112
|
-
ek_use_sharp_mask = e_use_sharp_mask[t_pvi_edge_indices]
|
|
1113
|
-
|
|
1114
|
-
# - Sharp edges are indicated in FBX as zero (False), so invert
|
|
1115
|
-
t_ps = np.invert(ek_use_sharp_mask, out=ek_use_sharp_mask)
|
|
1116
|
-
del ek_use_sharp_mask
|
|
1117
|
-
del e_use_sharp_mask
|
|
1118
|
-
del mesh_t_lei_view
|
|
1119
|
-
del mesh_t_ls_view
|
|
1120
|
-
else:
|
|
1121
|
-
t_ps = np.empty(0, dtype=ps_fbx_dtype)
|
|
1122
|
-
t_ps = t_ps.astype(ps_fbx_dtype, copy=False)
|
|
1123
|
-
lay_smooth = elem_data_single_int32(geom, b"LayerElementSmoothing", 0)
|
|
1124
|
-
elem_data_single_int32(lay_smooth, b"Version", FBX_GEOMETRY_SMOOTHING_VERSION)
|
|
1125
|
-
elem_data_single_string(lay_smooth, b"Name", b"")
|
|
1126
|
-
elem_data_single_string(lay_smooth, b"MappingInformationType", _map)
|
|
1127
|
-
elem_data_single_string(lay_smooth, b"ReferenceInformationType", b"Direct")
|
|
1128
|
-
elem_data_single_int32_array(lay_smooth, b"Smoothing", t_ps) # Sight, int32 for bool...
|
|
1129
|
-
del t_ps
|
|
1130
|
-
del t_ls
|
|
1131
|
-
del t_lei
|
|
1132
|
-
|
|
1133
|
-
# Edge crease for subdivision
|
|
1134
|
-
if write_crease:
|
|
1135
|
-
ec_fbx_dtype = np.float64
|
|
1136
|
-
if t_pvi_edge_indices.size:
|
|
1137
|
-
ec_bl_dtype = np.single
|
|
1138
|
-
edge_creases = me.edge_creases
|
|
1139
|
-
if edge_creases:
|
|
1140
|
-
t_ec_raw = np.empty(len(me.edges), dtype=ec_bl_dtype)
|
|
1141
|
-
edge_creases.data.foreach_get("value", t_ec_raw)
|
|
1142
|
-
|
|
1143
|
-
# Convert to t_pvi edge-keys.
|
|
1144
|
-
t_ec_ek_raw = t_ec_raw[t_pvi_edge_indices]
|
|
1145
|
-
|
|
1146
|
-
# Blender squares those values before sending them to OpenSubdiv, when other software don't,
|
|
1147
|
-
# so we need to compensate that to get similar results through FBX...
|
|
1148
|
-
# Use the precision of the fbx dtype for the calculation since it's usually higher precision.
|
|
1149
|
-
t_ec_ek_raw = t_ec_ek_raw.astype(ec_fbx_dtype, copy=False)
|
|
1150
|
-
t_ec = np.square(t_ec_ek_raw, out=t_ec_ek_raw)
|
|
1151
|
-
del t_ec_ek_raw
|
|
1152
|
-
del t_ec_raw
|
|
1153
|
-
else:
|
|
1154
|
-
# todo: Blender edge creases are optional now, we may be able to avoid writing the array to FBX when
|
|
1155
|
-
# there are no edge creases.
|
|
1156
|
-
t_ec = np.zeros(t_pvi_edge_indices.shape, dtype=ec_fbx_dtype)
|
|
1157
|
-
else:
|
|
1158
|
-
t_ec = np.empty(0, dtype=ec_fbx_dtype)
|
|
1159
|
-
|
|
1160
|
-
lay_crease = elem_data_single_int32(geom, b"LayerElementEdgeCrease", 0)
|
|
1161
|
-
elem_data_single_int32(lay_crease, b"Version", FBX_GEOMETRY_CREASE_VERSION)
|
|
1162
|
-
elem_data_single_string(lay_crease, b"Name", b"")
|
|
1163
|
-
elem_data_single_string(lay_crease, b"MappingInformationType", b"ByEdge")
|
|
1164
|
-
elem_data_single_string(lay_crease, b"ReferenceInformationType", b"Direct")
|
|
1165
|
-
elem_data_single_float64_array(lay_crease, b"EdgeCrease", t_ec)
|
|
1166
|
-
del t_ec
|
|
1167
|
-
|
|
1168
|
-
# And we are done with edges!
|
|
1169
|
-
del t_pvi_edge_indices
|
|
1170
|
-
|
|
1171
|
-
# Loop normals.
|
|
1172
|
-
tspacenumber = 0
|
|
1173
|
-
if write_normals:
|
|
1174
|
-
normal_bl_dtype = np.single
|
|
1175
|
-
normal_fbx_dtype = np.float64
|
|
1176
|
-
match me.normals_domain:
|
|
1177
|
-
case 'POINT':
|
|
1178
|
-
# All faces are smooth shaded, so we can get normals from the vertices.
|
|
1179
|
-
normal_source = me.vertex_normals
|
|
1180
|
-
normal_mapping = b"ByVertice"
|
|
1181
|
-
# External software support for b"ByPolygon" normals does not seem to be as widely available as the other
|
|
1182
|
-
# mappings. See blender/blender#117470.
|
|
1183
|
-
# case 'FACE':
|
|
1184
|
-
# # Either all faces or all edges are sharp, so we can get normals from the faces.
|
|
1185
|
-
# normal_source = me.polygon_normals
|
|
1186
|
-
# normal_mapping = b"ByPolygon"
|
|
1187
|
-
case 'CORNER' | 'FACE':
|
|
1188
|
-
# We have a mix of sharp/smooth edges/faces or custom normals, so need to get normals from corners.
|
|
1189
|
-
normal_source = me.corner_normals
|
|
1190
|
-
normal_mapping = b"ByPolygonVertex"
|
|
1191
|
-
case _:
|
|
1192
|
-
# Unreachable
|
|
1193
|
-
raise AssertionError("Unexpected normals domain '%s'" % me.normals_domain)
|
|
1194
|
-
# Each normal has 3 components, so the length is multiplied by 3.
|
|
1195
|
-
t_normal = np.empty(len(normal_source) * 3, dtype=normal_bl_dtype)
|
|
1196
|
-
normal_source.foreach_get("vector", t_normal)
|
|
1197
|
-
t_normal = nors_transformed(t_normal, geom_mat_no, normal_fbx_dtype)
|
|
1198
|
-
normal_idx_fbx_dtype = np.int32
|
|
1199
|
-
lay_nor = elem_data_single_int32(geom, b"LayerElementNormal", 0)
|
|
1200
|
-
elem_data_single_int32(lay_nor, b"Version", FBX_GEOMETRY_NORMAL_VERSION)
|
|
1201
|
-
elem_data_single_string(lay_nor, b"Name", b"")
|
|
1202
|
-
elem_data_single_string(lay_nor, b"MappingInformationType", normal_mapping)
|
|
1203
|
-
# FBX SDK documentation says that normals should use IndexToDirect.
|
|
1204
|
-
elem_data_single_string(lay_nor, b"ReferenceInformationType", b"IndexToDirect")
|
|
1205
|
-
|
|
1206
|
-
# Workaround for Unity FBX import issue where the normals are considered invalid if any normals are
|
|
1207
|
-
# deduplicated. See #123088.
|
|
1208
|
-
if normal_mapping == b"ByVertice":
|
|
1209
|
-
# Write every normal without any deduplication, so the indices array will be [0, 1, 2, ..., n].
|
|
1210
|
-
t_normal_idx = np.arange(len(t_normal.reshape(-1, 3)), dtype=normal_idx_fbx_dtype)
|
|
1211
|
-
else:
|
|
1212
|
-
# Tuple of unique sorted normals and then the index in the unique sorted normals of each normal in t_normal.
|
|
1213
|
-
# Since we don't care about how the normals are sorted, only that they're unique, we can use the fast unique
|
|
1214
|
-
# helper function.
|
|
1215
|
-
t_normal, t_normal_idx = fast_first_axis_unique(t_normal.reshape(-1, 3), return_inverse=True)
|
|
1216
|
-
|
|
1217
|
-
# Convert to the type for fbx
|
|
1218
|
-
t_normal_idx = astype_view_signedness(t_normal_idx, normal_idx_fbx_dtype)
|
|
1219
|
-
|
|
1220
|
-
elem_data_single_float64_array(lay_nor, b"Normals", t_normal)
|
|
1221
|
-
# Normal weights, no idea what it is.
|
|
1222
|
-
# t_normal_w = np.zeros(len(t_normal), dtype=np.float64)
|
|
1223
|
-
# elem_data_single_float64_array(lay_nor, b"NormalsW", t_normal_w)
|
|
1224
|
-
|
|
1225
|
-
elem_data_single_int32_array(lay_nor, b"NormalsIndex", t_normal_idx)
|
|
1226
|
-
|
|
1227
|
-
del t_normal_idx
|
|
1228
|
-
# del t_normal_w
|
|
1229
|
-
del t_normal
|
|
1230
|
-
|
|
1231
|
-
# tspace
|
|
1232
|
-
if scene_data.settings.use_tspace:
|
|
1233
|
-
tspacenumber = len(me.uv_layers)
|
|
1234
|
-
if tspacenumber:
|
|
1235
|
-
# We can only compute tspace on tessellated meshes, need to check that here...
|
|
1236
|
-
lt_bl_dtype = np.uintc
|
|
1237
|
-
t_lt = np.empty(len(me.polygons), dtype=lt_bl_dtype)
|
|
1238
|
-
me.polygons.foreach_get("loop_total", t_lt)
|
|
1239
|
-
if (t_lt > 4).any():
|
|
1240
|
-
del t_lt
|
|
1241
|
-
scene_data.settings.report(
|
|
1242
|
-
{'WARNING'},
|
|
1243
|
-
tip_("Mesh '%s' has polygons with more than 4 vertices, "
|
|
1244
|
-
"cannot compute/export tangent space for it") % me.name)
|
|
1245
|
-
else:
|
|
1246
|
-
del t_lt
|
|
1247
|
-
num_loops = len(me.loops)
|
|
1248
|
-
t_ln = np.empty(num_loops * 3, dtype=normal_bl_dtype)
|
|
1249
|
-
# t_lnw = np.zeros(len(me.loops), dtype=np.float64)
|
|
1250
|
-
# WARNING: Since tangent layers are recomputed inside the loop, do not directly iterate over the
|
|
1251
|
-
# uvlayers. Instead, cache their keys (names), and use this cached data inside the loop to compute
|
|
1252
|
-
# the tangent layers.
|
|
1253
|
-
uvlayer_names = [uvl.name for uvl in me.uv_layers]
|
|
1254
|
-
for idx, name in enumerate(uvlayer_names):
|
|
1255
|
-
# Annoying, `me.calc_tangent` errors in case there is no geometry...
|
|
1256
|
-
if num_loops > 0:
|
|
1257
|
-
me.calc_tangents(uvmap=name)
|
|
1258
|
-
|
|
1259
|
-
# Loop bitangents (aka binormals).
|
|
1260
|
-
# NOTE: this is not supported by importer currently.
|
|
1261
|
-
me.loops.foreach_get("bitangent", t_ln)
|
|
1262
|
-
lay_nor = elem_data_single_int32(geom, b"LayerElementBinormal", idx)
|
|
1263
|
-
elem_data_single_int32(lay_nor, b"Version", FBX_GEOMETRY_BINORMAL_VERSION)
|
|
1264
|
-
elem_data_single_string_unicode(lay_nor, b"Name", name)
|
|
1265
|
-
elem_data_single_string(lay_nor, b"MappingInformationType", b"ByPolygonVertex")
|
|
1266
|
-
elem_data_single_string(lay_nor, b"ReferenceInformationType", b"Direct")
|
|
1267
|
-
elem_data_single_float64_array(lay_nor, b"Binormals",
|
|
1268
|
-
nors_transformed(t_ln, geom_mat_no, normal_fbx_dtype))
|
|
1269
|
-
# Binormal weights, no idea what it is.
|
|
1270
|
-
# elem_data_single_float64_array(lay_nor, b"BinormalsW", t_lnw)
|
|
1271
|
-
|
|
1272
|
-
# Loop tangents.
|
|
1273
|
-
# NOTE: this is not supported by importer currently.
|
|
1274
|
-
me.loops.foreach_get("tangent", t_ln)
|
|
1275
|
-
lay_nor = elem_data_single_int32(geom, b"LayerElementTangent", idx)
|
|
1276
|
-
elem_data_single_int32(lay_nor, b"Version", FBX_GEOMETRY_TANGENT_VERSION)
|
|
1277
|
-
elem_data_single_string_unicode(lay_nor, b"Name", name)
|
|
1278
|
-
elem_data_single_string(lay_nor, b"MappingInformationType", b"ByPolygonVertex")
|
|
1279
|
-
elem_data_single_string(lay_nor, b"ReferenceInformationType", b"Direct")
|
|
1280
|
-
elem_data_single_float64_array(lay_nor, b"Tangents",
|
|
1281
|
-
nors_transformed(t_ln, geom_mat_no, normal_fbx_dtype))
|
|
1282
|
-
# Tangent weights, no idea what it is.
|
|
1283
|
-
# elem_data_single_float64_array(lay_nor, b"TangentsW", t_lnw)
|
|
1284
|
-
|
|
1285
|
-
del t_ln
|
|
1286
|
-
# del t_lnw
|
|
1287
|
-
me.free_tangents()
|
|
1288
|
-
|
|
1289
|
-
# Write VertexColor Layers.
|
|
1290
|
-
colors_type = scene_data.settings.colors_type
|
|
1291
|
-
vcolnumber = 0 if colors_type == 'NONE' else len(me.color_attributes)
|
|
1292
|
-
if vcolnumber:
|
|
1293
|
-
color_prop_name = "color_srgb" if colors_type == 'SRGB' else "color"
|
|
1294
|
-
# ByteColorAttribute color also gets returned by the API as single precision float
|
|
1295
|
-
bl_lc_dtype = np.single
|
|
1296
|
-
fbx_lc_dtype = np.float64
|
|
1297
|
-
fbx_lcidx_dtype = np.int32
|
|
1298
|
-
|
|
1299
|
-
color_attributes = me.color_attributes
|
|
1300
|
-
if scene_data.settings.prioritize_active_color:
|
|
1301
|
-
active_color = me.color_attributes.active_color
|
|
1302
|
-
color_attributes = sorted(color_attributes, key=lambda x: x == active_color, reverse=True)
|
|
1303
|
-
|
|
1304
|
-
for colindex, collayer in enumerate(color_attributes):
|
|
1305
|
-
is_point = collayer.domain == "POINT"
|
|
1306
|
-
vcollen = len(me.vertices if is_point else me.loops)
|
|
1307
|
-
# Each rgba component is flattened in the array
|
|
1308
|
-
t_lc = np.empty(vcollen * 4, dtype=bl_lc_dtype)
|
|
1309
|
-
collayer.data.foreach_get(color_prop_name, t_lc)
|
|
1310
|
-
lay_vcol = elem_data_single_int32(geom, b"LayerElementColor", colindex)
|
|
1311
|
-
elem_data_single_int32(lay_vcol, b"Version", FBX_GEOMETRY_VCOLOR_VERSION)
|
|
1312
|
-
elem_data_single_string_unicode(lay_vcol, b"Name", collayer.name)
|
|
1313
|
-
elem_data_single_string(lay_vcol, b"MappingInformationType", b"ByPolygonVertex")
|
|
1314
|
-
elem_data_single_string(lay_vcol, b"ReferenceInformationType", b"IndexToDirect")
|
|
1315
|
-
|
|
1316
|
-
# Use the fast uniqueness helper function since we don't care about sorting.
|
|
1317
|
-
t_lc, col_indices = fast_first_axis_unique(t_lc.reshape(-1, 4), return_inverse=True)
|
|
1318
|
-
|
|
1319
|
-
if is_point:
|
|
1320
|
-
# for "point" domain colors, we could directly emit them
|
|
1321
|
-
# with a "ByVertex" mapping type, but some software does not
|
|
1322
|
-
# properly understand that. So expand to full "ByPolygonVertex"
|
|
1323
|
-
# index map.
|
|
1324
|
-
# Ignore loops added for loose edges.
|
|
1325
|
-
col_indices = col_indices[t_lvi[:len(me.loops)]]
|
|
1326
|
-
|
|
1327
|
-
t_lc = t_lc.astype(fbx_lc_dtype, copy=False)
|
|
1328
|
-
col_indices = astype_view_signedness(col_indices, fbx_lcidx_dtype)
|
|
1329
|
-
|
|
1330
|
-
elem_data_single_float64_array(lay_vcol, b"Colors", t_lc)
|
|
1331
|
-
elem_data_single_int32_array(lay_vcol, b"ColorIndex", col_indices)
|
|
1332
|
-
|
|
1333
|
-
del t_lc
|
|
1334
|
-
del col_indices
|
|
1335
|
-
|
|
1336
|
-
# Write UV layers.
|
|
1337
|
-
# Note: LayerElementTexture is deprecated since FBX 2011 - luckily!
|
|
1338
|
-
# Textures are now only related to materials, in FBX!
|
|
1339
|
-
uvnumber = len(me.uv_layers)
|
|
1340
|
-
if uvnumber:
|
|
1341
|
-
luv_bl_dtype = np.single
|
|
1342
|
-
luv_fbx_dtype = np.float64
|
|
1343
|
-
lv_idx_fbx_dtype = np.int32
|
|
1344
|
-
|
|
1345
|
-
t_luv = np.empty(len(me.loops) * 2, dtype=luv_bl_dtype)
|
|
1346
|
-
# Fast view for sort-based uniqueness of pairs.
|
|
1347
|
-
t_luv_fast_pair_view = fast_first_axis_flat(t_luv.reshape(-1, 2))
|
|
1348
|
-
# It must be a view of t_luv otherwise it won't update when t_luv is updated.
|
|
1349
|
-
assert(t_luv_fast_pair_view.base is t_luv)
|
|
1350
|
-
|
|
1351
|
-
# Looks like this mapping is also expected to convey UV islands (arg..... :((((( ).
|
|
1352
|
-
# So we need to generate unique triplets (uv, vertex_idx) here, not only just based on UV values.
|
|
1353
|
-
# Ignore loops added for loose edges.
|
|
1354
|
-
t_lvidx = t_lvi[:len(me.loops)]
|
|
1355
|
-
|
|
1356
|
-
# If we were to create a combined array of (uv, vertex_idx) elements, we could find unique triplets by sorting
|
|
1357
|
-
# that array by first sorting by the vertex_idx column and then sorting by the uv column using a stable sorting
|
|
1358
|
-
# algorithm.
|
|
1359
|
-
# This is exactly what we'll do, but without creating the combined array, because only the uv elements are
|
|
1360
|
-
# included in the export and the vertex_idx column is the same for every uv layer.
|
|
1361
|
-
|
|
1362
|
-
# Because the vertex_idx column is the same for every uv layer, the vertex_idx column can be sorted in advance.
|
|
1363
|
-
# argsort gets the indices that sort the array, which are needed to be able to sort the array of uv pairs in the
|
|
1364
|
-
# same way to create the indices that recreate the full uvs from the unique uvs.
|
|
1365
|
-
# Loops and vertices tend to naturally have a partial ordering, which makes sorting with kind='stable' (radix
|
|
1366
|
-
# sort) faster than the default of kind='quicksort' (introsort) in most cases.
|
|
1367
|
-
perm_vidx = t_lvidx.argsort(kind='stable')
|
|
1368
|
-
|
|
1369
|
-
# Mask and uv indices arrays will be modified and re-used by each uv layer.
|
|
1370
|
-
unique_mask = np.empty(len(me.loops), dtype=np.bool_)
|
|
1371
|
-
unique_mask[:1] = True
|
|
1372
|
-
uv_indices = np.empty(len(me.loops), dtype=lv_idx_fbx_dtype)
|
|
1373
|
-
|
|
1374
|
-
for uvindex, uvlayer in enumerate(me.uv_layers):
|
|
1375
|
-
lay_uv = elem_data_single_int32(geom, b"LayerElementUV", uvindex)
|
|
1376
|
-
elem_data_single_int32(lay_uv, b"Version", FBX_GEOMETRY_UV_VERSION)
|
|
1377
|
-
elem_data_single_string_unicode(lay_uv, b"Name", uvlayer.name)
|
|
1378
|
-
elem_data_single_string(lay_uv, b"MappingInformationType", b"ByPolygonVertex")
|
|
1379
|
-
elem_data_single_string(lay_uv, b"ReferenceInformationType", b"IndexToDirect")
|
|
1380
|
-
|
|
1381
|
-
uvlayer.uv.foreach_get("vector", t_luv)
|
|
1382
|
-
|
|
1383
|
-
# t_luv_fast_pair_view is a view in a dtype that compares elements by individual bytes, but float types have
|
|
1384
|
-
# separate byte representations of positive and negative zero. For uniqueness, these should be considered
|
|
1385
|
-
# the same, so replace all -0.0 with 0.0 in advance.
|
|
1386
|
-
t_luv[t_luv == -0.0] = 0.0
|
|
1387
|
-
|
|
1388
|
-
# These steps to create unique_uv_pairs are the same as how np.unique would find unique values by sorting a
|
|
1389
|
-
# structured array where each element is a triplet of (uv, vertex_idx), except uv and vertex_idx are
|
|
1390
|
-
# separate arrays here and vertex_idx has already been sorted in advance.
|
|
1391
|
-
|
|
1392
|
-
# Sort according to the vertex_idx column, using the precalculated indices that sort it.
|
|
1393
|
-
sorted_t_luv_fast = t_luv_fast_pair_view[perm_vidx]
|
|
1394
|
-
|
|
1395
|
-
# Get the indices that would sort the sorted uv pairs. Stable sorting must be used to maintain the sorting
|
|
1396
|
-
# of the vertex indices.
|
|
1397
|
-
perm_uv_pairs = sorted_t_luv_fast.argsort(kind='stable')
|
|
1398
|
-
# Use the indices to sort both the uv pairs and the vertex_idx columns.
|
|
1399
|
-
perm_combined = perm_vidx[perm_uv_pairs]
|
|
1400
|
-
sorted_vidx = t_lvidx[perm_combined]
|
|
1401
|
-
sorted_t_luv_fast = sorted_t_luv_fast[perm_uv_pairs]
|
|
1402
|
-
|
|
1403
|
-
# Create a mask where either the uv pair doesn't equal the previous value in the array, or the vertex index
|
|
1404
|
-
# doesn't equal the previous value, these will be the unique uv-vidx triplets.
|
|
1405
|
-
# For an imaginary triplet array:
|
|
1406
|
-
# ...
|
|
1407
|
-
# [(0.4, 0.2), 0]
|
|
1408
|
-
# [(0.4, 0.2), 1] -> Unique because vertex index different from previous
|
|
1409
|
-
# [(0.4, 0.2), 2] -> Unique because vertex index different from previous
|
|
1410
|
-
# [(0.7, 0.6), 2] -> Unique because uv different from previous
|
|
1411
|
-
# [(0.7, 0.6), 2]
|
|
1412
|
-
# ...
|
|
1413
|
-
# Output the result into unique_mask.
|
|
1414
|
-
np.logical_or(sorted_t_luv_fast[1:] != sorted_t_luv_fast[:-1], sorted_vidx[1:] != sorted_vidx[:-1],
|
|
1415
|
-
out=unique_mask[1:])
|
|
1416
|
-
|
|
1417
|
-
# Get each uv pair marked as unique by the unique_mask and then view as the original dtype.
|
|
1418
|
-
unique_uvs = sorted_t_luv_fast[unique_mask].view(luv_bl_dtype)
|
|
1419
|
-
|
|
1420
|
-
# NaN values are considered invalid and indicate a bug somewhere else in Blender or in an addon, we want
|
|
1421
|
-
# these bugs to be reported instead of hiding them by allowing the export to continue.
|
|
1422
|
-
if np.isnan(unique_uvs).any():
|
|
1423
|
-
raise RuntimeError("UV layer %s on %r has invalid UVs containing NaN values" % (uvlayer.name, me))
|
|
1424
|
-
|
|
1425
|
-
# Convert to the type needed for fbx
|
|
1426
|
-
unique_uvs = unique_uvs.astype(luv_fbx_dtype, copy=False)
|
|
1427
|
-
|
|
1428
|
-
# Set the indices of pairs in unique_uvs that reconstruct the pairs in t_luv into uv_indices.
|
|
1429
|
-
# uv_indices will then be the same as an inverse array returned by np.unique with return_inverse=True.
|
|
1430
|
-
uv_indices[perm_combined] = np.cumsum(unique_mask, dtype=uv_indices.dtype) - 1
|
|
1431
|
-
|
|
1432
|
-
elem_data_single_float64_array(lay_uv, b"UV", unique_uvs)
|
|
1433
|
-
elem_data_single_int32_array(lay_uv, b"UVIndex", uv_indices)
|
|
1434
|
-
del unique_uvs
|
|
1435
|
-
del sorted_t_luv_fast
|
|
1436
|
-
del sorted_vidx
|
|
1437
|
-
del perm_uv_pairs
|
|
1438
|
-
del perm_combined
|
|
1439
|
-
del uv_indices
|
|
1440
|
-
del unique_mask
|
|
1441
|
-
del perm_vidx
|
|
1442
|
-
del t_lvidx
|
|
1443
|
-
del t_luv
|
|
1444
|
-
del t_luv_fast_pair_view
|
|
1445
|
-
del t_lvi
|
|
1446
|
-
|
|
1447
|
-
# Face's materials.
|
|
1448
|
-
me_fbxmaterials_idx = scene_data.mesh_material_indices.get(me)
|
|
1449
|
-
if me_fbxmaterials_idx is not None:
|
|
1450
|
-
# We cannot use me.materials here, as this array is filled with None in case materials are linked to object...
|
|
1451
|
-
me_blmaterials = me_obj.materials
|
|
1452
|
-
if me_fbxmaterials_idx and me_blmaterials:
|
|
1453
|
-
lay_ma = elem_data_single_int32(geom, b"LayerElementMaterial", 0)
|
|
1454
|
-
elem_data_single_int32(lay_ma, b"Version", FBX_GEOMETRY_MATERIAL_VERSION)
|
|
1455
|
-
elem_data_single_string(lay_ma, b"Name", b"")
|
|
1456
|
-
nbr_mats = len(me_fbxmaterials_idx)
|
|
1457
|
-
multiple_fbx_mats = nbr_mats > 1
|
|
1458
|
-
# If a mesh does not have more than one material its material_index attribute can be ignored.
|
|
1459
|
-
# If a mesh has multiple materials but all its polygons are assigned to the first material, its
|
|
1460
|
-
# material_index attribute may not exist.
|
|
1461
|
-
t_pm = None if not multiple_fbx_mats else MESH_ATTRIBUTE_MATERIAL_INDEX.get_ndarray(attributes)
|
|
1462
|
-
if t_pm is not None:
|
|
1463
|
-
fbx_pm_dtype = np.int32
|
|
1464
|
-
|
|
1465
|
-
# We have to validate mat indices, and map them to FBX indices.
|
|
1466
|
-
# Note a mat might not be in me_fbxmaterials_idx (e.g. node mats are ignored).
|
|
1467
|
-
|
|
1468
|
-
# The first valid material will be used for materials out of bounds of me_blmaterials or materials not
|
|
1469
|
-
# in me_fbxmaterials_idx.
|
|
1470
|
-
def_me_blmaterial_idx, def_ma = next(
|
|
1471
|
-
(i, me_fbxmaterials_idx[m]) for i, m in enumerate(me_blmaterials) if m in me_fbxmaterials_idx)
|
|
1472
|
-
|
|
1473
|
-
# Set material indices that are out of bounds to the default material index
|
|
1474
|
-
mat_idx_limit = len(me_blmaterials)
|
|
1475
|
-
# Material indices shouldn't be negative, but they technically could be. Viewing as unsigned before
|
|
1476
|
-
# checking for indices that are too large means that a single >= check will pick up both negative
|
|
1477
|
-
# indices and indices that are too large.
|
|
1478
|
-
t_pm[t_pm.view("u%i" % t_pm.itemsize) >= mat_idx_limit] = def_me_blmaterial_idx
|
|
1479
|
-
|
|
1480
|
-
# Map to FBX indices. Materials not in me_fbxmaterials_idx will be set to the default material index.
|
|
1481
|
-
blmat_fbx_idx = np.fromiter((me_fbxmaterials_idx.get(m, def_ma) for m in me_blmaterials),
|
|
1482
|
-
dtype=fbx_pm_dtype)
|
|
1483
|
-
t_pm = blmat_fbx_idx[t_pm]
|
|
1484
|
-
|
|
1485
|
-
elem_data_single_string(lay_ma, b"MappingInformationType", b"ByPolygon")
|
|
1486
|
-
# XXX Logically, should be "Direct" reference type, since we do not have any index array, and have one
|
|
1487
|
-
# value per polygon...
|
|
1488
|
-
# But looks like FBX expects it to be IndexToDirect here (maybe because materials are already
|
|
1489
|
-
# indices??? *sigh*).
|
|
1490
|
-
elem_data_single_string(lay_ma, b"ReferenceInformationType", b"IndexToDirect")
|
|
1491
|
-
elem_data_single_int32_array(lay_ma, b"Materials", t_pm)
|
|
1492
|
-
else:
|
|
1493
|
-
elem_data_single_string(lay_ma, b"MappingInformationType", b"AllSame")
|
|
1494
|
-
elem_data_single_string(lay_ma, b"ReferenceInformationType", b"IndexToDirect")
|
|
1495
|
-
if multiple_fbx_mats:
|
|
1496
|
-
# There's no material_index attribute, so every material index is effectively zero.
|
|
1497
|
-
# In the order of the mesh's materials, get the FBX index of the first material that is exported.
|
|
1498
|
-
all_same_idx = next(me_fbxmaterials_idx[m] for m in me_blmaterials if m in me_fbxmaterials_idx)
|
|
1499
|
-
else:
|
|
1500
|
-
# There's only one fbx material, so the index will always be zero.
|
|
1501
|
-
all_same_idx = 0
|
|
1502
|
-
elem_data_single_int32_array(lay_ma, b"Materials", [all_same_idx])
|
|
1503
|
-
del t_pm
|
|
1504
|
-
|
|
1505
|
-
# And the "layer TOC"...
|
|
1506
|
-
|
|
1507
|
-
layer = elem_data_single_int32(geom, b"Layer", 0)
|
|
1508
|
-
elem_data_single_int32(layer, b"Version", FBX_GEOMETRY_LAYER_VERSION)
|
|
1509
|
-
if write_normals:
|
|
1510
|
-
lay_nor = elem_empty(layer, b"LayerElement")
|
|
1511
|
-
elem_data_single_string(lay_nor, b"Type", b"LayerElementNormal")
|
|
1512
|
-
elem_data_single_int32(lay_nor, b"TypedIndex", 0)
|
|
1513
|
-
if tspacenumber:
|
|
1514
|
-
lay_binor = elem_empty(layer, b"LayerElement")
|
|
1515
|
-
elem_data_single_string(lay_binor, b"Type", b"LayerElementBinormal")
|
|
1516
|
-
elem_data_single_int32(lay_binor, b"TypedIndex", 0)
|
|
1517
|
-
lay_tan = elem_empty(layer, b"LayerElement")
|
|
1518
|
-
elem_data_single_string(lay_tan, b"Type", b"LayerElementTangent")
|
|
1519
|
-
elem_data_single_int32(lay_tan, b"TypedIndex", 0)
|
|
1520
|
-
if smooth_type in {'FACE', 'EDGE', 'SMOOTH_GROUP'}:
|
|
1521
|
-
lay_smooth = elem_empty(layer, b"LayerElement")
|
|
1522
|
-
elem_data_single_string(lay_smooth, b"Type", b"LayerElementSmoothing")
|
|
1523
|
-
elem_data_single_int32(lay_smooth, b"TypedIndex", 0)
|
|
1524
|
-
if write_crease:
|
|
1525
|
-
lay_crease = elem_empty(layer, b"LayerElement")
|
|
1526
|
-
elem_data_single_string(lay_crease, b"Type", b"LayerElementEdgeCrease")
|
|
1527
|
-
elem_data_single_int32(lay_crease, b"TypedIndex", 0)
|
|
1528
|
-
if vcolnumber:
|
|
1529
|
-
lay_vcol = elem_empty(layer, b"LayerElement")
|
|
1530
|
-
elem_data_single_string(lay_vcol, b"Type", b"LayerElementColor")
|
|
1531
|
-
elem_data_single_int32(lay_vcol, b"TypedIndex", 0)
|
|
1532
|
-
if uvnumber:
|
|
1533
|
-
lay_uv = elem_empty(layer, b"LayerElement")
|
|
1534
|
-
elem_data_single_string(lay_uv, b"Type", b"LayerElementUV")
|
|
1535
|
-
elem_data_single_int32(lay_uv, b"TypedIndex", 0)
|
|
1536
|
-
if me_fbxmaterials_idx is not None:
|
|
1537
|
-
lay_ma = elem_empty(layer, b"LayerElement")
|
|
1538
|
-
elem_data_single_string(lay_ma, b"Type", b"LayerElementMaterial")
|
|
1539
|
-
elem_data_single_int32(lay_ma, b"TypedIndex", 0)
|
|
1540
|
-
|
|
1541
|
-
# Add other uv and/or vcol layers...
|
|
1542
|
-
for vcolidx, uvidx, tspaceidx in zip_longest(range(1, vcolnumber), range(1, uvnumber), range(1, tspacenumber),
|
|
1543
|
-
fillvalue=0):
|
|
1544
|
-
layer = elem_data_single_int32(geom, b"Layer", max(vcolidx, uvidx))
|
|
1545
|
-
elem_data_single_int32(layer, b"Version", FBX_GEOMETRY_LAYER_VERSION)
|
|
1546
|
-
if vcolidx:
|
|
1547
|
-
lay_vcol = elem_empty(layer, b"LayerElement")
|
|
1548
|
-
elem_data_single_string(lay_vcol, b"Type", b"LayerElementColor")
|
|
1549
|
-
elem_data_single_int32(lay_vcol, b"TypedIndex", vcolidx)
|
|
1550
|
-
if uvidx:
|
|
1551
|
-
lay_uv = elem_empty(layer, b"LayerElement")
|
|
1552
|
-
elem_data_single_string(lay_uv, b"Type", b"LayerElementUV")
|
|
1553
|
-
elem_data_single_int32(lay_uv, b"TypedIndex", uvidx)
|
|
1554
|
-
if tspaceidx:
|
|
1555
|
-
lay_binor = elem_empty(layer, b"LayerElement")
|
|
1556
|
-
elem_data_single_string(lay_binor, b"Type", b"LayerElementBinormal")
|
|
1557
|
-
elem_data_single_int32(lay_binor, b"TypedIndex", tspaceidx)
|
|
1558
|
-
lay_tan = elem_empty(layer, b"LayerElement")
|
|
1559
|
-
elem_data_single_string(lay_tan, b"Type", b"LayerElementTangent")
|
|
1560
|
-
elem_data_single_int32(lay_tan, b"TypedIndex", tspaceidx)
|
|
1561
|
-
|
|
1562
|
-
# Shape keys...
|
|
1563
|
-
fbx_data_mesh_shapes_elements(root, me_obj, me, scene_data, tmpl, props)
|
|
1564
|
-
|
|
1565
|
-
elem_props_template_finalize(tmpl, props)
|
|
1566
|
-
done_meshes.add(me_key)
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
def fbx_data_material_elements(root, ma, scene_data):
|
|
1570
|
-
"""
|
|
1571
|
-
Write the Material data block.
|
|
1572
|
-
"""
|
|
1573
|
-
|
|
1574
|
-
ambient_color = (0.0, 0.0, 0.0)
|
|
1575
|
-
if scene_data.data_world:
|
|
1576
|
-
ambient_color = next(iter(scene_data.data_world.keys())).color
|
|
1577
|
-
|
|
1578
|
-
ma_wrap = node_shader_utils.PrincipledBSDFWrapper(ma, is_readonly=True)
|
|
1579
|
-
ma_key, _objs = scene_data.data_materials[ma]
|
|
1580
|
-
ma_type = b"Phong"
|
|
1581
|
-
|
|
1582
|
-
fbx_ma = elem_data_single_int64(root, b"Material", get_fbx_uuid_from_key(ma_key))
|
|
1583
|
-
fbx_ma.add_string(fbx_name_class(ma.name.encode(), b"Material"))
|
|
1584
|
-
fbx_ma.add_string(b"")
|
|
1585
|
-
|
|
1586
|
-
elem_data_single_int32(fbx_ma, b"Version", FBX_MATERIAL_VERSION)
|
|
1587
|
-
# those are not yet properties, it seems...
|
|
1588
|
-
elem_data_single_string(fbx_ma, b"ShadingModel", ma_type)
|
|
1589
|
-
elem_data_single_int32(fbx_ma, b"MultiLayer", 0) # Should be bool...
|
|
1590
|
-
|
|
1591
|
-
tmpl = elem_props_template_init(scene_data.templates, b"Material")
|
|
1592
|
-
props = elem_properties(fbx_ma)
|
|
1593
|
-
|
|
1594
|
-
elem_props_template_set(tmpl, props, "p_string", b"ShadingModel", ma_type.decode())
|
|
1595
|
-
elem_props_template_set(tmpl, props, "p_color", b"DiffuseColor", ma_wrap.base_color)
|
|
1596
|
-
# Not in Principled BSDF, so assuming always 1
|
|
1597
|
-
elem_props_template_set(tmpl, props, "p_number", b"DiffuseFactor", 1.0)
|
|
1598
|
-
# Principled BSDF only has an emissive color, so we assume factor to be always 1.0.
|
|
1599
|
-
elem_props_template_set(tmpl, props, "p_color", b"EmissiveColor", ma_wrap.emission_color)
|
|
1600
|
-
elem_props_template_set(tmpl, props, "p_number", b"EmissiveFactor", ma_wrap.emission_strength)
|
|
1601
|
-
# Not in Principled BSDF, so assuming always 0
|
|
1602
|
-
elem_props_template_set(tmpl, props, "p_color", b"AmbientColor", ambient_color)
|
|
1603
|
-
elem_props_template_set(tmpl, props, "p_number", b"AmbientFactor", 0.0)
|
|
1604
|
-
# Sweetness... Looks like we are not the only ones to not know exactly how FBX is supposed to work (see T59850).
|
|
1605
|
-
# According to one of its developers, Unity uses that formula to extract alpha value:
|
|
1606
|
-
#
|
|
1607
|
-
# alpha = 1 - TransparencyFactor
|
|
1608
|
-
# if (alpha == 1 or alpha == 0):
|
|
1609
|
-
# alpha = 1 - TransparentColor.r
|
|
1610
|
-
#
|
|
1611
|
-
# Until further info, let's assume this is correct way to do, hence the following code for TransparentColor.
|
|
1612
|
-
if ma_wrap.alpha < 1.0e-5 or ma_wrap.alpha > (1.0 - 1.0e-5):
|
|
1613
|
-
elem_props_template_set(tmpl, props, "p_color", b"TransparentColor", (1.0 - ma_wrap.alpha,) * 3)
|
|
1614
|
-
else:
|
|
1615
|
-
elem_props_template_set(tmpl, props, "p_color", b"TransparentColor", ma_wrap.base_color)
|
|
1616
|
-
elem_props_template_set(tmpl, props, "p_number", b"TransparencyFactor", 1.0 - ma_wrap.alpha)
|
|
1617
|
-
elem_props_template_set(tmpl, props, "p_number", b"Opacity", ma_wrap.alpha)
|
|
1618
|
-
elem_props_template_set(tmpl, props, "p_vector_3d", b"NormalMap", (0.0, 0.0, 0.0))
|
|
1619
|
-
elem_props_template_set(tmpl, props, "p_double", b"BumpFactor", ma_wrap.normalmap_strength)
|
|
1620
|
-
# Not sure about those...
|
|
1621
|
-
"""
|
|
1622
|
-
b"Bump": ((0.0, 0.0, 0.0), "p_vector_3d"),
|
|
1623
|
-
b"DisplacementColor": ((0.0, 0.0, 0.0), "p_color_rgb"),
|
|
1624
|
-
b"DisplacementFactor": (0.0, "p_double"),
|
|
1625
|
-
"""
|
|
1626
|
-
# TODO: use specular tint?
|
|
1627
|
-
elem_props_template_set(tmpl, props, "p_color", b"SpecularColor", ma_wrap.base_color)
|
|
1628
|
-
elem_props_template_set(tmpl, props, "p_number", b"SpecularFactor", ma_wrap.specular / 2.0)
|
|
1629
|
-
# See Material template about those two!
|
|
1630
|
-
# XXX Totally empirical conversion, trying to adapt it
|
|
1631
|
-
# (from 0.0 - 100.0 FBX shininess range to 1.0 - 0.0 Principled BSDF range)...
|
|
1632
|
-
shininess = (1.0 - ma_wrap.roughness) * 10
|
|
1633
|
-
shininess *= shininess
|
|
1634
|
-
elem_props_template_set(tmpl, props, "p_number", b"Shininess", shininess)
|
|
1635
|
-
elem_props_template_set(tmpl, props, "p_number", b"ShininessExponent", shininess)
|
|
1636
|
-
elem_props_template_set(tmpl, props, "p_color", b"ReflectionColor", ma_wrap.base_color)
|
|
1637
|
-
elem_props_template_set(tmpl, props, "p_number", b"ReflectionFactor", ma_wrap.metallic)
|
|
1638
|
-
|
|
1639
|
-
elem_props_template_finalize(tmpl, props)
|
|
1640
|
-
|
|
1641
|
-
# Custom properties.
|
|
1642
|
-
if scene_data.settings.use_custom_props:
|
|
1643
|
-
fbx_data_element_custom_properties(props, ma)
|
|
1644
|
-
|
|
1645
|
-
def _get_image_filepath(img):
|
|
1646
|
-
if len(img.filepath) > 0:
|
|
1647
|
-
return img.filepath
|
|
1648
|
-
|
|
1649
|
-
# It's possible to have a packed image without a filepath. Pick a filepath
|
|
1650
|
-
# that is unlikely to conflict.
|
|
1651
|
-
filepath = os.path.join("textures", "packed")
|
|
1652
|
-
if img.library:
|
|
1653
|
-
filepath = os.path.join(filepath, bpy.path.clean_name(img.library.name))
|
|
1654
|
-
return "//" + os.path.join(filepath, bpy.path.clean_name(img.name))
|
|
1655
|
-
|
|
1656
|
-
def _gen_vid_path(img, scene_data):
|
|
1657
|
-
msetts = scene_data.settings.media_settings
|
|
1658
|
-
img_filepath = _get_image_filepath(img)
|
|
1659
|
-
fname_rel = bpy_extras.io_utils.path_reference(img_filepath, msetts.base_src, msetts.base_dst, msetts.path_mode,
|
|
1660
|
-
msetts.subdir, msetts.copy_set, img.library)
|
|
1661
|
-
fname_abs = os.path.normpath(os.path.abspath(os.path.join(msetts.base_dst, fname_rel)))
|
|
1662
|
-
return fname_abs, fname_rel
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
def fbx_data_texture_file_elements(root, blender_tex_key, scene_data):
|
|
1666
|
-
"""
|
|
1667
|
-
Write the (file) Texture data block.
|
|
1668
|
-
"""
|
|
1669
|
-
# XXX All this is very fuzzy to me currently...
|
|
1670
|
-
# Textures do not seem to use properties as much as they could.
|
|
1671
|
-
# For now assuming most logical and simple stuff.
|
|
1672
|
-
|
|
1673
|
-
ma, sock_name = blender_tex_key
|
|
1674
|
-
ma_wrap = node_shader_utils.PrincipledBSDFWrapper(ma, is_readonly=True)
|
|
1675
|
-
tex_key, _fbx_prop = scene_data.data_textures[blender_tex_key]
|
|
1676
|
-
tex = getattr(ma_wrap, sock_name)
|
|
1677
|
-
img = tex.image
|
|
1678
|
-
fname_abs, fname_rel = _gen_vid_path(img, scene_data)
|
|
1679
|
-
|
|
1680
|
-
fbx_tex = elem_data_single_int64(root, b"Texture", get_fbx_uuid_from_key(tex_key))
|
|
1681
|
-
fbx_tex.add_string(fbx_name_class(sock_name.encode(), b"Texture"))
|
|
1682
|
-
fbx_tex.add_string(b"")
|
|
1683
|
-
|
|
1684
|
-
elem_data_single_string(fbx_tex, b"Type", b"TextureVideoClip")
|
|
1685
|
-
elem_data_single_int32(fbx_tex, b"Version", FBX_TEXTURE_VERSION)
|
|
1686
|
-
elem_data_single_string(fbx_tex, b"TextureName", fbx_name_class(sock_name.encode(), b"Texture"))
|
|
1687
|
-
elem_data_single_string(fbx_tex, b"Media", fbx_name_class(img.name.encode(), b"Video"))
|
|
1688
|
-
elem_data_single_string_unicode(fbx_tex, b"FileName", fname_abs)
|
|
1689
|
-
elem_data_single_string_unicode(fbx_tex, b"RelativeFilename", fname_rel)
|
|
1690
|
-
|
|
1691
|
-
alpha_source = 0 # None
|
|
1692
|
-
if img.alpha_mode != 'NONE':
|
|
1693
|
-
# ~ if tex.texture.use_calculate_alpha:
|
|
1694
|
-
# ~ alpha_source = 1 # RGBIntensity as alpha.
|
|
1695
|
-
# ~ else:
|
|
1696
|
-
# ~ alpha_source = 2 # Black, i.e. alpha channel.
|
|
1697
|
-
alpha_source = 2 # Black, i.e. alpha channel.
|
|
1698
|
-
# BlendMode not useful for now, only affects layered textures afaics.
|
|
1699
|
-
mapping = 0 # UV.
|
|
1700
|
-
uvset = None
|
|
1701
|
-
if tex.texcoords == 'ORCO': # XXX Others?
|
|
1702
|
-
if tex.projection == 'FLAT':
|
|
1703
|
-
mapping = 1 # Planar
|
|
1704
|
-
elif tex.projection == 'CUBE':
|
|
1705
|
-
mapping = 4 # Box
|
|
1706
|
-
elif tex.projection == 'TUBE':
|
|
1707
|
-
mapping = 3 # Cylindrical
|
|
1708
|
-
elif tex.projection == 'SPHERE':
|
|
1709
|
-
mapping = 2 # Spherical
|
|
1710
|
-
elif tex.texcoords == 'UV':
|
|
1711
|
-
mapping = 0 # UV
|
|
1712
|
-
# Yuck, UVs are linked by mere names it seems... :/
|
|
1713
|
-
# XXX TODO how to get that now???
|
|
1714
|
-
# uvset = tex.uv_layer
|
|
1715
|
-
wrap_mode = 1 # Clamp
|
|
1716
|
-
if tex.extension == 'REPEAT':
|
|
1717
|
-
wrap_mode = 0 # Repeat
|
|
1718
|
-
|
|
1719
|
-
tmpl = elem_props_template_init(scene_data.templates, b"TextureFile")
|
|
1720
|
-
props = elem_properties(fbx_tex)
|
|
1721
|
-
elem_props_template_set(tmpl, props, "p_enum", b"AlphaSource", alpha_source)
|
|
1722
|
-
elem_props_template_set(tmpl, props, "p_bool", b"PremultiplyAlpha",
|
|
1723
|
-
img.alpha_mode in {'STRAIGHT'}) # Or is it PREMUL?
|
|
1724
|
-
elem_props_template_set(tmpl, props, "p_enum", b"CurrentMappingType", mapping)
|
|
1725
|
-
if uvset is not None:
|
|
1726
|
-
elem_props_template_set(tmpl, props, "p_string", b"UVSet", uvset)
|
|
1727
|
-
elem_props_template_set(tmpl, props, "p_enum", b"WrapModeU", wrap_mode)
|
|
1728
|
-
elem_props_template_set(tmpl, props, "p_enum", b"WrapModeV", wrap_mode)
|
|
1729
|
-
elem_props_template_set(tmpl, props, "p_vector_3d", b"Translation", tex.translation)
|
|
1730
|
-
elem_props_template_set(tmpl, props, "p_vector_3d", b"Rotation", (-r for r in tex.rotation))
|
|
1731
|
-
elem_props_template_set(tmpl, props, "p_vector_3d", b"Scaling",
|
|
1732
|
-
(((1.0 / s) if s != 0.0 else 1.0) for s in tex.scale))
|
|
1733
|
-
# UseMaterial should always be ON imho.
|
|
1734
|
-
elem_props_template_set(tmpl, props, "p_bool", b"UseMaterial", True)
|
|
1735
|
-
elem_props_template_set(tmpl, props, "p_bool", b"UseMipMap", False)
|
|
1736
|
-
elem_props_template_finalize(tmpl, props)
|
|
1737
|
-
|
|
1738
|
-
# No custom properties, since that's not a data-block anymore.
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
def fbx_data_video_elements(root, vid, scene_data):
|
|
1742
|
-
"""
|
|
1743
|
-
Write the actual image data block.
|
|
1744
|
-
"""
|
|
1745
|
-
msetts = scene_data.settings.media_settings
|
|
1746
|
-
|
|
1747
|
-
vid_key, _texs = scene_data.data_videos[vid]
|
|
1748
|
-
fname_abs, fname_rel = _gen_vid_path(vid, scene_data)
|
|
1749
|
-
|
|
1750
|
-
fbx_vid = elem_data_single_int64(root, b"Video", get_fbx_uuid_from_key(vid_key))
|
|
1751
|
-
fbx_vid.add_string(fbx_name_class(vid.name.encode(), b"Video"))
|
|
1752
|
-
fbx_vid.add_string(b"Clip")
|
|
1753
|
-
|
|
1754
|
-
elem_data_single_string(fbx_vid, b"Type", b"Clip")
|
|
1755
|
-
# XXX No Version???
|
|
1756
|
-
|
|
1757
|
-
tmpl = elem_props_template_init(scene_data.templates, b"Video")
|
|
1758
|
-
props = elem_properties(fbx_vid)
|
|
1759
|
-
elem_props_template_set(tmpl, props, "p_string_url", b"Path", fname_abs)
|
|
1760
|
-
elem_props_template_finalize(tmpl, props)
|
|
1761
|
-
|
|
1762
|
-
elem_data_single_int32(fbx_vid, b"UseMipMap", 0)
|
|
1763
|
-
elem_data_single_string_unicode(fbx_vid, b"Filename", fname_abs)
|
|
1764
|
-
elem_data_single_string_unicode(fbx_vid, b"RelativeFilename", fname_rel)
|
|
1765
|
-
|
|
1766
|
-
if scene_data.settings.media_settings.embed_textures:
|
|
1767
|
-
if vid.packed_file is not None:
|
|
1768
|
-
# We only ever embed a given file once!
|
|
1769
|
-
if fname_abs not in msetts.embedded_set:
|
|
1770
|
-
elem_data_single_bytes(fbx_vid, b"Content", vid.packed_file.data)
|
|
1771
|
-
msetts.embedded_set.add(fname_abs)
|
|
1772
|
-
else:
|
|
1773
|
-
filepath = bpy.path.abspath(vid.filepath)
|
|
1774
|
-
# We only ever embed a given file once!
|
|
1775
|
-
if filepath not in msetts.embedded_set:
|
|
1776
|
-
try:
|
|
1777
|
-
with open(filepath, 'br') as f:
|
|
1778
|
-
elem_data_single_bytes(fbx_vid, b"Content", f.read())
|
|
1779
|
-
except Exception as e:
|
|
1780
|
-
print("WARNING: embedding file {:s} failed ({:s})".format(filepath, str(e)))
|
|
1781
|
-
elem_data_single_bytes(fbx_vid, b"Content", b"")
|
|
1782
|
-
msetts.embedded_set.add(filepath)
|
|
1783
|
-
# Looks like we'd rather not write any 'Content' element in this case (see T44442).
|
|
1784
|
-
# Sounds suspect, but let's try it!
|
|
1785
|
-
# ~ else:
|
|
1786
|
-
#~ elem_data_single_bytes(fbx_vid, b"Content", b"")
|
|
1787
|
-
|
|
1788
|
-
# Blender currently has no UI for editing custom properties on Images, but the importer will import Image custom
|
|
1789
|
-
# properties from either a Video Node or a Texture Node, preferring a Video node if one exists. We'll propagate
|
|
1790
|
-
# these custom properties only to Video Nodes because that is most likely where they were imported from, and Texture
|
|
1791
|
-
# Nodes are more like Blender's Shader Nodes than Images, which is what we're exporting here.
|
|
1792
|
-
if scene_data.settings.use_custom_props:
|
|
1793
|
-
fbx_data_element_custom_properties(props, vid)
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
def fbx_data_armature_elements(root, arm_obj, scene_data):
|
|
1797
|
-
"""
|
|
1798
|
-
Write:
|
|
1799
|
-
* Bones "data" (NodeAttribute::LimbNode, contains pretty much nothing!).
|
|
1800
|
-
* Deformers (i.e. Skin), bind between an armature and a mesh.
|
|
1801
|
-
** SubDeformers (i.e. Cluster), one per bone/vgroup pair.
|
|
1802
|
-
* BindPose.
|
|
1803
|
-
Note armature itself has no data, it is a mere "Null" Model...
|
|
1804
|
-
"""
|
|
1805
|
-
mat_world_arm = arm_obj.fbx_object_matrix(scene_data, global_space=True)
|
|
1806
|
-
bones = tuple(bo_obj for bo_obj in arm_obj.bones if bo_obj in scene_data.objects)
|
|
1807
|
-
|
|
1808
|
-
bone_radius_scale = 33.0
|
|
1809
|
-
|
|
1810
|
-
# Bones "data".
|
|
1811
|
-
for bo_obj in bones:
|
|
1812
|
-
bo = bo_obj.bdata
|
|
1813
|
-
bo_data_key = scene_data.data_bones[bo_obj]
|
|
1814
|
-
fbx_bo = elem_data_single_int64(root, b"NodeAttribute", get_fbx_uuid_from_key(bo_data_key))
|
|
1815
|
-
fbx_bo.add_string(fbx_name_class(bo.name.encode(), b"NodeAttribute"))
|
|
1816
|
-
fbx_bo.add_string(b"LimbNode")
|
|
1817
|
-
elem_data_single_string(fbx_bo, b"TypeFlags", b"Skeleton")
|
|
1818
|
-
|
|
1819
|
-
tmpl = elem_props_template_init(scene_data.templates, b"Bone")
|
|
1820
|
-
props = elem_properties(fbx_bo)
|
|
1821
|
-
elem_props_template_set(tmpl, props, "p_double", b"Size", bo.head_radius * bone_radius_scale)
|
|
1822
|
-
elem_props_template_finalize(tmpl, props)
|
|
1823
|
-
|
|
1824
|
-
# Custom properties.
|
|
1825
|
-
if scene_data.settings.use_custom_props:
|
|
1826
|
-
fbx_data_element_custom_properties(props, bo)
|
|
1827
|
-
|
|
1828
|
-
# Store Blender bone length - XXX Not much useful actually :/
|
|
1829
|
-
# (LimbLength can't be used because it is a scale factor 0-1 for the parent-child distance:
|
|
1830
|
-
# http://docs.autodesk.com/FBX/2014/ENU/FBX-SDK-Documentation/cpp_ref/class_fbx_skeleton.html#a9bbe2a70f4ed82cd162620259e649f0f )
|
|
1831
|
-
# elem_props_set(props, "p_double", "BlenderBoneLength".encode(), (bo.tail_local - bo.head_local).length, custom=True)
|
|
1832
|
-
|
|
1833
|
-
# Skin deformers and BindPoses.
|
|
1834
|
-
# Note: we might also use Deformers for our "parent to vertex" stuff???
|
|
1835
|
-
deformer = scene_data.data_deformers_skin.get(arm_obj, None)
|
|
1836
|
-
if deformer is not None:
|
|
1837
|
-
for me, (skin_key, ob_obj, clusters) in deformer.items():
|
|
1838
|
-
# BindPose.
|
|
1839
|
-
mat_world_obj, mat_world_bones = fbx_data_bindpose_element(root, ob_obj, me, scene_data,
|
|
1840
|
-
arm_obj, mat_world_arm, bones)
|
|
1841
|
-
|
|
1842
|
-
# Deformer.
|
|
1843
|
-
fbx_skin = elem_data_single_int64(root, b"Deformer", get_fbx_uuid_from_key(skin_key))
|
|
1844
|
-
fbx_skin.add_string(fbx_name_class(arm_obj.name.encode(), b"Deformer"))
|
|
1845
|
-
fbx_skin.add_string(b"Skin")
|
|
1846
|
-
|
|
1847
|
-
elem_data_single_int32(fbx_skin, b"Version", FBX_DEFORMER_SKIN_VERSION)
|
|
1848
|
-
elem_data_single_float64(fbx_skin, b"Link_DeformAcuracy", 50.0) # Only vague idea what it is...
|
|
1849
|
-
|
|
1850
|
-
# Pre-process vertex weights so that the vertices only need to be iterated once.
|
|
1851
|
-
ob = ob_obj.bdata
|
|
1852
|
-
bo_vg_idx = {bo_obj.bdata.name: ob.vertex_groups[bo_obj.bdata.name].index
|
|
1853
|
-
for bo_obj in clusters.keys() if bo_obj.bdata.name in ob.vertex_groups}
|
|
1854
|
-
valid_idxs = set(bo_vg_idx.values())
|
|
1855
|
-
vgroups = {vg.index: {} for vg in ob.vertex_groups}
|
|
1856
|
-
for idx, v in enumerate(me.vertices):
|
|
1857
|
-
for vg in v.groups:
|
|
1858
|
-
if (w := vg.weight) and (vg_idx := vg.group) in valid_idxs:
|
|
1859
|
-
vgroups[vg_idx][idx] = w
|
|
1860
|
-
|
|
1861
|
-
for bo_obj, clstr_key in clusters.items():
|
|
1862
|
-
bo = bo_obj.bdata
|
|
1863
|
-
# Find which vertices are affected by this bone/vgroup pair, and matching weights.
|
|
1864
|
-
# Note we still write a cluster for bones not affecting the mesh, to get 'rest pose' data
|
|
1865
|
-
# (the TransformBlah matrices).
|
|
1866
|
-
vg_idx = bo_vg_idx.get(bo.name, None)
|
|
1867
|
-
indices, weights = ((), ()) if vg_idx is None or not vgroups[vg_idx] else zip(*vgroups[vg_idx].items())
|
|
1868
|
-
|
|
1869
|
-
# Create the cluster.
|
|
1870
|
-
fbx_clstr = elem_data_single_int64(root, b"Deformer", get_fbx_uuid_from_key(clstr_key))
|
|
1871
|
-
fbx_clstr.add_string(fbx_name_class(bo.name.encode(), b"SubDeformer"))
|
|
1872
|
-
fbx_clstr.add_string(b"Cluster")
|
|
1873
|
-
|
|
1874
|
-
elem_data_single_int32(fbx_clstr, b"Version", FBX_DEFORMER_CLUSTER_VERSION)
|
|
1875
|
-
# No idea what that user data might be...
|
|
1876
|
-
fbx_userdata = elem_data_single_string(fbx_clstr, b"UserData", b"")
|
|
1877
|
-
fbx_userdata.add_string(b"")
|
|
1878
|
-
if indices:
|
|
1879
|
-
elem_data_single_int32_array(fbx_clstr, b"Indexes", indices)
|
|
1880
|
-
elem_data_single_float64_array(fbx_clstr, b"Weights", weights)
|
|
1881
|
-
# Transform, TransformLink and TransformAssociateModel matrices...
|
|
1882
|
-
# They seem to be doublons of BindPose ones??? Have armature (associatemodel) in addition, though.
|
|
1883
|
-
# WARNING! Even though official FBX API presents Transform in global space,
|
|
1884
|
-
# **it is stored in bone space in FBX data!** See:
|
|
1885
|
-
# http://area.autodesk.com/forum/autodesk-fbx/fbx-sdk/why-the-values-return-
|
|
1886
|
-
# by-fbxcluster-gettransformmatrix-x-not-same-with-the-value-in-ascii-fbx-file/
|
|
1887
|
-
elem_data_single_float64_array(
|
|
1888
|
-
fbx_clstr, b"Transform", matrix4_to_array(
|
|
1889
|
-
mat_world_bones[bo_obj].inverted_safe() @ mat_world_obj))
|
|
1890
|
-
elem_data_single_float64_array(fbx_clstr, b"TransformLink", matrix4_to_array(mat_world_bones[bo_obj]))
|
|
1891
|
-
elem_data_single_float64_array(fbx_clstr, b"TransformAssociateModel", matrix4_to_array(mat_world_arm))
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
def fbx_data_leaf_bone_elements(root, scene_data):
|
|
1895
|
-
# Write a dummy leaf bone that is used by applications to show the length of the last bone in a chain
|
|
1896
|
-
for (node_name, _par_uuid, node_uuid, attr_uuid, matrix, hide, size) in scene_data.data_leaf_bones:
|
|
1897
|
-
# Bone 'data'...
|
|
1898
|
-
fbx_bo = elem_data_single_int64(root, b"NodeAttribute", attr_uuid)
|
|
1899
|
-
fbx_bo.add_string(fbx_name_class(node_name.encode(), b"NodeAttribute"))
|
|
1900
|
-
fbx_bo.add_string(b"LimbNode")
|
|
1901
|
-
elem_data_single_string(fbx_bo, b"TypeFlags", b"Skeleton")
|
|
1902
|
-
|
|
1903
|
-
tmpl = elem_props_template_init(scene_data.templates, b"Bone")
|
|
1904
|
-
props = elem_properties(fbx_bo)
|
|
1905
|
-
elem_props_template_set(tmpl, props, "p_double", b"Size", size)
|
|
1906
|
-
elem_props_template_finalize(tmpl, props)
|
|
1907
|
-
|
|
1908
|
-
# And bone object.
|
|
1909
|
-
model = elem_data_single_int64(root, b"Model", node_uuid)
|
|
1910
|
-
model.add_string(fbx_name_class(node_name.encode(), b"Model"))
|
|
1911
|
-
model.add_string(b"LimbNode")
|
|
1912
|
-
|
|
1913
|
-
elem_data_single_int32(model, b"Version", FBX_MODELS_VERSION)
|
|
1914
|
-
|
|
1915
|
-
# Object transform info.
|
|
1916
|
-
loc, rot, scale = matrix.decompose()
|
|
1917
|
-
rot = rot.to_euler('XYZ')
|
|
1918
|
-
rot = tuple(convert_rad_to_deg_iter(rot))
|
|
1919
|
-
|
|
1920
|
-
tmpl = elem_props_template_init(scene_data.templates, b"Model")
|
|
1921
|
-
# For now add only loc/rot/scale...
|
|
1922
|
-
props = elem_properties(model)
|
|
1923
|
-
# Generated leaf bones are obviously never animated!
|
|
1924
|
-
elem_props_template_set(tmpl, props, "p_lcl_translation", b"Lcl Translation", loc)
|
|
1925
|
-
elem_props_template_set(tmpl, props, "p_lcl_rotation", b"Lcl Rotation", rot)
|
|
1926
|
-
elem_props_template_set(tmpl, props, "p_lcl_scaling", b"Lcl Scaling", scale)
|
|
1927
|
-
elem_props_template_set(tmpl, props, "p_visibility", b"Visibility", float(not hide))
|
|
1928
|
-
|
|
1929
|
-
# Absolutely no idea what this is, but seems mandatory for validity of the file, and defaults to
|
|
1930
|
-
# invalid -1 value...
|
|
1931
|
-
elem_props_template_set(tmpl, props, "p_integer", b"DefaultAttributeIndex", 0)
|
|
1932
|
-
|
|
1933
|
-
elem_props_template_set(tmpl, props, "p_enum", b"InheritType", 1) # RSrs
|
|
1934
|
-
|
|
1935
|
-
# Those settings would obviously need to be edited in a complete version of the exporter, may depends on
|
|
1936
|
-
# object type, etc.
|
|
1937
|
-
elem_data_single_int32(model, b"MultiLayer", 0)
|
|
1938
|
-
elem_data_single_int32(model, b"MultiTake", 0)
|
|
1939
|
-
# Probably the FbxNode.EShadingMode enum. Full description in fbx_data_object_elements.
|
|
1940
|
-
elem_data_single_char(model, b"Shading", b"\x01")
|
|
1941
|
-
elem_data_single_string(model, b"Culling", b"CullingOff")
|
|
1942
|
-
|
|
1943
|
-
elem_props_template_finalize(tmpl, props)
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
def fbx_data_object_elements(root, ob_obj, scene_data):
|
|
1947
|
-
"""
|
|
1948
|
-
Write the Object (Model) data blocks.
|
|
1949
|
-
Note this "Model" can also be bone or dupli!
|
|
1950
|
-
"""
|
|
1951
|
-
obj_type = b"Null" # default, sort of empty...
|
|
1952
|
-
if ob_obj.is_bone:
|
|
1953
|
-
obj_type = b"LimbNode"
|
|
1954
|
-
elif (ob_obj.type == 'ARMATURE'):
|
|
1955
|
-
if scene_data.settings.armature_nodetype == 'ROOT':
|
|
1956
|
-
obj_type = b"Root"
|
|
1957
|
-
elif scene_data.settings.armature_nodetype == 'LIMBNODE':
|
|
1958
|
-
obj_type = b"LimbNode"
|
|
1959
|
-
else: # Default, preferred option...
|
|
1960
|
-
obj_type = b"Null"
|
|
1961
|
-
elif (ob_obj.type in BLENDER_OBJECT_TYPES_MESHLIKE):
|
|
1962
|
-
obj_type = b"Mesh"
|
|
1963
|
-
elif (ob_obj.type == 'LIGHT'):
|
|
1964
|
-
obj_type = b"Light"
|
|
1965
|
-
elif (ob_obj.type == 'CAMERA'):
|
|
1966
|
-
obj_type = b"Camera"
|
|
1967
|
-
model = elem_data_single_int64(root, b"Model", ob_obj.fbx_uuid)
|
|
1968
|
-
model.add_string(fbx_name_class(ob_obj.name.encode(), b"Model"))
|
|
1969
|
-
model.add_string(obj_type)
|
|
1970
|
-
|
|
1971
|
-
elem_data_single_int32(model, b"Version", FBX_MODELS_VERSION)
|
|
1972
|
-
|
|
1973
|
-
# Object transform info.
|
|
1974
|
-
loc, rot, scale, matrix, matrix_rot = ob_obj.fbx_object_tx(scene_data)
|
|
1975
|
-
rot = tuple(convert_rad_to_deg_iter(rot))
|
|
1976
|
-
|
|
1977
|
-
tmpl = elem_props_template_init(scene_data.templates, b"Model")
|
|
1978
|
-
# For now add only loc/rot/scale...
|
|
1979
|
-
props = elem_properties(model)
|
|
1980
|
-
elem_props_template_set(tmpl, props, "p_lcl_translation", b"Lcl Translation", loc,
|
|
1981
|
-
animatable=True, animated=((ob_obj.key, "Lcl Translation") in scene_data.animated))
|
|
1982
|
-
elem_props_template_set(tmpl, props, "p_lcl_rotation", b"Lcl Rotation", rot,
|
|
1983
|
-
animatable=True, animated=((ob_obj.key, "Lcl Rotation") in scene_data.animated))
|
|
1984
|
-
elem_props_template_set(tmpl, props, "p_lcl_scaling", b"Lcl Scaling", scale,
|
|
1985
|
-
animatable=True, animated=((ob_obj.key, "Lcl Scaling") in scene_data.animated))
|
|
1986
|
-
elem_props_template_set(tmpl, props, "p_visibility", b"Visibility", float(not ob_obj.hide))
|
|
1987
|
-
|
|
1988
|
-
# Absolutely no idea what this is, but seems mandatory for validity of the file, and defaults to
|
|
1989
|
-
# invalid -1 value...
|
|
1990
|
-
elem_props_template_set(tmpl, props, "p_integer", b"DefaultAttributeIndex", 0)
|
|
1991
|
-
|
|
1992
|
-
elem_props_template_set(tmpl, props, "p_enum", b"InheritType", 1) # RSrs
|
|
1993
|
-
|
|
1994
|
-
# Custom properties.
|
|
1995
|
-
if scene_data.settings.use_custom_props:
|
|
1996
|
-
# Here we want customprops from the 'pose' bone, not the 'edit' bone...
|
|
1997
|
-
bdata = ob_obj.bdata_pose_bone if ob_obj.is_bone else ob_obj.bdata
|
|
1998
|
-
fbx_data_element_custom_properties(props, bdata)
|
|
1999
|
-
|
|
2000
|
-
# Those settings would obviously need to be edited in a complete version of the exporter, may depends on
|
|
2001
|
-
# object type, etc.
|
|
2002
|
-
elem_data_single_int32(model, b"MultiLayer", 0)
|
|
2003
|
-
elem_data_single_int32(model, b"MultiTake", 0)
|
|
2004
|
-
# This is probably the FbxNode.EShadingMode enum. Not directly used by the FBX SDK, but the SDK guarantees that the
|
|
2005
|
-
# value will be passed through from an imported file to an exported one. Common values are 'Y' and 'T'. 'U' and 'W'
|
|
2006
|
-
# have also been seen in older FBX files. It's not clear which enum member each of these values corresponds to or if
|
|
2007
|
-
# these values are actually application specific. Blender had been exporting this as a `True` bool for a long time
|
|
2008
|
-
# seemingly without issue. The '\x01' char is the same value as `True` in raw bytes.
|
|
2009
|
-
elem_data_single_char(model, b"Shading", b"\x01")
|
|
2010
|
-
elem_data_single_string(model, b"Culling", b"CullingOff")
|
|
2011
|
-
|
|
2012
|
-
if obj_type == b"Camera":
|
|
2013
|
-
# Why, oh why are FBX cameras such a mess???
|
|
2014
|
-
# And WHY add camera data HERE??? Not even sure this is needed...
|
|
2015
|
-
render = scene_data.scene.render
|
|
2016
|
-
width = render.resolution_x * 1.0
|
|
2017
|
-
height = render.resolution_y * 1.0
|
|
2018
|
-
elem_props_template_set(tmpl, props, "p_enum", b"ResolutionMode", 0) # Don't know what it means
|
|
2019
|
-
elem_props_template_set(tmpl, props, "p_double", b"AspectW", width)
|
|
2020
|
-
elem_props_template_set(tmpl, props, "p_double", b"AspectH", height)
|
|
2021
|
-
elem_props_template_set(tmpl, props, "p_bool", b"ViewFrustum", True)
|
|
2022
|
-
elem_props_template_set(tmpl, props, "p_enum", b"BackgroundMode", 0) # Don't know what it means
|
|
2023
|
-
elem_props_template_set(tmpl, props, "p_bool", b"ForegroundTransparent", True)
|
|
2024
|
-
|
|
2025
|
-
elem_props_template_finalize(tmpl, props)
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
def fbx_data_animation_elements(root, scene_data):
|
|
2029
|
-
"""
|
|
2030
|
-
Write animation data.
|
|
2031
|
-
"""
|
|
2032
|
-
animations = scene_data.animations
|
|
2033
|
-
if not animations:
|
|
2034
|
-
return
|
|
2035
|
-
|
|
2036
|
-
# Animation stacks.
|
|
2037
|
-
for astack_key, alayers, alayer_key, name, f_start, f_end in animations:
|
|
2038
|
-
astack = elem_data_single_int64(root, b"AnimationStack", get_fbx_uuid_from_key(astack_key))
|
|
2039
|
-
astack.add_string(fbx_name_class(name, b"AnimStack"))
|
|
2040
|
-
astack.add_string(b"")
|
|
2041
|
-
|
|
2042
|
-
astack_tmpl = elem_props_template_init(scene_data.templates, b"AnimationStack")
|
|
2043
|
-
astack_props = elem_properties(astack)
|
|
2044
|
-
r = scene_data.scene.render
|
|
2045
|
-
fps = r.fps / r.fps_base
|
|
2046
|
-
start = int(convert_sec_to_ktime(f_start / fps))
|
|
2047
|
-
end = int(convert_sec_to_ktime(f_end / fps))
|
|
2048
|
-
elem_props_template_set(astack_tmpl, astack_props, "p_timestamp", b"LocalStart", start)
|
|
2049
|
-
elem_props_template_set(astack_tmpl, astack_props, "p_timestamp", b"LocalStop", end)
|
|
2050
|
-
elem_props_template_set(astack_tmpl, astack_props, "p_timestamp", b"ReferenceStart", start)
|
|
2051
|
-
elem_props_template_set(astack_tmpl, astack_props, "p_timestamp", b"ReferenceStop", end)
|
|
2052
|
-
elem_props_template_finalize(astack_tmpl, astack_props)
|
|
2053
|
-
|
|
2054
|
-
# For now, only one layer for all animations.
|
|
2055
|
-
alayer = elem_data_single_int64(root, b"AnimationLayer", get_fbx_uuid_from_key(alayer_key))
|
|
2056
|
-
alayer.add_string(fbx_name_class(name, b"AnimLayer"))
|
|
2057
|
-
alayer.add_string(b"")
|
|
2058
|
-
|
|
2059
|
-
for ob_obj, (alayer_key, acurvenodes) in alayers.items():
|
|
2060
|
-
# Animation layer.
|
|
2061
|
-
# alayer = elem_data_single_int64(root, b"AnimationLayer", get_fbx_uuid_from_key(alayer_key))
|
|
2062
|
-
# alayer.add_string(fbx_name_class(ob_obj.name.encode(), b"AnimLayer"))
|
|
2063
|
-
# alayer.add_string(b"")
|
|
2064
|
-
|
|
2065
|
-
for fbx_prop, (acurvenode_key, acurves, acurvenode_name) in acurvenodes.items():
|
|
2066
|
-
# Animation curve node.
|
|
2067
|
-
acurvenode = elem_data_single_int64(root, b"AnimationCurveNode", get_fbx_uuid_from_key(acurvenode_key))
|
|
2068
|
-
acurvenode.add_string(fbx_name_class(acurvenode_name.encode(), b"AnimCurveNode"))
|
|
2069
|
-
acurvenode.add_string(b"")
|
|
2070
|
-
|
|
2071
|
-
acn_tmpl = elem_props_template_init(scene_data.templates, b"AnimationCurveNode")
|
|
2072
|
-
acn_props = elem_properties(acurvenode)
|
|
2073
|
-
|
|
2074
|
-
for fbx_item, (acurve_key, def_value, (keys, values), _acurve_valid) in acurves.items():
|
|
2075
|
-
elem_props_template_set(acn_tmpl, acn_props, "p_number", fbx_item.encode(),
|
|
2076
|
-
def_value, animatable=True)
|
|
2077
|
-
|
|
2078
|
-
# Only create Animation curve if needed!
|
|
2079
|
-
nbr_keys = len(keys)
|
|
2080
|
-
if nbr_keys:
|
|
2081
|
-
acurve = elem_data_single_int64(root, b"AnimationCurve", get_fbx_uuid_from_key(acurve_key))
|
|
2082
|
-
acurve.add_string(fbx_name_class(b"", b"AnimCurve"))
|
|
2083
|
-
acurve.add_string(b"")
|
|
2084
|
-
|
|
2085
|
-
# key attributes...
|
|
2086
|
-
# flags...
|
|
2087
|
-
keyattr_flags = (
|
|
2088
|
-
1 << 2 | # interpolation mode, 1 = constant, 2 = linear, 3 = cubic.
|
|
2089
|
-
1 << 8 | # tangent mode, 8 = auto, 9 = TCB, 10 = user, 11 = generic break,
|
|
2090
|
-
1 << 13 | # tangent mode, 12 = generic clamp, 13 = generic time independent,
|
|
2091
|
-
1 << 14 | # tangent mode, 13 + 14 = generic clamp progressive.
|
|
2092
|
-
0,
|
|
2093
|
-
)
|
|
2094
|
-
# Maybe values controlling TCB & co???
|
|
2095
|
-
keyattr_datafloat = (0.0, 0.0, 9.419963346924634e-30, 0.0)
|
|
2096
|
-
|
|
2097
|
-
# And now, the *real* data!
|
|
2098
|
-
elem_data_single_float64(acurve, b"Default", def_value)
|
|
2099
|
-
elem_data_single_int32(acurve, b"KeyVer", FBX_ANIM_KEY_VERSION)
|
|
2100
|
-
elem_data_single_int64_array(acurve, b"KeyTime", astype_view_signedness(keys, np.int64))
|
|
2101
|
-
elem_data_single_float32_array(acurve, b"KeyValueFloat", values.astype(np.float32, copy=False))
|
|
2102
|
-
elem_data_single_int32_array(acurve, b"KeyAttrFlags", keyattr_flags)
|
|
2103
|
-
elem_data_single_float32_array(acurve, b"KeyAttrDataFloat", keyattr_datafloat)
|
|
2104
|
-
elem_data_single_int32_array(acurve, b"KeyAttrRefCount", (nbr_keys,))
|
|
2105
|
-
|
|
2106
|
-
elem_props_template_finalize(acn_tmpl, acn_props)
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
# ##### Top-level FBX data container. #####
|
|
2110
|
-
|
|
2111
|
-
# Mapping Blender -> FBX (principled_socket_name, fbx_name).
|
|
2112
|
-
PRINCIPLED_TEXTURE_SOCKETS_TO_FBX = (
|
|
2113
|
-
# ("diffuse", "diffuse", b"DiffuseFactor"),
|
|
2114
|
-
("base_color_texture", b"DiffuseColor"),
|
|
2115
|
-
("alpha_texture", b"TransparencyFactor"), # Will be inverted in fact, not much we can do really...
|
|
2116
|
-
# ("base_color_texture", b"TransparentColor"), # Uses diffuse color in Blender!
|
|
2117
|
-
("emission_strength_texture", b"EmissiveFactor"),
|
|
2118
|
-
("emission_color_texture", b"EmissiveColor"),
|
|
2119
|
-
# ("ambient", "ambient", b"AmbientFactor"),
|
|
2120
|
-
# ("", "", b"AmbientColor"), # World stuff in Blender, for now ignore...
|
|
2121
|
-
("normalmap_texture", b"NormalMap"),
|
|
2122
|
-
# Note: unsure about those... :/
|
|
2123
|
-
# ("", "", b"Bump"),
|
|
2124
|
-
# ("", "", b"BumpFactor"),
|
|
2125
|
-
# ("", "", b"DisplacementColor"),
|
|
2126
|
-
# ("", "", b"DisplacementFactor"),
|
|
2127
|
-
("specular_texture", b"SpecularFactor"),
|
|
2128
|
-
# ("base_color", b"SpecularColor"), # TODO: use tint?
|
|
2129
|
-
# See Material template about those two!
|
|
2130
|
-
("roughness_texture", b"Shininess"),
|
|
2131
|
-
("roughness_texture", b"ShininessExponent"),
|
|
2132
|
-
# ("mirror", "mirror", b"ReflectionColor"),
|
|
2133
|
-
("metallic_texture", b"ReflectionFactor"),
|
|
2134
|
-
)
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
def fbx_skeleton_from_armature(scene, settings, arm_obj, objects, data_meshes,
|
|
2138
|
-
data_bones, data_deformers_skin, data_empties, arm_parents):
|
|
2139
|
-
"""
|
|
2140
|
-
Create skeleton from armature/bones (NodeAttribute/LimbNode and Model/LimbNode), and for each deformed mesh,
|
|
2141
|
-
create Pose/BindPose(with sub PoseNode) and Deformer/Skin(with Deformer/SubDeformer/Cluster).
|
|
2142
|
-
Also supports "parent to bone" (simple parent to Model/LimbNode).
|
|
2143
|
-
arm_parents is a set of tuples (armature, object) for all successful armature bindings.
|
|
2144
|
-
"""
|
|
2145
|
-
# We need some data for our armature 'object' too!!!
|
|
2146
|
-
data_empties[arm_obj] = get_blender_empty_key(arm_obj.bdata)
|
|
2147
|
-
|
|
2148
|
-
arm_data = arm_obj.bdata.data
|
|
2149
|
-
bones = {}
|
|
2150
|
-
for bo in arm_obj.bones:
|
|
2151
|
-
if settings.use_armature_deform_only:
|
|
2152
|
-
if bo.bdata.use_deform:
|
|
2153
|
-
bones[bo] = True
|
|
2154
|
-
bo_par = bo.parent
|
|
2155
|
-
while bo_par.is_bone:
|
|
2156
|
-
bones[bo_par] = True
|
|
2157
|
-
bo_par = bo_par.parent
|
|
2158
|
-
elif bo not in bones: # Do not override if already set in the loop above!
|
|
2159
|
-
bones[bo] = False
|
|
2160
|
-
else:
|
|
2161
|
-
bones[bo] = True
|
|
2162
|
-
|
|
2163
|
-
bones = {bo: None for bo, use in bones.items() if use}
|
|
2164
|
-
|
|
2165
|
-
if not bones:
|
|
2166
|
-
return
|
|
2167
|
-
|
|
2168
|
-
data_bones.update((bo, get_blender_bone_key(arm_obj.bdata, bo.bdata)) for bo in bones)
|
|
2169
|
-
|
|
2170
|
-
for ob_obj in objects:
|
|
2171
|
-
if not ob_obj.is_deformed_by_armature(arm_obj):
|
|
2172
|
-
continue
|
|
2173
|
-
|
|
2174
|
-
# Always handled by an Armature modifier...
|
|
2175
|
-
found = False
|
|
2176
|
-
for mod in ob_obj.bdata.modifiers:
|
|
2177
|
-
if mod.type not in {'ARMATURE'} or not mod.object:
|
|
2178
|
-
continue
|
|
2179
|
-
# We only support vertex groups binding method, not bone envelopes one!
|
|
2180
|
-
if mod.object == arm_obj.bdata and mod.use_vertex_groups:
|
|
2181
|
-
found = True
|
|
2182
|
-
break
|
|
2183
|
-
|
|
2184
|
-
if not found:
|
|
2185
|
-
continue
|
|
2186
|
-
|
|
2187
|
-
# Now we have a mesh using this armature.
|
|
2188
|
-
# Note: bindpose have no relations at all (no connections), so no need for any preprocess for them.
|
|
2189
|
-
# Create skin & clusters relations (note skins are connected to geometry, *not* model!).
|
|
2190
|
-
_key, me, _free = data_meshes[ob_obj]
|
|
2191
|
-
clusters = {bo: get_blender_bone_cluster_key(arm_obj.bdata, me, bo.bdata) for bo in bones}
|
|
2192
|
-
data_deformers_skin.setdefault(arm_obj, {})[me] = (get_blender_armature_skin_key(arm_obj.bdata, me),
|
|
2193
|
-
ob_obj, clusters)
|
|
2194
|
-
|
|
2195
|
-
# We don't want a regular parent relationship for those in FBX...
|
|
2196
|
-
arm_parents.add((arm_obj, ob_obj))
|
|
2197
|
-
# Needed to handle matrices/spaces (since we do not parent them to 'armature' in FBX :/ ).
|
|
2198
|
-
ob_obj.parented_to_armature = True
|
|
2199
|
-
|
|
2200
|
-
objects.update(bones)
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
def fbx_generate_leaf_bones(settings, data_bones):
|
|
2204
|
-
# find which bons have no children
|
|
2205
|
-
child_count = {bo: 0 for bo in data_bones.keys()}
|
|
2206
|
-
for bo in data_bones.keys():
|
|
2207
|
-
if bo.parent and bo.parent.is_bone:
|
|
2208
|
-
child_count[bo.parent] += 1
|
|
2209
|
-
|
|
2210
|
-
bone_radius_scale = settings.global_scale * 33.0
|
|
2211
|
-
|
|
2212
|
-
# generate bone data
|
|
2213
|
-
leaf_parents = [bo for bo, count in child_count.items() if count == 0]
|
|
2214
|
-
leaf_bones = []
|
|
2215
|
-
for parent in leaf_parents:
|
|
2216
|
-
node_name = parent.name + "_end"
|
|
2217
|
-
parent_uuid = parent.fbx_uuid
|
|
2218
|
-
parent_key = parent.key
|
|
2219
|
-
node_uuid = get_fbx_uuid_from_key(parent_key + "_end_node")
|
|
2220
|
-
attr_uuid = get_fbx_uuid_from_key(parent_key + "_end_nodeattr")
|
|
2221
|
-
|
|
2222
|
-
hide = parent.hide
|
|
2223
|
-
size = parent.bdata.head_radius * bone_radius_scale
|
|
2224
|
-
bone_length = (parent.bdata.tail_local - parent.bdata.head_local).length
|
|
2225
|
-
matrix = Matrix.Translation((0, bone_length, 0))
|
|
2226
|
-
if settings.bone_correction_matrix_inv:
|
|
2227
|
-
matrix = settings.bone_correction_matrix_inv @ matrix
|
|
2228
|
-
if settings.bone_correction_matrix:
|
|
2229
|
-
matrix = matrix @ settings.bone_correction_matrix
|
|
2230
|
-
leaf_bones.append((node_name, parent_uuid, node_uuid, attr_uuid, matrix, hide, size))
|
|
2231
|
-
|
|
2232
|
-
return leaf_bones
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=None, force_keep=False):
|
|
2236
|
-
"""
|
|
2237
|
-
Generate animation data (a single AnimStack) from objects, for a given frame range.
|
|
2238
|
-
"""
|
|
2239
|
-
bake_step = scene_data.settings.bake_anim_step
|
|
2240
|
-
simplify_fac = scene_data.settings.bake_anim_simplify_factor
|
|
2241
|
-
scene = scene_data.scene
|
|
2242
|
-
depsgraph = scene_data.depsgraph
|
|
2243
|
-
force_keying = scene_data.settings.bake_anim_use_all_bones
|
|
2244
|
-
force_sek = scene_data.settings.bake_anim_force_startend_keying
|
|
2245
|
-
gscale = scene_data.settings.global_scale
|
|
2246
|
-
|
|
2247
|
-
if objects is not None:
|
|
2248
|
-
# Add bones and duplis!
|
|
2249
|
-
for ob_obj in tuple(objects):
|
|
2250
|
-
if not ob_obj.is_object:
|
|
2251
|
-
continue
|
|
2252
|
-
if ob_obj.type == 'ARMATURE':
|
|
2253
|
-
objects |= {bo_obj for bo_obj in ob_obj.bones if bo_obj in scene_data.objects}
|
|
2254
|
-
for dp_obj in ob_obj.dupli_list_gen(depsgraph):
|
|
2255
|
-
if dp_obj in scene_data.objects:
|
|
2256
|
-
objects.add(dp_obj)
|
|
2257
|
-
else:
|
|
2258
|
-
objects = scene_data.objects
|
|
2259
|
-
|
|
2260
|
-
back_currframe = scene.frame_current
|
|
2261
|
-
animdata_ob = {}
|
|
2262
|
-
p_rots = {}
|
|
2263
|
-
|
|
2264
|
-
for ob_obj in objects:
|
|
2265
|
-
if ob_obj.parented_to_armature:
|
|
2266
|
-
continue
|
|
2267
|
-
ACNW = AnimationCurveNodeWrapper
|
|
2268
|
-
loc, rot, scale, _m, _mr = ob_obj.fbx_object_tx(scene_data)
|
|
2269
|
-
rot_deg = tuple(convert_rad_to_deg_iter(rot))
|
|
2270
|
-
force_key = (simplify_fac == 0.0) or (ob_obj.is_bone and force_keying)
|
|
2271
|
-
animdata_ob[ob_obj] = (ACNW(ob_obj.key, 'LCL_TRANSLATION', force_key, force_sek, loc),
|
|
2272
|
-
ACNW(ob_obj.key, 'LCL_ROTATION', force_key, force_sek, rot_deg),
|
|
2273
|
-
ACNW(ob_obj.key, 'LCL_SCALING', force_key, force_sek, scale))
|
|
2274
|
-
p_rots[ob_obj] = rot
|
|
2275
|
-
|
|
2276
|
-
force_key = (simplify_fac == 0.0)
|
|
2277
|
-
animdata_shapes = {}
|
|
2278
|
-
|
|
2279
|
-
for me, (me_key, _shapes_key, shapes) in scene_data.data_deformers_shape.items():
|
|
2280
|
-
# Ignore absolute shape keys for now!
|
|
2281
|
-
if not me.shape_keys.use_relative:
|
|
2282
|
-
continue
|
|
2283
|
-
for shape, (channel_key, geom_key, _shape_verts_co, _shape_verts_idx) in shapes.items():
|
|
2284
|
-
acnode = AnimationCurveNodeWrapper(channel_key, 'SHAPE_KEY', force_key, force_sek, (0.0,))
|
|
2285
|
-
# Sooooo happy to have to twist again like a mad snake... Yes, we need to write those curves twice. :/
|
|
2286
|
-
acnode.add_group(me_key, shape.name, shape.name, (shape.name,))
|
|
2287
|
-
animdata_shapes[channel_key] = (acnode, me, shape)
|
|
2288
|
-
|
|
2289
|
-
animdata_cameras = {}
|
|
2290
|
-
for cam_obj, cam_key in scene_data.data_cameras.items():
|
|
2291
|
-
cam = cam_obj.bdata.data
|
|
2292
|
-
acnode_lens = AnimationCurveNodeWrapper(cam_key, 'CAMERA_FOCAL', force_key, force_sek, (cam.lens,))
|
|
2293
|
-
acnode_focus_distance = AnimationCurveNodeWrapper(cam_key, 'CAMERA_FOCUS_DISTANCE', force_key,
|
|
2294
|
-
force_sek, (cam.dof.focus_distance,))
|
|
2295
|
-
animdata_cameras[cam_key] = (acnode_lens, acnode_focus_distance, cam)
|
|
2296
|
-
|
|
2297
|
-
# Get all parent bdata of animated dupli instances, so that we can quickly identify which instances in
|
|
2298
|
-
# `depsgraph.object_instances` are animated and need their ObjectWrappers' matrices updated each frame.
|
|
2299
|
-
dupli_parent_bdata = {dup.get_parent().bdata for dup in animdata_ob if dup.is_dupli}
|
|
2300
|
-
has_animated_duplis = bool(dupli_parent_bdata)
|
|
2301
|
-
|
|
2302
|
-
# Initialize keyframe times array. Each AnimationCurveNodeWrapper will share the same instance.
|
|
2303
|
-
# `np.arange` excludes the `stop` argument like when using `range`, so we use np.nextafter to get the next
|
|
2304
|
-
# representable value after f_end and use that as the `stop` argument instead.
|
|
2305
|
-
currframes = np.arange(f_start, np.nextafter(f_end, np.inf), step=bake_step)
|
|
2306
|
-
|
|
2307
|
-
# Convert from Blender time to FBX time.
|
|
2308
|
-
fps = scene.render.fps / scene.render.fps_base
|
|
2309
|
-
real_currframes = currframes - f_start if start_zero else currframes
|
|
2310
|
-
real_currframes = (real_currframes / fps * FBX_KTIME).astype(np.int64)
|
|
2311
|
-
|
|
2312
|
-
# Generator that yields the animated values of each frame in order.
|
|
2313
|
-
def frame_values_gen():
|
|
2314
|
-
# Precalculate integer frames and subframes.
|
|
2315
|
-
int_currframes = currframes.astype(int)
|
|
2316
|
-
subframes = currframes - int_currframes
|
|
2317
|
-
|
|
2318
|
-
# Create simpler iterables that return only the values we care about.
|
|
2319
|
-
animdata_shapes_only = [shape for _anim_shape, _me, shape in animdata_shapes.values()]
|
|
2320
|
-
animdata_cameras_only = [camera for _anim_camera_lens, _anim_camera_focus_distance, camera
|
|
2321
|
-
in animdata_cameras.values()]
|
|
2322
|
-
# Previous frame's rotation for each object in animdata_ob, this will be updated each frame.
|
|
2323
|
-
animdata_ob_p_rots = p_rots.values()
|
|
2324
|
-
|
|
2325
|
-
# Iterate through each frame and yield the values for that frame.
|
|
2326
|
-
# Iterating .data, the memoryview of an array, is faster than iterating the array directly.
|
|
2327
|
-
for int_currframe, subframe in zip(int_currframes.data, subframes.data):
|
|
2328
|
-
scene.frame_set(int_currframe, subframe=subframe)
|
|
2329
|
-
|
|
2330
|
-
if has_animated_duplis:
|
|
2331
|
-
# Changing the scene's frame invalidates existing dupli instances. To get the updated matrices of duplis
|
|
2332
|
-
# for this frame, we must get the duplis from the depsgraph again.
|
|
2333
|
-
for dup in depsgraph.object_instances:
|
|
2334
|
-
if (parent := dup.parent) and parent.original in dupli_parent_bdata:
|
|
2335
|
-
# ObjectWrapper caches its instances. Attempting to create a new instance updates the existing
|
|
2336
|
-
# ObjectWrapper instance with the current frame's matrix and then returns the existing instance.
|
|
2337
|
-
ObjectWrapper(dup)
|
|
2338
|
-
next_p_rots = []
|
|
2339
|
-
for ob_obj, p_rot in zip(animdata_ob, animdata_ob_p_rots):
|
|
2340
|
-
# We compute baked loc/rot/scale for all objects (rot being euler-compat with previous value!).
|
|
2341
|
-
loc, rot, scale, _m, _mr = ob_obj.fbx_object_tx(scene_data, rot_euler_compat=p_rot)
|
|
2342
|
-
next_p_rots.append(rot)
|
|
2343
|
-
yield from loc
|
|
2344
|
-
yield from rot
|
|
2345
|
-
yield from scale
|
|
2346
|
-
animdata_ob_p_rots = next_p_rots
|
|
2347
|
-
for shape in animdata_shapes_only:
|
|
2348
|
-
yield shape.value
|
|
2349
|
-
for camera in animdata_cameras_only:
|
|
2350
|
-
yield camera.lens
|
|
2351
|
-
yield camera.dof.focus_distance
|
|
2352
|
-
|
|
2353
|
-
# Providing `count` to np.fromiter pre-allocates the array, avoiding extra memory allocations while iterating.
|
|
2354
|
-
num_ob_values = len(animdata_ob) * 9 # Location, rotation and scale, each of which have x, y, and z components
|
|
2355
|
-
num_shape_values = len(animdata_shapes) # Only 1 value per shape key
|
|
2356
|
-
num_camera_values = len(animdata_cameras) * 2 # Focal length (`.lens`) and focus distance
|
|
2357
|
-
num_values_per_frame = num_ob_values + num_shape_values + num_camera_values
|
|
2358
|
-
num_frames = len(real_currframes)
|
|
2359
|
-
all_values_flat = np.fromiter(frame_values_gen(), dtype=float, count=num_frames * num_values_per_frame)
|
|
2360
|
-
|
|
2361
|
-
# Restore the scene's current frame.
|
|
2362
|
-
scene.frame_set(back_currframe, subframe=0.0)
|
|
2363
|
-
|
|
2364
|
-
# View such that each column is all values for a single frame and each row is all values for a single curve.
|
|
2365
|
-
all_values = all_values_flat.reshape(num_frames, num_values_per_frame).T
|
|
2366
|
-
# Split into views of the arrays for each curve type.
|
|
2367
|
-
split_at = [num_ob_values, num_shape_values, num_camera_values]
|
|
2368
|
-
# For unequal sized splits, np.split takes indices to split at, which can be acquired through a cumulative sum
|
|
2369
|
-
# across the list.
|
|
2370
|
-
# The last value isn't needed, because the last split is assumed to go to the end of the array.
|
|
2371
|
-
split_at = np.cumsum(split_at[:-1])
|
|
2372
|
-
all_ob_values, all_shape_key_values, all_camera_values = np.split(all_values, split_at)
|
|
2373
|
-
|
|
2374
|
-
all_anims = []
|
|
2375
|
-
|
|
2376
|
-
# Set location/rotation/scale curves.
|
|
2377
|
-
# Split into equal sized views of the arrays for each object.
|
|
2378
|
-
split_into = len(animdata_ob)
|
|
2379
|
-
per_ob_values = np.split(all_ob_values, split_into) if split_into > 0 else ()
|
|
2380
|
-
for anims, ob_values in zip(animdata_ob.values(), per_ob_values):
|
|
2381
|
-
# Split again into equal sized views of the location, rotation and scaling arrays.
|
|
2382
|
-
loc_xyz, rot_xyz, sca_xyz = np.split(ob_values, 3)
|
|
2383
|
-
# In-place convert from Blender rotation to FBX rotation.
|
|
2384
|
-
np.rad2deg(rot_xyz, out=rot_xyz)
|
|
2385
|
-
|
|
2386
|
-
anim_loc, anim_rot, anim_scale = anims
|
|
2387
|
-
anim_loc.set_keyframes(real_currframes, loc_xyz)
|
|
2388
|
-
anim_rot.set_keyframes(real_currframes, rot_xyz)
|
|
2389
|
-
anim_scale.set_keyframes(real_currframes, sca_xyz)
|
|
2390
|
-
all_anims.extend(anims)
|
|
2391
|
-
|
|
2392
|
-
# Set shape key curves.
|
|
2393
|
-
# There's only one array per shape key, so there's no need to split `all_shape_key_values`.
|
|
2394
|
-
for (anim_shape, _me, _shape), shape_key_values in zip(animdata_shapes.values(), all_shape_key_values):
|
|
2395
|
-
# In-place convert from Blender Shape Key Value to FBX Deform Percent.
|
|
2396
|
-
shape_key_values *= 100.0
|
|
2397
|
-
anim_shape.set_keyframes(real_currframes, shape_key_values)
|
|
2398
|
-
all_anims.append(anim_shape)
|
|
2399
|
-
|
|
2400
|
-
# Set camera curves.
|
|
2401
|
-
# Split into equal sized views of the arrays for each camera.
|
|
2402
|
-
split_into = len(animdata_cameras)
|
|
2403
|
-
per_camera_values = np.split(all_camera_values, split_into) if split_into > 0 else ()
|
|
2404
|
-
zipped = zip(animdata_cameras.values(), per_camera_values)
|
|
2405
|
-
for (anim_camera_lens, anim_camera_focus_distance, _camera), (lens_values, focus_distance_values) in zipped:
|
|
2406
|
-
# In-place convert from Blender focus distance to FBX.
|
|
2407
|
-
focus_distance_values *= (1000 * gscale)
|
|
2408
|
-
anim_camera_lens.set_keyframes(real_currframes, lens_values)
|
|
2409
|
-
anim_camera_focus_distance.set_keyframes(real_currframes, focus_distance_values)
|
|
2410
|
-
all_anims.append(anim_camera_lens)
|
|
2411
|
-
all_anims.append(anim_camera_focus_distance)
|
|
2412
|
-
|
|
2413
|
-
animations = {}
|
|
2414
|
-
|
|
2415
|
-
# And now, produce final data (usable by FBX export code)
|
|
2416
|
-
for anim in all_anims:
|
|
2417
|
-
anim.simplify(simplify_fac, bake_step, force_keep)
|
|
2418
|
-
if not anim:
|
|
2419
|
-
continue
|
|
2420
|
-
for obj_key, group_key, group, fbx_group, fbx_gname in anim.get_final_data(scene, ref_id, force_keep):
|
|
2421
|
-
anim_data = animations.setdefault(obj_key, ("dummy_unused_key", {}))
|
|
2422
|
-
anim_data[1][fbx_group] = (group_key, group, fbx_gname)
|
|
2423
|
-
|
|
2424
|
-
astack_key = get_blender_anim_stack_key(scene, ref_id)
|
|
2425
|
-
alayer_key = get_blender_anim_layer_key(scene, ref_id)
|
|
2426
|
-
name = (get_blenderID_name(ref_id) if ref_id else scene.name).encode()
|
|
2427
|
-
|
|
2428
|
-
if start_zero:
|
|
2429
|
-
f_end -= f_start
|
|
2430
|
-
f_start = 0.0
|
|
2431
|
-
|
|
2432
|
-
return (astack_key, animations, alayer_key, name, f_start, f_end) if animations else None
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
def fbx_animations(scene_data):
|
|
2436
|
-
"""
|
|
2437
|
-
Generate global animation data from objects.
|
|
2438
|
-
"""
|
|
2439
|
-
scene = scene_data.scene
|
|
2440
|
-
animations = []
|
|
2441
|
-
animated = set()
|
|
2442
|
-
frame_start = 1e100
|
|
2443
|
-
frame_end = -1e100
|
|
2444
|
-
|
|
2445
|
-
def add_anim(animations, animated, anim):
|
|
2446
|
-
nonlocal frame_start, frame_end
|
|
2447
|
-
if anim is not None:
|
|
2448
|
-
animations.append(anim)
|
|
2449
|
-
f_start, f_end = anim[4:6]
|
|
2450
|
-
if f_start < frame_start:
|
|
2451
|
-
frame_start = f_start
|
|
2452
|
-
if f_end > frame_end:
|
|
2453
|
-
frame_end = f_end
|
|
2454
|
-
|
|
2455
|
-
_astack_key, astack, _alayer_key, _name, _fstart, _fend = anim
|
|
2456
|
-
for elem_key, (alayer_key, acurvenodes) in astack.items():
|
|
2457
|
-
for fbx_prop, (acurvenode_key, acurves, acurvenode_name) in acurvenodes.items():
|
|
2458
|
-
animated.add((elem_key, fbx_prop))
|
|
2459
|
-
|
|
2460
|
-
# Per-NLA strip animstacks.
|
|
2461
|
-
if scene_data.settings.bake_anim_use_nla_strips:
|
|
2462
|
-
strips = []
|
|
2463
|
-
ob_actions = []
|
|
2464
|
-
for ob_obj in scene_data.objects:
|
|
2465
|
-
# NLA tracks only for objects, not bones!
|
|
2466
|
-
if not ob_obj.is_object:
|
|
2467
|
-
continue
|
|
2468
|
-
ob = ob_obj.bdata # Back to real Blender Object.
|
|
2469
|
-
if not ob.animation_data:
|
|
2470
|
-
continue
|
|
2471
|
-
|
|
2472
|
-
# Some actions are read-only, one cause is being in NLA tweakmode
|
|
2473
|
-
restore_use_tweak_mode = ob.animation_data.use_tweak_mode
|
|
2474
|
-
if ob.animation_data.is_property_readonly('action'):
|
|
2475
|
-
ob.animation_data.use_tweak_mode = False
|
|
2476
|
-
|
|
2477
|
-
# We have to remove active action from objects, it overwrites strips actions otherwise...
|
|
2478
|
-
ob_actions.append((ob, ob.animation_data.action, restore_use_tweak_mode))
|
|
2479
|
-
ob.animation_data.action = None
|
|
2480
|
-
for track in ob.animation_data.nla_tracks:
|
|
2481
|
-
if track.mute:
|
|
2482
|
-
continue
|
|
2483
|
-
for strip in track.strips:
|
|
2484
|
-
if strip.mute:
|
|
2485
|
-
continue
|
|
2486
|
-
strips.append(strip)
|
|
2487
|
-
strip.mute = True
|
|
2488
|
-
|
|
2489
|
-
for strip in strips:
|
|
2490
|
-
strip.mute = False
|
|
2491
|
-
add_anim(animations, animated,
|
|
2492
|
-
fbx_animations_do(scene_data, strip, strip.frame_start, strip.frame_end, True, force_keep=True))
|
|
2493
|
-
strip.mute = True
|
|
2494
|
-
scene.frame_set(scene.frame_current, subframe=0.0)
|
|
2495
|
-
|
|
2496
|
-
for strip in strips:
|
|
2497
|
-
strip.mute = False
|
|
2498
|
-
|
|
2499
|
-
for ob, ob_act, restore_use_tweak_mode in ob_actions:
|
|
2500
|
-
ob.animation_data.action = ob_act
|
|
2501
|
-
ob.animation_data.use_tweak_mode = restore_use_tweak_mode
|
|
2502
|
-
|
|
2503
|
-
# All actions.
|
|
2504
|
-
if scene_data.settings.bake_anim_use_all_actions:
|
|
2505
|
-
def find_validate_action_slot(act, path_resolve) -> bpy.types.ActionSlot | None:
|
|
2506
|
-
for layer in act.layers:
|
|
2507
|
-
for strip in layer.strips:
|
|
2508
|
-
for channelbag in strip.channelbags:
|
|
2509
|
-
if not channelbag.fcurves:
|
|
2510
|
-
# Do not export empty Channelbags.
|
|
2511
|
-
continue
|
|
2512
|
-
for fc in channelbag.fcurves:
|
|
2513
|
-
data_path = fc.data_path
|
|
2514
|
-
if fc.array_index:
|
|
2515
|
-
data_path = data_path + "[%d]" % fc.array_index
|
|
2516
|
-
try:
|
|
2517
|
-
path_resolve(data_path)
|
|
2518
|
-
except ValueError:
|
|
2519
|
-
break # Invalid, go to next strip.
|
|
2520
|
-
else:
|
|
2521
|
-
# Did not 'break', so all F-Curves are valid.
|
|
2522
|
-
return channelbag.slot
|
|
2523
|
-
return None # Found nothing to return.
|
|
2524
|
-
|
|
2525
|
-
def restore_object(ob_to, ob_from):
|
|
2526
|
-
# Restore org state of object (ugh :/ ).
|
|
2527
|
-
props = (
|
|
2528
|
-
'location', 'rotation_quaternion', 'rotation_axis_angle', 'rotation_euler', 'rotation_mode', 'scale',
|
|
2529
|
-
'delta_location', 'delta_rotation_euler', 'delta_rotation_quaternion', 'delta_scale',
|
|
2530
|
-
'lock_location', 'lock_rotation', 'lock_rotation_w', 'lock_rotations_4d', 'lock_scale',
|
|
2531
|
-
'tag', 'track_axis', 'up_axis', 'active_material', 'active_material_index',
|
|
2532
|
-
'matrix_parent_inverse', 'empty_display_type', 'empty_display_size', 'empty_image_offset', 'pass_index',
|
|
2533
|
-
'color', 'hide_viewport', 'hide_select', 'hide_render', 'instance_type',
|
|
2534
|
-
'use_instance_vertices_rotation', 'use_instance_faces_scale', 'instance_faces_scale',
|
|
2535
|
-
'display_type', 'show_bounds', 'display_bounds_type', 'show_name', 'show_axis', 'show_texture_space',
|
|
2536
|
-
'show_wire', 'show_all_edges', 'show_transparent', 'show_in_front',
|
|
2537
|
-
'show_only_shape_key', 'use_shape_key_edit_mode', 'active_shape_key_index',
|
|
2538
|
-
)
|
|
2539
|
-
for p in props:
|
|
2540
|
-
if not ob_to.is_property_readonly(p):
|
|
2541
|
-
setattr(ob_to, p, getattr(ob_from, p))
|
|
2542
|
-
|
|
2543
|
-
for ob_obj in scene_data.objects:
|
|
2544
|
-
# Actions only for objects, not bones!
|
|
2545
|
-
if not ob_obj.is_object:
|
|
2546
|
-
continue
|
|
2547
|
-
|
|
2548
|
-
ob = ob_obj.bdata # Back to real Blender Object.
|
|
2549
|
-
|
|
2550
|
-
if not ob.animation_data:
|
|
2551
|
-
continue # Do not export animations for objects that are absolutely not animated, see T44386.
|
|
2552
|
-
|
|
2553
|
-
if ob.animation_data.is_property_readonly('action'):
|
|
2554
|
-
continue # Cannot re-assign 'active action' to this object (usually related to NLA usage, see T48089).
|
|
2555
|
-
|
|
2556
|
-
# We can't play with animdata and actions and get back to org state easily.
|
|
2557
|
-
# So we have to add a temp copy of the object to the scene, animate it, and remove it... :/
|
|
2558
|
-
ob_copy = ob.copy()
|
|
2559
|
-
# Great, have to handle bones as well if needed...
|
|
2560
|
-
pbones_matrices = [pbo.matrix_basis.copy() for pbo in ob.pose.bones] if ob.type == 'ARMATURE' else ...
|
|
2561
|
-
|
|
2562
|
-
org_act = ob.animation_data.action
|
|
2563
|
-
org_act_slot = ob.animation_data.action_slot
|
|
2564
|
-
path_resolve = ob.path_resolve
|
|
2565
|
-
|
|
2566
|
-
for act in bpy.data.actions:
|
|
2567
|
-
# For now, *all* paths in the action must be valid for the object, to validate the action.
|
|
2568
|
-
# Unless that action was already assigned to the object!
|
|
2569
|
-
if act == org_act:
|
|
2570
|
-
act_slot = org_act_slot
|
|
2571
|
-
else:
|
|
2572
|
-
act_slot = find_validate_action_slot(act, path_resolve)
|
|
2573
|
-
if not act_slot:
|
|
2574
|
-
continue
|
|
2575
|
-
ob.animation_data.action = act
|
|
2576
|
-
ob.animation_data.action_slot = act_slot
|
|
2577
|
-
frame_start, frame_end = act.frame_range # sic!
|
|
2578
|
-
add_anim(animations, animated,
|
|
2579
|
-
fbx_animations_do(scene_data, (ob, act), frame_start, frame_end, True,
|
|
2580
|
-
objects={ob_obj}, force_keep=True))
|
|
2581
|
-
# Ugly! :/
|
|
2582
|
-
if pbones_matrices is not ...:
|
|
2583
|
-
for pbo, mat in zip(ob.pose.bones, pbones_matrices):
|
|
2584
|
-
pbo.matrix_basis = mat.copy()
|
|
2585
|
-
ob.animation_data.action = org_act
|
|
2586
|
-
if org_act:
|
|
2587
|
-
ob.animation_data.action_slot = org_act_slot
|
|
2588
|
-
restore_object(ob, ob_copy)
|
|
2589
|
-
scene.frame_set(scene.frame_current, subframe=0.0)
|
|
2590
|
-
|
|
2591
|
-
if pbones_matrices is not ...:
|
|
2592
|
-
for pbo, mat in zip(ob.pose.bones, pbones_matrices):
|
|
2593
|
-
pbo.matrix_basis = mat.copy()
|
|
2594
|
-
ob.animation_data.action = org_act
|
|
2595
|
-
if org_act:
|
|
2596
|
-
ob.animation_data.action_slot = org_act_slot
|
|
2597
|
-
|
|
2598
|
-
bpy.data.objects.remove(ob_copy)
|
|
2599
|
-
scene.frame_set(scene.frame_current, subframe=0.0)
|
|
2600
|
-
|
|
2601
|
-
# Global (containing everything) animstack, only if not exporting NLA strips and/or all actions.
|
|
2602
|
-
if not scene_data.settings.bake_anim_use_nla_strips and not scene_data.settings.bake_anim_use_all_actions:
|
|
2603
|
-
add_anim(animations, animated, fbx_animations_do(scene_data, None, scene.frame_start, scene.frame_end, False))
|
|
2604
|
-
|
|
2605
|
-
# Be sure to update all matrices back to org state!
|
|
2606
|
-
scene.frame_set(scene.frame_current, subframe=0.0)
|
|
2607
|
-
|
|
2608
|
-
return animations, animated, frame_start, frame_end
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
def fbx_data_from_scene(scene, depsgraph, settings):
|
|
2612
|
-
"""
|
|
2613
|
-
Do some pre-processing over scene's data...
|
|
2614
|
-
"""
|
|
2615
|
-
objtypes = settings.object_types
|
|
2616
|
-
dp_objtypes = objtypes - {'ARMATURE'} # Armatures are not supported as dupli instances currently...
|
|
2617
|
-
perfmon = PerfMon()
|
|
2618
|
-
perfmon.level_up()
|
|
2619
|
-
|
|
2620
|
-
# ##### Gathering data...
|
|
2621
|
-
|
|
2622
|
-
perfmon.step("FBX export prepare: Wrapping Objects...")
|
|
2623
|
-
|
|
2624
|
-
# This is rather simple for now, maybe we could end generating templates with most-used values
|
|
2625
|
-
# instead of default ones?
|
|
2626
|
-
objects = {} # Because we do not have any ordered set...
|
|
2627
|
-
for ob in settings.context_objects:
|
|
2628
|
-
if ob.type not in objtypes:
|
|
2629
|
-
continue
|
|
2630
|
-
ob_obj = ObjectWrapper(ob)
|
|
2631
|
-
objects[ob_obj] = None
|
|
2632
|
-
# Duplis...
|
|
2633
|
-
for dp_obj in ob_obj.dupli_list_gen(depsgraph):
|
|
2634
|
-
if dp_obj.type not in dp_objtypes:
|
|
2635
|
-
continue
|
|
2636
|
-
objects[dp_obj] = None
|
|
2637
|
-
|
|
2638
|
-
perfmon.step("FBX export prepare: Wrapping Data (lamps, cameras, empties)...")
|
|
2639
|
-
|
|
2640
|
-
data_lights = {ob_obj.bdata.data: get_blenderID_key(ob_obj.bdata.data)
|
|
2641
|
-
for ob_obj in objects if ob_obj.type == 'LIGHT'}
|
|
2642
|
-
# Unfortunately, FBX camera data contains object-level data (like position, orientation, etc.)...
|
|
2643
|
-
data_cameras = {ob_obj: get_blenderID_key(ob_obj.bdata.data)
|
|
2644
|
-
for ob_obj in objects if ob_obj.type == 'CAMERA'}
|
|
2645
|
-
# Yep! Contains nothing, but needed!
|
|
2646
|
-
data_empties = {ob_obj: get_blender_empty_key(ob_obj.bdata)
|
|
2647
|
-
for ob_obj in objects if ob_obj.type == 'EMPTY'}
|
|
2648
|
-
|
|
2649
|
-
perfmon.step("FBX export prepare: Wrapping Meshes...")
|
|
2650
|
-
|
|
2651
|
-
data_meshes = {}
|
|
2652
|
-
for ob_obj in objects:
|
|
2653
|
-
if ob_obj.type not in BLENDER_OBJECT_TYPES_MESHLIKE:
|
|
2654
|
-
continue
|
|
2655
|
-
ob = ob_obj.bdata
|
|
2656
|
-
org_ob_obj = None
|
|
2657
|
-
|
|
2658
|
-
# Do not want to systematically recreate a new mesh for dupliobject instances, kind of break purpose of those.
|
|
2659
|
-
if ob_obj.is_dupli:
|
|
2660
|
-
org_ob_obj = ObjectWrapper(ob) # We get the "real" object wrapper from that dupli instance.
|
|
2661
|
-
if org_ob_obj in data_meshes:
|
|
2662
|
-
data_meshes[ob_obj] = data_meshes[org_ob_obj]
|
|
2663
|
-
continue
|
|
2664
|
-
|
|
2665
|
-
# There are 4 different cases for what we need to do with the original data of each Object:
|
|
2666
|
-
# 1) The original data can be used without changes.
|
|
2667
|
-
# 2) A copy of the original data needs to be made.
|
|
2668
|
-
# - If an export option modifies the data, e.g. Triangulate Faces is enabled.
|
|
2669
|
-
# - If the Object has Object-linked materials. This is because our current mapping of materials to FBX requires
|
|
2670
|
-
# that multiple Objects sharing a single mesh must have the same materials.
|
|
2671
|
-
# 3) The Object needs to be converted to a mesh.
|
|
2672
|
-
# - All mesh-like Objects that are not meshes need to be converted to a mesh in order to be exported.
|
|
2673
|
-
# 4) The Object needs to be evaluated and then converted to a mesh.
|
|
2674
|
-
# - Whenever use_mesh_modifiers is enabled and either there are modifiers to apply or the Object needs to be
|
|
2675
|
-
# converted to a mesh.
|
|
2676
|
-
# If multiple cases apply to an Object, then only the last applicable case is relevant.
|
|
2677
|
-
do_copy = any(ms.link == 'OBJECT' for ms in ob.material_slots) or settings.use_triangles
|
|
2678
|
-
do_convert = ob.type in BLENDER_OTHER_OBJECT_TYPES
|
|
2679
|
-
do_evaluate = do_convert and settings.use_mesh_modifiers
|
|
2680
|
-
|
|
2681
|
-
# If the Object is a mesh, and we're applying modifiers, check if there are actually any modifiers to apply.
|
|
2682
|
-
# If there are then the mesh will need to be evaluated, and we may need to make some temporary changes to the
|
|
2683
|
-
# modifiers or scene before the mesh is evaluated.
|
|
2684
|
-
backup_pose_positions = []
|
|
2685
|
-
tmp_mods = []
|
|
2686
|
-
if ob.type == 'MESH' and settings.use_mesh_modifiers:
|
|
2687
|
-
# No need to create a new mesh in this case, if no modifier is active!
|
|
2688
|
-
last_subsurf = None
|
|
2689
|
-
for mod in ob.modifiers:
|
|
2690
|
-
# For meshes, when armature export is enabled, disable Armature modifiers here!
|
|
2691
|
-
# XXX Temp hacks here since currently we only have access to a viewport depsgraph...
|
|
2692
|
-
#
|
|
2693
|
-
# NOTE: We put armature to the rest pose instead of disabling it so we still
|
|
2694
|
-
# have vertex groups in the evaluated mesh.
|
|
2695
|
-
if mod.type == 'ARMATURE' and 'ARMATURE' in settings.object_types:
|
|
2696
|
-
object = mod.object
|
|
2697
|
-
if object and object.type == 'ARMATURE':
|
|
2698
|
-
armature = object.data
|
|
2699
|
-
# If armature is already in REST position, there's nothing to back-up
|
|
2700
|
-
# This cuts down on export time dramatically, if all armatures are already in REST position
|
|
2701
|
-
# by not triggering dependency graph update
|
|
2702
|
-
if armature.pose_position != 'REST':
|
|
2703
|
-
backup_pose_positions.append((armature, armature.pose_position))
|
|
2704
|
-
armature.pose_position = 'REST'
|
|
2705
|
-
elif mod.show_render or mod.show_viewport:
|
|
2706
|
-
# If exporting with subsurf collect the last Catmull-Clark subsurf modifier
|
|
2707
|
-
# and disable it. We can use the original data as long as this is the first
|
|
2708
|
-
# found applicable subsurf modifier.
|
|
2709
|
-
if settings.use_subsurf and mod.type == 'SUBSURF' and mod.subdivision_type == 'CATMULL_CLARK':
|
|
2710
|
-
if last_subsurf:
|
|
2711
|
-
do_evaluate = True
|
|
2712
|
-
last_subsurf = mod
|
|
2713
|
-
else:
|
|
2714
|
-
do_evaluate = True
|
|
2715
|
-
if settings.use_subsurf and last_subsurf:
|
|
2716
|
-
# XXX: When exporting with subsurf information temporarily disable
|
|
2717
|
-
# the last subsurf modifier.
|
|
2718
|
-
tmp_mods.append((last_subsurf, last_subsurf.show_render, last_subsurf.show_viewport))
|
|
2719
|
-
last_subsurf.show_render = False
|
|
2720
|
-
last_subsurf.show_viewport = False
|
|
2721
|
-
|
|
2722
|
-
if do_evaluate:
|
|
2723
|
-
# If modifiers has been altered need to update dependency graph.
|
|
2724
|
-
if backup_pose_positions or tmp_mods:
|
|
2725
|
-
depsgraph.update()
|
|
2726
|
-
ob_to_convert = ob.evaluated_get(depsgraph)
|
|
2727
|
-
# NOTE: The dependency graph might be re-evaluating multiple times, which could
|
|
2728
|
-
# potentially free the mesh created early on. So we put those meshes to bmain and
|
|
2729
|
-
# free them afterwards. Not ideal but ensures correct ownership.
|
|
2730
|
-
# This also converts non-mesh Objects to Mesh data.
|
|
2731
|
-
tmp_me = bpy.data.meshes.new_from_object(
|
|
2732
|
-
ob_to_convert, preserve_all_data_layers=True, depsgraph=depsgraph)
|
|
2733
|
-
|
|
2734
|
-
# Usually the materials of the evaluated Object converted to a Mesh will be the same as the original
|
|
2735
|
-
# Object, but modifiers, such as Geometry Nodes, can change the materials.
|
|
2736
|
-
orig_mats = [slot.material for slot in ob.material_slots]
|
|
2737
|
-
eval_mats = list(tmp_me.materials)
|
|
2738
|
-
if orig_mats != eval_mats:
|
|
2739
|
-
# An object-linked material slot replaces the material on the data at the slot's index. If applying
|
|
2740
|
-
# modifiers changes the materials on the data, the object-linked material slot will replace the new
|
|
2741
|
-
# material at the same index as before.
|
|
2742
|
-
for i, slot in zip(range(len(eval_mats)), ob.material_slots):
|
|
2743
|
-
if slot.link == 'OBJECT':
|
|
2744
|
-
eval_mats[i] = slot.material
|
|
2745
|
-
# Override the default behavior of getting materials from `ob_obj.bdata.material_slots`.
|
|
2746
|
-
ob_obj.override_materials = tuple(eval_mats)
|
|
2747
|
-
elif do_convert:
|
|
2748
|
-
tmp_me = bpy.data.meshes.new_from_object(ob, preserve_all_data_layers=True, depsgraph=depsgraph)
|
|
2749
|
-
elif do_copy:
|
|
2750
|
-
# bpy.data.meshes.new_from_object removes shape keys (see #104714), so create a copy of the mesh instead.
|
|
2751
|
-
tmp_me = ob.data.copy()
|
|
2752
|
-
else:
|
|
2753
|
-
tmp_me = None
|
|
2754
|
-
|
|
2755
|
-
if tmp_me is None:
|
|
2756
|
-
# Use the original data of this Object.
|
|
2757
|
-
data_meshes[ob_obj] = (get_blenderID_key(ob.data), ob.data, False)
|
|
2758
|
-
else:
|
|
2759
|
-
# Triangulate the mesh if requested
|
|
2760
|
-
if settings.use_triangles:
|
|
2761
|
-
import bmesh
|
|
2762
|
-
bm = bmesh.new()
|
|
2763
|
-
bm.from_mesh(tmp_me)
|
|
2764
|
-
bmesh.ops.triangulate(bm, faces=bm.faces)
|
|
2765
|
-
bm.to_mesh(tmp_me)
|
|
2766
|
-
bm.free()
|
|
2767
|
-
# A temporary mesh was created for this Object, which should be deleted once the export is complete.
|
|
2768
|
-
data_meshes[ob_obj] = (get_blenderID_key(tmp_me), tmp_me, True)
|
|
2769
|
-
|
|
2770
|
-
# Change armatures back.
|
|
2771
|
-
for armature, pose_position in backup_pose_positions:
|
|
2772
|
-
print((armature, pose_position))
|
|
2773
|
-
armature.pose_position = pose_position
|
|
2774
|
-
# Update now, so we don't leave modified state after last object was exported.
|
|
2775
|
-
# Re-enable temporary disabled modifiers.
|
|
2776
|
-
for mod, show_render, show_viewport in tmp_mods:
|
|
2777
|
-
mod.show_render = show_render
|
|
2778
|
-
mod.show_viewport = show_viewport
|
|
2779
|
-
if backup_pose_positions or tmp_mods:
|
|
2780
|
-
depsgraph.update()
|
|
2781
|
-
|
|
2782
|
-
# In case "real" source object of that dupli did not yet still existed in data_meshes, create it now!
|
|
2783
|
-
if org_ob_obj is not None:
|
|
2784
|
-
data_meshes[org_ob_obj] = data_meshes[ob_obj]
|
|
2785
|
-
|
|
2786
|
-
perfmon.step("FBX export prepare: Wrapping ShapeKeys...")
|
|
2787
|
-
|
|
2788
|
-
# ShapeKeys.
|
|
2789
|
-
data_deformers_shape = {}
|
|
2790
|
-
geom_mat_co = settings.global_matrix if settings.bake_space_transform else None
|
|
2791
|
-
co_bl_dtype = np.single
|
|
2792
|
-
co_fbx_dtype = np.float64
|
|
2793
|
-
idx_fbx_dtype = np.int32
|
|
2794
|
-
|
|
2795
|
-
def empty_verts_fallbacks():
|
|
2796
|
-
"""Create fallback arrays for when there are no verts"""
|
|
2797
|
-
# FBX does not like empty shapes (makes Unity crash e.g.).
|
|
2798
|
-
# To prevent this, we add a vertex that does nothing, but it keeps the shape key intact
|
|
2799
|
-
single_vert_co = np.zeros((1, 3), dtype=co_fbx_dtype)
|
|
2800
|
-
single_vert_idx = np.zeros(1, dtype=idx_fbx_dtype)
|
|
2801
|
-
return single_vert_co, single_vert_idx
|
|
2802
|
-
|
|
2803
|
-
for me_key, me, _free in data_meshes.values():
|
|
2804
|
-
if not (me.shape_keys and len(me.shape_keys.key_blocks) > 1): # We do not want basis-only relative skeys...
|
|
2805
|
-
continue
|
|
2806
|
-
if me in data_deformers_shape:
|
|
2807
|
-
continue
|
|
2808
|
-
|
|
2809
|
-
shapes_key = get_blender_mesh_shape_key(me)
|
|
2810
|
-
|
|
2811
|
-
sk_base = me.shape_keys.key_blocks[0]
|
|
2812
|
-
|
|
2813
|
-
# Get and cache only the cos that we need
|
|
2814
|
-
@cache
|
|
2815
|
-
def sk_cos(shape_key):
|
|
2816
|
-
if shape_key == sk_base:
|
|
2817
|
-
_cos = MESH_ATTRIBUTE_POSITION.to_ndarray(me.attributes)
|
|
2818
|
-
else:
|
|
2819
|
-
_cos = np.empty(len(me.vertices) * 3, dtype=co_bl_dtype)
|
|
2820
|
-
shape_key.points.foreach_get("co", _cos)
|
|
2821
|
-
return vcos_transformed(_cos, geom_mat_co, co_fbx_dtype)
|
|
2822
|
-
|
|
2823
|
-
for shape in me.shape_keys.key_blocks[1:]:
|
|
2824
|
-
# Only write vertices really different from base coordinates!
|
|
2825
|
-
relative_key = shape.relative_key
|
|
2826
|
-
if shape == relative_key:
|
|
2827
|
-
# Shape is its own relative key, so it does nothing
|
|
2828
|
-
shape_verts_co, shape_verts_idx = empty_verts_fallbacks()
|
|
2829
|
-
else:
|
|
2830
|
-
sv_cos = sk_cos(shape)
|
|
2831
|
-
ref_cos = sk_cos(shape.relative_key)
|
|
2832
|
-
|
|
2833
|
-
# Exclude cos similar to ref_cos and get the indices of the cos that remain
|
|
2834
|
-
shape_verts_co, shape_verts_idx = shape_difference_exclude_similar(sv_cos, ref_cos)
|
|
2835
|
-
|
|
2836
|
-
if not shape_verts_co.size:
|
|
2837
|
-
shape_verts_co, shape_verts_idx = empty_verts_fallbacks()
|
|
2838
|
-
else:
|
|
2839
|
-
# Ensure the indices are of the correct type
|
|
2840
|
-
shape_verts_idx = astype_view_signedness(shape_verts_idx, idx_fbx_dtype)
|
|
2841
|
-
|
|
2842
|
-
channel_key, geom_key = get_blender_mesh_shape_channel_key(me, shape)
|
|
2843
|
-
data = (channel_key, geom_key, shape_verts_co, shape_verts_idx)
|
|
2844
|
-
data_deformers_shape.setdefault(me, (me_key, shapes_key, {}))[2][shape] = data
|
|
2845
|
-
|
|
2846
|
-
del sk_cos
|
|
2847
|
-
|
|
2848
|
-
perfmon.step("FBX export prepare: Wrapping Armatures...")
|
|
2849
|
-
|
|
2850
|
-
# Armatures!
|
|
2851
|
-
data_deformers_skin = {}
|
|
2852
|
-
data_bones = {}
|
|
2853
|
-
arm_parents = set()
|
|
2854
|
-
for ob_obj in tuple(objects):
|
|
2855
|
-
if not (ob_obj.is_object and ob_obj.type in {'ARMATURE'}):
|
|
2856
|
-
continue
|
|
2857
|
-
fbx_skeleton_from_armature(scene, settings, ob_obj, objects, data_meshes,
|
|
2858
|
-
data_bones, data_deformers_skin, data_empties, arm_parents)
|
|
2859
|
-
|
|
2860
|
-
# Generate leaf bones
|
|
2861
|
-
data_leaf_bones = []
|
|
2862
|
-
if settings.add_leaf_bones:
|
|
2863
|
-
data_leaf_bones = fbx_generate_leaf_bones(settings, data_bones)
|
|
2864
|
-
|
|
2865
|
-
perfmon.step("FBX export prepare: Wrapping World...")
|
|
2866
|
-
|
|
2867
|
-
# Some world settings are embedded in FBX materials...
|
|
2868
|
-
if scene.world:
|
|
2869
|
-
data_world = {scene.world: get_blenderID_key(scene.world)}
|
|
2870
|
-
else:
|
|
2871
|
-
data_world = {}
|
|
2872
|
-
|
|
2873
|
-
perfmon.step("FBX export prepare: Wrapping Materials...")
|
|
2874
|
-
|
|
2875
|
-
# TODO: Check all the material stuff works even when they are linked to Objects
|
|
2876
|
-
# (we can then have the same mesh used with different materials...).
|
|
2877
|
-
# *Should* work, as FBX always links its materials to Models (i.e. objects).
|
|
2878
|
-
# XXX However, material indices would probably break...
|
|
2879
|
-
data_materials = {}
|
|
2880
|
-
for ob_obj in objects:
|
|
2881
|
-
# If obj is not a valid object for materials, wrapper will just return an empty tuple...
|
|
2882
|
-
for ma in ob_obj.materials:
|
|
2883
|
-
if ma is None:
|
|
2884
|
-
continue # Empty slots!
|
|
2885
|
-
# Note theoretically, FBX supports any kind of materials, even GLSL shaders etc.
|
|
2886
|
-
# However, I doubt anything else than Lambert/Phong is really portable!
|
|
2887
|
-
# Note we want to keep a 'dummy' empty material even when we can't really support it, see T41396.
|
|
2888
|
-
ma_data = data_materials.setdefault(ma, (get_blenderID_key(ma), []))
|
|
2889
|
-
ma_data[1].append(ob_obj)
|
|
2890
|
-
|
|
2891
|
-
perfmon.step("FBX export prepare: Wrapping Textures...")
|
|
2892
|
-
|
|
2893
|
-
# Note FBX textures also hold their mapping info.
|
|
2894
|
-
# TODO: Support layers?
|
|
2895
|
-
data_textures = {}
|
|
2896
|
-
# FbxVideo also used to store static images...
|
|
2897
|
-
data_videos = {}
|
|
2898
|
-
# For now, do not use world textures, don't think they can be linked to anything FBX wise...
|
|
2899
|
-
for ma in data_materials.keys():
|
|
2900
|
-
# Note: with nodal shaders, we'll could be generating much more textures, but that's kind of unavoidable,
|
|
2901
|
-
# given that textures actually do not exist anymore in material context in Blender...
|
|
2902
|
-
ma_wrap = node_shader_utils.PrincipledBSDFWrapper(ma, is_readonly=True)
|
|
2903
|
-
for sock_name, fbx_name in PRINCIPLED_TEXTURE_SOCKETS_TO_FBX:
|
|
2904
|
-
tex = getattr(ma_wrap, sock_name)
|
|
2905
|
-
if tex is None or tex.image is None:
|
|
2906
|
-
continue
|
|
2907
|
-
blender_tex_key = (ma, sock_name)
|
|
2908
|
-
data_textures[blender_tex_key] = (get_blender_nodetexture_key(*blender_tex_key), fbx_name)
|
|
2909
|
-
|
|
2910
|
-
img = tex.image
|
|
2911
|
-
vid_data = data_videos.setdefault(img, (get_blenderID_key(img), []))
|
|
2912
|
-
vid_data[1].append(blender_tex_key)
|
|
2913
|
-
|
|
2914
|
-
perfmon.step("FBX export prepare: Wrapping Animations...")
|
|
2915
|
-
|
|
2916
|
-
# Animation...
|
|
2917
|
-
animations = ()
|
|
2918
|
-
animated = set()
|
|
2919
|
-
frame_start = scene.frame_start
|
|
2920
|
-
frame_end = scene.frame_end
|
|
2921
|
-
if settings.bake_anim:
|
|
2922
|
-
# From objects & bones only for a start.
|
|
2923
|
-
# Kind of hack, we need a temp scene_data for object's space handling to bake animations...
|
|
2924
|
-
tmp_scdata = FBXExportData(
|
|
2925
|
-
None, None, None,
|
|
2926
|
-
settings, scene, depsgraph, objects, None, None, 0.0, 0.0,
|
|
2927
|
-
data_empties, data_lights, data_cameras, data_meshes, None,
|
|
2928
|
-
data_bones, data_leaf_bones, data_deformers_skin, data_deformers_shape,
|
|
2929
|
-
data_world, data_materials, data_textures, data_videos,
|
|
2930
|
-
)
|
|
2931
|
-
animations, animated, frame_start, frame_end = fbx_animations(tmp_scdata)
|
|
2932
|
-
|
|
2933
|
-
# ##### Creation of templates...
|
|
2934
|
-
|
|
2935
|
-
perfmon.step("FBX export prepare: Generating templates...")
|
|
2936
|
-
|
|
2937
|
-
templates = {}
|
|
2938
|
-
templates[b"GlobalSettings"] = fbx_template_def_globalsettings(scene, settings, nbr_users=1)
|
|
2939
|
-
|
|
2940
|
-
if data_empties:
|
|
2941
|
-
templates[b"Null"] = fbx_template_def_null(scene, settings, nbr_users=len(data_empties))
|
|
2942
|
-
|
|
2943
|
-
if data_lights:
|
|
2944
|
-
templates[b"Light"] = fbx_template_def_light(scene, settings, nbr_users=len(data_lights))
|
|
2945
|
-
|
|
2946
|
-
if data_cameras:
|
|
2947
|
-
templates[b"Camera"] = fbx_template_def_camera(scene, settings, nbr_users=len(data_cameras))
|
|
2948
|
-
|
|
2949
|
-
if data_bones:
|
|
2950
|
-
templates[b"Bone"] = fbx_template_def_bone(scene, settings, nbr_users=len(data_bones))
|
|
2951
|
-
|
|
2952
|
-
if data_meshes:
|
|
2953
|
-
nbr = len({me_key for me_key, _me, _free in data_meshes.values()})
|
|
2954
|
-
if data_deformers_shape:
|
|
2955
|
-
nbr += sum(len(shapes[2]) for shapes in data_deformers_shape.values())
|
|
2956
|
-
templates[b"Geometry"] = fbx_template_def_geometry(scene, settings, nbr_users=nbr)
|
|
2957
|
-
|
|
2958
|
-
if objects:
|
|
2959
|
-
templates[b"Model"] = fbx_template_def_model(scene, settings, nbr_users=len(objects))
|
|
2960
|
-
|
|
2961
|
-
if arm_parents:
|
|
2962
|
-
# Number of Pose|BindPose elements should be the same as number of meshes-parented-to-armatures
|
|
2963
|
-
templates[b"BindPose"] = fbx_template_def_pose(scene, settings, nbr_users=len(arm_parents))
|
|
2964
|
-
|
|
2965
|
-
if data_deformers_skin or data_deformers_shape:
|
|
2966
|
-
nbr = 0
|
|
2967
|
-
if data_deformers_skin:
|
|
2968
|
-
nbr += len(data_deformers_skin)
|
|
2969
|
-
nbr += sum(len(clusters) for def_me in data_deformers_skin.values() for a, b, clusters in def_me.values())
|
|
2970
|
-
if data_deformers_shape:
|
|
2971
|
-
nbr += len(data_deformers_shape)
|
|
2972
|
-
nbr += sum(len(shapes[2]) for shapes in data_deformers_shape.values())
|
|
2973
|
-
assert(nbr != 0)
|
|
2974
|
-
templates[b"Deformers"] = fbx_template_def_deformer(scene, settings, nbr_users=nbr)
|
|
2975
|
-
|
|
2976
|
-
# No world support in FBX...
|
|
2977
|
-
"""
|
|
2978
|
-
if data_world:
|
|
2979
|
-
templates[b"World"] = fbx_template_def_world(scene, settings, nbr_users=len(data_world))
|
|
2980
|
-
"""
|
|
2981
|
-
|
|
2982
|
-
if data_materials:
|
|
2983
|
-
templates[b"Material"] = fbx_template_def_material(scene, settings, nbr_users=len(data_materials))
|
|
2984
|
-
|
|
2985
|
-
if data_textures:
|
|
2986
|
-
templates[b"TextureFile"] = fbx_template_def_texture_file(scene, settings, nbr_users=len(data_textures))
|
|
2987
|
-
|
|
2988
|
-
if data_videos:
|
|
2989
|
-
templates[b"Video"] = fbx_template_def_video(scene, settings, nbr_users=len(data_videos))
|
|
2990
|
-
|
|
2991
|
-
if animations:
|
|
2992
|
-
nbr_astacks = len(animations)
|
|
2993
|
-
nbr_acnodes = 0
|
|
2994
|
-
nbr_acurves = 0
|
|
2995
|
-
for _astack_key, astack, _al, _n, _fs, _fe in animations:
|
|
2996
|
-
for _alayer_key, alayer in astack.values():
|
|
2997
|
-
for _acnode_key, acnode, _acnode_name in alayer.values():
|
|
2998
|
-
nbr_acnodes += 1
|
|
2999
|
-
for _acurve_key, _dval, (keys, _values), acurve_valid in acnode.values():
|
|
3000
|
-
if len(keys):
|
|
3001
|
-
nbr_acurves += 1
|
|
3002
|
-
|
|
3003
|
-
templates[b"AnimationStack"] = fbx_template_def_animstack(scene, settings, nbr_users=nbr_astacks)
|
|
3004
|
-
# Would be nice to have one layer per animated object, but this seems tricky and not that well supported.
|
|
3005
|
-
# So for now, only one layer per anim stack.
|
|
3006
|
-
templates[b"AnimationLayer"] = fbx_template_def_animlayer(scene, settings, nbr_users=nbr_astacks)
|
|
3007
|
-
templates[b"AnimationCurveNode"] = fbx_template_def_animcurvenode(scene, settings, nbr_users=nbr_acnodes)
|
|
3008
|
-
templates[b"AnimationCurve"] = fbx_template_def_animcurve(scene, settings, nbr_users=nbr_acurves)
|
|
3009
|
-
|
|
3010
|
-
templates_users = sum(tmpl.nbr_users for tmpl in templates.values())
|
|
3011
|
-
|
|
3012
|
-
# ##### Creation of connections...
|
|
3013
|
-
|
|
3014
|
-
perfmon.step("FBX export prepare: Generating Connections...")
|
|
3015
|
-
|
|
3016
|
-
connections = []
|
|
3017
|
-
|
|
3018
|
-
# Objects (with classical parenting).
|
|
3019
|
-
for ob_obj in objects:
|
|
3020
|
-
# Bones are handled later.
|
|
3021
|
-
if not ob_obj.is_bone:
|
|
3022
|
-
par_obj = ob_obj.parent
|
|
3023
|
-
# Meshes parented to armature are handled separately, yet we want the 'no parent' connection (0).
|
|
3024
|
-
if par_obj and ob_obj.has_valid_parent(objects) and (par_obj, ob_obj) not in arm_parents:
|
|
3025
|
-
connections.append((b"OO", ob_obj.fbx_uuid, par_obj.fbx_uuid, None))
|
|
3026
|
-
else:
|
|
3027
|
-
connections.append((b"OO", ob_obj.fbx_uuid, 0, None))
|
|
3028
|
-
|
|
3029
|
-
# Armature & Bone chains.
|
|
3030
|
-
for bo_obj in data_bones.keys():
|
|
3031
|
-
par_obj = bo_obj.parent
|
|
3032
|
-
if par_obj not in objects:
|
|
3033
|
-
continue
|
|
3034
|
-
connections.append((b"OO", bo_obj.fbx_uuid, par_obj.fbx_uuid, None))
|
|
3035
|
-
|
|
3036
|
-
# Object data.
|
|
3037
|
-
for ob_obj in objects:
|
|
3038
|
-
if ob_obj.is_bone:
|
|
3039
|
-
bo_data_key = data_bones[ob_obj]
|
|
3040
|
-
connections.append((b"OO", get_fbx_uuid_from_key(bo_data_key), ob_obj.fbx_uuid, None))
|
|
3041
|
-
else:
|
|
3042
|
-
if ob_obj.type == 'LIGHT':
|
|
3043
|
-
light_key = data_lights[ob_obj.bdata.data]
|
|
3044
|
-
connections.append((b"OO", get_fbx_uuid_from_key(light_key), ob_obj.fbx_uuid, None))
|
|
3045
|
-
elif ob_obj.type == 'CAMERA':
|
|
3046
|
-
cam_key = data_cameras[ob_obj]
|
|
3047
|
-
connections.append((b"OO", get_fbx_uuid_from_key(cam_key), ob_obj.fbx_uuid, None))
|
|
3048
|
-
elif ob_obj.type == 'EMPTY' or ob_obj.type == 'ARMATURE':
|
|
3049
|
-
empty_key = data_empties[ob_obj]
|
|
3050
|
-
connections.append((b"OO", get_fbx_uuid_from_key(empty_key), ob_obj.fbx_uuid, None))
|
|
3051
|
-
elif ob_obj.type in BLENDER_OBJECT_TYPES_MESHLIKE:
|
|
3052
|
-
mesh_key, _me, _free = data_meshes[ob_obj]
|
|
3053
|
-
connections.append((b"OO", get_fbx_uuid_from_key(mesh_key), ob_obj.fbx_uuid, None))
|
|
3054
|
-
|
|
3055
|
-
# Leaf Bones
|
|
3056
|
-
for (_node_name, par_uuid, node_uuid, attr_uuid, _matrix, _hide, _size) in data_leaf_bones:
|
|
3057
|
-
connections.append((b"OO", node_uuid, par_uuid, None))
|
|
3058
|
-
connections.append((b"OO", attr_uuid, node_uuid, None))
|
|
3059
|
-
|
|
3060
|
-
# 'Shape' deformers (shape keys, only for meshes currently)...
|
|
3061
|
-
for me_key, shapes_key, shapes in data_deformers_shape.values():
|
|
3062
|
-
# shape -> geometry
|
|
3063
|
-
connections.append((b"OO", get_fbx_uuid_from_key(shapes_key), get_fbx_uuid_from_key(me_key), None))
|
|
3064
|
-
for channel_key, geom_key, _shape_verts_co, _shape_verts_idx in shapes.values():
|
|
3065
|
-
# shape channel -> shape
|
|
3066
|
-
connections.append((b"OO", get_fbx_uuid_from_key(channel_key), get_fbx_uuid_from_key(shapes_key), None))
|
|
3067
|
-
# geometry (keys) -> shape channel
|
|
3068
|
-
connections.append((b"OO", get_fbx_uuid_from_key(geom_key), get_fbx_uuid_from_key(channel_key), None))
|
|
3069
|
-
|
|
3070
|
-
# 'Skin' deformers (armature-to-geometry, only for meshes currently)...
|
|
3071
|
-
for arm, deformed_meshes in data_deformers_skin.items():
|
|
3072
|
-
for me, (skin_key, ob_obj, clusters) in deformed_meshes.items():
|
|
3073
|
-
# skin -> geometry
|
|
3074
|
-
mesh_key, _me, _free = data_meshes[ob_obj]
|
|
3075
|
-
assert(me == _me)
|
|
3076
|
-
connections.append((b"OO", get_fbx_uuid_from_key(skin_key), get_fbx_uuid_from_key(mesh_key), None))
|
|
3077
|
-
for bo_obj, clstr_key in clusters.items():
|
|
3078
|
-
# cluster -> skin
|
|
3079
|
-
connections.append((b"OO", get_fbx_uuid_from_key(clstr_key), get_fbx_uuid_from_key(skin_key), None))
|
|
3080
|
-
# bone -> cluster
|
|
3081
|
-
connections.append((b"OO", bo_obj.fbx_uuid, get_fbx_uuid_from_key(clstr_key), None))
|
|
3082
|
-
|
|
3083
|
-
# Materials
|
|
3084
|
-
mesh_material_indices = {}
|
|
3085
|
-
for ob_obj in objects:
|
|
3086
|
-
ob_mat_idx = 0
|
|
3087
|
-
me = None
|
|
3088
|
-
if ob_obj.type in BLENDER_OBJECT_TYPES_MESHLIKE:
|
|
3089
|
-
_mesh_key, me, _free = data_meshes[ob_obj]
|
|
3090
|
-
# NOTE: If a mesh has multiple material slots with the same material, they are combined into one
|
|
3091
|
-
# single connexion (slot).
|
|
3092
|
-
# Even if duplicate materials were exported without combining them into one slot, keeping duplicate
|
|
3093
|
-
# materials separated does not appear to be common behavior of external software when importing FBX.
|
|
3094
|
-
# Also, None (empty slots, no material) are always skipped/ignored.
|
|
3095
|
-
done_materials_for_object = {None}
|
|
3096
|
-
for ma in ob_obj.materials:
|
|
3097
|
-
if ma in done_materials_for_object:
|
|
3098
|
-
continue
|
|
3099
|
-
done_materials_for_object.add(ma)
|
|
3100
|
-
ma_key, _ob_objs = data_materials[ma]
|
|
3101
|
-
connections.append((b"OO", get_fbx_uuid_from_key(ma_key), ob_obj.fbx_uuid, None))
|
|
3102
|
-
# Get index of this material for this object (or dupliobject).
|
|
3103
|
-
# Material indices for mesh faces are determined by their order in 'ma to ob' connections.
|
|
3104
|
-
# Only materials for meshes currently...
|
|
3105
|
-
# Note in case of dupliobjects a same me/ma idx will be generated several times...
|
|
3106
|
-
# Should not be an issue in practice, and it's needed in case we export duplis but not the original!
|
|
3107
|
-
if ob_obj.type not in BLENDER_OBJECT_TYPES_MESHLIKE:
|
|
3108
|
-
continue
|
|
3109
|
-
if ma not in mesh_material_indices.setdefault(me, {}):
|
|
3110
|
-
mesh_material_indices[me][ma] = ob_mat_idx
|
|
3111
|
-
else:
|
|
3112
|
-
print("WARNING: Cannot register a valid material index for '{}' from '{}' mesh, '{}' object. "
|
|
3113
|
-
"Most likely, different objects using the same mesh, but different material slots layouts."
|
|
3114
|
-
"".format(ma.name, me.name, ob_obj.name))
|
|
3115
|
-
ob_mat_idx += 1
|
|
3116
|
-
|
|
3117
|
-
# Textures
|
|
3118
|
-
for (ma, sock_name), (tex_key, fbx_prop) in data_textures.items():
|
|
3119
|
-
ma_key, _ob_objs = data_materials[ma]
|
|
3120
|
-
# texture -> material properties
|
|
3121
|
-
connections.append((b"OP", get_fbx_uuid_from_key(tex_key), get_fbx_uuid_from_key(ma_key), fbx_prop))
|
|
3122
|
-
|
|
3123
|
-
# Images
|
|
3124
|
-
for vid, (vid_key, blender_tex_keys) in data_videos.items():
|
|
3125
|
-
for blender_tex_key in blender_tex_keys:
|
|
3126
|
-
tex_key, _fbx_prop = data_textures[blender_tex_key]
|
|
3127
|
-
connections.append((b"OO", get_fbx_uuid_from_key(vid_key), get_fbx_uuid_from_key(tex_key), None))
|
|
3128
|
-
|
|
3129
|
-
# Animations
|
|
3130
|
-
for astack_key, astack, alayer_key, _name, _fstart, _fend in animations:
|
|
3131
|
-
# Animstack itself is linked nowhere!
|
|
3132
|
-
astack_id = get_fbx_uuid_from_key(astack_key)
|
|
3133
|
-
# For now, only one layer!
|
|
3134
|
-
alayer_id = get_fbx_uuid_from_key(alayer_key)
|
|
3135
|
-
connections.append((b"OO", alayer_id, astack_id, None))
|
|
3136
|
-
for elem_key, (alayer_key, acurvenodes) in astack.items():
|
|
3137
|
-
elem_id = get_fbx_uuid_from_key(elem_key)
|
|
3138
|
-
# Animlayer -> animstack.
|
|
3139
|
-
# alayer_id = get_fbx_uuid_from_key(alayer_key)
|
|
3140
|
-
# connections.append((b"OO", alayer_id, astack_id, None))
|
|
3141
|
-
for fbx_prop, (acurvenode_key, acurves, acurvenode_name) in acurvenodes.items():
|
|
3142
|
-
# Animcurvenode -> animalayer.
|
|
3143
|
-
acurvenode_id = get_fbx_uuid_from_key(acurvenode_key)
|
|
3144
|
-
connections.append((b"OO", acurvenode_id, alayer_id, None))
|
|
3145
|
-
# Animcurvenode -> object property.
|
|
3146
|
-
connections.append((b"OP", acurvenode_id, elem_id, fbx_prop.encode()))
|
|
3147
|
-
for fbx_item, (acurve_key, default_value, (keys, values), acurve_valid) in acurves.items():
|
|
3148
|
-
if len(keys):
|
|
3149
|
-
# Animcurve -> Animcurvenode.
|
|
3150
|
-
connections.append((b"OP", get_fbx_uuid_from_key(acurve_key), acurvenode_id, fbx_item.encode()))
|
|
3151
|
-
|
|
3152
|
-
perfmon.level_down()
|
|
3153
|
-
|
|
3154
|
-
# ##### And pack all this!
|
|
3155
|
-
|
|
3156
|
-
return FBXExportData(
|
|
3157
|
-
templates, templates_users, connections,
|
|
3158
|
-
settings, scene, depsgraph, objects, animations, animated, frame_start, frame_end,
|
|
3159
|
-
data_empties, data_lights, data_cameras, data_meshes, mesh_material_indices,
|
|
3160
|
-
data_bones, data_leaf_bones, data_deformers_skin, data_deformers_shape,
|
|
3161
|
-
data_world, data_materials, data_textures, data_videos,
|
|
3162
|
-
)
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
def fbx_scene_data_cleanup(scene_data):
|
|
3166
|
-
"""
|
|
3167
|
-
Some final cleanup...
|
|
3168
|
-
"""
|
|
3169
|
-
# Delete temp meshes.
|
|
3170
|
-
done_meshes = set()
|
|
3171
|
-
for me_key, me, free in scene_data.data_meshes.values():
|
|
3172
|
-
if free and me_key not in done_meshes:
|
|
3173
|
-
bpy.data.meshes.remove(me)
|
|
3174
|
-
done_meshes.add(me_key)
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
# ##### Top-level FBX elements generators. #####
|
|
3178
|
-
|
|
3179
|
-
def fbx_header_elements(root, scene_data, time=None):
|
|
3180
|
-
"""
|
|
3181
|
-
Write boiling code of FBX root.
|
|
3182
|
-
time is expected to be a datetime.datetime object, or None (using now() in this case).
|
|
3183
|
-
"""
|
|
3184
|
-
app_vendor = "Blender Foundation"
|
|
3185
|
-
app_name = "Blender (stable FBX IO)"
|
|
3186
|
-
app_ver = bpy.app.version_string
|
|
3187
|
-
|
|
3188
|
-
from . import bl_info
|
|
3189
|
-
addon_ver = bl_info["version"]
|
|
3190
|
-
del bl_info
|
|
3191
|
-
|
|
3192
|
-
# ##### Start of FBXHeaderExtension element.
|
|
3193
|
-
header_ext = elem_empty(root, b"FBXHeaderExtension")
|
|
3194
|
-
|
|
3195
|
-
elem_data_single_int32(header_ext, b"FBXHeaderVersion", FBX_HEADER_VERSION)
|
|
3196
|
-
|
|
3197
|
-
elem_data_single_int32(header_ext, b"FBXVersion", FBX_VERSION)
|
|
3198
|
-
|
|
3199
|
-
# No encryption!
|
|
3200
|
-
elem_data_single_int32(header_ext, b"EncryptionType", 0)
|
|
3201
|
-
|
|
3202
|
-
if time is None:
|
|
3203
|
-
time = datetime.datetime.now()
|
|
3204
|
-
elem = elem_empty(header_ext, b"CreationTimeStamp")
|
|
3205
|
-
elem_data_single_int32(elem, b"Version", 1000)
|
|
3206
|
-
elem_data_single_int32(elem, b"Year", time.year)
|
|
3207
|
-
elem_data_single_int32(elem, b"Month", time.month)
|
|
3208
|
-
elem_data_single_int32(elem, b"Day", time.day)
|
|
3209
|
-
elem_data_single_int32(elem, b"Hour", time.hour)
|
|
3210
|
-
elem_data_single_int32(elem, b"Minute", time.minute)
|
|
3211
|
-
elem_data_single_int32(elem, b"Second", time.second)
|
|
3212
|
-
elem_data_single_int32(elem, b"Millisecond", time.microsecond // 1000)
|
|
3213
|
-
|
|
3214
|
-
elem_data_single_string_unicode(header_ext, b"Creator", "%s - %s - %d.%d.%d"
|
|
3215
|
-
% (app_name, app_ver, addon_ver[0], addon_ver[1], addon_ver[2]))
|
|
3216
|
-
|
|
3217
|
-
# 'SceneInfo' seems mandatory to get a valid FBX file...
|
|
3218
|
-
# TODO use real values!
|
|
3219
|
-
# XXX Should we use scene.name.encode() here?
|
|
3220
|
-
scene_info = elem_data_single_string(header_ext, b"SceneInfo", fbx_name_class(b"GlobalInfo", b"SceneInfo"))
|
|
3221
|
-
scene_info.add_string(b"UserData")
|
|
3222
|
-
elem_data_single_string(scene_info, b"Type", b"UserData")
|
|
3223
|
-
elem_data_single_int32(scene_info, b"Version", FBX_SCENEINFO_VERSION)
|
|
3224
|
-
meta_data = elem_empty(scene_info, b"MetaData")
|
|
3225
|
-
elem_data_single_int32(meta_data, b"Version", FBX_SCENEINFO_VERSION)
|
|
3226
|
-
elem_data_single_string(meta_data, b"Title", b"")
|
|
3227
|
-
elem_data_single_string(meta_data, b"Subject", b"")
|
|
3228
|
-
elem_data_single_string(meta_data, b"Author", b"")
|
|
3229
|
-
elem_data_single_string(meta_data, b"Keywords", b"")
|
|
3230
|
-
elem_data_single_string(meta_data, b"Revision", b"")
|
|
3231
|
-
elem_data_single_string(meta_data, b"Comment", b"")
|
|
3232
|
-
|
|
3233
|
-
props = elem_properties(scene_info)
|
|
3234
|
-
elem_props_set(props, "p_string_url", b"DocumentUrl", "/foobar.fbx")
|
|
3235
|
-
elem_props_set(props, "p_string_url", b"SrcDocumentUrl", "/foobar.fbx")
|
|
3236
|
-
original = elem_props_compound(props, b"Original")
|
|
3237
|
-
original("p_string", b"ApplicationVendor", app_vendor)
|
|
3238
|
-
original("p_string", b"ApplicationName", app_name)
|
|
3239
|
-
original("p_string", b"ApplicationVersion", app_ver)
|
|
3240
|
-
original("p_datetime", b"DateTime_GMT", "01/01/1970 00:00:00.000")
|
|
3241
|
-
original("p_string", b"FileName", "/foobar.fbx")
|
|
3242
|
-
lastsaved = elem_props_compound(props, b"LastSaved")
|
|
3243
|
-
lastsaved("p_string", b"ApplicationVendor", app_vendor)
|
|
3244
|
-
lastsaved("p_string", b"ApplicationName", app_name)
|
|
3245
|
-
lastsaved("p_string", b"ApplicationVersion", app_ver)
|
|
3246
|
-
lastsaved("p_datetime", b"DateTime_GMT", "01/01/1970 00:00:00.000")
|
|
3247
|
-
original("p_string", b"ApplicationNativeFile", bpy.data.filepath)
|
|
3248
|
-
|
|
3249
|
-
# ##### End of FBXHeaderExtension element.
|
|
3250
|
-
|
|
3251
|
-
# FileID is replaced by dummy value currently...
|
|
3252
|
-
elem_data_single_bytes(root, b"FileId", b"FooBar")
|
|
3253
|
-
|
|
3254
|
-
# CreationTime is replaced by dummy value currently, but anyway...
|
|
3255
|
-
elem_data_single_string_unicode(root, b"CreationTime",
|
|
3256
|
-
"{:04}-{:02}-{:02} {:02}:{:02}:{:02}:{:03}"
|
|
3257
|
-
"".format(time.year, time.month, time.day, time.hour, time.minute, time.second,
|
|
3258
|
-
time.microsecond * 1000))
|
|
3259
|
-
|
|
3260
|
-
elem_data_single_string_unicode(root, b"Creator", "%s - %s - %d.%d.%d"
|
|
3261
|
-
% (app_name, app_ver, addon_ver[0], addon_ver[1], addon_ver[2]))
|
|
3262
|
-
|
|
3263
|
-
# ##### Start of GlobalSettings element.
|
|
3264
|
-
global_settings = elem_empty(root, b"GlobalSettings")
|
|
3265
|
-
scene = scene_data.scene
|
|
3266
|
-
|
|
3267
|
-
elem_data_single_int32(global_settings, b"Version", 1000)
|
|
3268
|
-
|
|
3269
|
-
props = elem_properties(global_settings)
|
|
3270
|
-
up_axis, front_axis, coord_axis = RIGHT_HAND_AXES[scene_data.settings.to_axes]
|
|
3271
|
-
# ~ # DO NOT take into account global scale here! That setting is applied to object transformations during export
|
|
3272
|
-
# ~ # (in other words, this is pure blender-exporter feature, and has nothing to do with FBX data).
|
|
3273
|
-
# ~ if scene_data.settings.apply_unit_scale:
|
|
3274
|
-
# ~ # Unit scaling is applied to objects' scale, so our unit is effectively FBX one (centimeter).
|
|
3275
|
-
# ~ scale_factor_org = 1.0
|
|
3276
|
-
# ~ scale_factor = 1.0 / units_blender_to_fbx_factor(scene)
|
|
3277
|
-
# ~ else:
|
|
3278
|
-
# ~ scale_factor_org = units_blender_to_fbx_factor(scene)
|
|
3279
|
-
# ~ scale_factor = scale_factor_org
|
|
3280
|
-
scale_factor = scale_factor_org = scene_data.settings.unit_scale
|
|
3281
|
-
elem_props_set(props, "p_integer", b"UpAxis", up_axis[0])
|
|
3282
|
-
elem_props_set(props, "p_integer", b"UpAxisSign", up_axis[1])
|
|
3283
|
-
elem_props_set(props, "p_integer", b"FrontAxis", front_axis[0])
|
|
3284
|
-
elem_props_set(props, "p_integer", b"FrontAxisSign", front_axis[1])
|
|
3285
|
-
elem_props_set(props, "p_integer", b"CoordAxis", coord_axis[0])
|
|
3286
|
-
elem_props_set(props, "p_integer", b"CoordAxisSign", coord_axis[1])
|
|
3287
|
-
elem_props_set(props, "p_integer", b"OriginalUpAxis", -1)
|
|
3288
|
-
elem_props_set(props, "p_integer", b"OriginalUpAxisSign", 1)
|
|
3289
|
-
elem_props_set(props, "p_double", b"UnitScaleFactor", scale_factor)
|
|
3290
|
-
elem_props_set(props, "p_double", b"OriginalUnitScaleFactor", scale_factor_org)
|
|
3291
|
-
elem_props_set(props, "p_color_rgb", b"AmbientColor", (0.0, 0.0, 0.0))
|
|
3292
|
-
elem_props_set(props, "p_string", b"DefaultCamera", "Producer Perspective")
|
|
3293
|
-
|
|
3294
|
-
# Global timing data.
|
|
3295
|
-
r = scene.render
|
|
3296
|
-
_, fbx_fps_mode = FBX_FRAMERATES[0] # Custom framerate.
|
|
3297
|
-
fbx_fps = fps = r.fps / r.fps_base
|
|
3298
|
-
for ref_fps, fps_mode in FBX_FRAMERATES:
|
|
3299
|
-
if similar_values(fps, ref_fps):
|
|
3300
|
-
fbx_fps = ref_fps
|
|
3301
|
-
fbx_fps_mode = fps_mode
|
|
3302
|
-
break
|
|
3303
|
-
elem_props_set(props, "p_enum", b"TimeMode", fbx_fps_mode)
|
|
3304
|
-
elem_props_set(props, "p_timestamp", b"TimeSpanStart", 0)
|
|
3305
|
-
elem_props_set(props, "p_timestamp", b"TimeSpanStop", FBX_KTIME)
|
|
3306
|
-
elem_props_set(props, "p_double", b"CustomFrameRate", fbx_fps)
|
|
3307
|
-
|
|
3308
|
-
# ##### End of GlobalSettings element.
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
def fbx_documents_elements(root, scene_data):
|
|
3312
|
-
"""
|
|
3313
|
-
Write 'Document' part of FBX root.
|
|
3314
|
-
Seems like FBX support multiple documents, but until I find examples of such, we'll stick to single doc!
|
|
3315
|
-
time is expected to be a datetime.datetime object, or None (using now() in this case).
|
|
3316
|
-
"""
|
|
3317
|
-
name = scene_data.scene.name
|
|
3318
|
-
|
|
3319
|
-
# ##### Start of Documents element.
|
|
3320
|
-
docs = elem_empty(root, b"Documents")
|
|
3321
|
-
|
|
3322
|
-
elem_data_single_int32(docs, b"Count", 1)
|
|
3323
|
-
|
|
3324
|
-
doc_uid = get_fbx_uuid_from_key("__FBX_Document__" + name)
|
|
3325
|
-
doc = elem_data_single_int64(docs, b"Document", doc_uid)
|
|
3326
|
-
doc.add_string_unicode(name)
|
|
3327
|
-
doc.add_string_unicode(name)
|
|
3328
|
-
|
|
3329
|
-
props = elem_properties(doc)
|
|
3330
|
-
elem_props_set(props, "p_object", b"SourceObject")
|
|
3331
|
-
elem_props_set(props, "p_string", b"ActiveAnimStackName", "")
|
|
3332
|
-
|
|
3333
|
-
# XXX Some kind of ID? Offset?
|
|
3334
|
-
# Anyway, as long as we have only one doc, probably not an issue.
|
|
3335
|
-
elem_data_single_int64(doc, b"RootNode", 0)
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
def fbx_references_elements(root, scene_data):
|
|
3339
|
-
"""
|
|
3340
|
-
Have no idea what references are in FBX currently... Just writing empty element.
|
|
3341
|
-
"""
|
|
3342
|
-
docs = elem_empty(root, b"References")
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
def fbx_definitions_elements(root, scene_data):
|
|
3346
|
-
"""
|
|
3347
|
-
Templates definitions. Only used by Objects data afaik (apart from dummy GlobalSettings one).
|
|
3348
|
-
"""
|
|
3349
|
-
definitions = elem_empty(root, b"Definitions")
|
|
3350
|
-
|
|
3351
|
-
elem_data_single_int32(definitions, b"Version", FBX_TEMPLATES_VERSION)
|
|
3352
|
-
elem_data_single_int32(definitions, b"Count", scene_data.templates_users)
|
|
3353
|
-
|
|
3354
|
-
fbx_templates_generate(definitions, scene_data.templates)
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
def fbx_objects_elements(root, scene_data):
|
|
3358
|
-
"""
|
|
3359
|
-
Data (objects, geometry, material, textures, armatures, etc.).
|
|
3360
|
-
"""
|
|
3361
|
-
perfmon = PerfMon()
|
|
3362
|
-
perfmon.level_up()
|
|
3363
|
-
objects = elem_empty(root, b"Objects")
|
|
3364
|
-
|
|
3365
|
-
perfmon.step("FBX export fetch empties (%d)..." % len(scene_data.data_empties))
|
|
3366
|
-
|
|
3367
|
-
for empty in scene_data.data_empties:
|
|
3368
|
-
fbx_data_empty_elements(objects, empty, scene_data)
|
|
3369
|
-
|
|
3370
|
-
perfmon.step("FBX export fetch lamps (%d)..." % len(scene_data.data_lights))
|
|
3371
|
-
|
|
3372
|
-
for lamp in scene_data.data_lights:
|
|
3373
|
-
fbx_data_light_elements(objects, lamp, scene_data)
|
|
3374
|
-
|
|
3375
|
-
perfmon.step("FBX export fetch cameras (%d)..." % len(scene_data.data_cameras))
|
|
3376
|
-
|
|
3377
|
-
for cam in scene_data.data_cameras:
|
|
3378
|
-
fbx_data_camera_elements(objects, cam, scene_data)
|
|
3379
|
-
|
|
3380
|
-
perfmon.step("FBX export fetch meshes (%d)..."
|
|
3381
|
-
% len({me_key for me_key, _me, _free in scene_data.data_meshes.values()}))
|
|
3382
|
-
|
|
3383
|
-
done_meshes = set()
|
|
3384
|
-
for me_obj in scene_data.data_meshes:
|
|
3385
|
-
fbx_data_mesh_elements(objects, me_obj, scene_data, done_meshes)
|
|
3386
|
-
del done_meshes
|
|
3387
|
-
|
|
3388
|
-
perfmon.step("FBX export fetch objects (%d)..." % len(scene_data.objects))
|
|
3389
|
-
|
|
3390
|
-
for ob_obj in scene_data.objects:
|
|
3391
|
-
if ob_obj.is_dupli:
|
|
3392
|
-
continue
|
|
3393
|
-
fbx_data_object_elements(objects, ob_obj, scene_data)
|
|
3394
|
-
for dp_obj in ob_obj.dupli_list_gen(scene_data.depsgraph):
|
|
3395
|
-
if dp_obj not in scene_data.objects:
|
|
3396
|
-
continue
|
|
3397
|
-
fbx_data_object_elements(objects, dp_obj, scene_data)
|
|
3398
|
-
|
|
3399
|
-
perfmon.step("FBX export fetch remaining...")
|
|
3400
|
-
|
|
3401
|
-
for ob_obj in scene_data.objects:
|
|
3402
|
-
if not (ob_obj.is_object and ob_obj.type == 'ARMATURE'):
|
|
3403
|
-
continue
|
|
3404
|
-
fbx_data_armature_elements(objects, ob_obj, scene_data)
|
|
3405
|
-
|
|
3406
|
-
if scene_data.data_leaf_bones:
|
|
3407
|
-
fbx_data_leaf_bone_elements(objects, scene_data)
|
|
3408
|
-
|
|
3409
|
-
for ma in scene_data.data_materials:
|
|
3410
|
-
fbx_data_material_elements(objects, ma, scene_data)
|
|
3411
|
-
|
|
3412
|
-
for blender_tex_key in scene_data.data_textures:
|
|
3413
|
-
fbx_data_texture_file_elements(objects, blender_tex_key, scene_data)
|
|
3414
|
-
|
|
3415
|
-
for vid in scene_data.data_videos:
|
|
3416
|
-
fbx_data_video_elements(objects, vid, scene_data)
|
|
3417
|
-
|
|
3418
|
-
perfmon.step("FBX export fetch animations...")
|
|
3419
|
-
start_time = time.process_time()
|
|
3420
|
-
|
|
3421
|
-
fbx_data_animation_elements(objects, scene_data)
|
|
3422
|
-
|
|
3423
|
-
perfmon.level_down()
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
def fbx_connections_elements(root, scene_data):
|
|
3427
|
-
"""
|
|
3428
|
-
Relations between Objects (which material uses which texture, and so on).
|
|
3429
|
-
"""
|
|
3430
|
-
connections = elem_empty(root, b"Connections")
|
|
3431
|
-
|
|
3432
|
-
for c in scene_data.connections:
|
|
3433
|
-
elem_connection(connections, *c)
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
def fbx_takes_elements(root, scene_data):
|
|
3437
|
-
"""
|
|
3438
|
-
Animations.
|
|
3439
|
-
"""
|
|
3440
|
-
# XXX Pretty sure takes are no more needed...
|
|
3441
|
-
takes = elem_empty(root, b"Takes")
|
|
3442
|
-
elem_data_single_string(takes, b"Current", b"")
|
|
3443
|
-
|
|
3444
|
-
animations = scene_data.animations
|
|
3445
|
-
for astack_key, animations, alayer_key, name, f_start, f_end in animations:
|
|
3446
|
-
scene = scene_data.scene
|
|
3447
|
-
fps = scene.render.fps / scene.render.fps_base
|
|
3448
|
-
start_ktime = int(convert_sec_to_ktime(f_start / fps))
|
|
3449
|
-
end_ktime = int(convert_sec_to_ktime(f_end / fps))
|
|
3450
|
-
|
|
3451
|
-
take = elem_data_single_string(takes, b"Take", name)
|
|
3452
|
-
elem_data_single_string(take, b"FileName", name + b".tak")
|
|
3453
|
-
take_loc_time = elem_data_single_int64(take, b"LocalTime", start_ktime)
|
|
3454
|
-
take_loc_time.add_int64(end_ktime)
|
|
3455
|
-
take_ref_time = elem_data_single_int64(take, b"ReferenceTime", start_ktime)
|
|
3456
|
-
take_ref_time.add_int64(end_ktime)
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
# ##### "Main" functions. #####
|
|
3460
|
-
|
|
3461
|
-
# This func can be called with just the filepath
|
|
3462
|
-
def save_single(operator, scene, depsgraph, filepath="",
|
|
3463
|
-
global_matrix=Matrix(),
|
|
3464
|
-
apply_unit_scale=False,
|
|
3465
|
-
global_scale=1.0,
|
|
3466
|
-
apply_scale_options='FBX_SCALE_NONE',
|
|
3467
|
-
axis_up="Z",
|
|
3468
|
-
axis_forward="Y",
|
|
3469
|
-
context_objects=None,
|
|
3470
|
-
object_types=None,
|
|
3471
|
-
use_mesh_modifiers=True,
|
|
3472
|
-
use_mesh_modifiers_render=True,
|
|
3473
|
-
mesh_smooth_type='FACE',
|
|
3474
|
-
use_subsurf=False,
|
|
3475
|
-
use_armature_deform_only=False,
|
|
3476
|
-
bake_anim=True,
|
|
3477
|
-
bake_anim_use_all_bones=True,
|
|
3478
|
-
bake_anim_use_nla_strips=True,
|
|
3479
|
-
bake_anim_use_all_actions=True,
|
|
3480
|
-
bake_anim_step=1.0,
|
|
3481
|
-
bake_anim_simplify_factor=1.0,
|
|
3482
|
-
bake_anim_force_startend_keying=True,
|
|
3483
|
-
add_leaf_bones=False,
|
|
3484
|
-
primary_bone_axis='Y',
|
|
3485
|
-
secondary_bone_axis='X',
|
|
3486
|
-
use_metadata=True,
|
|
3487
|
-
path_mode='AUTO',
|
|
3488
|
-
use_mesh_edges=True,
|
|
3489
|
-
use_tspace=True,
|
|
3490
|
-
use_triangles=False,
|
|
3491
|
-
embed_textures=False,
|
|
3492
|
-
use_custom_props=False,
|
|
3493
|
-
bake_space_transform=False,
|
|
3494
|
-
armature_nodetype='NULL',
|
|
3495
|
-
colors_type='SRGB',
|
|
3496
|
-
prioritize_active_color=False,
|
|
3497
|
-
**kwargs
|
|
3498
|
-
):
|
|
3499
|
-
|
|
3500
|
-
# Clear cached ObjectWrappers (just in case...).
|
|
3501
|
-
ObjectWrapper.cache_clear()
|
|
3502
|
-
|
|
3503
|
-
if object_types is None:
|
|
3504
|
-
object_types = {'EMPTY', 'CAMERA', 'LIGHT', 'ARMATURE', 'MESH', 'OTHER'}
|
|
3505
|
-
|
|
3506
|
-
if 'OTHER' in object_types:
|
|
3507
|
-
object_types |= BLENDER_OTHER_OBJECT_TYPES
|
|
3508
|
-
|
|
3509
|
-
# Default Blender unit is equivalent to meter, while FBX one is centimeter...
|
|
3510
|
-
unit_scale = units_blender_to_fbx_factor(scene) if apply_unit_scale else 100.0
|
|
3511
|
-
if apply_scale_options == 'FBX_SCALE_NONE':
|
|
3512
|
-
global_matrix = Matrix.Scale(unit_scale * global_scale, 4) @ global_matrix
|
|
3513
|
-
unit_scale = 1.0
|
|
3514
|
-
elif apply_scale_options == 'FBX_SCALE_UNITS':
|
|
3515
|
-
global_matrix = Matrix.Scale(global_scale, 4) @ global_matrix
|
|
3516
|
-
elif apply_scale_options == 'FBX_SCALE_CUSTOM':
|
|
3517
|
-
global_matrix = Matrix.Scale(unit_scale, 4) @ global_matrix
|
|
3518
|
-
unit_scale = global_scale
|
|
3519
|
-
else: # if apply_scale_options == 'FBX_SCALE_ALL':
|
|
3520
|
-
unit_scale = global_scale * unit_scale
|
|
3521
|
-
|
|
3522
|
-
global_scale = global_matrix.median_scale
|
|
3523
|
-
global_matrix_inv = global_matrix.inverted()
|
|
3524
|
-
# For transforming mesh normals.
|
|
3525
|
-
global_matrix_inv_transposed = global_matrix_inv.transposed()
|
|
3526
|
-
|
|
3527
|
-
# Only embed textures in COPY mode!
|
|
3528
|
-
if embed_textures and path_mode != 'COPY':
|
|
3529
|
-
embed_textures = False
|
|
3530
|
-
|
|
3531
|
-
# Calculate bone correction matrix
|
|
3532
|
-
bone_correction_matrix = None # Default is None = no change
|
|
3533
|
-
bone_correction_matrix_inv = None
|
|
3534
|
-
if (primary_bone_axis, secondary_bone_axis) != ('Y', 'X'):
|
|
3535
|
-
from bpy_extras.io_utils import axis_conversion
|
|
3536
|
-
bone_correction_matrix = axis_conversion(from_forward=secondary_bone_axis,
|
|
3537
|
-
from_up=primary_bone_axis,
|
|
3538
|
-
to_forward='X',
|
|
3539
|
-
to_up='Y',
|
|
3540
|
-
).to_4x4()
|
|
3541
|
-
bone_correction_matrix_inv = bone_correction_matrix.inverted()
|
|
3542
|
-
|
|
3543
|
-
media_settings = FBXExportSettingsMedia(
|
|
3544
|
-
path_mode,
|
|
3545
|
-
os.path.dirname(bpy.data.filepath), # base_src
|
|
3546
|
-
os.path.dirname(filepath), # base_dst
|
|
3547
|
-
# Local dir where to put images (media), using FBX conventions.
|
|
3548
|
-
os.path.splitext(os.path.basename(filepath))[0] + ".fbm", # subdir
|
|
3549
|
-
embed_textures,
|
|
3550
|
-
set(), # copy_set
|
|
3551
|
-
set(), # embedded_set
|
|
3552
|
-
)
|
|
3553
|
-
|
|
3554
|
-
settings = FBXExportSettings(
|
|
3555
|
-
operator.report, (axis_up, axis_forward), global_matrix, global_scale, apply_unit_scale, unit_scale,
|
|
3556
|
-
bake_space_transform, global_matrix_inv, global_matrix_inv_transposed,
|
|
3557
|
-
context_objects, object_types, use_mesh_modifiers, use_mesh_modifiers_render,
|
|
3558
|
-
mesh_smooth_type, use_subsurf, use_mesh_edges, use_tspace, use_triangles,
|
|
3559
|
-
armature_nodetype, use_armature_deform_only,
|
|
3560
|
-
add_leaf_bones, bone_correction_matrix, bone_correction_matrix_inv,
|
|
3561
|
-
bake_anim, bake_anim_use_all_bones, bake_anim_use_nla_strips, bake_anim_use_all_actions,
|
|
3562
|
-
bake_anim_step, bake_anim_simplify_factor, bake_anim_force_startend_keying,
|
|
3563
|
-
False, media_settings, use_custom_props, colors_type, prioritize_active_color
|
|
3564
|
-
)
|
|
3565
|
-
|
|
3566
|
-
import bpy_extras.io_utils
|
|
3567
|
-
|
|
3568
|
-
print('\nFBX export starting... %r' % filepath)
|
|
3569
|
-
start_time = time.time()
|
|
3570
|
-
|
|
3571
|
-
# Generate some data about exported scene...
|
|
3572
|
-
scene_data = fbx_data_from_scene(scene, depsgraph, settings)
|
|
3573
|
-
|
|
3574
|
-
# Enable multithreaded array compression in FBXElem and wait until all threads are done before exiting the context
|
|
3575
|
-
# manager.
|
|
3576
|
-
with encode_bin.FBXElem.enable_multithreading_cm():
|
|
3577
|
-
# Writing elements into an FBX hierarchy can now begin.
|
|
3578
|
-
root = elem_empty(None, b"") # Root element has no id, as it is not saved per se!
|
|
3579
|
-
|
|
3580
|
-
# Mostly FBXHeaderExtension and GlobalSettings.
|
|
3581
|
-
fbx_header_elements(root, scene_data)
|
|
3582
|
-
|
|
3583
|
-
# Documents and References are pretty much void currently.
|
|
3584
|
-
fbx_documents_elements(root, scene_data)
|
|
3585
|
-
fbx_references_elements(root, scene_data)
|
|
3586
|
-
|
|
3587
|
-
# Templates definitions.
|
|
3588
|
-
fbx_definitions_elements(root, scene_data)
|
|
3589
|
-
|
|
3590
|
-
# Actual data.
|
|
3591
|
-
fbx_objects_elements(root, scene_data)
|
|
3592
|
-
|
|
3593
|
-
# How data are inter-connected.
|
|
3594
|
-
fbx_connections_elements(root, scene_data)
|
|
3595
|
-
|
|
3596
|
-
# Animation.
|
|
3597
|
-
fbx_takes_elements(root, scene_data)
|
|
3598
|
-
|
|
3599
|
-
# Cleanup!
|
|
3600
|
-
fbx_scene_data_cleanup(scene_data)
|
|
3601
|
-
|
|
3602
|
-
# And we are done, all multithreaded tasks are complete, and we can write the whole thing to file!
|
|
3603
|
-
encode_bin.write(filepath, root, FBX_VERSION)
|
|
3604
|
-
|
|
3605
|
-
# Clear cached ObjectWrappers!
|
|
3606
|
-
ObjectWrapper.cache_clear()
|
|
3607
|
-
|
|
3608
|
-
# copy all collected files, if we did not embed them.
|
|
3609
|
-
if not media_settings.embed_textures:
|
|
3610
|
-
bpy_extras.io_utils.path_reference_copy(media_settings.copy_set)
|
|
3611
|
-
|
|
3612
|
-
print('export finished in %.4f sec.' % (time.time() - start_time))
|
|
3613
|
-
return {'FINISHED'}
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
# defaults for applications, currently only unity but could add others.
|
|
3617
|
-
def defaults_unity3d():
|
|
3618
|
-
return {
|
|
3619
|
-
# These options seem to produce the same result as the old Ascii exporter in Unity3D:
|
|
3620
|
-
"axis_up": 'Y',
|
|
3621
|
-
"axis_forward": '-Z',
|
|
3622
|
-
"global_matrix": Matrix.Rotation(-math.pi / 2.0, 4, 'X'),
|
|
3623
|
-
# Should really be True, but it can cause problems if a model is already in a scene or prefab
|
|
3624
|
-
# with the old transforms.
|
|
3625
|
-
"bake_space_transform": False,
|
|
3626
|
-
|
|
3627
|
-
"use_selection": False,
|
|
3628
|
-
|
|
3629
|
-
"object_types": {'ARMATURE', 'EMPTY', 'MESH', 'OTHER'},
|
|
3630
|
-
"use_mesh_modifiers": True,
|
|
3631
|
-
"use_mesh_modifiers_render": True,
|
|
3632
|
-
"use_mesh_edges": False,
|
|
3633
|
-
"mesh_smooth_type": 'FACE',
|
|
3634
|
-
"colors_type": 'SRGB',
|
|
3635
|
-
"use_subsurf": False,
|
|
3636
|
-
"use_tspace": False, # XXX Why? Unity is expected to support tspace import...
|
|
3637
|
-
"use_triangles": False,
|
|
3638
|
-
|
|
3639
|
-
"use_armature_deform_only": True,
|
|
3640
|
-
|
|
3641
|
-
"use_custom_props": True,
|
|
3642
|
-
|
|
3643
|
-
"bake_anim": True,
|
|
3644
|
-
"bake_anim_simplify_factor": 1.0,
|
|
3645
|
-
"bake_anim_step": 1.0,
|
|
3646
|
-
"bake_anim_use_nla_strips": True,
|
|
3647
|
-
"bake_anim_use_all_actions": True,
|
|
3648
|
-
"add_leaf_bones": False, # Avoid memory/performance cost for something only useful for modelling
|
|
3649
|
-
"primary_bone_axis": 'Y', # Doesn't really matter for Unity, so leave unchanged
|
|
3650
|
-
"secondary_bone_axis": 'X',
|
|
3651
|
-
|
|
3652
|
-
"path_mode": 'AUTO',
|
|
3653
|
-
"embed_textures": False,
|
|
3654
|
-
"batch_mode": 'OFF',
|
|
3655
|
-
}
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
def save(operator, context,
|
|
3659
|
-
filepath="",
|
|
3660
|
-
use_selection=False,
|
|
3661
|
-
use_visible=False,
|
|
3662
|
-
use_active_collection=False,
|
|
3663
|
-
collection="",
|
|
3664
|
-
batch_mode='OFF',
|
|
3665
|
-
use_batch_own_dir=False,
|
|
3666
|
-
**kwargs
|
|
3667
|
-
):
|
|
3668
|
-
"""
|
|
3669
|
-
This is a wrapper around save_single, which handles multi-scenes (or collections) cases, when batch-exporting
|
|
3670
|
-
a whole .blend file.
|
|
3671
|
-
"""
|
|
3672
|
-
|
|
3673
|
-
ret = {'FINISHED'}
|
|
3674
|
-
|
|
3675
|
-
active_object = context.view_layer.objects.active
|
|
3676
|
-
|
|
3677
|
-
org_mode = None
|
|
3678
|
-
if active_object and active_object.mode != 'OBJECT' and bpy.ops.object.mode_set.poll():
|
|
3679
|
-
org_mode = active_object.mode
|
|
3680
|
-
bpy.ops.object.mode_set(mode='OBJECT')
|
|
3681
|
-
|
|
3682
|
-
if batch_mode == 'OFF':
|
|
3683
|
-
kwargs_mod = kwargs.copy()
|
|
3684
|
-
|
|
3685
|
-
source_collection = None
|
|
3686
|
-
if use_active_collection:
|
|
3687
|
-
source_collection = context.view_layer.active_layer_collection.collection
|
|
3688
|
-
elif collection:
|
|
3689
|
-
local_collection = bpy.data.collections.get((collection, None))
|
|
3690
|
-
if local_collection:
|
|
3691
|
-
source_collection = local_collection
|
|
3692
|
-
else:
|
|
3693
|
-
operator.report({'ERROR'}, "Collection '%s' was not found" % collection)
|
|
3694
|
-
return {'CANCELLED'}
|
|
3695
|
-
|
|
3696
|
-
if source_collection:
|
|
3697
|
-
if use_selection:
|
|
3698
|
-
ctx_objects = tuple(obj for obj in source_collection.all_objects if obj.select_get())
|
|
3699
|
-
else:
|
|
3700
|
-
ctx_objects = source_collection.all_objects
|
|
3701
|
-
else:
|
|
3702
|
-
if use_selection:
|
|
3703
|
-
ctx_objects = context.selected_objects
|
|
3704
|
-
else:
|
|
3705
|
-
ctx_objects = context.view_layer.objects
|
|
3706
|
-
if use_visible:
|
|
3707
|
-
ctx_objects = tuple(obj for obj in ctx_objects if obj.visible_get())
|
|
3708
|
-
|
|
3709
|
-
# Sort exported objects by their names.
|
|
3710
|
-
ctx_objects = sorted(ctx_objects, key=lambda ob: ob.name)
|
|
3711
|
-
|
|
3712
|
-
# Ensure no Objects are in Edit mode.
|
|
3713
|
-
# Copy to a tuple for safety, to avoid the risk of modifying ctx_objects while iterating.
|
|
3714
|
-
for obj in ctx_objects:
|
|
3715
|
-
if not ensure_object_not_in_edit_mode(context, obj):
|
|
3716
|
-
operator.report({'ERROR'}, "%s could not be set out of Edit Mode, so cannot be exported" % obj.name)
|
|
3717
|
-
return {'CANCELLED'}
|
|
3718
|
-
|
|
3719
|
-
kwargs_mod["context_objects"] = ctx_objects
|
|
3720
|
-
|
|
3721
|
-
depsgraph = context.evaluated_depsgraph_get()
|
|
3722
|
-
ret = save_single(operator, context.scene, depsgraph, filepath, **kwargs_mod)
|
|
3723
|
-
else:
|
|
3724
|
-
# XXX We need a way to generate a depsgraph for inactive view_layers first...
|
|
3725
|
-
# XXX Also, what to do in case of batch-exporting scenes, when there is more than one view layer?
|
|
3726
|
-
# Scenes have no concept of 'active' view layer, that's on window level...
|
|
3727
|
-
fbxpath = filepath
|
|
3728
|
-
|
|
3729
|
-
prefix = os.path.basename(fbxpath)
|
|
3730
|
-
if prefix:
|
|
3731
|
-
fbxpath = os.path.dirname(fbxpath)
|
|
3732
|
-
|
|
3733
|
-
if batch_mode == 'COLLECTION':
|
|
3734
|
-
data_seq = tuple((coll, coll.name, 'objects') for coll in bpy.data.collections if coll.objects)
|
|
3735
|
-
elif batch_mode in {'SCENE_COLLECTION', 'ACTIVE_SCENE_COLLECTION'}:
|
|
3736
|
-
scenes = [context.scene] if batch_mode == 'ACTIVE_SCENE_COLLECTION' else bpy.data.scenes
|
|
3737
|
-
data_seq = []
|
|
3738
|
-
for scene in scenes:
|
|
3739
|
-
if not scene.objects:
|
|
3740
|
-
continue
|
|
3741
|
-
# Needed to avoid having tens of 'Scene Collection' entries.
|
|
3742
|
-
todo_collections = [(scene.collection, "_".join((scene.name, scene.collection.name)))]
|
|
3743
|
-
while todo_collections:
|
|
3744
|
-
coll, coll_name = todo_collections.pop()
|
|
3745
|
-
todo_collections.extend(((c, c.name) for c in coll.children if c.all_objects))
|
|
3746
|
-
data_seq.append((coll, coll_name, 'all_objects'))
|
|
3747
|
-
else:
|
|
3748
|
-
data_seq = tuple((scene, scene.name, 'objects') for scene in bpy.data.scenes if scene.objects)
|
|
3749
|
-
|
|
3750
|
-
# Ensure no Objects are in Edit mode.
|
|
3751
|
-
for data, data_name, data_obj_propname in data_seq:
|
|
3752
|
-
# Copy to a tuple for safety, to avoid the risk of modifying the data prop while iterating it.
|
|
3753
|
-
for obj in tuple(getattr(data, data_obj_propname)):
|
|
3754
|
-
if not ensure_object_not_in_edit_mode(context, obj):
|
|
3755
|
-
operator.report({'ERROR'},
|
|
3756
|
-
"%s in %s could not be set out of Edit Mode, so cannot be exported"
|
|
3757
|
-
% (obj.name, data_name))
|
|
3758
|
-
return {'CANCELLED'}
|
|
3759
|
-
|
|
3760
|
-
# call this function within a loop with BATCH_ENABLE == False
|
|
3761
|
-
|
|
3762
|
-
new_fbxpath = fbxpath # own dir option modifies, we need to keep an original
|
|
3763
|
-
for data, data_name, data_obj_propname in data_seq: # scene or collection
|
|
3764
|
-
newname = "_".join((prefix, bpy.path.clean_name(data_name))) if prefix else bpy.path.clean_name(data_name)
|
|
3765
|
-
|
|
3766
|
-
if use_batch_own_dir:
|
|
3767
|
-
new_fbxpath = os.path.join(fbxpath, newname)
|
|
3768
|
-
# path may already exist... and be a file.
|
|
3769
|
-
while os.path.isfile(new_fbxpath):
|
|
3770
|
-
new_fbxpath = "_".join((new_fbxpath, "dir"))
|
|
3771
|
-
if not os.path.exists(new_fbxpath):
|
|
3772
|
-
os.makedirs(new_fbxpath)
|
|
3773
|
-
|
|
3774
|
-
filepath = os.path.join(new_fbxpath, newname + '.fbx')
|
|
3775
|
-
|
|
3776
|
-
print('\nBatch exporting %s as...\n\t%r' % (data, filepath))
|
|
3777
|
-
|
|
3778
|
-
if batch_mode in {'COLLECTION', 'SCENE_COLLECTION', 'ACTIVE_SCENE_COLLECTION'}:
|
|
3779
|
-
# Collection, so that objects update properly, add a dummy scene.
|
|
3780
|
-
scene = bpy.data.scenes.new(name="FBX_Temp")
|
|
3781
|
-
src_scenes = {} # Count how much each 'source' scenes are used.
|
|
3782
|
-
for obj in getattr(data, data_obj_propname):
|
|
3783
|
-
for src_sce in obj.users_scene:
|
|
3784
|
-
src_scenes[src_sce] = src_scenes.setdefault(src_sce, 0) + 1
|
|
3785
|
-
scene.collection.objects.link(obj)
|
|
3786
|
-
|
|
3787
|
-
# Find the 'most used' source scene, and use its unit settings. This is somewhat weak, but should work
|
|
3788
|
-
# fine in most cases, and avoids stupid issues like T41931.
|
|
3789
|
-
best_src_scene = None
|
|
3790
|
-
best_src_scene_users = -1
|
|
3791
|
-
for sce, nbr_users in src_scenes.items():
|
|
3792
|
-
if (nbr_users) > best_src_scene_users:
|
|
3793
|
-
best_src_scene_users = nbr_users
|
|
3794
|
-
best_src_scene = sce
|
|
3795
|
-
scene.unit_settings.system = best_src_scene.unit_settings.system
|
|
3796
|
-
scene.unit_settings.system_rotation = best_src_scene.unit_settings.system_rotation
|
|
3797
|
-
scene.unit_settings.scale_length = best_src_scene.unit_settings.scale_length
|
|
3798
|
-
|
|
3799
|
-
# new scene [only one viewlayer to update]
|
|
3800
|
-
scene.view_layers[0].update()
|
|
3801
|
-
# TODO - BUMMER! Armatures not in the group wont animate the mesh
|
|
3802
|
-
else:
|
|
3803
|
-
scene = data
|
|
3804
|
-
|
|
3805
|
-
kwargs_batch = kwargs.copy()
|
|
3806
|
-
kwargs_batch["context_objects"] = getattr(data, data_obj_propname)
|
|
3807
|
-
|
|
3808
|
-
save_single(operator, scene, scene.view_layers[0].depsgraph, filepath, **kwargs_batch)
|
|
3809
|
-
|
|
3810
|
-
if batch_mode in {'COLLECTION', 'SCENE_COLLECTION', 'ACTIVE_SCENE_COLLECTION'}:
|
|
3811
|
-
# Remove temp collection scene.
|
|
3812
|
-
bpy.data.scenes.remove(scene)
|
|
3813
|
-
|
|
3814
|
-
if active_object and org_mode:
|
|
3815
|
-
context.view_layer.objects.active = active_object
|
|
3816
|
-
if bpy.ops.object.mode_set.poll():
|
|
3817
|
-
bpy.ops.object.mode_set(mode=org_mode)
|
|
3818
|
-
|
|
3819
|
-
return ret
|