@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.
Files changed (1216) hide show
  1. package/package.json +1 -1
  2. package/staging_area/Blender/blender.pdb.ts_part_0 +0 -0
  3. package/staging_area/Blender/5.0/scripts/addons_core/cycles/__init__.py +0 -173
  4. package/staging_area/Blender/5.0/scripts/addons_core/cycles/__pycache__/__init__.cpython-311.pyc +0 -0
  5. package/staging_area/Blender/5.0/scripts/addons_core/cycles/__pycache__/camera.cpython-311.pyc +0 -0
  6. package/staging_area/Blender/5.0/scripts/addons_core/cycles/__pycache__/engine.cpython-311.pyc +0 -0
  7. package/staging_area/Blender/5.0/scripts/addons_core/cycles/__pycache__/operators.cpython-311.pyc +0 -0
  8. package/staging_area/Blender/5.0/scripts/addons_core/cycles/__pycache__/presets.cpython-311.pyc +0 -0
  9. package/staging_area/Blender/5.0/scripts/addons_core/cycles/__pycache__/properties.cpython-311.pyc +0 -0
  10. package/staging_area/Blender/5.0/scripts/addons_core/cycles/__pycache__/ui.cpython-311.pyc +0 -0
  11. package/staging_area/Blender/5.0/scripts/addons_core/cycles/__pycache__/version_update.cpython-311.pyc +0 -0
  12. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/geom/shader_data.h +0 -452
  13. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/geom/triangle.h +0 -278
  14. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/geom/triangle_intersect.h +0 -166
  15. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/geom/volume.h +0 -104
  16. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/globals.h +0 -13
  17. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/image.h +0 -12
  18. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/displacement_shader.h +0 -43
  19. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/guiding.h +0 -641
  20. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/init_from_bake.h +0 -344
  21. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/init_from_camera.h +0 -110
  22. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/intersect_closest.h +0 -443
  23. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/intersect_dedicated_light.h +0 -232
  24. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/intersect_shadow.h +0 -183
  25. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/intersect_subsurface.h +0 -24
  26. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/intersect_volume_stack.h +0 -250
  27. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/megakernel.h +0 -114
  28. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/mnee.h +0 -1123
  29. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/path_state.h +0 -425
  30. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shade_background.h +0 -210
  31. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shade_dedicated_light.h +0 -243
  32. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shade_light.h +0 -95
  33. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shade_shadow.h +0 -192
  34. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shade_surface.h +0 -885
  35. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shade_volume.h +0 -2947
  36. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shadow_catcher.h +0 -79
  37. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shadow_linking.h +0 -69
  38. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/shadow_state_template.h +0 -99
  39. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/state.h +0 -276
  40. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/state_flow.h +0 -255
  41. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/state_template.h +0 -152
  42. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/state_util.h +0 -602
  43. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/subsurface.h +0 -251
  44. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/subsurface_disk.h +0 -220
  45. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/subsurface_random_walk.h +0 -462
  46. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/surface_shader.h +0 -1198
  47. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/volume_shader.h +0 -539
  48. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/integrator/volume_stack.h +0 -258
  49. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/area.h +0 -537
  50. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/background.h +0 -500
  51. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/common.h +0 -86
  52. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/distant.h +0 -167
  53. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/distribution.h +0 -60
  54. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/light.h +0 -499
  55. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/point.h +0 -240
  56. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/sample.h +0 -545
  57. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/spot.h +0 -347
  58. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/tree.h +0 -951
  59. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/light/triangle.h +0 -339
  60. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/osl/camera.h +0 -81
  61. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/osl/closures_setup.h +0 -1259
  62. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/osl/closures_template.h +0 -277
  63. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/osl/osl.h +0 -287
  64. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/osl/services_gpu.h +0 -1327
  65. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/osl/types.h +0 -157
  66. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/sample/lcg.h +0 -53
  67. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/sample/mapping.h +0 -251
  68. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/sample/mis.h +0 -41
  69. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/sample/pattern.h +0 -188
  70. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/sample/sobol_burley.h +0 -203
  71. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/sample/tabulated_sobol.h +0 -178
  72. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/sample/util.h +0 -79
  73. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/ao.h +0 -148
  74. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/aov.h +0 -49
  75. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/attribute.h +0 -326
  76. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/bevel.h +0 -334
  77. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/blackbody.h +0 -35
  78. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/brick.h +0 -147
  79. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/brightness.h +0 -32
  80. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/bump.h +0 -72
  81. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/camera.h +0 -42
  82. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/checker.h +0 -54
  83. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/clamp.h +0 -40
  84. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/closure.h +0 -1559
  85. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/color_util.h +0 -409
  86. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/convert.h +0 -66
  87. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/displace.h +0 -240
  88. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/fractal_noise.h +0 -550
  89. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/fresnel.h +0 -80
  90. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/gabor.h +0 -392
  91. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/gamma.h +0 -27
  92. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/geometry.h +0 -280
  93. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/gradient.h +0 -80
  94. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/hsv.h +0 -54
  95. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/ies.h +0 -38
  96. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/image.h +0 -273
  97. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/invert.h +0 -33
  98. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/light_path.h +0 -150
  99. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/magic.h +0 -132
  100. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/map_range.h +0 -164
  101. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/mapping.h +0 -74
  102. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/mapping_util.h +0 -37
  103. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/math.h +0 -73
  104. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/math_util.h +0 -278
  105. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/mix.h +0 -125
  106. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/node_types_template.h +0 -115
  107. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/noise.h +0 -761
  108. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/noisetex.h +0 -370
  109. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/normal.h +0 -38
  110. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/radial_tiling.h +0 -81
  111. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/radial_tiling_shared.h +0 -1179
  112. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/ramp.h +0 -185
  113. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/ramp_util.h +0 -80
  114. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/sepcomb_color.h +0 -62
  115. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/sepcomb_vector.h +0 -45
  116. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/sky.h +0 -309
  117. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/svm.h +0 -492
  118. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/tex_coord.h +0 -506
  119. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/types.h +0 -530
  120. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/util.h +0 -160
  121. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/value.h +0 -34
  122. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/vector_rotate.h +0 -79
  123. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/vector_transform.h +0 -130
  124. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/vertex_color.h +0 -107
  125. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/voronoi.h +0 -1248
  126. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/wave.h +0 -137
  127. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/wavelength.h +0 -36
  128. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/white_noise.h +0 -74
  129. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/svm/wireframe.h +0 -116
  130. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/tables.h +0 -124
  131. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/types.h +0 -1923
  132. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/util/colorspace.h +0 -54
  133. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/util/differential.h +0 -169
  134. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/util/ies.h +0 -145
  135. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/util/lookup_table.h +0 -74
  136. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/util/nanovdb.h +0 -436
  137. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/util/profiler.h +0 -28
  138. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/kernel/util/texture_3d.h +0 -232
  139. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/atomic.h +0 -315
  140. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/color.h +0 -439
  141. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/defines.h +0 -131
  142. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/guiding.h +0 -40
  143. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/half.h +0 -178
  144. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/hash.h +0 -650
  145. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math.h +0 -24
  146. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_base.h +0 -953
  147. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_dual.h +0 -59
  148. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_fast.h +0 -650
  149. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_float2.h +0 -274
  150. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_float3.h +0 -847
  151. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_float4.h +0 -666
  152. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_float8.h +0 -471
  153. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_int2.h +0 -59
  154. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_int3.h +0 -117
  155. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_int4.h +0 -296
  156. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_int8.h +0 -353
  157. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/math_intersect.h +0 -452
  158. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/projection.h +0 -308
  159. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/projection_inverse.h +0 -95
  160. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/rect.h +0 -61
  161. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/static_assert.h +0 -21
  162. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/texture.h +0 -100
  163. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/transform.h +0 -650
  164. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types.h +0 -32
  165. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_base.h +0 -94
  166. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_dual.h +0 -134
  167. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_float2.h +0 -71
  168. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_float3.h +0 -200
  169. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_float4.h +0 -134
  170. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_float8.h +0 -134
  171. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_int2.h +0 -44
  172. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_int3.h +0 -158
  173. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_int4.h +0 -91
  174. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_int8.h +0 -94
  175. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_rgbe.h +0 -109
  176. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_spectrum.h +0 -28
  177. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_uchar2.h +0 -39
  178. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_uchar3.h +0 -39
  179. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_uchar4.h +0 -45
  180. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_uint2.h +0 -37
  181. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_uint3.h +0 -91
  182. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_uint4.h +0 -37
  183. package/staging_area/Blender/5.0/scripts/addons_core/cycles/source/util/types_ushort4.h +0 -19
  184. package/staging_area/Blender/5.0/scripts/addons_core/cycles/ui.py +0 -2645
  185. package/staging_area/Blender/5.0/scripts/addons_core/cycles/version_update.py +0 -330
  186. package/staging_area/Blender/5.0/scripts/addons_core/hydra_storm/__init__.py +0 -33
  187. package/staging_area/Blender/5.0/scripts/addons_core/hydra_storm/engine.py +0 -47
  188. package/staging_area/Blender/5.0/scripts/addons_core/hydra_storm/properties.py +0 -62
  189. package/staging_area/Blender/5.0/scripts/addons_core/hydra_storm/ui.py +0 -280
  190. package/staging_area/Blender/5.0/scripts/addons_core/io_anim_bvh/__init__.py +0 -397
  191. package/staging_area/Blender/5.0/scripts/addons_core/io_anim_bvh/__pycache__/__init__.cpython-311.pyc +0 -0
  192. package/staging_area/Blender/5.0/scripts/addons_core/io_anim_bvh/export_bvh.py +0 -294
  193. package/staging_area/Blender/5.0/scripts/addons_core/io_anim_bvh/import_bvh.py +0 -795
  194. package/staging_area/Blender/5.0/scripts/addons_core/io_curve_svg/__init__.py +0 -115
  195. package/staging_area/Blender/5.0/scripts/addons_core/io_curve_svg/__pycache__/__init__.cpython-311.pyc +0 -0
  196. package/staging_area/Blender/5.0/scripts/addons_core/io_curve_svg/import_svg.py +0 -1911
  197. package/staging_area/Blender/5.0/scripts/addons_core/io_curve_svg/svg_colors.py +0 -153
  198. package/staging_area/Blender/5.0/scripts/addons_core/io_curve_svg/svg_util.py +0 -107
  199. package/staging_area/Blender/5.0/scripts/addons_core/io_curve_svg/svg_util_test.py +0 -166
  200. package/staging_area/Blender/5.0/scripts/addons_core/io_mesh_uv_layout/__init__.py +0 -302
  201. package/staging_area/Blender/5.0/scripts/addons_core/io_mesh_uv_layout/__pycache__/__init__.cpython-311.pyc +0 -0
  202. package/staging_area/Blender/5.0/scripts/addons_core/io_mesh_uv_layout/export_uv_eps.py +0 -82
  203. package/staging_area/Blender/5.0/scripts/addons_core/io_mesh_uv_layout/export_uv_png.py +0 -119
  204. package/staging_area/Blender/5.0/scripts/addons_core/io_mesh_uv_layout/export_uv_svg.py +0 -54
  205. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/__init__.py +0 -740
  206. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/__pycache__/__init__.cpython-311.pyc +0 -0
  207. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/data_types.py +0 -62
  208. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/encode_bin.py +0 -434
  209. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/export_fbx_bin.py +0 -3819
  210. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/fbx2json.py +0 -341
  211. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/fbx_utils.py +0 -1931
  212. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/fbx_utils_threading.py +0 -194
  213. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/import_fbx.py +0 -4045
  214. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/json2fbx.py +0 -165
  215. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_fbx/parse_fbx.py +0 -274
  216. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/__init__.py +0 -2250
  217. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/__pycache__/__init__.cpython-311.pyc +0 -0
  218. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/__init__.py +0 -3
  219. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/__pycache__/__init__.cpython-311.pyc +0 -0
  220. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/blender_default.cpython-311.pyc +0 -0
  221. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/conversion.cpython-311.pyc +0 -0
  222. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/data_path.cpython-311.pyc +0 -0
  223. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/extras.cpython-311.pyc +0 -0
  224. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/gltf2_blender_math.cpython-311.pyc +0 -0
  225. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/gltf2_blender_ui.cpython-311.pyc +0 -0
  226. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/gltf2_blender_utils.cpython-311.pyc +0 -0
  227. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/json_util.cpython-311.pyc +0 -0
  228. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/__pycache__/material_helpers.cpython-311.pyc +0 -0
  229. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/blender_default.py +0 -15
  230. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/conversion.py +0 -229
  231. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/data_path.py +0 -110
  232. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/extras.py +0 -89
  233. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/gltf2_blender_math.py +0 -209
  234. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/gltf2_blender_ui.py +0 -751
  235. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/gltf2_blender_utils.py +0 -70
  236. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/json_util.py +0 -27
  237. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/com/material_helpers.py +0 -32
  238. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/__pycache__/cache.cpython-311.pyc +0 -0
  239. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/__pycache__/sampler.cpython-311.pyc +0 -0
  240. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/accessors.py +0 -189
  241. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/action.py +0 -1062
  242. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/anim_utils.py +0 -321
  243. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/animations.py +0 -22
  244. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/drivers.py +0 -83
  245. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/fcurves/animation.py +0 -35
  246. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/fcurves/channel_target.py +0 -53
  247. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/fcurves/channels.py +0 -378
  248. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/fcurves/keyframes.py +0 -207
  249. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/fcurves/sampler.py +0 -231
  250. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/keyframes.py +0 -127
  251. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/armature/action_sampled.py +0 -55
  252. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/armature/channel_target.py +0 -54
  253. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/armature/channels.py +0 -236
  254. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/armature/keyframes.py +0 -95
  255. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/armature/sampler.py +0 -230
  256. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/data/channel_target.py +0 -48
  257. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/data/channels.py +0 -118
  258. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/data/keyframes.py +0 -152
  259. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/data/sampler.py +0 -135
  260. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/object/action_sampled.py +0 -58
  261. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/object/channel_target.py +0 -51
  262. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/object/channels.py +0 -136
  263. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/object/keyframes.py +0 -88
  264. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/object/sampler.py +0 -171
  265. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/sampling_cache.py +0 -754
  266. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/shapekeys/action_sampled.py +0 -43
  267. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/shapekeys/channel_target.py +0 -38
  268. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/shapekeys/channels.py +0 -79
  269. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/shapekeys/keyframes.py +0 -145
  270. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/sampled/shapekeys/sampler.py +0 -111
  271. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/scene_animation.py +0 -244
  272. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/animation/tracks.py +0 -846
  273. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/cache.py +0 -182
  274. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/cameras.py +0 -152
  275. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/export.py +0 -412
  276. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/exporter.py +0 -536
  277. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/gather.py +0 -157
  278. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/joints.py +0 -110
  279. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/light_spots.py +0 -47
  280. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/lights.py +0 -212
  281. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/__pycache__/encode_image.cpython-311.pyc +0 -0
  282. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/__pycache__/image.cpython-311.pyc +0 -0
  283. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/__pycache__/search_node_tree.cpython-311.pyc +0 -0
  284. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/__pycache__/texture.cpython-311.pyc +0 -0
  285. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/__pycache__/texture_info.cpython-311.pyc +0 -0
  286. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/__pycache__/unlit.cpython-311.pyc +0 -0
  287. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/encode_image.py +0 -491
  288. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/anisotropy.py +0 -259
  289. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/clearcoat.py +0 -156
  290. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/emission.py +0 -115
  291. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/ior.py +0 -45
  292. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/sheen.py +0 -129
  293. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/specular.py +0 -140
  294. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/transmission.py +0 -76
  295. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/variants.py +0 -19
  296. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/extensions/volume.py +0 -118
  297. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/image.py +0 -514
  298. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/material_utils.py +0 -13
  299. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/material_viewport.py +0 -32
  300. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/materials.py +0 -714
  301. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/pbr_metallic_roughness.py +0 -257
  302. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/search_node_tree.py +0 -1120
  303. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/texture.py +0 -248
  304. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/texture_info.py +0 -291
  305. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/material/unlit.py +0 -191
  306. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/mesh.py +0 -160
  307. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/nodes.py +0 -577
  308. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/primitive_attributes.py +0 -252
  309. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/primitive_extract.py +0 -1662
  310. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/primitives.py +0 -366
  311. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/sampler.py +0 -187
  312. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/skins.py +0 -148
  313. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/exp/tree.py +0 -976
  314. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/KHR_materials_anisotropy.py +0 -116
  315. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/KHR_materials_pbrSpecularGlossiness.py +0 -203
  316. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/KHR_materials_unlit.py +0 -56
  317. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/KHR_materials_anisotropy.cpython-311.pyc +0 -0
  318. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/KHR_materials_pbrSpecularGlossiness.cpython-311.pyc +0 -0
  319. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/KHR_materials_unlit.cpython-311.pyc +0 -0
  320. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/animation.cpython-311.pyc +0 -0
  321. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/animation_node.cpython-311.pyc +0 -0
  322. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/animation_pointer.cpython-311.pyc +0 -0
  323. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/animation_utils.cpython-311.pyc +0 -0
  324. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/animation_weight.cpython-311.pyc +0 -0
  325. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/blender_gltf.cpython-311.pyc +0 -0
  326. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/camera.cpython-311.pyc +0 -0
  327. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/draco_compression_extension.cpython-311.pyc +0 -0
  328. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/image.cpython-311.pyc +0 -0
  329. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/light.cpython-311.pyc +0 -0
  330. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/material.cpython-311.pyc +0 -0
  331. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/material_utils.cpython-311.pyc +0 -0
  332. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/mesh.cpython-311.pyc +0 -0
  333. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/node.cpython-311.pyc +0 -0
  334. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/pbrMetallicRoughness.cpython-311.pyc +0 -0
  335. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/scene.cpython-311.pyc +0 -0
  336. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/texture.cpython-311.pyc +0 -0
  337. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/__pycache__/vnode.cpython-311.pyc +0 -0
  338. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/animation.py +0 -170
  339. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/animation_node.py +0 -170
  340. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/animation_pointer.py +0 -787
  341. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/animation_utils.py +0 -174
  342. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/animation_weight.py +0 -95
  343. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/blender_gltf.py +0 -633
  344. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/camera.py +0 -75
  345. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/draco_compression_extension.py +0 -138
  346. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/image.py +0 -102
  347. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/light.py +0 -143
  348. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/material.py +0 -113
  349. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/material_utils.py +0 -196
  350. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/mesh.py +0 -920
  351. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/node.py +0 -348
  352. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/pbrMetallicRoughness.py +0 -903
  353. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/scene.py +0 -133
  354. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/texture.py +0 -233
  355. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/blender/imp/vnode.py +0 -661
  356. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/extern_draco.dll +0 -0
  357. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/__init__.py +0 -5
  358. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/__pycache__/__init__.cpython-311.pyc +0 -0
  359. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/__pycache__/constants.cpython-311.pyc +0 -0
  360. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/__pycache__/debug.cpython-311.pyc +0 -0
  361. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/__pycache__/draco.cpython-311.pyc +0 -0
  362. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/__pycache__/gltf2_io.cpython-311.pyc +0 -0
  363. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/__pycache__/gltf2_io_extensions.cpython-311.pyc +0 -0
  364. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/__pycache__/path.cpython-311.pyc +0 -0
  365. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/constants.py +0 -159
  366. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/debug.py +0 -129
  367. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/draco.py +0 -46
  368. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/gltf2_io.py +0 -1217
  369. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/gltf2_io_extensions.py +0 -30
  370. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/lights_punctual.py +0 -68
  371. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/path.py +0 -19
  372. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/com/variants.py +0 -32
  373. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/__pycache__/binary_data.cpython-311.pyc +0 -0
  374. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/__pycache__/image_data.cpython-311.pyc +0 -0
  375. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/__pycache__/user_extensions.cpython-311.pyc +0 -0
  376. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/binary_data.py +0 -35
  377. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/buffer.py +0 -54
  378. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/draco.py +0 -174
  379. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/export.py +0 -122
  380. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/image_data.py +0 -80
  381. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/exp/user_extensions.py +0 -17
  382. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/imp/__init__.py +0 -5
  383. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/imp/__pycache__/__init__.cpython-311.pyc +0 -0
  384. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/imp/__pycache__/gltf2_io_binary.cpython-311.pyc +0 -0
  385. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/imp/__pycache__/gltf2_io_gltf.cpython-311.pyc +0 -0
  386. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/imp/__pycache__/user_extensions.cpython-311.pyc +0 -0
  387. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/imp/gltf2_io_binary.py +0 -215
  388. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/imp/gltf2_io_gltf.py +0 -198
  389. package/staging_area/Blender/5.0/scripts/addons_core/io_scene_gltf2/io/imp/user_extensions.py +0 -13
  390. package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/README.md +0 -5
  391. package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/__init__.py +0 -64
  392. package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/interface.py +0 -526
  393. package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/operators.py +0 -2421
  394. package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/preferences.py +0 -398
  395. package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/utils/constants.py +0 -192
  396. package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/utils/draw.py +0 -219
  397. package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/utils/nodes.py +0 -299
  398. package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/utils/paths.py +0 -169
  399. package/staging_area/Blender/5.0/scripts/addons_core/node_wrangler/utils/paths_test.py +0 -290
  400. package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__init__.py +0 -56
  401. package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__pycache__/__init__.cpython-311.pyc +0 -0
  402. package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__pycache__/asset_browser.cpython-311.pyc +0 -0
  403. package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__pycache__/functions.cpython-311.pyc +0 -0
  404. package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__pycache__/gui.cpython-311.pyc +0 -0
  405. package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__pycache__/keymaps.cpython-311.pyc +0 -0
  406. package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__pycache__/operators.cpython-311.pyc +0 -0
  407. package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__pycache__/pose_creation.cpython-311.pyc +0 -0
  408. package/staging_area/Blender/5.0/scripts/addons_core/pose_library/__pycache__/pose_usage.cpython-311.pyc +0 -0
  409. package/staging_area/Blender/5.0/scripts/addons_core/pose_library/asset_browser.py +0 -99
  410. package/staging_area/Blender/5.0/scripts/addons_core/pose_library/functions.py +0 -57
  411. package/staging_area/Blender/5.0/scripts/addons_core/pose_library/gui.py +0 -229
  412. package/staging_area/Blender/5.0/scripts/addons_core/pose_library/keymaps.py +0 -29
  413. package/staging_area/Blender/5.0/scripts/addons_core/pose_library/operators.py +0 -299
  414. package/staging_area/Blender/5.0/scripts/addons_core/pose_library/pose_creation.py +0 -413
  415. package/staging_area/Blender/5.0/scripts/addons_core/pose_library/pose_usage.py +0 -85
  416. package/staging_area/Blender/5.0/scripts/addons_core/rigify/__init__.py +0 -907
  417. package/staging_area/Blender/5.0/scripts/addons_core/rigify/base_generate.py +0 -536
  418. package/staging_area/Blender/5.0/scripts/addons_core/rigify/base_rig.py +0 -351
  419. package/staging_area/Blender/5.0/scripts/addons_core/rigify/feature_set_list.py +0 -357
  420. package/staging_area/Blender/5.0/scripts/addons_core/rigify/feature_sets/__init__.py +0 -16
  421. package/staging_area/Blender/5.0/scripts/addons_core/rigify/generate.py +0 -762
  422. package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarig_menu.py +0 -271
  423. package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/Animals/__init__.py +0 -0
  424. package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/Animals/bird.py +0 -1397
  425. package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/Animals/cat.py +0 -2854
  426. package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/Animals/horse.py +0 -1401
  427. package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/Animals/shark.py +0 -692
  428. package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/Animals/wolf.py +0 -3088
  429. package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/Basic/basic_human.py +0 -618
  430. package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/Basic/basic_quadruped.py +0 -715
  431. package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/__init__.py +0 -0
  432. package/staging_area/Blender/5.0/scripts/addons_core/rigify/metarigs/human.py +0 -2625
  433. package/staging_area/Blender/5.0/scripts/addons_core/rigify/operators/__init__.py +0 -34
  434. package/staging_area/Blender/5.0/scripts/addons_core/rigify/operators/action_layers.py +0 -658
  435. package/staging_area/Blender/5.0/scripts/addons_core/rigify/operators/copy_mirror_parameters.py +0 -316
  436. package/staging_area/Blender/5.0/scripts/addons_core/rigify/operators/generic_ui_list.py +0 -191
  437. package/staging_area/Blender/5.0/scripts/addons_core/rigify/operators/upgrade_face.py +0 -457
  438. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rig_lists.py +0 -116
  439. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rig_ui_template.py +0 -1445
  440. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/__init__.py +0 -0
  441. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/basic/__init__.py +0 -0
  442. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/basic/copy_chain.py +0 -167
  443. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/basic/pivot.py +0 -242
  444. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/basic/raw_copy.py +0 -228
  445. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/basic/super_copy.py +0 -191
  446. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/chain_rigs.py +0 -388
  447. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/experimental/__init__.py +0 -0
  448. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/experimental/super_chain.py +0 -853
  449. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/face/basic_tongue.py +0 -195
  450. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/face/skin_eye.py +0 -843
  451. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/face/skin_jaw.py +0 -880
  452. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/faces/__init__.py +0 -0
  453. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/faces/super_face.py +0 -2378
  454. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/__init__.py +0 -0
  455. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/arm.py +0 -209
  456. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/front_paw.py +0 -270
  457. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/leg.py +0 -746
  458. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/limb_rigs.py +0 -1287
  459. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/limb_utils.py +0 -78
  460. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/paw.py +0 -360
  461. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/rear_paw.py +0 -172
  462. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/simple_tentacle.py +0 -169
  463. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/spline_tentacle.py +0 -1486
  464. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/super_finger.py +0 -699
  465. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/super_limb.py +0 -46
  466. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/limbs/super_palm.py +0 -426
  467. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/skin/anchor.py +0 -142
  468. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/skin/basic_chain.py +0 -565
  469. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/skin/glue.py +0 -325
  470. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/skin/skin_nodes.py +0 -604
  471. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/skin/skin_parents.py +0 -505
  472. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/skin/skin_rigs.py +0 -250
  473. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/skin/stretchy_chain.py +0 -422
  474. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/skin/transform/basic.py +0 -141
  475. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/spines/__init__.py +0 -0
  476. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/spines/basic_spine.py +0 -387
  477. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/spines/basic_tail.py +0 -242
  478. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/spines/spine_rigs.py +0 -295
  479. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/spines/super_head.py +0 -424
  480. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/spines/super_spine.py +0 -150
  481. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/utils.py +0 -175
  482. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rigs/widgets.py +0 -483
  483. package/staging_area/Blender/5.0/scripts/addons_core/rigify/rot_mode.py +0 -311
  484. package/staging_area/Blender/5.0/scripts/addons_core/rigify/ui.py +0 -1834
  485. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/__init__.py +0 -40
  486. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/action_layers.py +0 -454
  487. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/animation.py +0 -1024
  488. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/bones.py +0 -742
  489. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/collections.py +0 -83
  490. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/components.py +0 -102
  491. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/errors.py +0 -28
  492. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/layers.py +0 -396
  493. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/mechanism.py +0 -669
  494. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/metaclass.py +0 -170
  495. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/misc.py +0 -533
  496. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/naming.py +0 -366
  497. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/node_merger.py +0 -345
  498. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/objects.py +0 -206
  499. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/rig.py +0 -747
  500. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/switch_parent.py +0 -533
  501. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/widgets.py +0 -531
  502. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/widgets_basic.py +0 -305
  503. package/staging_area/Blender/5.0/scripts/addons_core/rigify/utils/widgets_special.py +0 -226
  504. package/staging_area/Blender/5.0/scripts/addons_core/ui_translate/__init__.py +0 -60
  505. package/staging_area/Blender/5.0/scripts/addons_core/ui_translate/settings.py +0 -194
  506. package/staging_area/Blender/5.0/scripts/addons_core/ui_translate/update_addon.py +0 -378
  507. package/staging_area/Blender/5.0/scripts/addons_core/ui_translate/update_repo.py +0 -248
  508. package/staging_area/Blender/5.0/scripts/addons_core/ui_translate/update_ui.py +0 -267
  509. package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/__init__.py +0 -55
  510. package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/action_map.py +0 -177
  511. package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/action_map_io.py +0 -346
  512. package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/configs/default.py +0 -434
  513. package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/defaults.py +0 -1587
  514. package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/gui.py +0 -295
  515. package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/operators.py +0 -540
  516. package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/preferences.py +0 -67
  517. package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/properties.py +0 -228
  518. package/staging_area/Blender/5.0/scripts/addons_core/viewport_vr_preview/versioning.py +0 -38
  519. package/staging_area/Blender/5.0/scripts/freestyle/modules/freestyle/__init__.py +0 -14
  520. package/staging_area/Blender/5.0/scripts/freestyle/modules/freestyle/chainingiterators.py +0 -644
  521. package/staging_area/Blender/5.0/scripts/freestyle/modules/freestyle/functions.py +0 -313
  522. package/staging_area/Blender/5.0/scripts/freestyle/modules/freestyle/predicates.py +0 -670
  523. package/staging_area/Blender/5.0/scripts/freestyle/modules/freestyle/shaders.py +0 -1248
  524. package/staging_area/Blender/5.0/scripts/freestyle/modules/freestyle/types.py +0 -159
  525. package/staging_area/Blender/5.0/scripts/freestyle/modules/freestyle/utils.py +0 -541
  526. package/staging_area/Blender/5.0/scripts/freestyle/modules/parameter_editor.py +0 -1589
  527. package/staging_area/Blender/5.0/scripts/freestyle/styles/anisotropic_diffusion.py +0 -41
  528. package/staging_area/Blender/5.0/scripts/freestyle/styles/apriori_and_causal_density.py +0 -34
  529. package/staging_area/Blender/5.0/scripts/freestyle/styles/apriori_density.py +0 -33
  530. package/staging_area/Blender/5.0/scripts/freestyle/styles/backbone_stretcher.py +0 -28
  531. package/staging_area/Blender/5.0/scripts/freestyle/styles/blueprint_circles.py +0 -39
  532. package/staging_area/Blender/5.0/scripts/freestyle/styles/blueprint_ellipses.py +0 -39
  533. package/staging_area/Blender/5.0/scripts/freestyle/styles/blueprint_squares.py +0 -40
  534. package/staging_area/Blender/5.0/scripts/freestyle/styles/cartoon.py +0 -32
  535. package/staging_area/Blender/5.0/scripts/freestyle/styles/contour.py +0 -33
  536. package/staging_area/Blender/5.0/scripts/freestyle/styles/curvature2d.py +0 -29
  537. package/staging_area/Blender/5.0/scripts/freestyle/styles/external_contour.py +0 -33
  538. package/staging_area/Blender/5.0/scripts/freestyle/styles/external_contour_sketchy.py +0 -39
  539. package/staging_area/Blender/5.0/scripts/freestyle/styles/external_contour_smooth.py +0 -37
  540. package/staging_area/Blender/5.0/scripts/freestyle/styles/haloing.py +0 -43
  541. package/staging_area/Blender/5.0/scripts/freestyle/styles/ignore_small_occlusions.py +0 -30
  542. package/staging_area/Blender/5.0/scripts/freestyle/styles/invisible_lines.py +0 -32
  543. package/staging_area/Blender/5.0/scripts/freestyle/styles/japanese_bigbrush.py +0 -53
  544. package/staging_area/Blender/5.0/scripts/freestyle/styles/long_anisotropically_dense.py +0 -67
  545. package/staging_area/Blender/5.0/scripts/freestyle/styles/multiple_parameterization.py +0 -41
  546. package/staging_area/Blender/5.0/scripts/freestyle/styles/nature.py +0 -32
  547. package/staging_area/Blender/5.0/scripts/freestyle/styles/near_lines.py +0 -32
  548. package/staging_area/Blender/5.0/scripts/freestyle/styles/occluded_by_specific_object.py +0 -36
  549. package/staging_area/Blender/5.0/scripts/freestyle/styles/polygonalize.py +0 -32
  550. package/staging_area/Blender/5.0/scripts/freestyle/styles/qi0.py +0 -31
  551. package/staging_area/Blender/5.0/scripts/freestyle/styles/qi0_not_external_contour.py +0 -38
  552. package/staging_area/Blender/5.0/scripts/freestyle/styles/qi1.py +0 -32
  553. package/staging_area/Blender/5.0/scripts/freestyle/styles/qi2.py +0 -32
  554. package/staging_area/Blender/5.0/scripts/freestyle/styles/sequentialsplit_sketchy.py +0 -39
  555. package/staging_area/Blender/5.0/scripts/freestyle/styles/sketchy_multiple_parameterization.py +0 -37
  556. package/staging_area/Blender/5.0/scripts/freestyle/styles/sketchy_topology_broken.py +0 -39
  557. package/staging_area/Blender/5.0/scripts/freestyle/styles/sketchy_topology_preserved.py +0 -36
  558. package/staging_area/Blender/5.0/scripts/freestyle/styles/split_at_highest_2d_curvatures.py +0 -34
  559. package/staging_area/Blender/5.0/scripts/freestyle/styles/split_at_tvertices.py +0 -33
  560. package/staging_area/Blender/5.0/scripts/freestyle/styles/suggestive.py +0 -33
  561. package/staging_area/Blender/5.0/scripts/freestyle/styles/thickness_fof_depth_discontinuity.py +0 -32
  562. package/staging_area/Blender/5.0/scripts/freestyle/styles/tipremover.py +0 -32
  563. package/staging_area/Blender/5.0/scripts/freestyle/styles/tvertex_remover.py +0 -32
  564. package/staging_area/Blender/5.0/scripts/freestyle/styles/uniformpruning_zsort.py +0 -31
  565. package/staging_area/Blender/5.0/scripts/modules/__pycache__/_bpy_restrict_state.cpython-311.pyc +0 -0
  566. package/staging_area/Blender/5.0/scripts/modules/__pycache__/_bpy_types.cpython-311.pyc +0 -0
  567. package/staging_area/Blender/5.0/scripts/modules/__pycache__/_console_python.cpython-311.pyc +0 -0
  568. package/staging_area/Blender/5.0/scripts/modules/__pycache__/_keyingsets_utils.cpython-311.pyc +0 -0
  569. package/staging_area/Blender/5.0/scripts/modules/__pycache__/_rna_xml.cpython-311.pyc +0 -0
  570. package/staging_area/Blender/5.0/scripts/modules/__pycache__/addon_utils.cpython-311.pyc +0 -0
  571. package/staging_area/Blender/5.0/scripts/modules/__pycache__/bl_app_template_utils.cpython-311.pyc +0 -0
  572. package/staging_area/Blender/5.0/scripts/modules/__pycache__/nodeitems_utils.cpython-311.pyc +0 -0
  573. package/staging_area/Blender/5.0/scripts/modules/__pycache__/rna_keymap_ui.cpython-311.pyc +0 -0
  574. package/staging_area/Blender/5.0/scripts/modules/__pycache__/rna_prop_ui.cpython-311.pyc +0 -0
  575. package/staging_area/Blender/5.0/scripts/modules/_animsys_refactor.py +0 -230
  576. package/staging_area/Blender/5.0/scripts/modules/_bl_console_utils/__init__.py +0 -7
  577. package/staging_area/Blender/5.0/scripts/modules/_bl_console_utils/autocomplete/__init__.py +0 -7
  578. package/staging_area/Blender/5.0/scripts/modules/_bl_console_utils/autocomplete/complete_calltip.py +0 -174
  579. package/staging_area/Blender/5.0/scripts/modules/_bl_console_utils/autocomplete/complete_import.py +0 -180
  580. package/staging_area/Blender/5.0/scripts/modules/_bl_console_utils/autocomplete/complete_namespace.py +0 -192
  581. package/staging_area/Blender/5.0/scripts/modules/_bl_console_utils/autocomplete/intellisense.py +0 -138
  582. package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/__init__.py +0 -5
  583. package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/bl_extract_messages.py +0 -1363
  584. package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/merge_po.py +0 -132
  585. package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/settings.py +0 -824
  586. package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/settings_user.py +0 -7
  587. package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/utils.py +0 -1709
  588. package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/utils_cli.py +0 -144
  589. package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/utils_languages_menu.py +0 -68
  590. package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/utils_rtl.py +0 -179
  591. package/staging_area/Blender/5.0/scripts/modules/_bl_i18n_utils/utils_spell_check.py +0 -955
  592. package/staging_area/Blender/5.0/scripts/modules/_bl_previews_utils/bl_previews_render.py +0 -537
  593. package/staging_area/Blender/5.0/scripts/modules/_bl_rna_utils/__init__.py +0 -0
  594. package/staging_area/Blender/5.0/scripts/modules/_bl_rna_utils/__pycache__/__init__.cpython-311.pyc +0 -0
  595. package/staging_area/Blender/5.0/scripts/modules/_bl_rna_utils/__pycache__/data_path.cpython-311.pyc +0 -0
  596. package/staging_area/Blender/5.0/scripts/modules/_bl_rna_utils/data_path.py +0 -76
  597. package/staging_area/Blender/5.0/scripts/modules/_bl_text_utils/__init__.py +0 -0
  598. package/staging_area/Blender/5.0/scripts/modules/_bl_text_utils/external_editor.py +0 -54
  599. package/staging_area/Blender/5.0/scripts/modules/_bl_ui_utils/__init__.py +0 -0
  600. package/staging_area/Blender/5.0/scripts/modules/_bl_ui_utils/__pycache__/__init__.cpython-311.pyc +0 -0
  601. package/staging_area/Blender/5.0/scripts/modules/_bl_ui_utils/__pycache__/layout.cpython-311.pyc +0 -0
  602. package/staging_area/Blender/5.0/scripts/modules/_bl_ui_utils/layout.py +0 -21
  603. package/staging_area/Blender/5.0/scripts/modules/_blendfile_header.py +0 -234
  604. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/__init__.py +0 -3
  605. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/__pycache__/__init__.cpython-311.pyc +0 -0
  606. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/addons/__init__.py +0 -3
  607. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/addons/cli.py +0 -42
  608. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/assets/__init__.py +0 -3
  609. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/assets/remote_library_listing/__init__.py +0 -3
  610. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/assets/remote_library_listing/blender_asset_library_openapi.py +0 -98
  611. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/assets/remote_library_listing/blender_asset_library_openapi.yaml +0 -83
  612. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/__init__.py +0 -3
  613. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/__pycache__/__init__.cpython-311.pyc +0 -0
  614. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/__pycache__/junction_module.cpython-311.pyc +0 -0
  615. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/__pycache__/wheel_manager.cpython-311.pyc +0 -0
  616. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/junction_module.py +0 -165
  617. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/permissions.py +0 -16
  618. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/stale_file_manager.py +0 -417
  619. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/tags.py +0 -54
  620. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/extensions/wheel_manager.py +0 -686
  621. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/freedesktop.py +0 -598
  622. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/grease_pencil/__init__.py +0 -3
  623. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/grease_pencil/stroke.py +0 -402
  624. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/http/__init__.py +0 -3
  625. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/http/downloader.py +0 -1348
  626. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/system_info/text_generate_runtime.py +0 -256
  627. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/system_info/url_prefill_runtime.py +0 -60
  628. package/staging_area/Blender/5.0/scripts/modules/_bpy_internal/system_info/url_prefill_startup.py +0 -107
  629. package/staging_area/Blender/5.0/scripts/modules/_bpy_restrict_state.py +0 -50
  630. package/staging_area/Blender/5.0/scripts/modules/_bpy_types.py +0 -1563
  631. package/staging_area/Blender/5.0/scripts/modules/_console_python.py +0 -368
  632. package/staging_area/Blender/5.0/scripts/modules/_console_shell.py +0 -73
  633. package/staging_area/Blender/5.0/scripts/modules/_graphviz_export.py +0 -194
  634. package/staging_area/Blender/5.0/scripts/modules/_keyingsets_utils.py +0 -355
  635. package/staging_area/Blender/5.0/scripts/modules/_rna_info.py +0 -984
  636. package/staging_area/Blender/5.0/scripts/modules/_rna_manual_reference.py +0 -4446
  637. package/staging_area/Blender/5.0/scripts/modules/_rna_xml.py +0 -422
  638. package/staging_area/Blender/5.0/scripts/modules/addon_utils.py +0 -1992
  639. package/staging_area/Blender/5.0/scripts/modules/bl_app_override/__init__.py +0 -211
  640. package/staging_area/Blender/5.0/scripts/modules/bl_app_override/helpers.py +0 -153
  641. package/staging_area/Blender/5.0/scripts/modules/bl_app_template_utils.py +0 -177
  642. package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/__init__.py +0 -9
  643. package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/__pycache__/__init__.cpython-311.pyc +0 -0
  644. package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/__pycache__/io.cpython-311.pyc +0 -0
  645. package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/__pycache__/keymap_from_toolbar.cpython-311.pyc +0 -0
  646. package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/__pycache__/keymap_hierarchy.cpython-311.pyc +0 -0
  647. package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/io.py +0 -308
  648. package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py +0 -394
  649. package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/keymap_hierarchy.py +0 -247
  650. package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/platform_helpers.py +0 -55
  651. package/staging_area/Blender/5.0/scripts/modules/bl_keymap_utils/versioning.py +0 -328
  652. package/staging_area/Blender/5.0/scripts/modules/blend_render_info.py +0 -123
  653. package/staging_area/Blender/5.0/scripts/modules/bpy/__init__.py +0 -75
  654. package/staging_area/Blender/5.0/scripts/modules/bpy/__pycache__/__init__.cpython-311.pyc +0 -0
  655. package/staging_area/Blender/5.0/scripts/modules/bpy/__pycache__/ops.cpython-311.pyc +0 -0
  656. package/staging_area/Blender/5.0/scripts/modules/bpy/__pycache__/path.cpython-311.pyc +0 -0
  657. package/staging_area/Blender/5.0/scripts/modules/bpy/ops.py +0 -184
  658. package/staging_area/Blender/5.0/scripts/modules/bpy/path.py +0 -459
  659. package/staging_area/Blender/5.0/scripts/modules/bpy/utils/__init__.py +0 -1382
  660. package/staging_area/Blender/5.0/scripts/modules/bpy/utils/__pycache__/__init__.cpython-311.pyc +0 -0
  661. package/staging_area/Blender/5.0/scripts/modules/bpy/utils/__pycache__/previews.cpython-311.pyc +0 -0
  662. package/staging_area/Blender/5.0/scripts/modules/bpy/utils/previews.py +0 -136
  663. package/staging_area/Blender/5.0/scripts/modules/bpy/utils/toolsystem.py +0 -11
  664. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/__init__.py +0 -20
  665. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/__pycache__/__init__.cpython-311.pyc +0 -0
  666. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/__pycache__/asset_utils.cpython-311.pyc +0 -0
  667. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/__pycache__/io_utils.cpython-311.pyc +0 -0
  668. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/__pycache__/node_utils.cpython-311.pyc +0 -0
  669. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/__pycache__/object_utils.cpython-311.pyc +0 -0
  670. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/anim_utils.py +0 -1038
  671. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/asset_utils.py +0 -50
  672. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/bmesh_utils.py +0 -56
  673. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/id_map_utils.py +0 -53
  674. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/image_utils.py +0 -194
  675. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/io_utils.py +0 -620
  676. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/keyconfig_utils.py +0 -141
  677. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/mesh_utils.py +0 -464
  678. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/node_shader_utils.py +0 -829
  679. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/node_utils.py +0 -88
  680. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/object_utils.py +0 -289
  681. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/view3d_utils.py +0 -181
  682. package/staging_area/Blender/5.0/scripts/modules/bpy_extras/wm_utils/progress_report.py +0 -160
  683. package/staging_area/Blender/5.0/scripts/modules/gpu_extras/__init__.py +0 -8
  684. package/staging_area/Blender/5.0/scripts/modules/gpu_extras/__pycache__/__init__.cpython-311.pyc +0 -0
  685. package/staging_area/Blender/5.0/scripts/modules/gpu_extras/__pycache__/presets.cpython-311.pyc +0 -0
  686. package/staging_area/Blender/5.0/scripts/modules/gpu_extras/batch.py +0 -80
  687. package/staging_area/Blender/5.0/scripts/modules/gpu_extras/presets.py +0 -102
  688. package/staging_area/Blender/5.0/scripts/modules/nodeitems_utils.py +0 -178
  689. package/staging_area/Blender/5.0/scripts/modules/rna_keymap_ui.py +0 -505
  690. package/staging_area/Blender/5.0/scripts/modules/rna_prop_ui.py +0 -269
  691. package/staging_area/Blender/5.0/scripts/presets/camera/1_inch.py +0 -4
  692. package/staging_area/Blender/5.0/scripts/presets/camera/1_slash_1.8_inch.py +0 -4
  693. package/staging_area/Blender/5.0/scripts/presets/camera/1_slash_2.3_inch.py +0 -4
  694. package/staging_area/Blender/5.0/scripts/presets/camera/1_slash_2.5_inch.py +0 -4
  695. package/staging_area/Blender/5.0/scripts/presets/camera/1_slash_2.7_inch.py +0 -4
  696. package/staging_area/Blender/5.0/scripts/presets/camera/1_slash_3.2_inch.py +0 -4
  697. package/staging_area/Blender/5.0/scripts/presets/camera/2_slash_3_inch.py +0 -4
  698. package/staging_area/Blender/5.0/scripts/presets/camera/APS-C.py +0 -4
  699. package/staging_area/Blender/5.0/scripts/presets/camera/APS-C_(Canon).py +0 -4
  700. package/staging_area/Blender/5.0/scripts/presets/camera/APS-H_(Canon).py +0 -4
  701. package/staging_area/Blender/5.0/scripts/presets/camera/Analog_16mm.py +0 -4
  702. package/staging_area/Blender/5.0/scripts/presets/camera/Analog_35mm.py +0 -4
  703. package/staging_area/Blender/5.0/scripts/presets/camera/Analog_65mm.py +0 -4
  704. package/staging_area/Blender/5.0/scripts/presets/camera/Analog_IMAX.py +0 -4
  705. package/staging_area/Blender/5.0/scripts/presets/camera/Analog_Super_16.py +0 -4
  706. package/staging_area/Blender/5.0/scripts/presets/camera/Analog_Super_35.py +0 -4
  707. package/staging_area/Blender/5.0/scripts/presets/camera/Arri_Alexa_65.py +0 -4
  708. package/staging_area/Blender/5.0/scripts/presets/camera/Arri_Alexa_LF.py +0 -4
  709. package/staging_area/Blender/5.0/scripts/presets/camera/Arri_Alexa_Mini_&_SXT.py +0 -4
  710. package/staging_area/Blender/5.0/scripts/presets/camera/Blackmagic_Pocket_&_Studio.py +0 -4
  711. package/staging_area/Blender/5.0/scripts/presets/camera/Blackmagic_Pocket_4K.py +0 -4
  712. package/staging_area/Blender/5.0/scripts/presets/camera/Blackmagic_Pocket_6k.py +0 -4
  713. package/staging_area/Blender/5.0/scripts/presets/camera/Blackmagic_URSA_4.6K.py +0 -4
  714. package/staging_area/Blender/5.0/scripts/presets/camera/Foveon_(Sigma).py +0 -4
  715. package/staging_area/Blender/5.0/scripts/presets/camera/Fullframe.py +0 -4
  716. package/staging_area/Blender/5.0/scripts/presets/camera/MFT.py +0 -4
  717. package/staging_area/Blender/5.0/scripts/presets/camera/Medium-format_(Hasselblad).py +0 -4
  718. package/staging_area/Blender/5.0/scripts/presets/camera/RED_Dragon_5K.py +0 -4
  719. package/staging_area/Blender/5.0/scripts/presets/camera/RED_Dragon_6K.py +0 -4
  720. package/staging_area/Blender/5.0/scripts/presets/camera/RED_Helium_8K.py +0 -4
  721. package/staging_area/Blender/5.0/scripts/presets/camera/RED_Monstro_8K.py +0 -4
  722. package/staging_area/Blender/5.0/scripts/presets/cloth/Cotton.py +0 -25
  723. package/staging_area/Blender/5.0/scripts/presets/cloth/Denim.py +0 -25
  724. package/staging_area/Blender/5.0/scripts/presets/cloth/Leather.py +0 -25
  725. package/staging_area/Blender/5.0/scripts/presets/cloth/Rubber.py +0 -25
  726. package/staging_area/Blender/5.0/scripts/presets/cloth/Silk.py +0 -25
  727. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_A.py +0 -5
  728. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_B.py +0 -5
  729. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_C.py +0 -5
  730. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_D50.py +0 -5
  731. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_D55.py +0 -5
  732. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_D65.py +0 -5
  733. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_D75.py +0 -5
  734. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_D93.py +0 -5
  735. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_E.py +0 -5
  736. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F1.py +0 -5
  737. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F10.py +0 -5
  738. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F11.py +0 -5
  739. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F12.py +0 -5
  740. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F2.py +0 -5
  741. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F3.py +0 -5
  742. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F4.py +0 -5
  743. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F5.py +0 -5
  744. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F6.py +0 -5
  745. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F7.py +0 -5
  746. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F8.py +0 -5
  747. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_F9.py +0 -5
  748. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-B1.py +0 -5
  749. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-B2.py +0 -5
  750. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-B3.py +0 -5
  751. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-B4.py +0 -5
  752. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-B5.py +0 -5
  753. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-BH1.py +0 -5
  754. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-RGB1.py +0 -5
  755. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-V1.py +0 -5
  756. package/staging_area/Blender/5.0/scripts/presets/color_management/white_balance/Illuminant_LED-V2.py +0 -5
  757. package/staging_area/Blender/5.0/scripts/presets/cycles/integrator/Default.py +0 -14
  758. package/staging_area/Blender/5.0/scripts/presets/cycles/integrator/Direct_Light.py +0 -14
  759. package/staging_area/Blender/5.0/scripts/presets/cycles/integrator/Fast_Global_Illumination.py +0 -14
  760. package/staging_area/Blender/5.0/scripts/presets/cycles/integrator/Full_Global_Illumination.py +0 -14
  761. package/staging_area/Blender/5.0/scripts/presets/cycles/integrator/Limited_Global_Illumination.py +0 -14
  762. package/staging_area/Blender/5.0/scripts/presets/cycles/performance/Default.py +0 -11
  763. package/staging_area/Blender/5.0/scripts/presets/cycles/performance/Faster_Render.py +0 -11
  764. package/staging_area/Blender/5.0/scripts/presets/cycles/performance/Lower_Memory.py +0 -11
  765. package/staging_area/Blender/5.0/scripts/presets/cycles/sampling/Final.py +0 -12
  766. package/staging_area/Blender/5.0/scripts/presets/cycles/sampling/Preview.py +0 -12
  767. package/staging_area/Blender/5.0/scripts/presets/cycles/viewport_sampling/Final.py +0 -11
  768. package/staging_area/Blender/5.0/scripts/presets/cycles/viewport_sampling/Preview.py +0 -11
  769. package/staging_area/Blender/5.0/scripts/presets/eevee/raytracing/Default.py +0 -22
  770. package/staging_area/Blender/5.0/scripts/presets/ffmpeg/DVD_(note_colon__this_changes_render_resolution).py +0 -24
  771. package/staging_area/Blender/5.0/scripts/presets/ffmpeg/H264_in_MP4.py +0 -18
  772. package/staging_area/Blender/5.0/scripts/presets/ffmpeg/H264_in_Matroska.py +0 -17
  773. package/staging_area/Blender/5.0/scripts/presets/ffmpeg/H264_in_Matroska_for_scrubbing.py +0 -14
  774. package/staging_area/Blender/5.0/scripts/presets/ffmpeg/Ogg_Theora.py +0 -18
  775. package/staging_area/Blender/5.0/scripts/presets/ffmpeg/WebM_(VP9+Opus).py +0 -9
  776. package/staging_area/Blender/5.0/scripts/presets/ffmpeg/Xvid.py +0 -18
  777. package/staging_area/Blender/5.0/scripts/presets/fluid/Honey.py +0 -3
  778. package/staging_area/Blender/5.0/scripts/presets/fluid/Oil.py +0 -3
  779. package/staging_area/Blender/5.0/scripts/presets/fluid/Water.py +0 -3
  780. package/staging_area/Blender/5.0/scripts/presets/framerate/12.py +0 -3
  781. package/staging_area/Blender/5.0/scripts/presets/framerate/120.py +0 -3
  782. package/staging_area/Blender/5.0/scripts/presets/framerate/23.98.py +0 -3
  783. package/staging_area/Blender/5.0/scripts/presets/framerate/24.py +0 -3
  784. package/staging_area/Blender/5.0/scripts/presets/framerate/240.py +0 -3
  785. package/staging_area/Blender/5.0/scripts/presets/framerate/25.py +0 -3
  786. package/staging_area/Blender/5.0/scripts/presets/framerate/29.97.py +0 -3
  787. package/staging_area/Blender/5.0/scripts/presets/framerate/30.py +0 -3
  788. package/staging_area/Blender/5.0/scripts/presets/framerate/50.py +0 -3
  789. package/staging_area/Blender/5.0/scripts/presets/framerate/59.94.py +0 -3
  790. package/staging_area/Blender/5.0/scripts/presets/framerate/6.py +0 -3
  791. package/staging_area/Blender/5.0/scripts/presets/framerate/60.py +0 -3
  792. package/staging_area/Blender/5.0/scripts/presets/framerate/8.py +0 -3
  793. package/staging_area/Blender/5.0/scripts/presets/framerate/Custom.py +0 -1
  794. package/staging_area/Blender/5.0/scripts/presets/framerate/__pycache__/30.cpython-311.pyc +0 -0
  795. package/staging_area/Blender/5.0/scripts/presets/gpencil_material/Fill_Only.py +0 -25
  796. package/staging_area/Blender/5.0/scripts/presets/gpencil_material/Stroke_Only.py +0 -25
  797. package/staging_area/Blender/5.0/scripts/presets/gpencil_material/Stroke_and_Fill.py +0 -25
  798. package/staging_area/Blender/5.0/scripts/presets/hair_dynamics/Default.py +0 -17
  799. package/staging_area/Blender/5.0/scripts/presets/interface_theme/Blender_Dark.xml +0 -6
  800. package/staging_area/Blender/5.0/scripts/presets/interface_theme/Blender_Light.xml +0 -1246
  801. package/staging_area/Blender/5.0/scripts/presets/keyconfig/Blender.py +0 -384
  802. package/staging_area/Blender/5.0/scripts/presets/keyconfig/Blender_27x.py +0 -106
  803. package/staging_area/Blender/5.0/scripts/presets/keyconfig/Industry_Compatible.py +0 -41
  804. package/staging_area/Blender/5.0/scripts/presets/keyconfig/__pycache__/Blender.cpython-311.pyc +0 -0
  805. package/staging_area/Blender/5.0/scripts/presets/keyconfig/keymap_data/__pycache__/blender_default.cpython-311.pyc +0 -0
  806. package/staging_area/Blender/5.0/scripts/presets/keyconfig/keymap_data/blender_default.py +0 -9083
  807. package/staging_area/Blender/5.0/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +0 -3896
  808. package/staging_area/Blender/5.0/scripts/presets/pixel_density/Custom.py +0 -1
  809. package/staging_area/Blender/5.0/scripts/presets/pixel_density/Pixels_slash_Centimeter.py +0 -2
  810. package/staging_area/Blender/5.0/scripts/presets/pixel_density/Pixels_slash_Inch.py +0 -2
  811. package/staging_area/Blender/5.0/scripts/presets/pixel_density/Pixels_slash_Meter.py +0 -2
  812. package/staging_area/Blender/5.0/scripts/presets/render/4K_DCI_2160p.py +0 -8
  813. package/staging_area/Blender/5.0/scripts/presets/render/4K_UHDTV_2160p.py +0 -8
  814. package/staging_area/Blender/5.0/scripts/presets/render/4K_UW_1600p.py +0 -8
  815. package/staging_area/Blender/5.0/scripts/presets/render/DVCPRO_HD_1080p.py +0 -8
  816. package/staging_area/Blender/5.0/scripts/presets/render/DVCPRO_HD_720p.py +0 -8
  817. package/staging_area/Blender/5.0/scripts/presets/render/HDTV_1080p.py +0 -8
  818. package/staging_area/Blender/5.0/scripts/presets/render/HDTV_720p.py +0 -8
  819. package/staging_area/Blender/5.0/scripts/presets/render/HDV_1080p.py +0 -8
  820. package/staging_area/Blender/5.0/scripts/presets/render/HDV_NTSC_1080p.py +0 -8
  821. package/staging_area/Blender/5.0/scripts/presets/render/HDV_PAL_1080p.py +0 -8
  822. package/staging_area/Blender/5.0/scripts/presets/render/TV_NTSC_16_colon_9.py +0 -8
  823. package/staging_area/Blender/5.0/scripts/presets/render/TV_NTSC_4_colon_3.py +0 -8
  824. package/staging_area/Blender/5.0/scripts/presets/render/TV_PAL_16_colon_9.py +0 -8
  825. package/staging_area/Blender/5.0/scripts/presets/render/TV_PAL_4_colon_3.py +0 -8
  826. package/staging_area/Blender/5.0/scripts/presets/safe_areas/14_colon_9_in_16_colon_9.py +0 -7
  827. package/staging_area/Blender/5.0/scripts/presets/safe_areas/16_colon_9.py +0 -7
  828. package/staging_area/Blender/5.0/scripts/presets/safe_areas/4_colon_3_in_16_colon_9.py +0 -7
  829. package/staging_area/Blender/5.0/scripts/presets/text_editor/Internal.py +0 -6
  830. package/staging_area/Blender/5.0/scripts/presets/text_editor/Visual_Studio_Code.py +0 -12
  831. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/1_inch.py +0 -6
  832. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/1_slash_1.8_inch.py +0 -6
  833. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/1_slash_2.3_inch.py +0 -6
  834. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/1_slash_2.5_inch.py +0 -6
  835. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/1_slash_2.7_inch.py +0 -6
  836. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/1_slash_3.2_inch.py +0 -6
  837. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/2_slash_3_inch.py +0 -6
  838. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/APS-C.py +0 -6
  839. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/APS-C_(Canon).py +0 -6
  840. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/APS-H_(Canon).py +0 -6
  841. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Analog_16mm.py +0 -6
  842. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Analog_35mm.py +0 -6
  843. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Analog_65mm.py +0 -6
  844. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Analog_IMAX.py +0 -6
  845. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Analog_Super_16.py +0 -6
  846. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Analog_Super_35.py +0 -6
  847. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Arri_Alexa_65.py +0 -6
  848. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Arri_Alexa_LF.py +0 -6
  849. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Arri_Alexa_Mini_&_SXT.py +0 -6
  850. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Blackmagic_Pocket_&_Studio.py +0 -6
  851. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Blackmagic_Pocket_4K.py +0 -6
  852. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Blackmagic_Pocket_6k.py +0 -6
  853. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Blackmagic_URSA_4.6K.py +0 -6
  854. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Foveon_(Sigma).py +0 -6
  855. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Fullframe.py +0 -6
  856. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/MFT.py +0 -6
  857. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/Medium-format_(Hasselblad).py +0 -6
  858. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/RED_Dragon_5K.py +0 -6
  859. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/RED_Dragon_6K.py +0 -6
  860. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/RED_Helium_8K.py +0 -6
  861. package/staging_area/Blender/5.0/scripts/presets/tracking_camera/RED_Monstro_8K.py +0 -6
  862. package/staging_area/Blender/5.0/scripts/presets/tracking_settings/Blurry_Footage.py +0 -18
  863. package/staging_area/Blender/5.0/scripts/presets/tracking_settings/Default.py +0 -18
  864. package/staging_area/Blender/5.0/scripts/presets/tracking_settings/Fast_Motion.py +0 -18
  865. package/staging_area/Blender/5.0/scripts/presets/tracking_settings/Planar.py +0 -18
  866. package/staging_area/Blender/5.0/scripts/presets/tracking_track_color/Default.py +0 -5
  867. package/staging_area/Blender/5.0/scripts/presets/tracking_track_color/Far_Plane.py +0 -5
  868. package/staging_area/Blender/5.0/scripts/presets/tracking_track_color/Near_Plane.py +0 -5
  869. package/staging_area/Blender/5.0/scripts/presets/tracking_track_color/Object.py +0 -5
  870. package/staging_area/Blender/5.0/scripts/startup/__pycache__/keyingsets_builtins.cpython-311.pyc +0 -0
  871. package/staging_area/Blender/5.0/scripts/startup/__pycache__/nodeitems_builtins.cpython-311.pyc +0 -0
  872. package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/2D_Animation/__init__.py +0 -56
  873. package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/2D_Animation/__pycache__/__init__.cpython-311.pyc +0 -0
  874. package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/2D_Animation/startup.blend +0 -0
  875. package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/Sculpting/__init__.py +0 -30
  876. package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/Sculpting/startup.blend +0 -0
  877. package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/Storyboarding/__init__.py +0 -51
  878. package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/Storyboarding/__pycache__/__init__.cpython-311.pyc +0 -0
  879. package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/Storyboarding/startup.blend +0 -0
  880. package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/VFX/startup.blend +0 -0
  881. package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/Video_Editing/__init__.py +0 -51
  882. package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/Video_Editing/__pycache__/__init__.cpython-311.pyc +0 -0
  883. package/staging_area/Blender/5.0/scripts/startup/bl_app_templates_system/Video_Editing/startup.blend +0 -0
  884. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__init__.py +0 -88
  885. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/__init__.cpython-311.pyc +0 -0
  886. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/add_mesh_torus.cpython-311.pyc +0 -0
  887. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/anim.cpython-311.pyc +0 -0
  888. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/assets.cpython-311.pyc +0 -0
  889. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/bone_selection_sets.cpython-311.pyc +0 -0
  890. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/clip.cpython-311.pyc +0 -0
  891. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/connect_to_output.cpython-311.pyc +0 -0
  892. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/console.cpython-311.pyc +0 -0
  893. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/constraint.cpython-311.pyc +0 -0
  894. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/copy_global_transform.cpython-311.pyc +0 -0
  895. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/file.cpython-311.pyc +0 -0
  896. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/freestyle.cpython-311.pyc +0 -0
  897. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/geometry_nodes.cpython-311.pyc +0 -0
  898. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/grease_pencil.cpython-311.pyc +0 -0
  899. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/image.cpython-311.pyc +0 -0
  900. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/image_as_planes.cpython-311.pyc +0 -0
  901. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/mesh.cpython-311.pyc +0 -0
  902. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/node.cpython-311.pyc +0 -0
  903. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/object.cpython-311.pyc +0 -0
  904. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/object_align.cpython-311.pyc +0 -0
  905. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/object_quick_effects.cpython-311.pyc +0 -0
  906. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/object_randomize_transform.cpython-311.pyc +0 -0
  907. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/presets.cpython-311.pyc +0 -0
  908. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/rigidbody.cpython-311.pyc +0 -0
  909. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/screen_play_rendered_anim.cpython-311.pyc +0 -0
  910. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/sequencer.cpython-311.pyc +0 -0
  911. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/spreadsheet.cpython-311.pyc +0 -0
  912. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/userpref.cpython-311.pyc +0 -0
  913. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/uvcalc_follow_active.cpython-311.pyc +0 -0
  914. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/uvcalc_lightmap.cpython-311.pyc +0 -0
  915. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/uvcalc_transform.cpython-311.pyc +0 -0
  916. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/vertexpaint_dirt.cpython-311.pyc +0 -0
  917. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/view3d.cpython-311.pyc +0 -0
  918. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/wm.cpython-311.pyc +0 -0
  919. package/staging_area/Blender/5.0/scripts/startup/bl_operators/__pycache__/world.cpython-311.pyc +0 -0
  920. package/staging_area/Blender/5.0/scripts/startup/bl_operators/add_mesh_torus.py +0 -262
  921. package/staging_area/Blender/5.0/scripts/startup/bl_operators/anim.py +0 -924
  922. package/staging_area/Blender/5.0/scripts/startup/bl_operators/assets.py +0 -157
  923. package/staging_area/Blender/5.0/scripts/startup/bl_operators/bmesh/find_adjacent.py +0 -341
  924. package/staging_area/Blender/5.0/scripts/startup/bl_operators/bone_selection_sets.py +0 -439
  925. package/staging_area/Blender/5.0/scripts/startup/bl_operators/clip.py +0 -1044
  926. package/staging_area/Blender/5.0/scripts/startup/bl_operators/connect_to_output.py +0 -360
  927. package/staging_area/Blender/5.0/scripts/startup/bl_operators/console.py +0 -156
  928. package/staging_area/Blender/5.0/scripts/startup/bl_operators/constraint.py +0 -121
  929. package/staging_area/Blender/5.0/scripts/startup/bl_operators/copy_global_transform.py +0 -823
  930. package/staging_area/Blender/5.0/scripts/startup/bl_operators/file.py +0 -308
  931. package/staging_area/Blender/5.0/scripts/startup/bl_operators/freestyle.py +0 -226
  932. package/staging_area/Blender/5.0/scripts/startup/bl_operators/geometry_nodes.py +0 -394
  933. package/staging_area/Blender/5.0/scripts/startup/bl_operators/grease_pencil.py +0 -63
  934. package/staging_area/Blender/5.0/scripts/startup/bl_operators/image.py +0 -322
  935. package/staging_area/Blender/5.0/scripts/startup/bl_operators/image_as_planes.py +0 -1216
  936. package/staging_area/Blender/5.0/scripts/startup/bl_operators/mesh.py +0 -61
  937. package/staging_area/Blender/5.0/scripts/startup/bl_operators/node.py +0 -1340
  938. package/staging_area/Blender/5.0/scripts/startup/bl_operators/node_editor/__pycache__/node_functions.cpython-311.pyc +0 -0
  939. package/staging_area/Blender/5.0/scripts/startup/bl_operators/node_editor/node_functions.py +0 -97
  940. package/staging_area/Blender/5.0/scripts/startup/bl_operators/object.py +0 -1014
  941. package/staging_area/Blender/5.0/scripts/startup/bl_operators/object_align.py +0 -407
  942. package/staging_area/Blender/5.0/scripts/startup/bl_operators/object_quick_effects.py +0 -680
  943. package/staging_area/Blender/5.0/scripts/startup/bl_operators/object_randomize_transform.py +0 -181
  944. package/staging_area/Blender/5.0/scripts/startup/bl_operators/presets.py +0 -1057
  945. package/staging_area/Blender/5.0/scripts/startup/bl_operators/rigidbody.py +0 -323
  946. package/staging_area/Blender/5.0/scripts/startup/bl_operators/screen_play_rendered_anim.py +0 -219
  947. package/staging_area/Blender/5.0/scripts/startup/bl_operators/sequencer.py +0 -438
  948. package/staging_area/Blender/5.0/scripts/startup/bl_operators/spreadsheet.py +0 -46
  949. package/staging_area/Blender/5.0/scripts/startup/bl_operators/userpref.py +0 -1324
  950. package/staging_area/Blender/5.0/scripts/startup/bl_operators/uvcalc_follow_active.py +0 -313
  951. package/staging_area/Blender/5.0/scripts/startup/bl_operators/uvcalc_lightmap.py +0 -688
  952. package/staging_area/Blender/5.0/scripts/startup/bl_operators/uvcalc_transform.py +0 -551
  953. package/staging_area/Blender/5.0/scripts/startup/bl_operators/vertexpaint_dirt.py +0 -198
  954. package/staging_area/Blender/5.0/scripts/startup/bl_operators/view3d.py +0 -316
  955. package/staging_area/Blender/5.0/scripts/startup/bl_operators/wm.py +0 -3722
  956. package/staging_area/Blender/5.0/scripts/startup/bl_operators/world.py +0 -168
  957. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__init__.py +0 -299
  958. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/__init__.cpython-311.pyc +0 -0
  959. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/anim.cpython-311.pyc +0 -0
  960. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/asset_shelf.cpython-311.pyc +0 -0
  961. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/generic_ui_list.cpython-311.pyc +0 -0
  962. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/node_add_menu.cpython-311.pyc +0 -0
  963. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/node_add_menu_compositor.cpython-311.pyc +0 -0
  964. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/node_add_menu_geometry.cpython-311.pyc +0 -0
  965. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/node_add_menu_shader.cpython-311.pyc +0 -0
  966. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/node_add_menu_texture.cpython-311.pyc +0 -0
  967. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_animviz.cpython-311.pyc +0 -0
  968. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_collection.cpython-311.pyc +0 -0
  969. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_constraint.cpython-311.pyc +0 -0
  970. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_armature.cpython-311.pyc +0 -0
  971. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_bone.cpython-311.pyc +0 -0
  972. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_camera.cpython-311.pyc +0 -0
  973. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_curve.cpython-311.pyc +0 -0
  974. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_curves.cpython-311.pyc +0 -0
  975. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_empty.cpython-311.pyc +0 -0
  976. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_grease_pencil.cpython-311.pyc +0 -0
  977. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_lattice.cpython-311.pyc +0 -0
  978. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_light.cpython-311.pyc +0 -0
  979. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_lightprobe.cpython-311.pyc +0 -0
  980. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_mesh.cpython-311.pyc +0 -0
  981. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_metaball.cpython-311.pyc +0 -0
  982. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_modifier.cpython-311.pyc +0 -0
  983. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_pointcloud.cpython-311.pyc +0 -0
  984. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_shaderfx.cpython-311.pyc +0 -0
  985. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_speaker.cpython-311.pyc +0 -0
  986. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_data_volume.cpython-311.pyc +0 -0
  987. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_freestyle.cpython-311.pyc +0 -0
  988. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_grease_pencil_common.cpython-311.pyc +0 -0
  989. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_mask_common.cpython-311.pyc +0 -0
  990. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_material.cpython-311.pyc +0 -0
  991. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_material_gpencil.cpython-311.pyc +0 -0
  992. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_object.cpython-311.pyc +0 -0
  993. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_output.cpython-311.pyc +0 -0
  994. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_paint_common.cpython-311.pyc +0 -0
  995. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_particle.cpython-311.pyc +0 -0
  996. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_cloth.cpython-311.pyc +0 -0
  997. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_common.cpython-311.pyc +0 -0
  998. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_dynamicpaint.cpython-311.pyc +0 -0
  999. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_field.cpython-311.pyc +0 -0
  1000. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_fluid.cpython-311.pyc +0 -0
  1001. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_geometry_nodes.cpython-311.pyc +0 -0
  1002. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_rigidbody.cpython-311.pyc +0 -0
  1003. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_rigidbody_constraint.cpython-311.pyc +0 -0
  1004. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_physics_softbody.cpython-311.pyc +0 -0
  1005. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_render.cpython-311.pyc +0 -0
  1006. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_scene.cpython-311.pyc +0 -0
  1007. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_strip.cpython-311.pyc +0 -0
  1008. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_strip_modifier.cpython-311.pyc +0 -0
  1009. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_texture.cpython-311.pyc +0 -0
  1010. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_view_layer.cpython-311.pyc +0 -0
  1011. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_workspace.cpython-311.pyc +0 -0
  1012. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/properties_world.cpython-311.pyc +0 -0
  1013. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_clip.cpython-311.pyc +0 -0
  1014. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_console.cpython-311.pyc +0 -0
  1015. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_dopesheet.cpython-311.pyc +0 -0
  1016. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_filebrowser.cpython-311.pyc +0 -0
  1017. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_graph.cpython-311.pyc +0 -0
  1018. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_image.cpython-311.pyc +0 -0
  1019. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_info.cpython-311.pyc +0 -0
  1020. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_nla.cpython-311.pyc +0 -0
  1021. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_node.cpython-311.pyc +0 -0
  1022. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_outliner.cpython-311.pyc +0 -0
  1023. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_properties.cpython-311.pyc +0 -0
  1024. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_sequencer.cpython-311.pyc +0 -0
  1025. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_spreadsheet.cpython-311.pyc +0 -0
  1026. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_statusbar.cpython-311.pyc +0 -0
  1027. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_text.cpython-311.pyc +0 -0
  1028. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_time.cpython-311.pyc +0 -0
  1029. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_toolsystem_common.cpython-311.pyc +0 -0
  1030. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_toolsystem_toolbar.cpython-311.pyc +0 -0
  1031. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_topbar.cpython-311.pyc +0 -0
  1032. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_userpref.cpython-311.pyc +0 -0
  1033. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_view3d.cpython-311.pyc +0 -0
  1034. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_view3d_sidebar.cpython-311.pyc +0 -0
  1035. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/space_view3d_toolbar.cpython-311.pyc +0 -0
  1036. package/staging_area/Blender/5.0/scripts/startup/bl_ui/__pycache__/utils.cpython-311.pyc +0 -0
  1037. package/staging_area/Blender/5.0/scripts/startup/bl_ui/anim.py +0 -62
  1038. package/staging_area/Blender/5.0/scripts/startup/bl_ui/asset_shelf.py +0 -41
  1039. package/staging_area/Blender/5.0/scripts/startup/bl_ui/generic_ui_list.py +0 -262
  1040. package/staging_area/Blender/5.0/scripts/startup/bl_ui/node_add_menu.py +0 -505
  1041. package/staging_area/Blender/5.0/scripts/startup/bl_ui/node_add_menu_compositor.py +0 -437
  1042. package/staging_area/Blender/5.0/scripts/startup/bl_ui/node_add_menu_geometry.py +0 -1158
  1043. package/staging_area/Blender/5.0/scripts/startup/bl_ui/node_add_menu_shader.py +0 -511
  1044. package/staging_area/Blender/5.0/scripts/startup/bl_ui/node_add_menu_texture.py +0 -167
  1045. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_animviz.py +0 -123
  1046. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_collection.py +0 -146
  1047. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_constraint.py +0 -1793
  1048. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_armature.py +0 -436
  1049. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_bone.py +0 -625
  1050. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_camera.py +0 -603
  1051. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_curve.py +0 -461
  1052. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_curves.py +0 -219
  1053. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_empty.py +0 -84
  1054. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_grease_pencil.py +0 -536
  1055. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_lattice.py +0 -105
  1056. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_light.py +0 -315
  1057. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_lightprobe.py +0 -413
  1058. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_mesh.py +0 -744
  1059. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_metaball.py +0 -137
  1060. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_modifier.py +0 -323
  1061. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_pointcloud.py +0 -175
  1062. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_shaderfx.py +0 -31
  1063. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_speaker.py +0 -157
  1064. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_data_volume.py +0 -239
  1065. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_freestyle.py +0 -1343
  1066. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_grease_pencil_common.py +0 -607
  1067. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_mask_common.py +0 -461
  1068. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_material.py +0 -460
  1069. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_material_gpencil.py +0 -272
  1070. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_object.py +0 -656
  1071. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_output.py +0 -736
  1072. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_paint_common.py +0 -1904
  1073. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_particle.py +0 -2308
  1074. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_cloth.py +0 -524
  1075. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_common.py +0 -360
  1076. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +0 -974
  1077. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_field.py +0 -487
  1078. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_fluid.py +0 -1629
  1079. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_geometry_nodes.py +0 -64
  1080. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_rigidbody.py +0 -345
  1081. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py +0 -554
  1082. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_physics_softbody.py +0 -471
  1083. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_render.py +0 -1180
  1084. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_scene.py +0 -495
  1085. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_strip.py +0 -1056
  1086. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_strip_modifier.py +0 -49
  1087. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_texture.py +0 -997
  1088. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_view_layer.py +0 -348
  1089. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_workspace.py +0 -195
  1090. package/staging_area/Blender/5.0/scripts/startup/bl_ui/properties_world.py +0 -282
  1091. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_clip.py +0 -2112
  1092. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_console.py +0 -157
  1093. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_dopesheet.py +0 -1123
  1094. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_filebrowser.py +0 -950
  1095. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_graph.py +0 -615
  1096. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_image.py +0 -1896
  1097. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_info.py +0 -117
  1098. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_nla.py +0 -429
  1099. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_node.py +0 -1247
  1100. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_outliner.py +0 -559
  1101. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_properties.py +0 -205
  1102. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_sequencer.py +0 -2097
  1103. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_spreadsheet.py +0 -83
  1104. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_statusbar.py +0 -41
  1105. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_text.py +0 -479
  1106. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_time.py +0 -364
  1107. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_toolsystem_common.py +0 -1256
  1108. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_toolsystem_toolbar.py +0 -4123
  1109. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_topbar.py +0 -891
  1110. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_userpref.py +0 -3108
  1111. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_view3d.py +0 -9421
  1112. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_view3d_sidebar.py +0 -183
  1113. package/staging_area/Blender/5.0/scripts/startup/bl_ui/space_view3d_toolbar.py +0 -2438
  1114. package/staging_area/Blender/5.0/scripts/startup/bl_ui/utils.py +0 -40
  1115. package/staging_area/Blender/5.0/scripts/startup/keyingsets_builtins.py +0 -686
  1116. package/staging_area/Blender/5.0/scripts/startup/nodeitems_builtins.py +0 -54
  1117. package/staging_area/Blender/5.0/scripts/templates_osl/advanced_camera.osl +0 -76
  1118. package/staging_area/Blender/5.0/scripts/templates_osl/basic_camera.osl +0 -14
  1119. package/staging_area/Blender/5.0/scripts/templates_osl/basic_shader.osl +0 -10
  1120. package/staging_area/Blender/5.0/scripts/templates_osl/cubemap_camera.osl +0 -42
  1121. package/staging_area/Blender/5.0/scripts/templates_osl/empty_shader.osl +0 -6
  1122. package/staging_area/Blender/5.0/scripts/templates_osl/gabor_noise.osl +0 -17
  1123. package/staging_area/Blender/5.0/scripts/templates_osl/lyapunov_texture.osl +0 -141
  1124. package/staging_area/Blender/5.0/scripts/templates_osl/noise.osl +0 -27
  1125. package/staging_area/Blender/5.0/scripts/templates_osl/ramp_closure.osl +0 -20
  1126. package/staging_area/Blender/5.0/scripts/templates_py/addon_add_object.py +0 -84
  1127. package/staging_area/Blender/5.0/scripts/templates_py/background_job.py +0 -118
  1128. package/staging_area/Blender/5.0/scripts/templates_py/batch_export.py +0 -42
  1129. package/staging_area/Blender/5.0/scripts/templates_py/bmesh_simple.py +0 -22
  1130. package/staging_area/Blender/5.0/scripts/templates_py/bmesh_simple_editmode.py +0 -23
  1131. package/staging_area/Blender/5.0/scripts/templates_py/builtin_keyingset.py +0 -37
  1132. package/staging_area/Blender/5.0/scripts/templates_py/custom_nodes.py +0 -172
  1133. package/staging_area/Blender/5.0/scripts/templates_py/driver_functions.py +0 -35
  1134. package/staging_area/Blender/5.0/scripts/templates_py/external_script_stub.py +0 -13
  1135. package/staging_area/Blender/5.0/scripts/templates_py/gizmo_custom_geometry.py +0 -157
  1136. package/staging_area/Blender/5.0/scripts/templates_py/gizmo_operator.py +0 -235
  1137. package/staging_area/Blender/5.0/scripts/templates_py/gizmo_operator_target.py +0 -50
  1138. package/staging_area/Blender/5.0/scripts/templates_py/gizmo_simple_2d.py +0 -59
  1139. package/staging_area/Blender/5.0/scripts/templates_py/gizmo_simple_3d.py +0 -47
  1140. package/staging_area/Blender/5.0/scripts/templates_py/image_processing.py +0 -35
  1141. package/staging_area/Blender/5.0/scripts/templates_py/operator_file_export.py +0 -76
  1142. package/staging_area/Blender/5.0/scripts/templates_py/operator_file_import.py +0 -79
  1143. package/staging_area/Blender/5.0/scripts/templates_py/operator_mesh_add.py +0 -116
  1144. package/staging_area/Blender/5.0/scripts/templates_py/operator_mesh_uv.py +0 -56
  1145. package/staging_area/Blender/5.0/scripts/templates_py/operator_modal.py +0 -58
  1146. package/staging_area/Blender/5.0/scripts/templates_py/operator_modal_draw.py +0 -83
  1147. package/staging_area/Blender/5.0/scripts/templates_py/operator_modal_timer.py +0 -54
  1148. package/staging_area/Blender/5.0/scripts/templates_py/operator_modal_view3d.py +0 -77
  1149. package/staging_area/Blender/5.0/scripts/templates_py/operator_modal_view3d_raycast.py +0 -115
  1150. package/staging_area/Blender/5.0/scripts/templates_py/operator_node.py +0 -66
  1151. package/staging_area/Blender/5.0/scripts/templates_py/operator_simple.py +0 -42
  1152. package/staging_area/Blender/5.0/scripts/templates_py/ui_asset_shelf.py +0 -29
  1153. package/staging_area/Blender/5.0/scripts/templates_py/ui_list.py +0 -44
  1154. package/staging_area/Blender/5.0/scripts/templates_py/ui_list_generic.py +0 -47
  1155. package/staging_area/Blender/5.0/scripts/templates_py/ui_list_simple.py +0 -70
  1156. package/staging_area/Blender/5.0/scripts/templates_py/ui_menu.py +0 -50
  1157. package/staging_area/Blender/5.0/scripts/templates_py/ui_menu_simple.py +0 -27
  1158. package/staging_area/Blender/5.0/scripts/templates_py/ui_panel.py +0 -73
  1159. package/staging_area/Blender/5.0/scripts/templates_py/ui_panel_simple.py +0 -38
  1160. package/staging_area/Blender/5.0/scripts/templates_py/ui_pie_menu.py +0 -31
  1161. package/staging_area/Blender/5.0/scripts/templates_py/ui_previews_custom_icon.py +0 -76
  1162. package/staging_area/Blender/5.0/scripts/templates_py/ui_previews_dynamic_enum.py +0 -141
  1163. package/staging_area/Blender/5.0/scripts/templates_py/ui_tool_simple.py +0 -91
  1164. package/staging_area/Blender/5.0/scripts/templates_toml/blender_manifest.toml +0 -75
  1165. package/staging_area/Blender/blender-launcher.exe +0 -0
  1166. package/staging_area/Blender/blender.crt/api-ms-win-core-console-l1-1-0.dll +0 -0
  1167. package/staging_area/Blender/blender.crt/api-ms-win-core-console-l1-2-0.dll +0 -0
  1168. package/staging_area/Blender/blender.crt/api-ms-win-core-datetime-l1-1-0.dll +0 -0
  1169. package/staging_area/Blender/blender.crt/api-ms-win-core-debug-l1-1-0.dll +0 -0
  1170. package/staging_area/Blender/blender.crt/api-ms-win-core-errorhandling-l1-1-0.dll +0 -0
  1171. package/staging_area/Blender/blender.crt/api-ms-win-core-fibers-l1-1-0.dll +0 -0
  1172. package/staging_area/Blender/blender.crt/api-ms-win-core-file-l1-1-0.dll +0 -0
  1173. package/staging_area/Blender/blender.crt/api-ms-win-core-file-l1-2-0.dll +0 -0
  1174. package/staging_area/Blender/blender.crt/api-ms-win-core-file-l2-1-0.dll +0 -0
  1175. package/staging_area/Blender/blender.crt/api-ms-win-core-handle-l1-1-0.dll +0 -0
  1176. package/staging_area/Blender/blender.crt/api-ms-win-core-heap-l1-1-0.dll +0 -0
  1177. package/staging_area/Blender/blender.crt/api-ms-win-core-interlocked-l1-1-0.dll +0 -0
  1178. package/staging_area/Blender/blender.crt/api-ms-win-core-libraryloader-l1-1-0.dll +0 -0
  1179. package/staging_area/Blender/blender.crt/api-ms-win-core-localization-l1-2-0.dll +0 -0
  1180. package/staging_area/Blender/blender.crt/api-ms-win-core-memory-l1-1-0.dll +0 -0
  1181. package/staging_area/Blender/blender.crt/api-ms-win-core-namedpipe-l1-1-0.dll +0 -0
  1182. package/staging_area/Blender/blender.crt/api-ms-win-core-processenvironment-l1-1-0.dll +0 -0
  1183. package/staging_area/Blender/blender.crt/api-ms-win-core-processthreads-l1-1-0.dll +0 -0
  1184. package/staging_area/Blender/blender.crt/api-ms-win-core-processthreads-l1-1-1.dll +0 -0
  1185. package/staging_area/Blender/blender.crt/api-ms-win-core-profile-l1-1-0.dll +0 -0
  1186. package/staging_area/Blender/blender.crt/api-ms-win-core-rtlsupport-l1-1-0.dll +0 -0
  1187. package/staging_area/Blender/blender.crt/api-ms-win-core-string-l1-1-0.dll +0 -0
  1188. package/staging_area/Blender/blender.crt/api-ms-win-core-synch-l1-1-0.dll +0 -0
  1189. package/staging_area/Blender/blender.crt/api-ms-win-core-synch-l1-2-0.dll +0 -0
  1190. package/staging_area/Blender/blender.crt/api-ms-win-core-sysinfo-l1-1-0.dll +0 -0
  1191. package/staging_area/Blender/blender.crt/api-ms-win-core-timezone-l1-1-0.dll +0 -0
  1192. package/staging_area/Blender/blender.crt/api-ms-win-core-util-l1-1-0.dll +0 -0
  1193. package/staging_area/Blender/blender.crt/api-ms-win-crt-conio-l1-1-0.dll +0 -0
  1194. package/staging_area/Blender/blender.crt/api-ms-win-crt-convert-l1-1-0.dll +0 -0
  1195. package/staging_area/Blender/blender.crt/api-ms-win-crt-environment-l1-1-0.dll +0 -0
  1196. package/staging_area/Blender/blender.crt/api-ms-win-crt-filesystem-l1-1-0.dll +0 -0
  1197. package/staging_area/Blender/blender.crt/api-ms-win-crt-heap-l1-1-0.dll +0 -0
  1198. package/staging_area/Blender/blender.crt/api-ms-win-crt-locale-l1-1-0.dll +0 -0
  1199. package/staging_area/Blender/blender.crt/api-ms-win-crt-math-l1-1-0.dll +0 -0
  1200. package/staging_area/Blender/blender.crt/api-ms-win-crt-multibyte-l1-1-0.dll +0 -0
  1201. package/staging_area/Blender/blender.crt/api-ms-win-crt-private-l1-1-0.dll +0 -0
  1202. package/staging_area/Blender/blender.crt/api-ms-win-crt-process-l1-1-0.dll +0 -0
  1203. package/staging_area/Blender/blender.crt/api-ms-win-crt-runtime-l1-1-0.dll +0 -0
  1204. package/staging_area/Blender/blender.crt/api-ms-win-crt-stdio-l1-1-0.dll +0 -0
  1205. package/staging_area/Blender/blender.crt/api-ms-win-crt-string-l1-1-0.dll +0 -0
  1206. package/staging_area/Blender/blender.crt/api-ms-win-crt-time-l1-1-0.dll +0 -0
  1207. package/staging_area/Blender/blender.crt/api-ms-win-crt-utility-l1-1-0.dll +0 -0
  1208. package/staging_area/Blender/blender.crt/blender.crt.manifest +0 -54
  1209. package/staging_area/Blender/blender.crt/concrt140.dll +0 -0
  1210. package/staging_area/Blender/blender.crt/msvcp140.dll +0 -0
  1211. package/staging_area/Blender/blender.crt/msvcp140_1.dll +0 -0
  1212. package/staging_area/Blender/blender.crt/msvcp140_2.dll +0 -0
  1213. package/staging_area/Blender/blender.crt/msvcp140_atomic_wait.dll +0 -0
  1214. package/staging_area/Blender/blender.crt/msvcp140_codecvt_ids.dll +0 -0
  1215. package/staging_area/Blender/blender.crt/vcruntime140.dll +0 -0
  1216. package/staging_area/Blender/blender.crt/vcruntime140_1.dll +0 -0
@@ -1,4045 +0,0 @@
1
- # SPDX-FileCopyrightText: 2013-2023 Blender Foundation
2
- #
3
- # SPDX-License-Identifier: GPL-2.0-or-later
4
-
5
- # FBX 7.1.0 -> 7.4.0 loader for Blender
6
-
7
- # Not totally pep8 compliant.
8
- # pep8 import_fbx.py --ignore=E501,E123,E702,E125
9
-
10
- if "bpy" in locals():
11
- import importlib
12
- if "parse_fbx" in locals():
13
- importlib.reload(parse_fbx)
14
- if "fbx_utils" in locals():
15
- importlib.reload(fbx_utils)
16
-
17
- import bpy
18
- from bpy.app.translations import pgettext_rpt as rpt_
19
- from mathutils import Matrix, Euler, Vector, Quaternion
20
- from bpy_extras import anim_utils
21
-
22
- # Also imported in .fbx_utils, so importing here is unlikely to further affect Blender startup time.
23
- import numpy as np
24
-
25
- # -----
26
- # Utils
27
- from . import parse_fbx, fbx_utils
28
-
29
- from .parse_fbx import (
30
- data_types,
31
- FBXElem,
32
- )
33
- from .fbx_utils import (
34
- PerfMon,
35
- units_blender_to_fbx_factor,
36
- units_convertor_iter,
37
- array_to_matrix4,
38
- similar_values,
39
- similar_values_iter,
40
- FBXImportSettings,
41
- vcos_transformed,
42
- nors_transformed,
43
- parray_as_ndarray,
44
- astype_view_signedness,
45
- MESH_ATTRIBUTE_MATERIAL_INDEX,
46
- MESH_ATTRIBUTE_POSITION,
47
- MESH_ATTRIBUTE_EDGE_VERTS,
48
- MESH_ATTRIBUTE_CORNER_VERT,
49
- MESH_ATTRIBUTE_SHARP_FACE,
50
- MESH_ATTRIBUTE_SHARP_EDGE,
51
- expand_shape_key_range,
52
- FBX_KTIME_V7,
53
- FBX_KTIME_V8,
54
- FBX_TIMECODE_DEFINITION_TO_KTIME_PER_SECOND,
55
- )
56
-
57
- LINEAR_INTERPOLATION_VALUE = bpy.types.Keyframe.bl_rna.properties['interpolation'].enum_items['LINEAR'].value
58
-
59
- # global singleton, assign on execution
60
- fbx_elem_nil = None
61
-
62
- # Units converters...
63
- convert_deg_to_rad_iter = units_convertor_iter("degree", "radian")
64
-
65
- MAT_CONVERT_BONE = fbx_utils.MAT_CONVERT_BONE.inverted()
66
- MAT_CONVERT_LIGHT = fbx_utils.MAT_CONVERT_LIGHT.inverted()
67
- MAT_CONVERT_CAMERA = fbx_utils.MAT_CONVERT_CAMERA.inverted()
68
-
69
-
70
- def validate_blend_names(name):
71
- assert(type(name) == bytes)
72
- # Blender typically does not accept names over 63 bytes...
73
- if len(name) > 63:
74
- import hashlib
75
- h = hashlib.sha1(name).hexdigest()
76
- n = 55
77
- name_utf8 = name[:n].decode('utf-8', 'replace') + "_" + h[:7]
78
- while len(name_utf8.encode()) > 63:
79
- n -= 1
80
- name_utf8 = name[:n].decode('utf-8', 'replace') + "_" + h[:7]
81
- return name_utf8
82
- else:
83
- # We use 'replace' even though FBX 'specs' say it should always be utf8, see T53841.
84
- return name.decode('utf-8', 'replace')
85
-
86
-
87
- def elem_find_first(elem, id_search, default=None):
88
- for fbx_item in elem.elems:
89
- if fbx_item.id == id_search:
90
- return fbx_item
91
- return default
92
-
93
-
94
- def elem_find_iter(elem, id_search):
95
- for fbx_item in elem.elems:
96
- if fbx_item.id == id_search:
97
- yield fbx_item
98
-
99
-
100
- def elem_find_first_string(elem, id_search):
101
- fbx_item = elem_find_first(elem, id_search)
102
- if fbx_item is not None and fbx_item.props: # Do not error on complete empty properties (see T45291).
103
- assert(len(fbx_item.props) == 1)
104
- assert(fbx_item.props_type[0] == data_types.STRING)
105
- return fbx_item.props[0].decode('utf-8', 'replace')
106
- return None
107
-
108
-
109
- def elem_find_first_string_as_bytes(elem, id_search):
110
- fbx_item = elem_find_first(elem, id_search)
111
- if fbx_item is not None and fbx_item.props: # Do not error on complete empty properties (see T45291).
112
- assert(len(fbx_item.props) == 1)
113
- assert(fbx_item.props_type[0] == data_types.STRING)
114
- return fbx_item.props[0] # Keep it as bytes as requested...
115
- return None
116
-
117
-
118
- def elem_find_first_bytes(elem, id_search, decode=True):
119
- fbx_item = elem_find_first(elem, id_search)
120
- if fbx_item is not None and fbx_item.props: # Do not error on complete empty properties (see T45291).
121
- assert(len(fbx_item.props) == 1)
122
- assert(fbx_item.props_type[0] == data_types.BYTES)
123
- return fbx_item.props[0]
124
- return None
125
-
126
-
127
- def elem_repr(elem):
128
- return "%s: props[%d=%r], elems=(%r)" % (
129
- elem.id,
130
- len(elem.props),
131
- ", ".join([repr(p) for p in elem.props]),
132
- # elem.props_type,
133
- b", ".join([e.id for e in elem.elems]),
134
- )
135
-
136
-
137
- def elem_split_name_class(elem):
138
- assert(elem.props_type[-2] == data_types.STRING)
139
- elem_name, elem_class = elem.props[-2].split(b'\x00\x01')
140
- return elem_name, elem_class
141
-
142
-
143
- def elem_name_ensure_class(elem, clss=...):
144
- elem_name, elem_class = elem_split_name_class(elem)
145
- if clss is not ...:
146
- assert(elem_class == clss)
147
- return validate_blend_names(elem_name)
148
-
149
-
150
- def elem_name_ensure_classes(elem, clss=...):
151
- elem_name, elem_class = elem_split_name_class(elem)
152
- if clss is not ...:
153
- assert(elem_class in clss)
154
- return validate_blend_names(elem_name)
155
-
156
-
157
- def elem_split_name_class_nodeattr(elem):
158
- assert(elem.props_type[-2] == data_types.STRING)
159
- elem_name, elem_class = elem.props[-2].split(b'\x00\x01')
160
- assert(elem_class == b'NodeAttribute')
161
- assert(elem.props_type[-1] == data_types.STRING)
162
- elem_class = elem.props[-1]
163
- return elem_name, elem_class
164
-
165
-
166
- def elem_uuid(elem):
167
- assert(elem.props_type[0] == data_types.INT64)
168
- return elem.props[0]
169
-
170
-
171
- def elem_prop_first(elem, default=None):
172
- return elem.props[0] if (elem is not None) and elem.props else default
173
-
174
-
175
- # ----
176
- # Support for
177
- # Properties70: { ... P:
178
- # Custom properties ("user properties" in FBX) are ignored here and get handled separately (see #104773).
179
- def elem_props_find_first(elem, elem_prop_id):
180
- if elem is None:
181
- # When properties are not found... Should never happen, but happens - as usual.
182
- return None
183
- # support for templates (tuple of elems)
184
- if type(elem) is not FBXElem:
185
- assert(type(elem) is tuple)
186
- for e in elem:
187
- result = elem_props_find_first(e, elem_prop_id)
188
- if result is not None:
189
- return result
190
- assert(len(elem) > 0)
191
- return None
192
-
193
- for subelem in elem.elems:
194
- assert(subelem.id == b'P')
195
- # 'U' flag indicates that the property has been defined by the user.
196
- if subelem.props[0] == elem_prop_id and b'U' not in subelem.props[3]:
197
- return subelem
198
- return None
199
-
200
-
201
- def elem_props_get_color_rgb(elem, elem_prop_id, default=None):
202
- elem_prop = elem_props_find_first(elem, elem_prop_id)
203
- if elem_prop is not None:
204
- assert(elem_prop.props[0] == elem_prop_id)
205
- if elem_prop.props[1] == b'Color':
206
- # FBX version 7300
207
- assert(elem_prop.props[1] == b'Color')
208
- assert(elem_prop.props[2] == b'')
209
- else:
210
- assert(elem_prop.props[1] == b'ColorRGB')
211
- assert(elem_prop.props[2] == b'Color')
212
- assert(elem_prop.props_type[4:7] == bytes((data_types.FLOAT64,)) * 3)
213
- return elem_prop.props[4:7]
214
- return default
215
-
216
-
217
- def elem_props_get_vector_3d(elem, elem_prop_id, default=None):
218
- elem_prop = elem_props_find_first(elem, elem_prop_id)
219
- if elem_prop is not None:
220
- assert(elem_prop.props_type[4:7] == bytes((data_types.FLOAT64,)) * 3)
221
- return elem_prop.props[4:7]
222
- return default
223
-
224
-
225
- def elem_props_get_number(elem, elem_prop_id, default=None):
226
- elem_prop = elem_props_find_first(elem, elem_prop_id)
227
- if elem_prop is not None:
228
- assert(elem_prop.props[0] == elem_prop_id)
229
- if elem_prop.props[1] == b'double':
230
- assert(elem_prop.props[1] == b'double')
231
- assert(elem_prop.props[2] == b'Number')
232
- else:
233
- assert(elem_prop.props[1] == b'Number')
234
- assert(elem_prop.props[2] == b'')
235
-
236
- # we could allow other number types
237
- assert(elem_prop.props_type[4] == data_types.FLOAT64)
238
-
239
- return elem_prop.props[4]
240
- return default
241
-
242
-
243
- def elem_props_get_integer(elem, elem_prop_id, default=None):
244
- elem_prop = elem_props_find_first(elem, elem_prop_id)
245
- if elem_prop is not None:
246
- assert(elem_prop.props[0] == elem_prop_id)
247
- if elem_prop.props[1] == b'int':
248
- assert(elem_prop.props[1] == b'int')
249
- assert(elem_prop.props[2] == b'Integer')
250
- elif elem_prop.props[1] == b'ULongLong':
251
- assert(elem_prop.props[1] == b'ULongLong')
252
- assert(elem_prop.props[2] == b'')
253
-
254
- # we could allow other number types
255
- assert(elem_prop.props_type[4] in {data_types.INT32, data_types.INT64})
256
-
257
- return elem_prop.props[4]
258
- return default
259
-
260
-
261
- def elem_props_get_bool(elem, elem_prop_id, default=None):
262
- elem_prop = elem_props_find_first(elem, elem_prop_id)
263
- if elem_prop is not None:
264
- assert(elem_prop.props[0] == elem_prop_id)
265
- # b'Bool' with a capital seems to be used for animated property... go figure...
266
- assert(elem_prop.props[1] in {b'bool', b'Bool'})
267
- assert(elem_prop.props[2] == b'')
268
-
269
- # we could allow other number types
270
- assert(elem_prop.props_type[4] == data_types.INT32)
271
- assert(elem_prop.props[4] in {0, 1})
272
-
273
- return bool(elem_prop.props[4])
274
- return default
275
-
276
-
277
- def elem_props_get_enum(elem, elem_prop_id, default=None):
278
- elem_prop = elem_props_find_first(elem, elem_prop_id)
279
- if elem_prop is not None:
280
- assert(elem_prop.props[0] == elem_prop_id)
281
- assert(elem_prop.props[1] == b'enum')
282
- assert(elem_prop.props[2] == b'')
283
- assert(elem_prop.props[3] == b'')
284
-
285
- # we could allow other number types
286
- assert(elem_prop.props_type[4] == data_types.INT32)
287
-
288
- return elem_prop.props[4]
289
- return default
290
-
291
-
292
- def elem_props_get_visibility(elem, elem_prop_id, default=None):
293
- elem_prop = elem_props_find_first(elem, elem_prop_id)
294
- if elem_prop is not None:
295
- assert(elem_prop.props[0] == elem_prop_id)
296
- assert(elem_prop.props[1] == b'Visibility')
297
- assert(elem_prop.props[2] == b'')
298
-
299
- # we could allow other number types
300
- assert(elem_prop.props_type[4] == data_types.FLOAT64)
301
-
302
- return elem_prop.props[4]
303
- return default
304
-
305
-
306
- # ----------------------------------------------------------------------------
307
- # Blender
308
-
309
- # ------
310
- # Object
311
- from collections import namedtuple
312
-
313
-
314
- FBXTransformData = namedtuple("FBXTransformData", (
315
- "loc", "geom_loc",
316
- "rot", "rot_ofs", "rot_piv", "pre_rot", "pst_rot", "rot_ord", "rot_alt_mat", "geom_rot",
317
- "sca", "sca_ofs", "sca_piv", "geom_sca",
318
- ))
319
-
320
-
321
- def blen_read_custom_properties(fbx_obj, blen_obj, settings):
322
- # There doesn't seem to be a way to put user properties into templates, so this only get the object properties:
323
- fbx_obj_props = elem_find_first(fbx_obj, b'Properties70')
324
- if fbx_obj_props:
325
- for fbx_prop in fbx_obj_props.elems:
326
- assert(fbx_prop.id == b'P')
327
-
328
- if b'U' in fbx_prop.props[3]:
329
- if fbx_prop.props[0] == b'UDP3DSMAX':
330
- # Special case for 3DS Max user properties:
331
- try:
332
- assert(fbx_prop.props[1] == b'KString')
333
- except AssertionError as exc:
334
- print(exc)
335
- assert(fbx_prop.props_type[4] == data_types.STRING)
336
- items = fbx_prop.props[4].decode('utf-8', 'replace')
337
- for item in items.split('\r\n'):
338
- if item:
339
- split_item = item.split('=', 1)
340
- if len(split_item) != 2:
341
- split_item = item.split(':', 1)
342
- if len(split_item) != 2:
343
- print("cannot parse UDP3DSMAX custom property '%s', ignoring..." % item)
344
- else:
345
- prop_name, prop_value = split_item
346
- prop_name = validate_blend_names(prop_name.strip().encode('utf-8'))
347
- blen_obj[prop_name] = prop_value.strip()
348
- else:
349
- prop_name = validate_blend_names(fbx_prop.props[0])
350
- prop_type = fbx_prop.props[1]
351
- if prop_type in {b'Vector', b'Vector3D', b'Color', b'ColorRGB'}:
352
- assert(fbx_prop.props_type[4:7] == bytes((data_types.FLOAT64,)) * 3)
353
- blen_obj[prop_name] = fbx_prop.props[4:7]
354
- elif prop_type in {b'Vector4', b'ColorRGBA'}:
355
- assert(fbx_prop.props_type[4:8] == bytes((data_types.FLOAT64,)) * 4)
356
- blen_obj[prop_name] = fbx_prop.props[4:8]
357
- elif prop_type == b'Vector2D':
358
- assert(fbx_prop.props_type[4:6] == bytes((data_types.FLOAT64,)) * 2)
359
- blen_obj[prop_name] = fbx_prop.props[4:6]
360
- elif prop_type in {b'Integer', b'int'}:
361
- assert(fbx_prop.props_type[4] == data_types.INT32)
362
- blen_obj[prop_name] = fbx_prop.props[4]
363
- elif prop_type == b'KString':
364
- assert(fbx_prop.props_type[4] == data_types.STRING)
365
- blen_obj[prop_name] = fbx_prop.props[4].decode('utf-8', 'replace')
366
- elif prop_type in {b'Number', b'double', b'Double'}:
367
- assert(fbx_prop.props_type[4] == data_types.FLOAT64)
368
- blen_obj[prop_name] = fbx_prop.props[4]
369
- elif prop_type in {b'Float', b'float'}:
370
- assert(fbx_prop.props_type[4] == data_types.FLOAT32)
371
- blen_obj[prop_name] = fbx_prop.props[4]
372
- elif prop_type in {b'Bool', b'bool'}:
373
- assert(fbx_prop.props_type[4] == data_types.INT32)
374
- blen_obj[prop_name] = fbx_prop.props[4] != 0
375
- elif prop_type in {b'Enum', b'enum'}:
376
- assert(fbx_prop.props_type[4:6] == bytes((data_types.INT32, data_types.STRING)))
377
- val = fbx_prop.props[4]
378
- if settings.use_custom_props_enum_as_string and fbx_prop.props[5]:
379
- enum_items = fbx_prop.props[5].decode('utf-8', 'replace').split('~')
380
- if val >= 0 and val < len(enum_items):
381
- blen_obj[prop_name] = enum_items[val]
382
- else:
383
- print("WARNING: User property '%s' has wrong enum value, skipped" % prop_name)
384
- else:
385
- blen_obj[prop_name] = val
386
- else:
387
- print(
388
- "WARNING: User property type '%s' is not supported" %
389
- prop_type.decode(
390
- 'utf-8', 'replace'))
391
-
392
-
393
- def blen_read_object_transform_do(transform_data):
394
- # This is a nightmare. FBX SDK uses Maya way to compute the transformation matrix of a node - utterly simple:
395
- #
396
- # WorldTransform = ParentWorldTransform @ T @ Roff @ Rp @ Rpre @ R @ Rpost-1 @ Rp-1 @ Soff @ Sp @ S @ Sp-1
397
- #
398
- # Where all those terms are 4 x 4 matrices that contain:
399
- # WorldTransform: Transformation matrix of the node in global space.
400
- # ParentWorldTransform: Transformation matrix of the parent node in global space.
401
- # T: Translation
402
- # Roff: Rotation offset
403
- # Rp: Rotation pivot
404
- # Rpre: Pre-rotation
405
- # R: Rotation
406
- # Rpost-1: Inverse of the post-rotation (FBX 2011 documentation incorrectly specifies this without inversion)
407
- # Rp-1: Inverse of the rotation pivot
408
- # Soff: Scaling offset
409
- # Sp: Scaling pivot
410
- # S: Scaling
411
- # Sp-1: Inverse of the scaling pivot
412
- #
413
- # But it was still too simple, and FBX notion of compatibility is... quite specific. So we also have to
414
- # support 3DSMax way:
415
- #
416
- # WorldTransform = ParentWorldTransform @ T @ R @ S @ OT @ OR @ OS
417
- #
418
- # Where all those terms are 4 x 4 matrices that contain:
419
- # WorldTransform: Transformation matrix of the node in global space
420
- # ParentWorldTransform: Transformation matrix of the parent node in global space
421
- # T: Translation
422
- # R: Rotation
423
- # S: Scaling
424
- # OT: Geometric transform translation
425
- # OR: Geometric transform rotation
426
- # OS: Geometric transform scale
427
- #
428
- # Notes:
429
- # Geometric transformations ***are not inherited***: ParentWorldTransform does not contain the OT, OR, OS
430
- # of WorldTransform's parent node.
431
- # The R matrix takes into account the rotation order. Other rotation matrices are always 'XYZ' order.
432
- #
433
- # Taken from https://help.autodesk.com/view/FBX/2020/ENU/
434
- # ?guid=FBX_Developer_Help_nodes_and_scene_graph_fbx_nodes_computing_transformation_matrix_html
435
-
436
- # translation
437
- lcl_translation = Matrix.Translation(transform_data.loc)
438
- geom_loc = Matrix.Translation(transform_data.geom_loc)
439
-
440
- # rotation
441
- def to_rot(rot, rot_ord): return Euler(convert_deg_to_rad_iter(rot), rot_ord).to_matrix().to_4x4()
442
- lcl_rot = to_rot(transform_data.rot, transform_data.rot_ord) @ transform_data.rot_alt_mat
443
- pre_rot = to_rot(transform_data.pre_rot, 'XYZ')
444
- pst_rot = to_rot(transform_data.pst_rot, 'XYZ')
445
- geom_rot = to_rot(transform_data.geom_rot, 'XYZ')
446
-
447
- rot_ofs = Matrix.Translation(transform_data.rot_ofs)
448
- rot_piv = Matrix.Translation(transform_data.rot_piv)
449
- sca_ofs = Matrix.Translation(transform_data.sca_ofs)
450
- sca_piv = Matrix.Translation(transform_data.sca_piv)
451
-
452
- # scale
453
- lcl_scale = Matrix()
454
- lcl_scale[0][0], lcl_scale[1][1], lcl_scale[2][2] = transform_data.sca
455
- geom_scale = Matrix()
456
- geom_scale[0][0], geom_scale[1][1], geom_scale[2][2] = transform_data.geom_sca
457
-
458
- base_mat = (
459
- lcl_translation @
460
- rot_ofs @
461
- rot_piv @
462
- pre_rot @
463
- lcl_rot @
464
- pst_rot.inverted_safe() @
465
- rot_piv.inverted_safe() @
466
- sca_ofs @
467
- sca_piv @
468
- lcl_scale @
469
- sca_piv.inverted_safe()
470
- )
471
- geom_mat = geom_loc @ geom_rot @ geom_scale
472
- # We return mat without 'geometric transforms' too, because it is to be used for children, sigh...
473
- return (base_mat @ geom_mat, base_mat, geom_mat)
474
-
475
-
476
- # XXX This might be weak, now that we can add vgroups from both bones and shapes, name collisions become
477
- # more likely, will have to make this more robust!!!
478
- def add_vgroup_to_objects(vg_indices, vg_weights, vg_name, objects):
479
- assert(len(vg_indices) == len(vg_weights))
480
- if vg_indices:
481
- for obj in objects:
482
- # We replace/override here...
483
- vg = obj.vertex_groups.get(vg_name)
484
- if vg is None:
485
- vg = obj.vertex_groups.new(name=vg_name)
486
- vg_add = vg.add
487
- for i, w in zip(vg_indices, vg_weights):
488
- vg_add((i,), w, 'REPLACE')
489
-
490
-
491
- def blen_read_object_transform_preprocess(fbx_props, fbx_obj, rot_alt_mat, use_prepost_rot):
492
- # This is quite involved, 'fbxRNode.cpp' from openscenegraph used as a reference
493
- const_vector_zero_3d = 0.0, 0.0, 0.0
494
- const_vector_one_3d = 1.0, 1.0, 1.0
495
-
496
- loc = list(elem_props_get_vector_3d(fbx_props, b'Lcl Translation', const_vector_zero_3d))
497
- rot = list(elem_props_get_vector_3d(fbx_props, b'Lcl Rotation', const_vector_zero_3d))
498
- sca = list(elem_props_get_vector_3d(fbx_props, b'Lcl Scaling', const_vector_one_3d))
499
-
500
- geom_loc = list(elem_props_get_vector_3d(fbx_props, b'GeometricTranslation', const_vector_zero_3d))
501
- geom_rot = list(elem_props_get_vector_3d(fbx_props, b'GeometricRotation', const_vector_zero_3d))
502
- geom_sca = list(elem_props_get_vector_3d(fbx_props, b'GeometricScaling', const_vector_one_3d))
503
-
504
- rot_ofs = elem_props_get_vector_3d(fbx_props, b'RotationOffset', const_vector_zero_3d)
505
- rot_piv = elem_props_get_vector_3d(fbx_props, b'RotationPivot', const_vector_zero_3d)
506
- sca_ofs = elem_props_get_vector_3d(fbx_props, b'ScalingOffset', const_vector_zero_3d)
507
- sca_piv = elem_props_get_vector_3d(fbx_props, b'ScalingPivot', const_vector_zero_3d)
508
-
509
- is_rot_act = elem_props_get_bool(fbx_props, b'RotationActive', False)
510
-
511
- if is_rot_act:
512
- if use_prepost_rot:
513
- pre_rot = elem_props_get_vector_3d(fbx_props, b'PreRotation', const_vector_zero_3d)
514
- pst_rot = elem_props_get_vector_3d(fbx_props, b'PostRotation', const_vector_zero_3d)
515
- else:
516
- pre_rot = const_vector_zero_3d
517
- pst_rot = const_vector_zero_3d
518
- rot_ord = {
519
- 0: 'XYZ',
520
- 1: 'XZY',
521
- 2: 'YZX',
522
- 3: 'YXZ',
523
- 4: 'ZXY',
524
- 5: 'ZYX',
525
- 6: 'XYZ', # XXX eSphericXYZ, not really supported...
526
- }.get(elem_props_get_enum(fbx_props, b'RotationOrder', 0))
527
- else:
528
- pre_rot = const_vector_zero_3d
529
- pst_rot = const_vector_zero_3d
530
- rot_ord = 'XYZ'
531
-
532
- return FBXTransformData(loc, geom_loc,
533
- rot, rot_ofs, rot_piv, pre_rot, pst_rot, rot_ord, rot_alt_mat, geom_rot,
534
- sca, sca_ofs, sca_piv, geom_sca)
535
-
536
-
537
- # ---------
538
- # Animation
539
- def _blen_read_object_transform_do_anim(transform_data, lcl_translation_mat, lcl_rot_euler, lcl_scale_mat,
540
- extra_pre_matrix, extra_post_matrix):
541
- """Specialized version of blen_read_object_transform_do for animation that pre-calculates the non-animated matrices
542
- and returns a function that calculates (base_mat @ geom_mat). See the comments in blen_read_object_transform_do for
543
- a full description of what this function is doing.
544
-
545
- The lcl_translation_mat, lcl_rot_euler and lcl_scale_mat arguments should have their values updated each frame and
546
- then calling the returned function will calculate the matrix for the current frame.
547
-
548
- extra_pre_matrix and extra_post_matrix are any extra matrices to multiply first/last."""
549
- # Translation
550
- geom_loc = Matrix.Translation(transform_data.geom_loc)
551
-
552
- # Rotation
553
- def to_rot_xyz(rot):
554
- # All the rotations that can be precalculated have a fixed XYZ order.
555
- return Euler(convert_deg_to_rad_iter(rot), 'XYZ').to_matrix().to_4x4()
556
- pre_rot = to_rot_xyz(transform_data.pre_rot)
557
- pst_rot_inv = to_rot_xyz(transform_data.pst_rot).inverted_safe()
558
- geom_rot = to_rot_xyz(transform_data.geom_rot)
559
-
560
- # Offsets and pivots
561
- rot_ofs = Matrix.Translation(transform_data.rot_ofs)
562
- rot_piv = Matrix.Translation(transform_data.rot_piv)
563
- rot_piv_inv = rot_piv.inverted_safe()
564
- sca_ofs = Matrix.Translation(transform_data.sca_ofs)
565
- sca_piv = Matrix.Translation(transform_data.sca_piv)
566
- sca_piv_inv = sca_piv.inverted_safe()
567
-
568
- # Scale
569
- geom_scale = Matrix()
570
- geom_scale[0][0], geom_scale[1][1], geom_scale[2][2] = transform_data.geom_sca
571
-
572
- # Some matrices can be combined in advance, using the associative property of matrix multiplication, so that less
573
- # matrix multiplication is required each frame.
574
- geom_mat = geom_loc @ geom_rot @ geom_scale
575
- post_lcl_translation = rot_ofs @ rot_piv @ pre_rot
576
- post_lcl_rotation = transform_data.rot_alt_mat @ pst_rot_inv @ rot_piv_inv @ sca_ofs @ sca_piv
577
- post_lcl_scaling = sca_piv_inv @ geom_mat @ extra_post_matrix
578
-
579
- # Get the bound to_matrix method to avoid re-binding it on each call.
580
- lcl_rot_euler_to_matrix_3x3 = lcl_rot_euler.to_matrix
581
- # Get the unbound Matrix.to_4x4 method to avoid having to look it up again on each call.
582
- matrix_to_4x4 = Matrix.to_4x4
583
-
584
- if extra_pre_matrix == Matrix():
585
- # There aren't any other matrices that must be multiplied before lcl_translation_mat that extra_pre_matrix can
586
- # be combined with, so skip extra_pre_matrix when it's the identity matrix.
587
- return lambda: (lcl_translation_mat @
588
- post_lcl_translation @
589
- matrix_to_4x4(lcl_rot_euler_to_matrix_3x3()) @
590
- post_lcl_rotation @
591
- lcl_scale_mat @
592
- post_lcl_scaling)
593
- else:
594
- return lambda: (extra_pre_matrix @
595
- lcl_translation_mat @
596
- post_lcl_translation @
597
- matrix_to_4x4(lcl_rot_euler_to_matrix_3x3()) @
598
- post_lcl_rotation @
599
- lcl_scale_mat @
600
- post_lcl_scaling)
601
-
602
-
603
- def _transformation_curves_gen(item, values_arrays, channel_keys):
604
- """Yields flattened location/rotation/scaling values for imported PoseBone/Object Lcl Translation/Rotation/Scaling
605
- animation curve values.
606
-
607
- The value arrays must have the same lengths, where each index of each array corresponds to a single keyframe.
608
-
609
- Each value array must have a corresponding channel key tuple that identifies the fbx property
610
- (b'Lcl Translation'/b'Lcl Rotation'/b'Lcl Scaling') and the channel (x/y/z as 0/1/2) of that property."""
611
- from operator import setitem
612
- from functools import partial
613
-
614
- if item.is_bone:
615
- bl_obj = item.bl_obj.pose.bones[item.bl_bone]
616
- else:
617
- bl_obj = item.bl_obj
618
-
619
- rot_mode = bl_obj.rotation_mode
620
- transform_data = item.fbx_transform_data
621
- rot_eul_prev = bl_obj.rotation_euler.copy()
622
- rot_quat_prev = bl_obj.rotation_quaternion.copy()
623
-
624
- # Pre-compute combined pre-matrix
625
- # Remove that rest pose matrix from current matrix (also in parent space) by computing the inverted local rest
626
- # matrix of the bone, if relevant.
627
- combined_pre_matrix = item.get_bind_matrix().inverted_safe() if item.is_bone else Matrix()
628
- # item.pre_matrix will contain any correction for a parent's correction matrix or the global matrix
629
- if item.pre_matrix:
630
- combined_pre_matrix @= item.pre_matrix
631
-
632
- # Pre-compute combined post-matrix
633
- # Compensate for changes in the local matrix during processing
634
- combined_post_matrix = item.anim_compensation_matrix.copy() if item.anim_compensation_matrix else Matrix()
635
- # item.post_matrix will contain any correction for lights, camera and bone orientation
636
- if item.post_matrix:
637
- combined_post_matrix @= item.post_matrix
638
-
639
- # Create matrices/euler from the initial transformation values of this item.
640
- # These variables will be updated in-place as we iterate through each frame.
641
- lcl_translation_mat = Matrix.Translation(transform_data.loc)
642
- lcl_rotation_eul = Euler(convert_deg_to_rad_iter(transform_data.rot), transform_data.rot_ord)
643
- lcl_scaling_mat = Matrix()
644
- lcl_scaling_mat[0][0], lcl_scaling_mat[1][1], lcl_scaling_mat[2][2] = transform_data.sca
645
-
646
- # Create setters into lcl_translation_mat, lcl_rotation_eul and lcl_scaling_mat for each values_array and convert
647
- # any rotation values into radians.
648
- lcl_setters = []
649
- values_arrays_converted = []
650
- for values_array, (fbx_prop, channel) in zip(values_arrays, channel_keys):
651
- if fbx_prop == b'Lcl Translation':
652
- # lcl_translation_mat.translation[channel] = value
653
- setter = partial(setitem, lcl_translation_mat.translation, channel)
654
- elif fbx_prop == b'Lcl Rotation':
655
- # FBX rotations are in degrees, but Blender uses radians, so convert all rotation values in advance.
656
- values_array = np.deg2rad(values_array)
657
- # lcl_rotation_eul[channel] = value
658
- setter = partial(setitem, lcl_rotation_eul, channel)
659
- else:
660
- assert(fbx_prop == b'Lcl Scaling')
661
- # lcl_scaling_mat[channel][channel] = value
662
- setter = partial(setitem, lcl_scaling_mat[channel], channel)
663
- lcl_setters.append(setter)
664
- values_arrays_converted.append(values_array)
665
-
666
- # Create an iterator that gets one value from each array. Each iterated tuple will be all the imported
667
- # Lcl Translation/Lcl Rotation/Lcl Scaling values for a single frame, in that order.
668
- # Note that an FBX animation does not have to animate all the channels, so only the animated channels of each
669
- # property will be present.
670
- # .data, the memoryview of an np.ndarray, is faster to iterate than the ndarray itself.
671
- frame_values_it = zip(*(arr.data for arr in values_arrays_converted))
672
-
673
- # Getting the unbound methods in advance avoids having to look them up again on each call within the loop.
674
- mat_decompose = Matrix.decompose
675
- quat_to_axis_angle = Quaternion.to_axis_angle
676
- quat_to_euler = Quaternion.to_euler
677
- quat_dot = Quaternion.dot
678
-
679
- calc_mat = _blen_read_object_transform_do_anim(transform_data,
680
- lcl_translation_mat, lcl_rotation_eul, lcl_scaling_mat,
681
- combined_pre_matrix, combined_post_matrix)
682
-
683
- # Iterate through the values for each frame.
684
- for frame_values in frame_values_it:
685
- # Set each value into its corresponding lcl matrix/euler.
686
- for lcl_setter, value in zip(lcl_setters, frame_values):
687
- lcl_setter(value)
688
-
689
- # Calculate the updated matrix for this frame.
690
- mat = calc_mat()
691
-
692
- # Now we have a virtual matrix of transform from AnimCurves, we can yield keyframe values!
693
- loc, rot, sca = mat_decompose(mat)
694
- if rot_mode == 'QUATERNION':
695
- if quat_dot(rot_quat_prev, rot) < 0.0:
696
- rot = -rot
697
- rot_quat_prev = rot
698
- elif rot_mode == 'AXIS_ANGLE':
699
- vec, ang = quat_to_axis_angle(rot)
700
- rot = ang, vec.x, vec.y, vec.z
701
- else: # Euler
702
- rot = quat_to_euler(rot, rot_mode, rot_eul_prev)
703
- rot_eul_prev = rot
704
-
705
- # Yield order matches the order that the location/rotation/scale FCurves are created in.
706
- yield from loc
707
- yield from rot
708
- yield from sca
709
-
710
-
711
- def _combine_curve_keyframe_times(times_and_values_tuples, initial_values):
712
- """Combine multiple parsed animation curves, that affect different channels, such that every animation curve
713
- contains the keyframes from every other curve, interpolating the values for the newly inserted keyframes in each
714
- curve.
715
-
716
- Currently, linear interpolation is assumed, but FBX does store how keyframes should be interpolated, so correctly
717
- interpolating the keyframe values is a TODO."""
718
- if len(times_and_values_tuples) == 1:
719
- # Nothing to do when there is only a single curve.
720
- times, values = times_and_values_tuples[0]
721
- return times, [values]
722
-
723
- all_times = [t[0] for t in times_and_values_tuples]
724
-
725
- # Get the combined sorted unique times of all the curves.
726
- sorted_all_times = np.unique(np.concatenate(all_times))
727
-
728
- values_arrays = []
729
- for (times, values), initial_value in zip(times_and_values_tuples, initial_values):
730
- if sorted_all_times.size == times.size:
731
- # `sorted_all_times` will always contain all values in `times` and both `times` and `sorted_all_times` must
732
- # be strictly increasing, so if both arrays have the same size, they must be identical.
733
- extended_values = values
734
- else:
735
- # For now, linear interpolation is assumed. NumPy conveniently has a fast C-compiled function for this.
736
- # Efficiently implementing other FBX supported interpolation will most likely be much more complicated.
737
- extended_values = np.interp(sorted_all_times, times, values, left=initial_value)
738
- values_arrays.append(extended_values)
739
- return sorted_all_times, values_arrays
740
-
741
-
742
- def blen_read_invalid_animation_curve(key_times, key_values):
743
- """FBX will parse animation curves even when their keyframe times are invalid (not strictly increasing). It's
744
- unclear exactly how FBX handles invalid curves, but this matches in some cases and is how the FBX IO addon has been
745
- handling invalid keyframe times for a long time.
746
-
747
- Notably, this function will also correctly parse valid animation curves, though is much slower than the trivial,
748
- regular way.
749
-
750
- The returned keyframe times are guaranteed to be strictly increasing."""
751
- sorted_unique_times = np.unique(key_times)
752
-
753
- # Unsure if this can be vectorized with numpy, so using iteration for now.
754
- def index_gen():
755
- idx = 0
756
- key_times_data = key_times.data
757
- key_times_len = len(key_times)
758
- # Iterating .data, the memoryview of the array, is faster than iterating the array directly.
759
- for curr_fbxktime in sorted_unique_times.data:
760
- if key_times_data[idx] < curr_fbxktime:
761
- if idx >= 0:
762
- idx += 1
763
- if idx >= key_times_len:
764
- # We have reached our last element for this curve, stay on it from now on...
765
- idx = -1
766
- yield idx
767
-
768
- indices = np.fromiter(index_gen(), dtype=np.int64, count=len(sorted_unique_times))
769
- indexed_times = key_times[indices]
770
- indexed_values = key_values[indices]
771
-
772
- # Linear interpolate the value for each time in sorted_unique_times according to the times and values at each index
773
- # and the previous index.
774
- interpolated_values = np.empty_like(indexed_values)
775
-
776
- # Where the index is 0, there's no previous value to interpolate from, so we set the value without interpolating.
777
- # Because the indices are in increasing order, all zeroes must be at the start, so we can find the index of the last
778
- # zero and use that to index with a slice instead of a boolean array for performance.
779
- # Equivalent to, but as a slice:
780
- # idx_zero_mask = indices == 0
781
- # idx_nonzero_mask = ~idx_zero_mask
782
- first_nonzero_idx = np.searchsorted(indices, 0, side='right')
783
- idx_zero_slice = slice(0, first_nonzero_idx) # [:first_nonzero_idx]
784
- idx_nonzero_slice = slice(first_nonzero_idx, None) # [first_nonzero_idx:]
785
-
786
- interpolated_values[idx_zero_slice] = indexed_values[idx_zero_slice]
787
-
788
- indexed_times_nonzero_idx = indexed_times[idx_nonzero_slice]
789
- indexed_values_nonzero_idx = indexed_values[idx_nonzero_slice]
790
- indices_nonzero = indices[idx_nonzero_slice]
791
-
792
- prev_indices_nonzero = indices_nonzero - 1
793
- prev_indexed_times_nonzero_idx = key_times[prev_indices_nonzero]
794
- prev_indexed_values_nonzero_idx = key_values[prev_indices_nonzero]
795
-
796
- ifac_a = sorted_unique_times[idx_nonzero_slice] - prev_indexed_times_nonzero_idx
797
- ifac_b = indexed_times_nonzero_idx - prev_indexed_times_nonzero_idx
798
- # If key_times contains two (or more) duplicate times in a row, then values in `ifac_b` can be zero which would
799
- # result in division by zero.
800
- # Use the `np.errstate` context manager to suppress printing the RuntimeWarning to the system console.
801
- with np.errstate(divide='ignore'):
802
- ifac = ifac_a / ifac_b
803
- interpolated_values[idx_nonzero_slice] = ((indexed_values_nonzero_idx - prev_indexed_values_nonzero_idx) * ifac
804
- + prev_indexed_values_nonzero_idx)
805
-
806
- # If the time to interpolate at is larger than the time in indexed_times, then the value has been extrapolated.
807
- # Extrapolated values are excluded.
808
- valid_mask = indexed_times >= sorted_unique_times
809
-
810
- key_times = sorted_unique_times[valid_mask]
811
- key_values = interpolated_values[valid_mask]
812
-
813
- return key_times, key_values
814
-
815
-
816
- def _convert_fbx_time_to_blender_time(key_times, blen_start_offset, fbx_start_offset, fps, fbx_ktime):
817
- timefac = fps / fbx_ktime
818
-
819
- # Convert from FBX timing to Blender timing.
820
- # Cannot subtract in-place because key_times could be read directly from FBX and could be used by multiple Actions.
821
- key_times = key_times - fbx_start_offset
822
- # FBX times are integers and timefac is a Python float, so the new array will be a np.float64 array.
823
- key_times = key_times * timefac
824
-
825
- key_times += blen_start_offset
826
-
827
- return key_times
828
-
829
-
830
- def blen_read_animation_curve(fbx_curve):
831
- """Read an animation curve from FBX data.
832
-
833
- The parsed keyframe times are guaranteed to be strictly increasing."""
834
- key_times = parray_as_ndarray(elem_prop_first(elem_find_first(fbx_curve, b'KeyTime')))
835
- key_values = parray_as_ndarray(elem_prop_first(elem_find_first(fbx_curve, b'KeyValueFloat')))
836
-
837
- assert(len(key_values) == len(key_times))
838
-
839
- # The FBX SDK specifies that only one key per time is allowed and that the keys are sorted in time order.
840
- # https://help.autodesk.com/view/FBX/2020/ENU/?guid=FBX_Developer_Help_cpp_ref_class_fbx_anim_curve_html
841
- all_times_strictly_increasing = (key_times[1:] > key_times[:-1]).all()
842
-
843
- if all_times_strictly_increasing:
844
- return key_times, key_values
845
- else:
846
- # FBX will still read animation curves even if they are invalid.
847
- return blen_read_invalid_animation_curve(key_times, key_values)
848
-
849
-
850
- def blen_store_keyframes(fbx_key_times, blen_fcurve, key_values, blen_start_offset, fps, fbx_ktime, fbx_start_offset=0):
851
- """Set all keyframe times and values for a newly created FCurve.
852
- Linear interpolation is currently assumed.
853
-
854
- This is a convenience function for calling blen_store_keyframes_multi with only a single fcurve and values array."""
855
- blen_store_keyframes_multi(fbx_key_times, [(blen_fcurve, key_values)], blen_start_offset, fps, fbx_ktime,
856
- fbx_start_offset)
857
-
858
-
859
- def blen_store_keyframes_multi(fbx_key_times, fcurve_and_key_values_pairs, blen_start_offset, fps, fbx_ktime,
860
- fbx_start_offset=0):
861
- """Set all keyframe times and values for multiple pairs of newly created FCurves and keyframe values arrays, where
862
- each pair has the same keyframe times.
863
- Linear interpolation is currently assumed."""
864
- bl_key_times = _convert_fbx_time_to_blender_time(fbx_key_times, blen_start_offset, fbx_start_offset, fps, fbx_ktime)
865
- num_keys = len(bl_key_times)
866
-
867
- # Compatible with C float type
868
- bl_keyframe_dtype = np.single
869
- # Compatible with C char type
870
- bl_enum_dtype = np.ubyte
871
-
872
- # The keyframe_points 'co' are accessed as flattened pairs of (time, value).
873
- # The key times are the same for each (blen_fcurve, key_values) pair, so only the values need to be updated for each
874
- # array of values.
875
- keyframe_points_co = np.empty(len(bl_key_times) * 2, dtype=bl_keyframe_dtype)
876
- # Even indices are times.
877
- keyframe_points_co[0::2] = bl_key_times
878
-
879
- interpolation_array = np.full(num_keys, LINEAR_INTERPOLATION_VALUE, dtype=bl_enum_dtype)
880
-
881
- for blen_fcurve, key_values in fcurve_and_key_values_pairs:
882
- # The fcurve must be newly created and thus have no keyframe_points.
883
- assert(len(blen_fcurve.keyframe_points) == 0)
884
-
885
- # Odd indices are values.
886
- keyframe_points_co[1::2] = key_values
887
-
888
- # Add the keyframe points to the FCurve and then set the 'co' and 'interpolation' of each point.
889
- blen_fcurve.keyframe_points.add(num_keys)
890
- blen_fcurve.keyframe_points.foreach_set('co', keyframe_points_co)
891
- blen_fcurve.keyframe_points.foreach_set('interpolation', interpolation_array)
892
-
893
- # Since we inserted our keyframes in 'ultra-fast' mode, we have to update the fcurves now.
894
- blen_fcurve.update()
895
-
896
-
897
- def blen_read_animations_action_item(channelbag, item, cnodes, fps, anim_offset, global_scale, shape_key_deforms,
898
- fbx_ktime):
899
- """
900
- 'Bake' loc/rot/scale into the channelbag,
901
- taking any pre_ and post_ matrix into account to transform from fbx into blender space.
902
- """
903
- from bpy.types import ShapeKey, Material, Camera
904
-
905
- fbx_curves: dict[bytes, dict[int, FBXElem]] = {}
906
- for curves, fbxprop in cnodes.values():
907
- channels_dict = fbx_curves.setdefault(fbxprop, {})
908
- for (fbx_acdata, _blen_data), channel in curves.values():
909
- if channel in channels_dict:
910
- # Ignore extra curves when one has already been found for this channel because FBX's default animation
911
- # system implementation only uses the first curve assigned to a channel.
912
- # Additional curves per channel are allowed by the FBX specification, but the handling of these curves
913
- # is considered the responsibility of the application that created them. Note that each curve node is
914
- # expected to have a unique set of channels, so these additional curves with the same channel would have
915
- # to belong to separate curve nodes. See the FBX SDK documentation for FbxAnimCurveNode.
916
- continue
917
- channels_dict[channel] = fbx_acdata
918
-
919
- # Leave if no curves are attached (if a blender curve is attached to scale but without keys it defaults to 0).
920
- if len(fbx_curves) == 0:
921
- return
922
-
923
- if isinstance(item, Material):
924
- grpname = item.name
925
- props = [("diffuse_color", 3, grpname or "Diffuse Color")]
926
- elif isinstance(item, ShapeKey):
927
- props = [(item.path_from_id("value"), 1, "Key")]
928
- elif isinstance(item, Camera):
929
- props = [(item.path_from_id("lens"), 1, "Camera"), (item.dof.path_from_id("focus_distance"), 1, "Camera")]
930
- else: # Object or PoseBone:
931
- if item.is_bone:
932
- bl_obj = item.bl_obj.pose.bones[item.bl_bone]
933
- else:
934
- bl_obj = item.bl_obj
935
-
936
- # We want to create actions for objects, but for bones we 'reuse' armatures' actions!
937
- grpname = bl_obj.name
938
-
939
- # Since we might get other channels animated in the end, due to all FBX transform magic,
940
- # we need to add curves for whole loc/rot/scale in any case.
941
- props = [(bl_obj.path_from_id("location"), 3, grpname or "Location"),
942
- None,
943
- (bl_obj.path_from_id("scale"), 3, grpname or "Scale")]
944
- rot_mode = bl_obj.rotation_mode
945
- if rot_mode == 'QUATERNION':
946
- props[1] = (bl_obj.path_from_id("rotation_quaternion"), 4, grpname or "Quaternion Rotation")
947
- elif rot_mode == 'AXIS_ANGLE':
948
- props[1] = (bl_obj.path_from_id("rotation_axis_angle"), 4, grpname or "Axis Angle Rotation")
949
- else: # Euler
950
- props[1] = (bl_obj.path_from_id("rotation_euler"), 3, grpname or "Euler Rotation")
951
-
952
- blen_curves = [channelbag.fcurves.new(prop, index=channel, group_name=grpname)
953
- for prop, nbr_channels, grpname in props for channel in range(nbr_channels)]
954
-
955
- if isinstance(item, Material):
956
- for fbxprop, channel_to_curve in fbx_curves.items():
957
- assert(fbxprop == b'DiffuseColor')
958
- for channel, curve in channel_to_curve.items():
959
- assert(channel in {0, 1, 2})
960
- blen_curve = blen_curves[channel]
961
- fbx_key_times, values = blen_read_animation_curve(curve)
962
- blen_store_keyframes(fbx_key_times, blen_curve, values, anim_offset, fps, fbx_ktime)
963
-
964
- elif isinstance(item, ShapeKey):
965
- for fbxprop, channel_to_curve in fbx_curves.items():
966
- assert(fbxprop == b'DeformPercent')
967
- for channel, curve in channel_to_curve.items():
968
- assert(channel == 0)
969
- blen_curve = blen_curves[channel]
970
-
971
- fbx_key_times, values = blen_read_animation_curve(curve)
972
- # A fully activated shape key in FBX DeformPercent is 100.0 whereas it is 1.0 in Blender.
973
- values = values / 100.0
974
- blen_store_keyframes(fbx_key_times, blen_curve, values, anim_offset, fps, fbx_ktime)
975
-
976
- # Store the minimum and maximum shape key values, so that the shape key's slider range can be expanded
977
- # if necessary after reading all animations.
978
- if values.size:
979
- deform_values = shape_key_deforms.setdefault(item, [])
980
- deform_values.append(values.min())
981
- deform_values.append(values.max())
982
-
983
- elif isinstance(item, Camera):
984
- for fbxprop, channel_to_curve in fbx_curves.items():
985
- is_focus_distance = fbxprop == b'FocusDistance'
986
- assert(fbxprop == b'FocalLength' or is_focus_distance)
987
- for channel, curve in channel_to_curve.items():
988
- assert(channel == 0)
989
- # The indices are determined by the creation of the `props` list above.
990
- blen_curve = blen_curves[1 if is_focus_distance else 0]
991
-
992
- fbx_key_times, values = blen_read_animation_curve(curve)
993
- if is_focus_distance:
994
- # Remap the imported values from FBX to Blender.
995
- values = values / 1000.0
996
- values *= global_scale
997
- blen_store_keyframes(fbx_key_times, blen_curve, values, anim_offset, fps, fbx_ktime)
998
-
999
- else: # Object or PoseBone:
1000
- transform_data = item.fbx_transform_data
1001
-
1002
- # Each transformation curve needs to have keyframes at the times of every other transformation curve
1003
- # (interpolating missing values), so that we can construct a matrix at every keyframe.
1004
- transform_prop_to_attr = {
1005
- b'Lcl Translation': transform_data.loc,
1006
- b'Lcl Rotation': transform_data.rot,
1007
- b'Lcl Scaling': transform_data.sca,
1008
- }
1009
-
1010
- times_and_values_tuples = []
1011
- initial_values = []
1012
- channel_keys = []
1013
- for fbxprop, channel_to_curve in fbx_curves.items():
1014
- if fbxprop not in transform_prop_to_attr:
1015
- # Currently, we only care about transformation curves.
1016
- continue
1017
- for channel, curve in channel_to_curve.items():
1018
- assert(channel in {0, 1, 2})
1019
- fbx_key_times, values = blen_read_animation_curve(curve)
1020
-
1021
- channel_keys.append((fbxprop, channel))
1022
-
1023
- initial_values.append(transform_prop_to_attr[fbxprop][channel])
1024
-
1025
- times_and_values_tuples.append((fbx_key_times, values))
1026
- if not times_and_values_tuples:
1027
- # If `times_and_values_tuples` is empty, all the imported animation curves are for properties other than
1028
- # transformation (e.g. animated custom properties), so there is nothing to do until support for those other
1029
- # properties is added.
1030
- return
1031
-
1032
- # Combine the keyframe times of all the transformation curves so that each curve has a value at every time.
1033
- combined_fbx_times, values_arrays = _combine_curve_keyframe_times(times_and_values_tuples, initial_values)
1034
-
1035
- # Convert from FBX Lcl Translation/Lcl Rotation/Lcl Scaling to the Blender location/rotation/scaling properties
1036
- # of this Object/PoseBone.
1037
- # The number of fcurves for the Blender properties varies depending on the rotation mode.
1038
- num_loc_channels = 3
1039
- num_rot_channels = 4 if rot_mode in {'QUATERNION', 'AXIS_ANGLE'} else 3 # Variations of EULER are all 3
1040
- num_sca_channels = 3
1041
- num_channels = num_loc_channels + num_rot_channels + num_sca_channels
1042
- num_frames = len(combined_fbx_times)
1043
- full_length = num_channels * num_frames
1044
-
1045
- # Do the conversion.
1046
- flattened_channel_values_gen = _transformation_curves_gen(item, values_arrays, channel_keys)
1047
- flattened_channel_values = np.fromiter(flattened_channel_values_gen, dtype=np.single, count=full_length)
1048
-
1049
- # Reshape to one row per frame and then view the transpose so that each row corresponds to a single channel.
1050
- # e.g.
1051
- # loc_channels = channel_values[:num_loc_channels]
1052
- # rot_channels = channel_values[num_loc_channels:num_loc_channels + num_rot_channels]
1053
- # sca_channels = channel_values[num_loc_channels + num_rot_channels:]
1054
- channel_values = flattened_channel_values.reshape(num_frames, num_channels).T
1055
-
1056
- # Each channel has the same keyframe times, so the combined times can be passed once along with all the curves
1057
- # and values arrays.
1058
- blen_store_keyframes_multi(combined_fbx_times, zip(blen_curves, channel_values), anim_offset, fps, fbx_ktime)
1059
-
1060
-
1061
- def blen_read_animations(fbx_tmpl_astack, fbx_tmpl_alayer, stacks, scene, anim_offset, global_scale, fbx_ktime):
1062
- """
1063
- Recreate an action per stack/layer/object combinations.
1064
- Only the first found action is linked to objects, more complex setups are not handled,
1065
- it's up to user to reproduce them!
1066
- """
1067
- from bpy.types import ShapeKey, Material, Camera
1068
-
1069
- shape_key_values = {}
1070
- actions = {}
1071
- for as_uuid, ((fbx_asdata, _blen_data), alayers) in stacks.items():
1072
- stack_name = elem_name_ensure_class(fbx_asdata, b'AnimStack')
1073
- for al_uuid, ((fbx_aldata, _blen_data), items) in alayers.items():
1074
- layer_name = elem_name_ensure_class(fbx_aldata, b'AnimLayer')
1075
- for item, cnodes in items.items():
1076
- if isinstance(item, Material):
1077
- id_data = item
1078
- elif isinstance(item, ShapeKey):
1079
- id_data = item.id_data
1080
- elif isinstance(item, Camera):
1081
- id_data = item
1082
- else:
1083
- id_data = item.bl_obj
1084
- # XXX Ignore rigged mesh animations - those are a nightmare to handle, see note about it in
1085
- # FbxImportHelperNode class definition.
1086
- if id_data and id_data.type == 'MESH' and id_data.parent and id_data.parent.type == 'ARMATURE':
1087
- continue
1088
- if id_data is None:
1089
- continue
1090
-
1091
- # Create new action if needed (should always be needed, except for keyblocks from shapekeys cases).
1092
- key = (as_uuid, al_uuid, id_data)
1093
- action = actions.get(key)
1094
- if action is None:
1095
- if stack_name == layer_name:
1096
- action_name = "|".join((id_data.name, stack_name))
1097
- else:
1098
- action_name = "|".join((id_data.name, stack_name, layer_name))
1099
- actions[key] = action = bpy.data.actions.new(action_name)
1100
- action.use_fake_user = True
1101
-
1102
- # Always use the same name for the slot. It should be simple
1103
- # to switch between imported Actions while keeping Slot
1104
- # auto-assignment, which means that all Actions should use
1105
- # the same slot name. As long as there's no separate
1106
- # indicator for the "intended object name" for this FBX
1107
- # animation, this is the best Blender can do. Maybe the
1108
- # 'stack name' would be a better choice?
1109
- action.slots.new(id_data.id_type, "Slot")
1110
-
1111
- # If none yet assigned, assign this action to id_data.
1112
- if not id_data.animation_data:
1113
- id_data.animation_data_create()
1114
- if not id_data.animation_data.action:
1115
- id_data.animation_data.action = action
1116
- id_data.animation_data.action_slot = action.slots[0]
1117
-
1118
- # And actually populate the action!
1119
- channelbag = anim_utils.action_ensure_channelbag_for_slot(action, action.slots[0])
1120
- blen_read_animations_action_item(channelbag, item, cnodes, scene.render.fps, anim_offset, global_scale,
1121
- shape_key_values, fbx_ktime)
1122
-
1123
- # If the minimum/maximum animated value is outside the slider range of the shape key, attempt to expand the slider
1124
- # range until the animated range fits and has extra room to be decreased or increased further.
1125
- # Shape key slider_min and slider_max have hard min/max values, if an imported animation uses a value outside that
1126
- # range, a warning message will be printed to the console and the slider_min/slider_max values will end up clamped.
1127
- shape_key_values_in_range = True
1128
- for shape_key, deform_values in shape_key_values.items():
1129
- min_animated_deform = min(deform_values)
1130
- max_animated_deform = max(deform_values)
1131
- shape_key_values_in_range &= expand_shape_key_range(shape_key, min_animated_deform)
1132
- shape_key_values_in_range &= expand_shape_key_range(shape_key, max_animated_deform)
1133
- if not shape_key_values_in_range:
1134
- print("WARNING: The imported animated Value of a Shape Key is beyond the minimum/maximum allowed and will be"
1135
- " clamped during playback.")
1136
-
1137
-
1138
- # ----
1139
- # Mesh
1140
-
1141
- def blen_read_geom_layerinfo(fbx_layer):
1142
- return (
1143
- validate_blend_names(elem_find_first_string_as_bytes(fbx_layer, b'Name')),
1144
- elem_find_first_string_as_bytes(fbx_layer, b'MappingInformationType'),
1145
- elem_find_first_string_as_bytes(fbx_layer, b'ReferenceInformationType'),
1146
- )
1147
-
1148
-
1149
- def blen_read_geom_validate_blen_data(blen_data, blen_dtype, item_size):
1150
- """Validate blen_data when it's not a bpy_prop_collection.
1151
- Returns whether blen_data is a bpy_prop_collection"""
1152
- blen_data_is_collection = isinstance(blen_data, bpy.types.bpy_prop_collection)
1153
- if not blen_data_is_collection:
1154
- if item_size > 1:
1155
- assert(len(blen_data.shape) == 2)
1156
- assert(blen_data.shape[1] == item_size)
1157
- assert(blen_data.dtype == blen_dtype)
1158
- return blen_data_is_collection
1159
-
1160
-
1161
- def blen_read_geom_parse_fbx_data(fbx_data, stride, item_size):
1162
- """Parse fbx_data as an array.array into a 2d np.ndarray that shares the same memory, where each row is a single
1163
- item"""
1164
- # Technically stride < item_size could be supported, but there's probably not a use case for it since it would
1165
- # result in a view of the data with self-overlapping memory.
1166
- assert(stride >= item_size)
1167
- # View the array.array as an np.ndarray.
1168
- fbx_data_np = parray_as_ndarray(fbx_data)
1169
-
1170
- if stride == item_size:
1171
- if item_size > 1:
1172
- # Need to make sure fbx_data_np has a whole number of items to be able to view item_size elements per row.
1173
- items_remainder = len(fbx_data_np) % item_size
1174
- if items_remainder:
1175
- print("ERROR: not a whole number of items in this FBX layer, skipping the partial item!")
1176
- fbx_data_np = fbx_data_np[:-items_remainder]
1177
- fbx_data_np = fbx_data_np.reshape(-1, item_size)
1178
- else:
1179
- # Create a view of fbx_data_np that is only the first item_size elements of each stride. Note that the view will
1180
- # not be C-contiguous.
1181
- stride_remainder = len(fbx_data_np) % stride
1182
- if stride_remainder:
1183
- if stride_remainder < item_size:
1184
- print("ERROR: not a whole number of items in this FBX layer, skipping the partial item!")
1185
- # Not enough in the remainder for a full item, so cut off the partial stride
1186
- fbx_data_np = fbx_data_np[:-stride_remainder]
1187
- # Reshape to one stride per row and then create a view that includes only the first item_size elements
1188
- # of each stride.
1189
- fbx_data_np = fbx_data_np.reshape(-1, stride)[:, :item_size]
1190
- else:
1191
- print("ERROR: not a whole number of strides in this FBX layer! There are a whole number of items, but"
1192
- " this could indicate an error!")
1193
- # There is not a whole number of strides, but there is a whole number of items.
1194
- # This is a pain to deal with because fbx_data_np.reshape(-1, stride) is not possible.
1195
- # A view of just the items can be created using stride_tricks.as_strided by specifying the shape and
1196
- # strides of the view manually.
1197
- # Extreme care must be taken when using stride_tricks.as_strided because improper usage can result in
1198
- # a view that gives access to memory outside the array.
1199
- from numpy.lib import stride_tricks
1200
-
1201
- # fbx_data_np should always start off as flat and C-contiguous.
1202
- assert(fbx_data_np.strides == (fbx_data_np.itemsize,))
1203
-
1204
- num_whole_strides = len(fbx_data_np) // stride
1205
- # Plus the one partial stride that is enough elements for a complete item.
1206
- num_items = num_whole_strides + 1
1207
- shape = (num_items, item_size)
1208
-
1209
- # strides are the number of bytes to step to get to the next element, for each axis.
1210
- step_per_item = fbx_data_np.itemsize * stride
1211
- step_per_item_element = fbx_data_np.itemsize
1212
- strides = (step_per_item, step_per_item_element)
1213
-
1214
- fbx_data_np = stride_tricks.as_strided(fbx_data_np, shape, strides)
1215
- else:
1216
- # There's a whole number of strides, so first reshape to one stride per row and then create a view that
1217
- # includes only the first item_size elements of each stride.
1218
- fbx_data_np = fbx_data_np.reshape(-1, stride)[:, :item_size]
1219
-
1220
- return fbx_data_np
1221
-
1222
-
1223
- def blen_read_geom_check_fbx_data_length(blen_data, fbx_data_np, is_indices=False):
1224
- """Check that there are the same number of items in blen_data and fbx_data_np.
1225
-
1226
- Returns a tuple of two elements:
1227
- 0: fbx_data_np or, if fbx_data_np contains more items than blen_data, a view of fbx_data_np with the excess
1228
- items removed
1229
- 1: Whether the returned fbx_data_np contains enough items to completely fill blen_data"""
1230
- bl_num_items = len(blen_data)
1231
- fbx_num_items = len(fbx_data_np)
1232
- enough_data = fbx_num_items >= bl_num_items
1233
- if not enough_data:
1234
- if is_indices:
1235
- print("ERROR: not enough indices in this FBX layer, missing data will be left as default!")
1236
- else:
1237
- print("ERROR: not enough data in this FBX layer, missing data will be left as default!")
1238
- elif fbx_num_items > bl_num_items:
1239
- if is_indices:
1240
- print("ERROR: too many indices in this FBX layer, skipping excess!")
1241
- else:
1242
- print("ERROR: too much data in this FBX layer, skipping excess!")
1243
- fbx_data_np = fbx_data_np[:bl_num_items]
1244
-
1245
- return fbx_data_np, enough_data
1246
-
1247
-
1248
- def blen_read_geom_xform(fbx_data_np, xform):
1249
- """xform is either None, or a function that takes fbx_data_np as its only positional argument and returns an
1250
- np.ndarray with the same total number of elements as fbx_data_np.
1251
- It is acceptable for xform to return an array with a different dtype to fbx_data_np.
1252
-
1253
- Returns xform(fbx_data_np) when xform is not None and ensures the result of xform(fbx_data_np) has the same shape as
1254
- fbx_data_np before returning it.
1255
- When xform is None, fbx_data_np is returned as is."""
1256
- if xform is not None:
1257
- item_size = fbx_data_np.shape[1]
1258
- fbx_total_data = fbx_data_np.size
1259
- fbx_data_np = xform(fbx_data_np)
1260
- # The amount of data should not be changed by xform
1261
- assert(fbx_data_np.size == fbx_total_data)
1262
- # Ensure fbx_data_np is still item_size elements per row
1263
- if len(fbx_data_np.shape) != 2 or fbx_data_np.shape[1] != item_size:
1264
- fbx_data_np = fbx_data_np.reshape(-1, item_size)
1265
- return fbx_data_np
1266
-
1267
-
1268
- def blen_read_geom_array_foreach_set_direct(blen_data, blen_attr, blen_dtype, fbx_data, stride, item_size, descr,
1269
- xform):
1270
- """Generic fbx_layer to blen_data foreach setter for Direct layers.
1271
- blen_data must be a bpy_prop_collection or 2d np.ndarray whose second axis length is item_size.
1272
- fbx_data must be an array.array."""
1273
- fbx_data_np = blen_read_geom_parse_fbx_data(fbx_data, stride, item_size)
1274
- fbx_data_np, enough_data = blen_read_geom_check_fbx_data_length(blen_data, fbx_data_np)
1275
- fbx_data_np = blen_read_geom_xform(fbx_data_np, xform)
1276
-
1277
- blen_data_is_collection = blen_read_geom_validate_blen_data(blen_data, blen_dtype, item_size)
1278
-
1279
- if blen_data_is_collection:
1280
- if not enough_data:
1281
- blen_total_data = len(blen_data) * item_size
1282
- buffer = np.empty(blen_total_data, dtype=blen_dtype)
1283
- # It's not clear what values should be used for the missing data, so read the current values into a buffer.
1284
- blen_data.foreach_get(blen_attr, buffer)
1285
-
1286
- # Change the buffer shape to one item per row
1287
- buffer.shape = (-1, item_size)
1288
-
1289
- # Copy the fbx data into the start of the buffer
1290
- buffer[:len(fbx_data_np)] = fbx_data_np
1291
- else:
1292
- # Convert the buffer to the Blender C type of blen_attr
1293
- buffer = astype_view_signedness(fbx_data_np, blen_dtype)
1294
-
1295
- # Set blen_attr of blen_data. The buffer must be flat and C-contiguous, which ravel() ensures
1296
- blen_data.foreach_set(blen_attr, buffer.ravel())
1297
- else:
1298
- assert(blen_data.size % item_size == 0)
1299
- blen_data = blen_data.view()
1300
- blen_data.shape = (-1, item_size)
1301
- blen_data[:len(fbx_data_np)] = fbx_data_np
1302
-
1303
-
1304
- def blen_read_geom_array_foreach_set_indexed(blen_data, blen_attr, blen_dtype, fbx_data, fbx_layer_index, stride,
1305
- item_size, descr, xform):
1306
- """Generic fbx_layer to blen_data foreach setter for IndexToDirect layers.
1307
- blen_data must be a bpy_prop_collection or 2d np.ndarray whose second axis length is item_size.
1308
- fbx_data must be an array.array or a 1d np.ndarray."""
1309
- fbx_data_np = blen_read_geom_parse_fbx_data(fbx_data, stride, item_size)
1310
- fbx_data_np = blen_read_geom_xform(fbx_data_np, xform)
1311
-
1312
- # fbx_layer_index is allowed to be a 1d np.ndarray for use with blen_read_geom_array_foreach_set_looptovert.
1313
- if not isinstance(fbx_layer_index, np.ndarray):
1314
- fbx_layer_index = parray_as_ndarray(fbx_layer_index)
1315
-
1316
- fbx_layer_index, enough_indices = blen_read_geom_check_fbx_data_length(blen_data, fbx_layer_index, is_indices=True)
1317
-
1318
- blen_data_is_collection = blen_read_geom_validate_blen_data(blen_data, blen_dtype, item_size)
1319
-
1320
- blen_data_items_len = len(blen_data)
1321
- blen_data_len = blen_data_items_len * item_size
1322
- fbx_num_items = len(fbx_data_np)
1323
-
1324
- # Find all indices that are out of bounds of fbx_data_np.
1325
- min_index_inclusive = -fbx_num_items
1326
- max_index_inclusive = fbx_num_items - 1
1327
- valid_index_mask = np.equal(fbx_layer_index, fbx_layer_index.clip(min_index_inclusive, max_index_inclusive))
1328
- indices_invalid = not valid_index_mask.all()
1329
-
1330
- fbx_data_items = fbx_data_np.reshape(-1, item_size)
1331
-
1332
- if indices_invalid or not enough_indices:
1333
- if blen_data_is_collection:
1334
- buffer = np.empty(blen_data_len, dtype=blen_dtype)
1335
- buffer_item_view = buffer.view()
1336
- buffer_item_view.shape = (-1, item_size)
1337
- # Since we don't know what the default values should be for the missing data, read the current values into a
1338
- # buffer.
1339
- blen_data.foreach_get(blen_attr, buffer)
1340
- else:
1341
- buffer_item_view = blen_data
1342
-
1343
- if not enough_indices:
1344
- # Reduce the length of the view to the same length as the number of indices.
1345
- buffer_item_view = buffer_item_view[:len(fbx_layer_index)]
1346
-
1347
- # Copy the result of indexing fbx_data_items by each element in fbx_layer_index into the buffer.
1348
- if indices_invalid:
1349
- print("ERROR: indices in this FBX layer out of bounds of the FBX data, skipping invalid indices!")
1350
- buffer_item_view[valid_index_mask] = fbx_data_items[fbx_layer_index[valid_index_mask]]
1351
- else:
1352
- buffer_item_view[:] = fbx_data_items[fbx_layer_index]
1353
-
1354
- if blen_data_is_collection:
1355
- blen_data.foreach_set(blen_attr, buffer.ravel())
1356
- else:
1357
- if blen_data_is_collection:
1358
- # Cast the buffer to the Blender C type of blen_attr
1359
- fbx_data_items = astype_view_signedness(fbx_data_items, blen_dtype)
1360
- buffer_items = fbx_data_items[fbx_layer_index]
1361
- blen_data.foreach_set(blen_attr, buffer_items.ravel())
1362
- else:
1363
- blen_data[:] = fbx_data_items[fbx_layer_index]
1364
-
1365
-
1366
- def blen_read_geom_array_foreach_set_allsame(blen_data, blen_attr, blen_dtype, fbx_data, stride, item_size, descr,
1367
- xform):
1368
- """Generic fbx_layer to blen_data foreach setter for AllSame layers.
1369
- blen_data must be a bpy_prop_collection or 2d np.ndarray whose second axis length is item_size.
1370
- fbx_data must be an array.array."""
1371
- fbx_data_np = blen_read_geom_parse_fbx_data(fbx_data, stride, item_size)
1372
- fbx_data_np = blen_read_geom_xform(fbx_data_np, xform)
1373
- blen_data_is_collection = blen_read_geom_validate_blen_data(blen_data, blen_dtype, item_size)
1374
- fbx_items_len = len(fbx_data_np)
1375
- blen_items_len = len(blen_data)
1376
-
1377
- if fbx_items_len < 1:
1378
- print("ERROR: not enough data in this FBX layer, skipping!")
1379
- return
1380
-
1381
- if blen_data_is_collection:
1382
- # Create an array filled with the value from fbx_data_np
1383
- buffer = np.full((blen_items_len, item_size), fbx_data_np[0], dtype=blen_dtype)
1384
-
1385
- blen_data.foreach_set(blen_attr, buffer.ravel())
1386
- else:
1387
- blen_data[:] = fbx_data_np[0]
1388
-
1389
-
1390
- def blen_read_geom_array_foreach_set_looptovert(mesh, blen_data, blen_attr, blen_dtype, fbx_data, stride, item_size,
1391
- descr, xform):
1392
- """Generic fbx_layer to blen_data foreach setter for face corner ByVertice layers.
1393
- blen_data must be a bpy_prop_collection or 2d np.ndarray whose second axis length is item_size.
1394
- fbx_data must be an array.array"""
1395
- # The fbx_data is mapped to vertices. To expand fbx_data to face corners, get an array of the vertex index of each
1396
- # face corner that will then be used to index fbx_data.
1397
- corner_vertex_indices = MESH_ATTRIBUTE_CORNER_VERT.to_ndarray(mesh.attributes)
1398
- blen_read_geom_array_foreach_set_indexed(blen_data, blen_attr, blen_dtype, fbx_data, corner_vertex_indices, stride,
1399
- item_size, descr, xform)
1400
-
1401
-
1402
- # generic error printers.
1403
- def blen_read_geom_array_error_mapping(descr, fbx_layer_mapping, quiet=False):
1404
- if not quiet:
1405
- print("warning layer %r mapping type unsupported: %r" % (descr, fbx_layer_mapping))
1406
-
1407
-
1408
- def blen_read_geom_array_error_ref(descr, fbx_layer_ref, quiet=False):
1409
- if not quiet:
1410
- print("warning layer %r ref type unsupported: %r" % (descr, fbx_layer_ref))
1411
-
1412
-
1413
- def blen_read_geom_array_mapped_vert(
1414
- mesh, blen_data, blen_attr, blen_dtype,
1415
- fbx_layer_data, fbx_layer_index,
1416
- fbx_layer_mapping, fbx_layer_ref,
1417
- stride, item_size, descr,
1418
- xform=None, quiet=False,
1419
- ):
1420
- if fbx_layer_mapping == b'ByVertice':
1421
- if fbx_layer_ref == b'IndexToDirect':
1422
- # XXX Looks like we often get no fbx_layer_index in this case, shall not happen but happens...
1423
- # We fallback to 'Direct' mapping in this case.
1424
- # ~ assert(fbx_layer_index is not None)
1425
- if fbx_layer_index is None:
1426
- blen_read_geom_array_foreach_set_direct(blen_data, blen_attr, blen_dtype, fbx_layer_data, stride,
1427
- item_size, descr, xform)
1428
- else:
1429
- blen_read_geom_array_foreach_set_indexed(blen_data, blen_attr, blen_dtype, fbx_layer_data,
1430
- fbx_layer_index, stride, item_size, descr, xform)
1431
- return True
1432
- elif fbx_layer_ref == b'Direct':
1433
- assert(fbx_layer_index is None)
1434
- blen_read_geom_array_foreach_set_direct(blen_data, blen_attr, blen_dtype, fbx_layer_data, stride, item_size,
1435
- descr, xform)
1436
- return True
1437
- blen_read_geom_array_error_ref(descr, fbx_layer_ref, quiet)
1438
- elif fbx_layer_mapping == b'AllSame':
1439
- if fbx_layer_ref == b'IndexToDirect':
1440
- assert(fbx_layer_index is None)
1441
- blen_read_geom_array_foreach_set_allsame(blen_data, blen_attr, blen_dtype, fbx_layer_data, stride,
1442
- item_size, descr, xform)
1443
- return True
1444
- blen_read_geom_array_error_ref(descr, fbx_layer_ref, quiet)
1445
- else:
1446
- blen_read_geom_array_error_mapping(descr, fbx_layer_mapping, quiet)
1447
-
1448
- return False
1449
-
1450
-
1451
- def blen_read_geom_array_mapped_edge(
1452
- mesh, blen_data, blen_attr, blen_dtype,
1453
- fbx_layer_data, fbx_layer_index,
1454
- fbx_layer_mapping, fbx_layer_ref,
1455
- stride, item_size, descr,
1456
- xform=None, quiet=False,
1457
- ):
1458
- if fbx_layer_mapping == b'ByEdge':
1459
- if fbx_layer_ref == b'Direct':
1460
- blen_read_geom_array_foreach_set_direct(blen_data, blen_attr, blen_dtype, fbx_layer_data, stride, item_size,
1461
- descr, xform)
1462
- return True
1463
- blen_read_geom_array_error_ref(descr, fbx_layer_ref, quiet)
1464
- elif fbx_layer_mapping == b'AllSame':
1465
- if fbx_layer_ref == b'IndexToDirect':
1466
- assert(fbx_layer_index is None)
1467
- blen_read_geom_array_foreach_set_allsame(blen_data, blen_attr, blen_dtype, fbx_layer_data, stride,
1468
- item_size, descr, xform)
1469
- return True
1470
- blen_read_geom_array_error_ref(descr, fbx_layer_ref, quiet)
1471
- else:
1472
- blen_read_geom_array_error_mapping(descr, fbx_layer_mapping, quiet)
1473
-
1474
- return False
1475
-
1476
-
1477
- def blen_read_geom_array_mapped_polygon(
1478
- mesh, blen_data, blen_attr, blen_dtype,
1479
- fbx_layer_data, fbx_layer_index,
1480
- fbx_layer_mapping, fbx_layer_ref,
1481
- stride, item_size, descr,
1482
- xform=None, quiet=False,
1483
- ):
1484
- if fbx_layer_mapping == b'ByPolygon':
1485
- if fbx_layer_ref == b'IndexToDirect':
1486
- # XXX Looks like we often get no fbx_layer_index in this case, shall not happen but happens...
1487
- # We fallback to 'Direct' mapping in this case.
1488
- # ~ assert(fbx_layer_index is not None)
1489
- if fbx_layer_index is None:
1490
- blen_read_geom_array_foreach_set_direct(blen_data, blen_attr, blen_dtype, fbx_layer_data, stride,
1491
- item_size, descr, xform)
1492
- else:
1493
- blen_read_geom_array_foreach_set_indexed(blen_data, blen_attr, blen_dtype, fbx_layer_data,
1494
- fbx_layer_index, stride, item_size, descr, xform)
1495
- return True
1496
- elif fbx_layer_ref == b'Direct':
1497
- blen_read_geom_array_foreach_set_direct(blen_data, blen_attr, blen_dtype, fbx_layer_data, stride, item_size,
1498
- descr, xform)
1499
- return True
1500
- blen_read_geom_array_error_ref(descr, fbx_layer_ref, quiet)
1501
- elif fbx_layer_mapping == b'AllSame':
1502
- if fbx_layer_ref == b'IndexToDirect':
1503
- assert(fbx_layer_index is None)
1504
- blen_read_geom_array_foreach_set_allsame(blen_data, blen_attr, blen_dtype, fbx_layer_data, stride,
1505
- item_size, descr, xform)
1506
- return True
1507
- blen_read_geom_array_error_ref(descr, fbx_layer_ref, quiet)
1508
- else:
1509
- blen_read_geom_array_error_mapping(descr, fbx_layer_mapping, quiet)
1510
-
1511
- return False
1512
-
1513
-
1514
- def blen_read_geom_array_mapped_polyloop(
1515
- mesh, blen_data, blen_attr, blen_dtype,
1516
- fbx_layer_data, fbx_layer_index,
1517
- fbx_layer_mapping, fbx_layer_ref,
1518
- stride, item_size, descr,
1519
- xform=None, quiet=False,
1520
- ):
1521
- if fbx_layer_mapping == b'ByPolygonVertex':
1522
- if fbx_layer_ref == b'IndexToDirect':
1523
- # XXX Looks like we often get no fbx_layer_index in this case, shall not happen but happens...
1524
- # We fallback to 'Direct' mapping in this case.
1525
- # ~ assert(fbx_layer_index is not None)
1526
- if fbx_layer_index is None:
1527
- blen_read_geom_array_foreach_set_direct(blen_data, blen_attr, blen_dtype, fbx_layer_data, stride,
1528
- item_size, descr, xform)
1529
- else:
1530
- blen_read_geom_array_foreach_set_indexed(blen_data, blen_attr, blen_dtype, fbx_layer_data,
1531
- fbx_layer_index, stride, item_size, descr, xform)
1532
- return True
1533
- elif fbx_layer_ref == b'Direct':
1534
- blen_read_geom_array_foreach_set_direct(blen_data, blen_attr, blen_dtype, fbx_layer_data, stride, item_size,
1535
- descr, xform)
1536
- return True
1537
- blen_read_geom_array_error_ref(descr, fbx_layer_ref, quiet)
1538
- elif fbx_layer_mapping == b'ByVertice':
1539
- if fbx_layer_ref == b'Direct':
1540
- assert(fbx_layer_index is None)
1541
- blen_read_geom_array_foreach_set_looptovert(mesh, blen_data, blen_attr, blen_dtype, fbx_layer_data, stride,
1542
- item_size, descr, xform)
1543
- return True
1544
- blen_read_geom_array_error_ref(descr, fbx_layer_ref, quiet)
1545
- elif fbx_layer_mapping == b'AllSame':
1546
- if fbx_layer_ref == b'IndexToDirect':
1547
- assert(fbx_layer_index is None)
1548
- blen_read_geom_array_foreach_set_allsame(blen_data, blen_attr, blen_dtype, fbx_layer_data, stride,
1549
- item_size, descr, xform)
1550
- return True
1551
- blen_read_geom_array_error_ref(descr, fbx_layer_ref, quiet)
1552
- else:
1553
- blen_read_geom_array_error_mapping(descr, fbx_layer_mapping, quiet)
1554
-
1555
- return False
1556
-
1557
-
1558
- def blen_read_geom_layer_material(fbx_obj, mesh):
1559
- fbx_layer = elem_find_first(fbx_obj, b'LayerElementMaterial')
1560
-
1561
- if fbx_layer is None:
1562
- return
1563
-
1564
- (fbx_layer_name,
1565
- fbx_layer_mapping,
1566
- fbx_layer_ref,
1567
- ) = blen_read_geom_layerinfo(fbx_layer)
1568
-
1569
- layer_id = b'Materials'
1570
- fbx_layer_data = elem_prop_first(elem_find_first(fbx_layer, layer_id))
1571
-
1572
- blen_data = MESH_ATTRIBUTE_MATERIAL_INDEX.ensure(mesh.attributes).data
1573
- fbx_item_size = 1
1574
- assert(fbx_item_size == MESH_ATTRIBUTE_MATERIAL_INDEX.item_size)
1575
- blen_read_geom_array_mapped_polygon(
1576
- mesh, blen_data, MESH_ATTRIBUTE_MATERIAL_INDEX.foreach_attribute, MESH_ATTRIBUTE_MATERIAL_INDEX.dtype,
1577
- fbx_layer_data, None,
1578
- fbx_layer_mapping, fbx_layer_ref,
1579
- 1, fbx_item_size, layer_id,
1580
- )
1581
-
1582
-
1583
- def blen_read_geom_layer_uv(fbx_obj, mesh):
1584
- for layer_id in (b'LayerElementUV',):
1585
- for fbx_layer in elem_find_iter(fbx_obj, layer_id):
1586
- # all should be valid
1587
- (fbx_layer_name,
1588
- fbx_layer_mapping,
1589
- fbx_layer_ref,
1590
- ) = blen_read_geom_layerinfo(fbx_layer)
1591
-
1592
- fbx_layer_data = elem_prop_first(elem_find_first(fbx_layer, b'UV'))
1593
- fbx_layer_index = elem_prop_first(elem_find_first(fbx_layer, b'UVIndex'))
1594
-
1595
- # Always init our new layers with (0, 0) UVs.
1596
- uv_lay = mesh.uv_layers.new(name=fbx_layer_name, do_init=False)
1597
- if uv_lay is None:
1598
- print("Failed to add {%r %r} UVLayer to %r (probably too many of them?)"
1599
- "" % (layer_id, fbx_layer_name, mesh.name))
1600
- continue
1601
-
1602
- blen_data = uv_lay.uv
1603
-
1604
- # some valid files omit this data
1605
- if fbx_layer_data is None:
1606
- print("%r %r missing data" % (layer_id, fbx_layer_name))
1607
- continue
1608
-
1609
- blen_read_geom_array_mapped_polyloop(
1610
- mesh, blen_data, "vector", np.single,
1611
- fbx_layer_data, fbx_layer_index,
1612
- fbx_layer_mapping, fbx_layer_ref,
1613
- 2, 2, layer_id,
1614
- )
1615
-
1616
-
1617
- def blen_read_geom_layer_color(fbx_obj, mesh, colors_type):
1618
- if colors_type == 'NONE':
1619
- return
1620
- use_srgb = colors_type == 'SRGB'
1621
- layer_type = 'BYTE_COLOR' if use_srgb else 'FLOAT_COLOR'
1622
- color_prop_name = "color_srgb" if use_srgb else "color"
1623
- # almost same as UVs
1624
- for layer_id in (b'LayerElementColor',):
1625
- for fbx_layer in elem_find_iter(fbx_obj, layer_id):
1626
- # all should be valid
1627
- (fbx_layer_name,
1628
- fbx_layer_mapping,
1629
- fbx_layer_ref,
1630
- ) = blen_read_geom_layerinfo(fbx_layer)
1631
-
1632
- fbx_layer_data = elem_prop_first(elem_find_first(fbx_layer, b'Colors'))
1633
- fbx_layer_index = elem_prop_first(elem_find_first(fbx_layer, b'ColorIndex'))
1634
-
1635
- color_lay = mesh.color_attributes.new(name=fbx_layer_name, type=layer_type, domain='CORNER')
1636
-
1637
- if color_lay is None:
1638
- print("Failed to add {%r %r} vertex color layer to %r (probably too many of them?)"
1639
- "" % (layer_id, fbx_layer_name, mesh.name))
1640
- continue
1641
-
1642
- blen_data = color_lay.data
1643
-
1644
- # some valid files omit this data
1645
- if fbx_layer_data is None:
1646
- print("%r %r missing data" % (layer_id, fbx_layer_name))
1647
- continue
1648
-
1649
- blen_read_geom_array_mapped_polyloop(
1650
- mesh, blen_data, color_prop_name, np.single,
1651
- fbx_layer_data, fbx_layer_index,
1652
- fbx_layer_mapping, fbx_layer_ref,
1653
- 4, 4, layer_id,
1654
- )
1655
-
1656
-
1657
- def blen_read_geom_layer_smooth(fbx_obj, mesh):
1658
- fbx_layer = elem_find_first(fbx_obj, b'LayerElementSmoothing')
1659
-
1660
- if fbx_layer is None:
1661
- return
1662
-
1663
- # all should be valid
1664
- (fbx_layer_name,
1665
- fbx_layer_mapping,
1666
- fbx_layer_ref,
1667
- ) = blen_read_geom_layerinfo(fbx_layer)
1668
-
1669
- layer_id = b'Smoothing'
1670
- fbx_layer_data = elem_prop_first(elem_find_first(fbx_layer, layer_id))
1671
-
1672
- # udk has 'Direct' mapped, with no Smoothing, not sure why, but ignore these
1673
- if fbx_layer_data is None:
1674
- return
1675
-
1676
- if fbx_layer_mapping == b'ByEdge':
1677
- # some models have bad edge data, we can't use this info...
1678
- if not mesh.edges:
1679
- print("warning skipping sharp edges data, no valid edges...")
1680
- return
1681
-
1682
- blen_data = MESH_ATTRIBUTE_SHARP_EDGE.ensure(mesh.attributes).data
1683
- fbx_item_size = 1
1684
- assert(fbx_item_size == MESH_ATTRIBUTE_SHARP_EDGE.item_size)
1685
- blen_read_geom_array_mapped_edge(
1686
- mesh, blen_data, MESH_ATTRIBUTE_SHARP_EDGE.foreach_attribute, MESH_ATTRIBUTE_SHARP_EDGE.dtype,
1687
- fbx_layer_data, None,
1688
- fbx_layer_mapping, fbx_layer_ref,
1689
- 1, fbx_item_size, layer_id,
1690
- xform=np.logical_not, # in FBX, 0 (False) is sharp, but in Blender True is sharp.
1691
- )
1692
- elif fbx_layer_mapping == b'ByPolygon':
1693
- sharp_face = MESH_ATTRIBUTE_SHARP_FACE.ensure(mesh.attributes)
1694
- blen_data = sharp_face.data
1695
- fbx_item_size = 1
1696
- assert(fbx_item_size == MESH_ATTRIBUTE_SHARP_FACE.item_size)
1697
- sharp_face_set_successfully = blen_read_geom_array_mapped_polygon(
1698
- mesh, blen_data, MESH_ATTRIBUTE_SHARP_FACE.foreach_attribute, MESH_ATTRIBUTE_SHARP_FACE.dtype,
1699
- fbx_layer_data, None,
1700
- fbx_layer_mapping, fbx_layer_ref,
1701
- 1, fbx_item_size, layer_id,
1702
- xform=lambda s: (s == 0), # smoothgroup bitflags, treat as booleans for now
1703
- )
1704
- if not sharp_face_set_successfully:
1705
- mesh.attributes.remove(sharp_face)
1706
- else:
1707
- print("warning layer %r mapping type unsupported: %r" % (fbx_layer.id, fbx_layer_mapping))
1708
-
1709
-
1710
- def blen_read_geom_layer_edge_crease(fbx_obj, mesh):
1711
- fbx_layer = elem_find_first(fbx_obj, b'LayerElementEdgeCrease')
1712
-
1713
- if fbx_layer is None:
1714
- return False
1715
-
1716
- # all should be valid
1717
- (fbx_layer_name,
1718
- fbx_layer_mapping,
1719
- fbx_layer_ref,
1720
- ) = blen_read_geom_layerinfo(fbx_layer)
1721
-
1722
- if fbx_layer_mapping != b'ByEdge':
1723
- return False
1724
-
1725
- layer_id = b'EdgeCrease'
1726
- fbx_layer_data = elem_prop_first(elem_find_first(fbx_layer, layer_id))
1727
-
1728
- # some models have bad edge data, we can't use this info...
1729
- if not mesh.edges:
1730
- print("warning skipping edge crease data, no valid edges...")
1731
- return False
1732
-
1733
- if fbx_layer_mapping == b'ByEdge':
1734
- # some models have bad edge data, we can't use this info...
1735
- if not mesh.edges:
1736
- print("warning skipping edge crease data, no valid edges...")
1737
- return False
1738
-
1739
- blen_data = mesh.edge_creases_ensure().data
1740
- return blen_read_geom_array_mapped_edge(
1741
- mesh, blen_data, "value", np.single,
1742
- fbx_layer_data, None,
1743
- fbx_layer_mapping, fbx_layer_ref,
1744
- 1, 1, layer_id,
1745
- # Blender squares those values before sending them to OpenSubdiv, when other software don't,
1746
- # so we need to compensate that to get similar results through FBX...
1747
- xform=np.sqrt,
1748
- )
1749
- else:
1750
- print("warning layer %r mapping type unsupported: %r" % (fbx_layer.id, fbx_layer_mapping))
1751
- return False
1752
-
1753
-
1754
- def blen_read_geom_layer_normal(fbx_obj, mesh, xform=None):
1755
- fbx_layer = elem_find_first(fbx_obj, b'LayerElementNormal')
1756
-
1757
- if fbx_layer is None:
1758
- return False
1759
-
1760
- (fbx_layer_name,
1761
- fbx_layer_mapping,
1762
- fbx_layer_ref,
1763
- ) = blen_read_geom_layerinfo(fbx_layer)
1764
-
1765
- layer_id = b'Normals'
1766
- fbx_layer_data = elem_prop_first(elem_find_first(fbx_layer, layer_id))
1767
- fbx_layer_index = elem_prop_first(elem_find_first(fbx_layer, b'NormalsIndex'))
1768
-
1769
- if fbx_layer_data is None:
1770
- print("warning %r %r missing data" % (layer_id, fbx_layer_name))
1771
- return False
1772
-
1773
- # Normals are temporarily set here so that they can be retrieved again after a call to Mesh.validate().
1774
- bl_norm_dtype = np.single
1775
- item_size = 3
1776
- # try loops, then polygons, then vertices.
1777
- tries = ((mesh.attributes["temp_custom_normals"].data, "Loops", False, blen_read_geom_array_mapped_polyloop),
1778
- (mesh.polygons, "Polygons", True, blen_read_geom_array_mapped_polygon),
1779
- (mesh.vertices, "Vertices", True, blen_read_geom_array_mapped_vert))
1780
- for blen_data, blen_data_type, is_fake, func in tries:
1781
- bdata = np.zeros((len(blen_data), item_size), dtype=bl_norm_dtype) if is_fake else blen_data
1782
- if func(mesh, bdata, "vector", bl_norm_dtype,
1783
- fbx_layer_data, fbx_layer_index, fbx_layer_mapping, fbx_layer_ref, 3, item_size, layer_id, xform, True):
1784
- if blen_data_type == "Polygons":
1785
- # To expand to per-loop normals, repeat each per-polygon normal by the number of loops of each polygon.
1786
- poly_loop_totals = np.empty(len(mesh.polygons), dtype=np.uintc)
1787
- mesh.polygons.foreach_get("loop_total", poly_loop_totals)
1788
- loop_normals = np.repeat(bdata, poly_loop_totals, axis=0)
1789
- mesh.attributes["temp_custom_normals"].data.foreach_set("vector", loop_normals.ravel())
1790
- elif blen_data_type == "Vertices":
1791
- # We have to copy vnors to lnors! Far from elegant, but simple.
1792
- loop_vertex_indices = MESH_ATTRIBUTE_CORNER_VERT.to_ndarray(mesh.attributes)
1793
- mesh.attributes["temp_custom_normals"].data.foreach_set("vector", bdata[loop_vertex_indices].ravel())
1794
- return True
1795
-
1796
- blen_read_geom_array_error_mapping("normal", fbx_layer_mapping)
1797
- blen_read_geom_array_error_ref("normal", fbx_layer_ref)
1798
- return False
1799
-
1800
-
1801
- def blen_read_geom(fbx_tmpl, fbx_obj, settings):
1802
- # Vertices are in object space, but we are post-multiplying all transforms with the inverse of the
1803
- # global matrix, so we need to apply the global matrix to the vertices to get the correct result.
1804
- geom_mat_co = settings.global_matrix if settings.bake_space_transform else None
1805
- # We need to apply the inverse transpose of the global matrix when transforming normals.
1806
- geom_mat_no = Matrix(settings.global_matrix_inv_transposed) if settings.bake_space_transform else None
1807
- if geom_mat_no is not None:
1808
- # Remove translation & scaling!
1809
- geom_mat_no.translation = Vector()
1810
- geom_mat_no.normalize()
1811
-
1812
- # TODO, use 'fbx_tmpl'
1813
- elem_name_utf8 = elem_name_ensure_class(fbx_obj, b'Geometry')
1814
-
1815
- fbx_verts = elem_prop_first(elem_find_first(fbx_obj, b'Vertices'))
1816
- fbx_polys = elem_prop_first(elem_find_first(fbx_obj, b'PolygonVertexIndex'))
1817
- fbx_edges = elem_prop_first(elem_find_first(fbx_obj, b'Edges'))
1818
-
1819
- # The dtypes when empty don't matter, but are set to what the fbx arrays are expected to be.
1820
- fbx_verts = parray_as_ndarray(fbx_verts) if fbx_verts else np.empty(0, dtype=data_types.ARRAY_FLOAT64)
1821
- fbx_polys = parray_as_ndarray(fbx_polys) if fbx_polys else np.empty(0, dtype=data_types.ARRAY_INT32)
1822
- fbx_edges = parray_as_ndarray(fbx_edges) if fbx_edges else np.empty(0, dtype=data_types.ARRAY_INT32)
1823
-
1824
- # Each vert is a 3d vector so is made of 3 components.
1825
- tot_verts = len(fbx_verts) // 3
1826
- if tot_verts * 3 != len(fbx_verts):
1827
- print("ERROR: Not a whole number of vertices. Ignoring the partial vertex!")
1828
- # Remove any remainder.
1829
- fbx_verts = fbx_verts[:tot_verts * 3]
1830
-
1831
- tot_loops = len(fbx_polys)
1832
- tot_edges = len(fbx_edges)
1833
-
1834
- mesh = bpy.data.meshes.new(name=elem_name_utf8)
1835
- attributes = mesh.attributes
1836
-
1837
- if tot_verts:
1838
- if geom_mat_co is not None:
1839
- fbx_verts = vcos_transformed(fbx_verts, geom_mat_co, MESH_ATTRIBUTE_POSITION.dtype)
1840
- else:
1841
- fbx_verts = fbx_verts.astype(MESH_ATTRIBUTE_POSITION.dtype, copy=False)
1842
-
1843
- mesh.vertices.add(tot_verts)
1844
- MESH_ATTRIBUTE_POSITION.foreach_set(attributes, fbx_verts.ravel())
1845
-
1846
- if tot_loops:
1847
- bl_loop_start_dtype = np.uintc
1848
-
1849
- mesh.loops.add(tot_loops)
1850
- # The end of each polygon is specified by an inverted index.
1851
- fbx_loop_end_idx = np.flatnonzero(fbx_polys < 0)
1852
-
1853
- tot_polys = len(fbx_loop_end_idx)
1854
-
1855
- # Un-invert the loop ends.
1856
- fbx_polys[fbx_loop_end_idx] ^= -1
1857
- # Set loop vertex indices, casting to the Blender C type first for performance.
1858
- MESH_ATTRIBUTE_CORNER_VERT.foreach_set(
1859
- attributes, astype_view_signedness(fbx_polys, MESH_ATTRIBUTE_CORNER_VERT.dtype))
1860
-
1861
- poly_loop_starts = np.empty(tot_polys, dtype=bl_loop_start_dtype)
1862
- # The first loop is always a loop start.
1863
- poly_loop_starts[0] = 0
1864
- # Ignoring the last loop end, the indices after every loop end are the remaining loop starts.
1865
- poly_loop_starts[1:] = fbx_loop_end_idx[:-1] + 1
1866
-
1867
- mesh.polygons.add(tot_polys)
1868
- mesh.polygons.foreach_set("loop_start", poly_loop_starts)
1869
-
1870
- blen_read_geom_layer_material(fbx_obj, mesh)
1871
- blen_read_geom_layer_uv(fbx_obj, mesh)
1872
- blen_read_geom_layer_color(fbx_obj, mesh, settings.colors_type)
1873
-
1874
- if tot_edges:
1875
- # edges in fact index the polygons (NOT the vertices)
1876
-
1877
- # The first vertex index of each edge is the vertex index of the corresponding loop in fbx_polys.
1878
- edges_a = fbx_polys[fbx_edges]
1879
-
1880
- # The second vertex index of each edge is the vertex index of the next loop in the same polygon. The
1881
- # complexity here is that if the first vertex index was the last loop of that polygon in fbx_polys, the next
1882
- # loop in the polygon is the first loop of that polygon, which is not the next loop in fbx_polys.
1883
-
1884
- # Copy fbx_polys, but rolled backwards by 1 so that indexing the result by [fbx_edges] will get the next
1885
- # loop of the same polygon unless the first vertex index was the last loop of the polygon.
1886
- fbx_polys_next = np.roll(fbx_polys, -1)
1887
- # Get the first loop of each polygon and set them into fbx_polys_next at the same indices as the last loop
1888
- # of each polygon in fbx_polys.
1889
- fbx_polys_next[fbx_loop_end_idx] = fbx_polys[poly_loop_starts]
1890
-
1891
- # Indexing fbx_polys_next by fbx_edges now gets the vertex index of the next loop in fbx_polys.
1892
- edges_b = fbx_polys_next[fbx_edges]
1893
-
1894
- # edges_a and edges_b need to be combined so that the first vertex index of each edge is immediately
1895
- # followed by the second vertex index of that same edge.
1896
- # Stack edges_a and edges_b as individual columns like np.column_stack((edges_a, edges_b)).
1897
- # np.concatenate is used because np.column_stack doesn't allow specifying the dtype of the returned array.
1898
- edges_conv = np.concatenate((edges_a.reshape(-1, 1), edges_b.reshape(-1, 1)),
1899
- axis=1, dtype=MESH_ATTRIBUTE_EDGE_VERTS.dtype, casting='unsafe')
1900
-
1901
- # Add the edges and set their vertex indices.
1902
- mesh.edges.add(len(edges_conv))
1903
- # ravel() because edges_conv must be flat and C-contiguous when passed to foreach_set.
1904
- MESH_ATTRIBUTE_EDGE_VERTS.foreach_set(attributes, edges_conv.ravel())
1905
- elif tot_edges:
1906
- print("ERROR: No polygons, but edges exist. Ignoring the edges!")
1907
-
1908
- # must be after edge, face loading.
1909
- blen_read_geom_layer_smooth(fbx_obj, mesh)
1910
-
1911
- blen_read_geom_layer_edge_crease(fbx_obj, mesh)
1912
-
1913
- ok_normals = False
1914
- if settings.use_custom_normals:
1915
- # Note: we store 'temp' normals in loops, since validate() may alter final mesh,
1916
- # we can only set custom lnors *after* calling it.
1917
- mesh.attributes.new("temp_custom_normals", 'FLOAT_VECTOR', 'CORNER')
1918
- if geom_mat_no is None:
1919
- ok_normals = blen_read_geom_layer_normal(fbx_obj, mesh)
1920
- else:
1921
- ok_normals = blen_read_geom_layer_normal(fbx_obj, mesh,
1922
- lambda v_array: nors_transformed(v_array, geom_mat_no))
1923
-
1924
- mesh.validate(clean_customdata=False) # *Very* important to not remove lnors here!
1925
-
1926
- if ok_normals:
1927
- bl_nors_dtype = np.single
1928
- clnors = np.empty(len(mesh.loops) * 3, dtype=bl_nors_dtype)
1929
- mesh.attributes["temp_custom_normals"].data.foreach_get("vector", clnors)
1930
-
1931
- # Iterating clnors into a nested tuple first is faster than passing clnors.reshape(-1, 3) directly into
1932
- # normals_split_custom_set. We use clnors.data since it is a memoryview, which is faster to iterate than clnors.
1933
- mesh.normals_split_custom_set(tuple(zip(*(iter(clnors.data),) * 3)))
1934
- if settings.use_custom_normals:
1935
- mesh.attributes.remove(mesh.attributes["temp_custom_normals"])
1936
-
1937
- if settings.use_custom_props:
1938
- blen_read_custom_properties(fbx_obj, mesh, settings)
1939
-
1940
- return mesh
1941
-
1942
-
1943
- def blen_read_shapes(fbx_tmpl, fbx_data, objects, me, scene):
1944
- if not fbx_data:
1945
- # No shape key data. Nothing to do.
1946
- return
1947
-
1948
- me_vcos = MESH_ATTRIBUTE_POSITION.to_ndarray(me.attributes)
1949
- me_vcos_vector_view = me_vcos.reshape(-1, 3)
1950
-
1951
- objects = list({node.bl_obj for node in objects})
1952
- assert(objects)
1953
-
1954
- # Blender has a hard minimum and maximum shape key Value. If an imported shape key has a value outside this range it
1955
- # will be clamped, and we'll print a warning message to the console.
1956
- shape_key_values_in_range = True
1957
- bc_uuid_to_keyblocks = {}
1958
- for bc_uuid, fbx_sdata, fbx_bcdata, shapes_assigned_to_channel in fbx_data:
1959
- num_shapes_assigned_to_channel = len(shapes_assigned_to_channel)
1960
- if num_shapes_assigned_to_channel > 1:
1961
- # Relevant design task: #104698
1962
- raise RuntimeError("FBX in-between Shapes are not currently supported") # See bug report #84111
1963
- elem_name_utf8 = elem_name_ensure_class(fbx_sdata, b'Geometry')
1964
- indices = elem_prop_first(elem_find_first(fbx_sdata, b'Indexes'))
1965
- dvcos = elem_prop_first(elem_find_first(fbx_sdata, b'Vertices'))
1966
-
1967
- indices = parray_as_ndarray(indices) if indices else np.empty(0, dtype=data_types.ARRAY_INT32)
1968
- dvcos = parray_as_ndarray(dvcos) if dvcos else np.empty(0, dtype=data_types.ARRAY_FLOAT64)
1969
-
1970
- # If there's not a whole number of vectors, trim off the remainder.
1971
- # 3 components per vector.
1972
- remainder = len(dvcos) % 3
1973
- if remainder:
1974
- dvcos = dvcos[:-remainder]
1975
- dvcos = dvcos.reshape(-1, 3)
1976
-
1977
- # There must be the same number of indices as vertex coordinate differences.
1978
- assert(len(indices) == len(dvcos))
1979
-
1980
- # We completely ignore normals here!
1981
- weight = elem_prop_first(elem_find_first(fbx_bcdata, b'DeformPercent'), default=100.0) / 100.0
1982
-
1983
- # The FullWeights array stores the deformation percentages of the BlendShapeChannel that fully activate each
1984
- # Shape assigned to the BlendShapeChannel. Blender also uses this array to store Vertex Group weights, but this
1985
- # is not part of the FBX standard.
1986
- full_weights = elem_prop_first(elem_find_first(fbx_bcdata, b'FullWeights'))
1987
- full_weights = parray_as_ndarray(full_weights) if full_weights else np.empty(0, dtype=data_types.ARRAY_FLOAT64)
1988
-
1989
- # Special case for Blender exported Shape Keys with a Vertex Group assigned. The Vertex Group weights are stored
1990
- # in the FullWeights array.
1991
- # XXX - It's possible, though very rare, to get a false positive here and create a Vertex Group when we
1992
- # shouldn't. This should only be possible when there are extraneous FullWeights or when there is a single
1993
- # FullWeight and its value is not 100.0.
1994
- if (
1995
- # Blender exported Shape Keys only ever export as 1 Shape per BlendShapeChannel.
1996
- num_shapes_assigned_to_channel == 1
1997
- # There should be one vertex weight for each vertex moved by the Shape.
1998
- and len(full_weights) == len(indices)
1999
- # Skip creating a Vertex Group when all the weights are 100.0 because such a Vertex Group has no effect.
2000
- # This also avoids creating a Vertex Group for imported Shapes that only move a single vertex because
2001
- # their BlendShapeChannel's singular FullWeight is expected to always be 100.0.
2002
- and not np.all(full_weights == 100.0)
2003
- # Blender vertex weights are always within the [0.0, 1.0] range (scaled to [0.0, 100.0] when saving to
2004
- # FBX). This can eliminate imported BlendShapeChannels from Unreal that have extraneous FullWeights
2005
- # because the extraneous values are usually negative.
2006
- and np.all((full_weights >= 0.0) & (full_weights <= 100.0))
2007
- ):
2008
- # Not doing the division in-place because it's technically possible for FBX BlendShapeChannels to be used by
2009
- # more than one FBX BlendShape, though this shouldn't be the case for Blender exported Shape Keys.
2010
- vgweights = full_weights / 100.0
2011
- else:
2012
- vgweights = None
2013
- # There must be a FullWeight for each Shape. Any extra FullWeights are ignored.
2014
- assert(len(full_weights) >= num_shapes_assigned_to_channel)
2015
-
2016
- # To add shape keys to the mesh, an Object using the mesh is needed.
2017
- if me.shape_keys is None:
2018
- objects[0].shape_key_add(name="Basis", from_mix=False)
2019
- kb = objects[0].shape_key_add(name=elem_name_utf8, from_mix=False)
2020
- kb.value = 0.0
2021
- me.shape_keys.use_relative = True # Should already be set as such.
2022
-
2023
- # Only need to set the shape key co if there are any non-zero dvcos.
2024
- if dvcos.any():
2025
- shape_cos = me_vcos_vector_view.copy()
2026
- shape_cos[indices] += dvcos
2027
- kb.points.foreach_set("co", shape_cos.ravel())
2028
-
2029
- shape_key_values_in_range &= expand_shape_key_range(kb, weight)
2030
-
2031
- kb.value = weight
2032
-
2033
- # Add vgroup if necessary.
2034
- if vgweights is not None:
2035
- # VertexGroup.add only allows sequences of int indices, but iterating the indices array directly would
2036
- # produce numpy scalars of types such as np.int32. The underlying memoryview of the indices array, however,
2037
- # does produce standard Python ints when iterated, so pass indices.data to add_vgroup_to_objects instead of
2038
- # indices.
2039
- # memoryviews tend to be faster to iterate than numpy arrays anyway, so vgweights.data is passed too.
2040
- add_vgroup_to_objects(indices.data, vgweights.data, kb.name, objects)
2041
- kb.vertex_group = kb.name
2042
-
2043
- bc_uuid_to_keyblocks.setdefault(bc_uuid, []).append(kb)
2044
-
2045
- if not shape_key_values_in_range:
2046
- print("WARNING: The imported Value of a Shape Key on the Mesh '%s' is beyond the minimum/maximum allowed and"
2047
- " has been clamped." % me.name)
2048
-
2049
- return bc_uuid_to_keyblocks
2050
-
2051
-
2052
- # --------
2053
- # Material
2054
-
2055
- def blen_read_material(fbx_tmpl, fbx_obj, settings):
2056
- from bpy_extras import node_shader_utils
2057
- from math import sqrt
2058
-
2059
- elem_name_utf8 = elem_name_ensure_class(fbx_obj, b'Material')
2060
-
2061
- if settings.mtl_name_collision_mode == "REFERENCE_EXISTING":
2062
- if (ma := bpy.data.materials.get(elem_name_utf8)):
2063
- return ma
2064
-
2065
- nodal_material_wrap_map = settings.nodal_material_wrap_map
2066
- ma = bpy.data.materials.new(name=elem_name_utf8)
2067
-
2068
- const_color_white = 1.0, 1.0, 1.0
2069
- const_color_black = 0.0, 0.0, 0.0
2070
-
2071
- fbx_props = (elem_find_first(fbx_obj, b'Properties70'),
2072
- elem_find_first(fbx_tmpl, b'Properties70', fbx_elem_nil))
2073
- fbx_props_no_template = (fbx_props[0], fbx_elem_nil)
2074
-
2075
- ma_wrap = node_shader_utils.PrincipledBSDFWrapper(ma, is_readonly=False)
2076
- ma_wrap.base_color = elem_props_get_color_rgb(fbx_props, b'DiffuseColor', const_color_white)
2077
- # No specular color in Principled BSDF shader, assumed to be either white or take some tint from diffuse one...
2078
- # TODO: add way to handle tint option (guesstimate from spec color + intensity...)?
2079
- ma_wrap.specular = elem_props_get_number(fbx_props, b'SpecularFactor', 0.25) * 2.0
2080
- # XXX Totally empirical conversion, trying to adapt it (and protect against invalid negative values, see T96076):
2081
- # From [1.0 - 0.0] Principled BSDF range to [0.0 - 100.0] FBX shininess range)...
2082
- fbx_shininess = max(elem_props_get_number(fbx_props, b'Shininess', 20.0), 0.0)
2083
- ma_wrap.roughness = 1.0 - (sqrt(fbx_shininess) / 10.0)
2084
- # Sweetness... Looks like we are not the only ones to not know exactly how FBX is supposed to work (see T59850).
2085
- # According to one of its developers, Unity uses that formula to extract alpha value:
2086
- #
2087
- # alpha = 1 - TransparencyFactor
2088
- # if (alpha == 1 or alpha == 0):
2089
- # alpha = 1 - TransparentColor.r
2090
- #
2091
- # Until further info, let's assume this is correct way to do, hence the following code for TransparentColor.
2092
- # However, there are some cases (from 3DSMax, see T65065), where we do have TransparencyFactor only defined
2093
- # in the template to 0.0, and then materials defining TransparentColor to pure white (1.0, 1.0, 1.0),
2094
- # and setting alpha value in Opacity... try to cope with that too. :((((
2095
- alpha = 1.0 - elem_props_get_number(fbx_props, b'TransparencyFactor', 0.0)
2096
- if (alpha == 1.0 or alpha == 0.0):
2097
- alpha = elem_props_get_number(fbx_props_no_template, b'Opacity', None)
2098
- if alpha is None:
2099
- alpha = 1.0 - elem_props_get_color_rgb(fbx_props, b'TransparentColor', const_color_black)[0]
2100
- ma_wrap.alpha = alpha
2101
- ma_wrap.metallic = elem_props_get_number(fbx_props, b'ReflectionFactor', 0.0)
2102
- # We have no metallic (a.k.a. reflection) color...
2103
- # elem_props_get_color_rgb(fbx_props, b'ReflectionColor', const_color_white)
2104
- ma_wrap.normalmap_strength = elem_props_get_number(fbx_props, b'BumpFactor', 1.0)
2105
- # Emission strength and color
2106
- ma_wrap.emission_strength = elem_props_get_number(fbx_props, b'EmissiveFactor', 1.0)
2107
- ma_wrap.emission_color = elem_props_get_color_rgb(fbx_props, b'EmissiveColor', const_color_black)
2108
-
2109
- nodal_material_wrap_map[ma] = ma_wrap
2110
-
2111
- if settings.use_custom_props:
2112
- blen_read_custom_properties(fbx_obj, ma, settings)
2113
-
2114
- return ma
2115
-
2116
-
2117
- # -------
2118
- # Image & Texture
2119
-
2120
- def blen_read_texture_image(fbx_tmpl, fbx_obj, basedir, settings):
2121
- import os
2122
- from bpy_extras import image_utils
2123
-
2124
- def pack_data_from_content(image, fbx_obj):
2125
- data = elem_find_first_bytes(fbx_obj, b'Content')
2126
- if (data):
2127
- data_len = len(data)
2128
- if (data_len):
2129
- image.pack(data=data, data_len=data_len)
2130
-
2131
- elem_name_utf8 = elem_name_ensure_classes(fbx_obj, {b'Texture', b'Video'})
2132
-
2133
- image_cache = settings.image_cache
2134
-
2135
- # Yet another beautiful logic demonstration by Master FBX:
2136
- # * RelativeFilename in both Video and Texture nodes.
2137
- # * FileName in texture nodes.
2138
- # * Filename in video nodes.
2139
- # Aaaaaaaarrrrrrrrgggggggggggg!!!!!!!!!!!!!!
2140
- filepath = elem_find_first_string(fbx_obj, b'RelativeFilename')
2141
- if filepath:
2142
- # Make sure we do handle a relative path, and not an absolute one (see D5143).
2143
- filepath = filepath.lstrip(os.path.sep).lstrip(os.path.altsep)
2144
- filepath = os.path.join(basedir, filepath)
2145
- else:
2146
- filepath = elem_find_first_string(fbx_obj, b'FileName')
2147
- if not filepath:
2148
- filepath = elem_find_first_string(fbx_obj, b'Filename')
2149
- if not filepath:
2150
- print("Error, could not find any file path in ", fbx_obj)
2151
- print(" Falling back to: ", elem_name_utf8)
2152
- filepath = elem_name_utf8
2153
- else:
2154
- filepath = filepath.replace('\\', '/') if (os.sep == '/') else filepath.replace('/', '\\')
2155
-
2156
- image = image_cache.get(filepath)
2157
- if image is not None:
2158
- # Data is only embedded once, we may have already created the image but still be missing its data!
2159
- if not image.has_data:
2160
- pack_data_from_content(image, fbx_obj)
2161
- return image
2162
-
2163
- image = image_utils.load_image(
2164
- filepath,
2165
- dirname=basedir,
2166
- place_holder=True,
2167
- recursive=settings.use_image_search,
2168
- )
2169
-
2170
- # Try to use embedded data, if available!
2171
- pack_data_from_content(image, fbx_obj)
2172
-
2173
- image_cache[filepath] = image
2174
- # name can be ../a/b/c
2175
- image.name = os.path.basename(elem_name_utf8)
2176
-
2177
- if settings.use_custom_props:
2178
- blen_read_custom_properties(fbx_obj, image, settings)
2179
-
2180
- return image
2181
-
2182
-
2183
- def blen_read_camera(fbx_tmpl, fbx_obj, settings):
2184
- # meters to inches
2185
- M2I = 0.0393700787
2186
-
2187
- global_scale = settings.global_scale
2188
-
2189
- elem_name_utf8 = elem_name_ensure_class(fbx_obj, b'NodeAttribute')
2190
-
2191
- fbx_props = (elem_find_first(fbx_obj, b'Properties70'),
2192
- elem_find_first(fbx_tmpl, b'Properties70', fbx_elem_nil))
2193
-
2194
- camera = bpy.data.cameras.new(name=elem_name_utf8)
2195
-
2196
- camera.type = 'ORTHO' if elem_props_get_enum(fbx_props, b'CameraProjectionType', 0) == 1 else 'PERSP'
2197
-
2198
- camera.dof.focus_distance = elem_props_get_number(fbx_props, b'FocusDistance', 10) * global_scale
2199
- if (elem_props_get_bool(fbx_props, b'UseDepthOfField', False)):
2200
- camera.dof.use_dof = True
2201
-
2202
- camera.lens = elem_props_get_number(fbx_props, b'FocalLength', 35.0)
2203
- camera.sensor_width = elem_props_get_number(fbx_props, b'FilmWidth', 32.0 * M2I) / M2I
2204
- camera.sensor_height = elem_props_get_number(fbx_props, b'FilmHeight', 32.0 * M2I) / M2I
2205
-
2206
- camera.ortho_scale = elem_props_get_number(fbx_props, b'OrthoZoom', 1.0)
2207
-
2208
- filmaspect = camera.sensor_width / camera.sensor_height
2209
- # film offset
2210
- camera.shift_x = elem_props_get_number(fbx_props, b'FilmOffsetX', 0.0) / (M2I * camera.sensor_width)
2211
- camera.shift_y = elem_props_get_number(fbx_props, b'FilmOffsetY', 0.0) / (M2I * camera.sensor_height * filmaspect)
2212
-
2213
- camera.clip_start = elem_props_get_number(fbx_props, b'NearPlane', 0.01) * global_scale
2214
- camera.clip_end = elem_props_get_number(fbx_props, b'FarPlane', 100.0) * global_scale
2215
-
2216
- if settings.use_custom_props:
2217
- blen_read_custom_properties(fbx_obj, camera, settings)
2218
-
2219
- return camera
2220
-
2221
-
2222
- def blen_read_light(fbx_tmpl, fbx_obj, settings):
2223
- import math
2224
- elem_name_utf8 = elem_name_ensure_class(fbx_obj, b'NodeAttribute')
2225
-
2226
- fbx_props = (elem_find_first(fbx_obj, b'Properties70'),
2227
- elem_find_first(fbx_tmpl, b'Properties70', fbx_elem_nil))
2228
-
2229
- light_type = {
2230
- 0: 'POINT',
2231
- 1: 'SUN',
2232
- 2: 'SPOT'}.get(elem_props_get_enum(fbx_props, b'LightType', 0), 'POINT')
2233
-
2234
- lamp = bpy.data.lights.new(name=elem_name_utf8, type=light_type)
2235
-
2236
- if light_type == 'SPOT':
2237
- spot_size = elem_props_get_number(fbx_props, b'OuterAngle', None)
2238
- if spot_size is None:
2239
- # Deprecated.
2240
- spot_size = elem_props_get_number(fbx_props, b'Cone angle', 45.0)
2241
- lamp.spot_size = math.radians(spot_size)
2242
-
2243
- spot_blend = elem_props_get_number(fbx_props, b'InnerAngle', None)
2244
- if spot_blend is None:
2245
- # Deprecated.
2246
- spot_blend = elem_props_get_number(fbx_props, b'HotSpot', 45.0)
2247
- lamp.spot_blend = 1.0 - (spot_blend / spot_size)
2248
-
2249
- # TODO, cycles nodes???
2250
- lamp.color = elem_props_get_color_rgb(fbx_props, b'Color', (1.0, 1.0, 1.0))
2251
- lamp.energy = elem_props_get_number(fbx_props, b'Intensity', 100.0) / 100.0
2252
- lamp.exposure = elem_props_get_number(fbx_props, b'Exposure', 0.0)
2253
- lamp.use_shadow = elem_props_get_bool(fbx_props, b'CastShadow', True)
2254
- if hasattr(lamp, "cycles"):
2255
- lamp.cycles.cast_shadow = lamp.use_shadow
2256
- # Removed but could be restored if the value can be applied.
2257
- # `lamp.shadow_color = elem_props_get_color_rgb(fbx_props, b'ShadowColor', (0.0, 0.0, 0.0))`
2258
-
2259
- if settings.use_custom_props:
2260
- blen_read_custom_properties(fbx_obj, lamp, settings)
2261
-
2262
- return lamp
2263
-
2264
-
2265
- # ### Import Utility class
2266
- class FbxImportHelperNode:
2267
- """
2268
- Temporary helper node to store a hierarchy of fbxNode objects before building Objects, Armatures and Bones.
2269
- It tries to keep the correction data in one place so it can be applied consistently to the imported data.
2270
- """
2271
-
2272
- __slots__ = (
2273
- '_parent', 'anim_compensation_matrix', 'is_global_animation', 'armature_setup', 'armature', 'bind_matrix',
2274
- 'bl_bone', 'bl_data', 'bl_obj', 'bone_child_matrix', 'children', 'clusters',
2275
- 'fbx_elem', 'fbx_data_elem', 'fbx_name', 'fbx_transform_data', 'fbx_type',
2276
- 'is_armature', 'has_bone_children', 'is_bone', 'is_root', 'is_leaf',
2277
- 'matrix', 'matrix_as_parent', 'matrix_geom', 'meshes', 'post_matrix', 'pre_matrix')
2278
-
2279
- def __init__(self, fbx_elem, bl_data, fbx_transform_data, is_bone):
2280
- self.fbx_name = elem_name_ensure_class(fbx_elem, b'Model') if fbx_elem else 'Unknown'
2281
- self.fbx_type = fbx_elem.props[2] if fbx_elem else None
2282
- self.fbx_elem = fbx_elem
2283
- # FBX elem of a connected NodeAttribute/Geometry for helpers whose bl_data
2284
- # does not exist or is yet to be created.
2285
- self.fbx_data_elem = None
2286
- self.bl_obj = None
2287
- self.bl_data = bl_data
2288
- # Name of bone if this is a bone (this may be different to fbx_name if there was a name conflict in Blender!)
2289
- self.bl_bone = None
2290
- self.fbx_transform_data = fbx_transform_data
2291
- self.is_root = False
2292
- self.is_bone = is_bone
2293
- self.is_armature = False
2294
- self.armature = None # For bones only, relevant armature node.
2295
- # True if the hierarchy below this node contains bones, important to support mixed hierarchies.
2296
- self.has_bone_children = False
2297
- # True for leaf-bones added to the end of some bone chains to set the lengths.
2298
- self.is_leaf = False
2299
- self.pre_matrix = None # correction matrix that needs to be applied before the FBX transform
2300
- self.bind_matrix = None # for bones this is the matrix used to bind to the skin
2301
- if fbx_transform_data:
2302
- self.matrix, self.matrix_as_parent, self.matrix_geom = blen_read_object_transform_do(fbx_transform_data)
2303
- else:
2304
- self.matrix, self.matrix_as_parent, self.matrix_geom = (None, None, None)
2305
- self.post_matrix = None # correction matrix that needs to be applied after the FBX transform
2306
- self.bone_child_matrix = None # Objects attached to a bone end not the beginning, this matrix corrects for that
2307
-
2308
- # XXX Those two are to handle the fact that rigged meshes are not linked to their armature in FBX, which implies
2309
- # that their animation is in global space (afaik...).
2310
- # This is actually not really solvable currently, since anim_compensation_matrix is not valid if armature
2311
- # itself is animated (we'd have to recompute global-to-local anim_compensation_matrix for each frame,
2312
- # and for each armature action... beyond being an insane work).
2313
- # Solution for now: do not read rigged meshes animations at all! sic...
2314
- # a mesh moved in the hierarchy may have a different local matrix. This compensates animations for this.
2315
- self.anim_compensation_matrix = None
2316
- self.is_global_animation = False
2317
-
2318
- self.meshes = None # List of meshes influenced by this bone.
2319
- self.clusters = [] # Deformer Cluster nodes
2320
- self.armature_setup = {} # mesh and armature matrix when the mesh was bound
2321
-
2322
- self._parent = None
2323
- self.children = []
2324
-
2325
- @property
2326
- def parent(self):
2327
- return self._parent
2328
-
2329
- @parent.setter
2330
- def parent(self, value):
2331
- if self._parent is not None:
2332
- self._parent.children.remove(self)
2333
- self._parent = value
2334
- if self._parent is not None:
2335
- self._parent.children.append(self)
2336
-
2337
- @property
2338
- def ignore(self):
2339
- # Separating leaf status from ignore status itself.
2340
- # Currently they are equivalent, but this may change in future.
2341
- return self.is_leaf
2342
-
2343
- def __repr__(self):
2344
- if self.fbx_elem:
2345
- return self.fbx_elem.props[1].decode()
2346
- else:
2347
- return "None"
2348
-
2349
- def print_info(self, indent=0):
2350
- print(" " * indent + (self.fbx_name if self.fbx_name else "(Null)")
2351
- + ("[root]" if self.is_root else "")
2352
- + ("[leaf]" if self.is_leaf else "")
2353
- + ("[ignore]" if self.ignore else "")
2354
- + ("[armature]" if self.is_armature else "")
2355
- + ("[bone]" if self.is_bone else "")
2356
- + ("[HBC]" if self.has_bone_children else "")
2357
- )
2358
- for c in self.children:
2359
- c.print_info(indent + 1)
2360
-
2361
- def mark_leaf_bones(self):
2362
- if self.is_bone and len(self.children) == 1:
2363
- child = self.children[0]
2364
- if child.is_bone and len(child.children) == 0:
2365
- child.is_leaf = True
2366
- for child in self.children:
2367
- child.mark_leaf_bones()
2368
-
2369
- def do_bake_transform(self, settings):
2370
- return (settings.bake_space_transform and self.fbx_type in (b'Mesh', b'Null') and
2371
- not self.is_armature and not self.is_bone)
2372
-
2373
- def find_correction_matrix(self, settings, parent_correction_inv=None):
2374
- from bpy_extras.io_utils import axis_conversion
2375
-
2376
- if self.parent and (self.parent.is_root or self.parent.do_bake_transform(settings)):
2377
- self.pre_matrix = settings.global_matrix
2378
-
2379
- if parent_correction_inv:
2380
- self.pre_matrix = parent_correction_inv @ (self.pre_matrix if self.pre_matrix else Matrix())
2381
-
2382
- correction_matrix = None
2383
-
2384
- if self.is_bone:
2385
- if settings.automatic_bone_orientation:
2386
- # find best orientation to align bone with
2387
- bone_children = tuple(child for child in self.children if child.is_bone)
2388
- if len(bone_children) == 0:
2389
- # no children, inherit the correction from parent (if possible)
2390
- if self.parent and self.parent.is_bone:
2391
- correction_matrix = parent_correction_inv.inverted() if parent_correction_inv else None
2392
- else:
2393
- # else find how best to rotate the bone to align the Y axis with the children
2394
- best_axis = (1, 0, 0)
2395
- if len(bone_children) == 1:
2396
- vec = bone_children[0].get_bind_matrix().to_translation()
2397
- best_axis = Vector((0, 0, 1 if vec[2] >= 0 else -1))
2398
- if abs(vec[0]) > abs(vec[1]):
2399
- if abs(vec[0]) > abs(vec[2]):
2400
- best_axis = Vector((1 if vec[0] >= 0 else -1, 0, 0))
2401
- elif abs(vec[1]) > abs(vec[2]):
2402
- best_axis = Vector((0, 1 if vec[1] >= 0 else -1, 0))
2403
- else:
2404
- # get the child directions once because they may be checked several times
2405
- child_locs = (child.get_bind_matrix().to_translation() for child in bone_children)
2406
- child_locs = tuple(loc.normalized() for loc in child_locs if loc.magnitude > 0.0)
2407
-
2408
- # I'm not sure which one I like better...
2409
- if False:
2410
- best_angle = -1.0
2411
- for i in range(6):
2412
- a = i // 2
2413
- s = -1 if i % 2 == 1 else 1
2414
- test_axis = Vector((s if a == 0 else 0, s if a == 1 else 0, s if a == 2 else 0))
2415
-
2416
- # find max angle to children
2417
- max_angle = 1.0
2418
- for loc in child_locs:
2419
- max_angle = min(max_angle, test_axis.dot(loc))
2420
-
2421
- # is it better than the last one?
2422
- if best_angle < max_angle:
2423
- best_angle = max_angle
2424
- best_axis = test_axis
2425
- else:
2426
- best_angle = -1.0
2427
- for vec in child_locs:
2428
- test_axis = Vector((0, 0, 1 if vec[2] >= 0 else -1))
2429
- if abs(vec[0]) > abs(vec[1]):
2430
- if abs(vec[0]) > abs(vec[2]):
2431
- test_axis = Vector((1 if vec[0] >= 0 else -1, 0, 0))
2432
- elif abs(vec[1]) > abs(vec[2]):
2433
- test_axis = Vector((0, 1 if vec[1] >= 0 else -1, 0))
2434
-
2435
- # find max angle to children
2436
- max_angle = 1.0
2437
- for loc in child_locs:
2438
- max_angle = min(max_angle, test_axis.dot(loc))
2439
-
2440
- # is it better than the last one?
2441
- if best_angle < max_angle:
2442
- best_angle = max_angle
2443
- best_axis = test_axis
2444
-
2445
- # convert best_axis to axis string
2446
- to_up = 'Z' if best_axis[2] >= 0 else '-Z'
2447
- if abs(best_axis[0]) > abs(best_axis[1]):
2448
- if abs(best_axis[0]) > abs(best_axis[2]):
2449
- to_up = 'X' if best_axis[0] >= 0 else '-X'
2450
- elif abs(best_axis[1]) > abs(best_axis[2]):
2451
- to_up = 'Y' if best_axis[1] >= 0 else '-Y'
2452
- to_forward = 'X' if to_up not in {'X', '-X'} else 'Y'
2453
-
2454
- # Build correction matrix
2455
- if (to_up, to_forward) != ('Y', 'X'):
2456
- correction_matrix = axis_conversion(from_forward='X',
2457
- from_up='Y',
2458
- to_forward=to_forward,
2459
- to_up=to_up,
2460
- ).to_4x4()
2461
- else:
2462
- correction_matrix = settings.bone_correction_matrix
2463
- else:
2464
- # camera and light can be hard wired
2465
- if self.fbx_type == b'Camera':
2466
- correction_matrix = MAT_CONVERT_CAMERA
2467
- elif self.fbx_type == b'Light':
2468
- correction_matrix = MAT_CONVERT_LIGHT
2469
-
2470
- self.post_matrix = correction_matrix
2471
-
2472
- if self.do_bake_transform(settings):
2473
- self.post_matrix = settings.global_matrix_inv @ (self.post_matrix if self.post_matrix else Matrix())
2474
-
2475
- # process children
2476
- correction_matrix_inv = correction_matrix.inverted_safe() if correction_matrix else None
2477
- for child in self.children:
2478
- child.find_correction_matrix(settings, correction_matrix_inv)
2479
-
2480
- def find_armature_bones(self, armature):
2481
- for child in self.children:
2482
- if child.is_bone:
2483
- child.armature = armature
2484
- child.find_armature_bones(armature)
2485
-
2486
- def find_armatures(self):
2487
- needs_armature = False
2488
- for child in self.children:
2489
- if child.is_bone:
2490
- needs_armature = True
2491
- break
2492
- if needs_armature:
2493
- if self.fbx_type in {b'Null', b'Root'}:
2494
- # if empty then convert into armature
2495
- self.is_armature = True
2496
- armature = self
2497
- else:
2498
- # otherwise insert a new node
2499
- # XXX Maybe in case self is virtual FBX root node, we should instead add one armature per bone child?
2500
- armature = FbxImportHelperNode(None, None, None, False)
2501
- armature.fbx_name = "Armature"
2502
- armature.is_armature = True
2503
-
2504
- for child in tuple(self.children):
2505
- if child.is_bone:
2506
- child.parent = armature
2507
-
2508
- armature.parent = self
2509
-
2510
- armature.find_armature_bones(armature)
2511
-
2512
- for child in self.children:
2513
- if child.is_armature or child.is_bone:
2514
- continue
2515
- child.find_armatures()
2516
-
2517
- def find_bone_children(self):
2518
- has_bone_children = False
2519
- for child in self.children:
2520
- has_bone_children |= child.find_bone_children()
2521
- self.has_bone_children = has_bone_children
2522
- return self.is_bone or has_bone_children
2523
-
2524
- def find_fake_bones(self, in_armature=False):
2525
- if in_armature and not self.is_bone and self.has_bone_children:
2526
- self.is_bone = True
2527
- # if we are not a null node we need an intermediate node for the data
2528
- if self.fbx_type not in {b'Null', b'Root'}:
2529
- node = FbxImportHelperNode(self.fbx_elem, self.bl_data, None, False)
2530
- self.fbx_elem = None
2531
- self.bl_data = None
2532
-
2533
- # transfer children
2534
- for child in self.children:
2535
- if child.is_bone or child.has_bone_children:
2536
- continue
2537
- child.parent = node
2538
-
2539
- # attach to parent
2540
- node.parent = self
2541
-
2542
- if self.is_armature:
2543
- in_armature = True
2544
- for child in self.children:
2545
- child.find_fake_bones(in_armature)
2546
-
2547
- def get_world_matrix_as_parent(self):
2548
- matrix = self.parent.get_world_matrix_as_parent() if self.parent else Matrix()
2549
- if self.matrix_as_parent:
2550
- matrix = matrix @ self.matrix_as_parent
2551
- return matrix
2552
-
2553
- def get_world_matrix(self):
2554
- matrix = self.parent.get_world_matrix_as_parent() if self.parent else Matrix()
2555
- if self.matrix:
2556
- matrix = matrix @ self.matrix
2557
- return matrix
2558
-
2559
- def get_matrix(self):
2560
- matrix = self.matrix if self.matrix else Matrix()
2561
- if self.pre_matrix:
2562
- matrix = self.pre_matrix @ matrix
2563
- if self.post_matrix:
2564
- matrix = matrix @ self.post_matrix
2565
- return matrix
2566
-
2567
- def get_bind_matrix(self):
2568
- matrix = self.bind_matrix if self.bind_matrix else Matrix()
2569
- if self.pre_matrix:
2570
- matrix = self.pre_matrix @ matrix
2571
- if self.post_matrix:
2572
- matrix = matrix @ self.post_matrix
2573
- return matrix
2574
-
2575
- def make_bind_pose_local(self, parent_matrix=None):
2576
- if parent_matrix is None:
2577
- parent_matrix = Matrix()
2578
-
2579
- if self.bind_matrix:
2580
- bind_matrix = parent_matrix.inverted_safe() @ self.bind_matrix
2581
- else:
2582
- bind_matrix = self.matrix.copy() if self.matrix else None
2583
-
2584
- self.bind_matrix = bind_matrix
2585
- if bind_matrix:
2586
- parent_matrix = parent_matrix @ bind_matrix
2587
-
2588
- for child in self.children:
2589
- child.make_bind_pose_local(parent_matrix)
2590
-
2591
- def collect_skeleton_meshes(self, meshes):
2592
- for _, m in self.clusters:
2593
- meshes.update(m)
2594
- for child in self.children:
2595
- if not child.meshes:
2596
- child.collect_skeleton_meshes(meshes)
2597
-
2598
- def collect_armature_meshes(self):
2599
- if self.is_armature:
2600
- armature_matrix_inv = self.get_world_matrix().inverted_safe()
2601
-
2602
- meshes = set()
2603
- for child in self.children:
2604
- # Children meshes may be linked to children armatures, in which case we do not want to link them
2605
- # to a parent one. See T70244.
2606
- child.collect_armature_meshes()
2607
- if not child.meshes:
2608
- child.collect_skeleton_meshes(meshes)
2609
- for m in meshes:
2610
- old_matrix = m.matrix
2611
- m.matrix = armature_matrix_inv @ m.get_world_matrix()
2612
- m.anim_compensation_matrix = old_matrix.inverted_safe() @ m.matrix
2613
- m.is_global_animation = True
2614
- m.parent = self
2615
- self.meshes = meshes
2616
- else:
2617
- for child in self.children:
2618
- child.collect_armature_meshes()
2619
-
2620
- def build_skeleton(self, arm, parent_matrix, settings, parent_bone_size=1):
2621
- def child_connect(par_bone, child_bone, child_head, connect_ctx):
2622
- # child_bone or child_head may be None.
2623
- force_connect_children, connected = connect_ctx
2624
- if child_bone is not None:
2625
- child_bone.parent = par_bone
2626
- child_head = child_bone.head
2627
-
2628
- if similar_values_iter(par_bone.tail, child_head):
2629
- if child_bone is not None:
2630
- child_bone.use_connect = True
2631
- # Disallow any force-connection at this level from now on, since that child was 'really'
2632
- # connected, we do not want to move current bone's tail anymore!
2633
- connected = None
2634
- elif force_connect_children and connected is not None:
2635
- # We only store position where tail of par_bone should be in the end.
2636
- # Actual tail moving and force connection of compatible child bones will happen
2637
- # once all have been checked.
2638
- if connected is ...:
2639
- connected = ([child_head.copy(), 1], [child_bone] if child_bone is not None else [])
2640
- else:
2641
- connected[0][0] += child_head
2642
- connected[0][1] += 1
2643
- if child_bone is not None:
2644
- connected[1].append(child_bone)
2645
- connect_ctx[1] = connected
2646
-
2647
- def child_connect_finalize(par_bone, connect_ctx):
2648
- force_connect_children, connected = connect_ctx
2649
- # Do nothing if force connection is not enabled!
2650
- if force_connect_children and connected is not None and connected is not ...:
2651
- # Here again we have to be wary about zero-length bones!!!
2652
- par_tail = connected[0][0] / connected[0][1]
2653
- if (par_tail - par_bone.head).magnitude < 1e-2:
2654
- par_bone_vec = (par_bone.tail - par_bone.head).normalized()
2655
- par_tail = par_bone.head + par_bone_vec * 0.01
2656
- par_bone.tail = par_tail
2657
- for child_bone in connected[1]:
2658
- if similar_values_iter(par_tail, child_bone.head):
2659
- child_bone.use_connect = True
2660
-
2661
- # Create the (edit)bone.
2662
- bone = arm.bl_data.edit_bones.new(name=self.fbx_name)
2663
- bone.select = True
2664
- self.bl_obj = arm.bl_obj
2665
- self.bl_data = arm.bl_data
2666
- self.bl_bone = bone.name # Could be different from the FBX name!
2667
- # Read EditBone custom props the NodeAttribute
2668
- if settings.use_custom_props and self.fbx_data_elem:
2669
- blen_read_custom_properties(self.fbx_data_elem, bone, settings)
2670
-
2671
- # get average distance to children
2672
- bone_size = 0.0
2673
- bone_count = 0
2674
- for child in self.children:
2675
- if child.is_bone:
2676
- bone_size += child.get_bind_matrix().to_translation().magnitude
2677
- bone_count += 1
2678
- if bone_count > 0:
2679
- bone_size /= bone_count
2680
- else:
2681
- bone_size = parent_bone_size
2682
-
2683
- # So that our bone gets its final length, but still Y-aligned in armature space.
2684
- # 0-length bones are automatically collapsed into their parent when you leave edit mode,
2685
- # so this enforces a minimum length.
2686
- bone_tail = Vector((0.0, 1.0, 0.0)) * max(0.01, bone_size)
2687
- bone.tail = bone_tail
2688
-
2689
- # And rotate/move it to its final "rest pose".
2690
- bone_matrix = parent_matrix @ self.get_bind_matrix().normalized()
2691
-
2692
- bone.matrix = bone_matrix
2693
-
2694
- force_connect_children = settings.force_connect_children
2695
-
2696
- connect_ctx = [force_connect_children, ...]
2697
- for child in self.children:
2698
- if child.is_leaf and force_connect_children:
2699
- # Arggggggggggggggggg! We do not want to create this bone, but we need its 'virtual head' location
2700
- # to orient current one!!!
2701
- child_head = (bone_matrix @ child.get_bind_matrix().normalized()).translation
2702
- child_connect(bone, None, child_head, connect_ctx)
2703
- elif child.is_bone and not child.ignore:
2704
- child_bone = child.build_skeleton(arm, bone_matrix, settings, bone_size)
2705
- # Connection to parent.
2706
- child_connect(bone, child_bone, None, connect_ctx)
2707
-
2708
- child_connect_finalize(bone, connect_ctx)
2709
-
2710
- # Correction for children attached to a bone. FBX expects to attach to the head of a bone, while Blender
2711
- # attaches to the tail.
2712
- if force_connect_children:
2713
- # When forcefully connecting, the bone's tail position may be changed, which can change both the bone's
2714
- # rotation and its length.
2715
- # Set the correction matrix such that it transforms the current tail transformation back to the original
2716
- # head transformation.
2717
- head_to_origin = bone.matrix.inverted_safe()
2718
- tail_to_head = Matrix.Translation(bone.head - bone.tail)
2719
- origin_to_original_head = bone_matrix
2720
- tail_to_original_head = head_to_origin @ tail_to_head @ origin_to_original_head
2721
- self.bone_child_matrix = tail_to_original_head
2722
- else:
2723
- self.bone_child_matrix = Matrix.Translation(-bone_tail)
2724
-
2725
- return bone
2726
-
2727
- def build_node_obj(self, fbx_tmpl, settings):
2728
- if self.bl_obj:
2729
- return self.bl_obj
2730
-
2731
- if self.is_bone or not self.fbx_elem:
2732
- return None
2733
-
2734
- # create when linking since we need object data
2735
- elem_name_utf8 = self.fbx_name
2736
-
2737
- # Object data must be created already
2738
- self.bl_obj = obj = bpy.data.objects.new(name=elem_name_utf8, object_data=self.bl_data)
2739
-
2740
- fbx_props = (elem_find_first(self.fbx_elem, b'Properties70'),
2741
- elem_find_first(fbx_tmpl, b'Properties70', fbx_elem_nil))
2742
-
2743
- # ----
2744
- # Misc Attributes
2745
-
2746
- obj.color[0:3] = elem_props_get_color_rgb(fbx_props, b'Color', (0.8, 0.8, 0.8))
2747
- obj.hide_viewport = not bool(elem_props_get_visibility(fbx_props, b'Visibility', 1.0))
2748
-
2749
- obj.matrix_basis = self.get_matrix()
2750
-
2751
- if settings.use_custom_props:
2752
- blen_read_custom_properties(self.fbx_elem, obj, settings)
2753
-
2754
- return obj
2755
-
2756
- def build_skeleton_children(self, fbx_tmpl, settings, scene, view_layer):
2757
- if self.is_bone:
2758
- for child in self.children:
2759
- if child.ignore:
2760
- continue
2761
- child.build_skeleton_children(fbx_tmpl, settings, scene, view_layer)
2762
- return None
2763
- else:
2764
- # child is not a bone
2765
- obj = self.build_node_obj(fbx_tmpl, settings)
2766
-
2767
- if obj is None:
2768
- return None
2769
-
2770
- for child in self.children:
2771
- if child.ignore:
2772
- continue
2773
- child.build_skeleton_children(fbx_tmpl, settings, scene, view_layer)
2774
-
2775
- # instance in scene
2776
- view_layer.active_layer_collection.collection.objects.link(obj)
2777
- obj.select_set(True)
2778
-
2779
- return obj
2780
-
2781
- def link_skeleton_children(self, fbx_tmpl, settings, scene):
2782
- if self.is_bone:
2783
- for child in self.children:
2784
- if child.ignore:
2785
- continue
2786
- child_obj = child.bl_obj
2787
- if child_obj and child_obj != self.bl_obj:
2788
- child_obj.parent = self.bl_obj # get the armature the bone belongs to
2789
- child_obj.parent_bone = self.bl_bone
2790
- child_obj.parent_type = 'BONE'
2791
- child_obj.matrix_parent_inverse = Matrix()
2792
-
2793
- # Blender attaches to the end of a bone, while FBX attaches to the start.
2794
- # bone_child_matrix corrects for that.
2795
- if child.pre_matrix:
2796
- child.pre_matrix = self.bone_child_matrix @ child.pre_matrix
2797
- else:
2798
- child.pre_matrix = self.bone_child_matrix
2799
-
2800
- child_obj.matrix_basis = child.get_matrix()
2801
- child.link_skeleton_children(fbx_tmpl, settings, scene)
2802
- return None
2803
- else:
2804
- obj = self.bl_obj
2805
-
2806
- for child in self.children:
2807
- if child.ignore:
2808
- continue
2809
- child_obj = child.link_skeleton_children(fbx_tmpl, settings, scene)
2810
- if child_obj:
2811
- child_obj.parent = obj
2812
-
2813
- return obj
2814
-
2815
- def set_pose_matrix_and_custom_props(self, arm, settings):
2816
- pose_bone = arm.bl_obj.pose.bones[self.bl_bone]
2817
- pose_bone.matrix_basis = self.get_bind_matrix().inverted_safe() @ self.get_matrix()
2818
-
2819
- # `self.fbx_elem` can be `None` in cases where the imported hierarchy contains a mix of bone and non-bone FBX
2820
- # Nodes parented to one another, e.g. "bone1"->"mesh1"->"bone2". In Blender, an Armature can only consist of
2821
- # bones, so to maintain the imported hierarchy, a placeholder bone with the same name as "mesh1" is inserted
2822
- # into the Armature and then the imported "mesh1" Object is parented to the placeholder bone. The placeholder
2823
- # bone won't have a `self.fbx_elem` because it belongs to the "mesh1" Object instead.
2824
- # See FbxImportHelperNode.find_fake_bones().
2825
- if settings.use_custom_props and self.fbx_elem:
2826
- blen_read_custom_properties(self.fbx_elem, pose_bone, settings)
2827
-
2828
- for child in self.children:
2829
- if child.ignore:
2830
- continue
2831
- if child.is_bone:
2832
- child.set_pose_matrix_and_custom_props(arm, settings)
2833
-
2834
- def merge_weights(self, combined_weights, fbx_cluster):
2835
- indices = elem_prop_first(elem_find_first(fbx_cluster, b'Indexes', default=None), default=())
2836
- weights = elem_prop_first(elem_find_first(fbx_cluster, b'Weights', default=None), default=())
2837
-
2838
- for index, weight in zip(indices, weights):
2839
- w = combined_weights.get(index)
2840
- if w is None:
2841
- combined_weights[index] = [weight]
2842
- else:
2843
- w.append(weight)
2844
-
2845
- def set_bone_weights(self):
2846
- ignored_children = tuple(child for child in self.children
2847
- if child.is_bone and child.ignore and len(child.clusters) > 0)
2848
-
2849
- if len(ignored_children) > 0:
2850
- # If we have an ignored child bone we need to merge their weights into the current bone weights.
2851
- # This can happen both intentionally and accidentally when skinning a model. Either way, they
2852
- # need to be moved into a parent bone or they cause animation glitches.
2853
- for fbx_cluster, meshes in self.clusters:
2854
- combined_weights = {}
2855
- self.merge_weights(combined_weights, fbx_cluster)
2856
-
2857
- for child in ignored_children:
2858
- for child_cluster, child_meshes in child.clusters:
2859
- if not meshes.isdisjoint(child_meshes):
2860
- self.merge_weights(combined_weights, child_cluster)
2861
-
2862
- # combine child weights
2863
- indices = []
2864
- weights = []
2865
- for i, w in combined_weights.items():
2866
- indices.append(i)
2867
- if len(w) > 1:
2868
- # Add ignored child weights to the current bone's weight.
2869
- # XXX - Weights that sum to more than 1.0 get clamped to 1.0 when set in the vertex group.
2870
- weights.append(sum(w))
2871
- else:
2872
- weights.append(w[0])
2873
-
2874
- add_vgroup_to_objects(indices, weights, self.bl_bone, [node.bl_obj for node in meshes])
2875
-
2876
- # clusters that drive meshes not included in a parent don't need to be merged
2877
- all_meshes = set().union(*[meshes for _, meshes in self.clusters])
2878
- for child in ignored_children:
2879
- for child_cluster, child_meshes in child.clusters:
2880
- if all_meshes.isdisjoint(child_meshes):
2881
- indices = elem_prop_first(elem_find_first(child_cluster, b'Indexes', default=None), default=())
2882
- weights = elem_prop_first(elem_find_first(child_cluster, b'Weights', default=None), default=())
2883
- add_vgroup_to_objects(indices, weights, self.bl_bone, [node.bl_obj for node in child_meshes])
2884
- else:
2885
- # set the vertex weights on meshes
2886
- for fbx_cluster, meshes in self.clusters:
2887
- indices = elem_prop_first(elem_find_first(fbx_cluster, b'Indexes', default=None), default=())
2888
- weights = elem_prop_first(elem_find_first(fbx_cluster, b'Weights', default=None), default=())
2889
- add_vgroup_to_objects(indices, weights, self.bl_bone, [node.bl_obj for node in meshes])
2890
-
2891
- for child in self.children:
2892
- if child.is_bone and not child.ignore:
2893
- child.set_bone_weights()
2894
-
2895
- def build_hierarchy(self, fbx_tmpl, settings, scene, view_layer):
2896
- if self.is_armature:
2897
- # create when linking since we need object data
2898
- elem_name_utf8 = self.fbx_name
2899
-
2900
- self.bl_data = arm_data = bpy.data.armatures.new(name=elem_name_utf8)
2901
-
2902
- # Object data must be created already
2903
- self.bl_obj = arm = bpy.data.objects.new(name=elem_name_utf8, object_data=arm_data)
2904
-
2905
- arm.matrix_basis = self.get_matrix()
2906
-
2907
- if self.fbx_elem:
2908
- fbx_props = (elem_find_first(self.fbx_elem, b'Properties70'),
2909
- elem_find_first(fbx_tmpl, b'Properties70', fbx_elem_nil))
2910
-
2911
- if settings.use_custom_props:
2912
- # Read Armature Object custom props from the Node
2913
- blen_read_custom_properties(self.fbx_elem, arm, settings)
2914
-
2915
- if self.fbx_data_elem:
2916
- # Read Armature Data custom props from the NodeAttribute
2917
- blen_read_custom_properties(self.fbx_data_elem, arm_data, settings)
2918
-
2919
- # instance in scene
2920
- view_layer.active_layer_collection.collection.objects.link(arm)
2921
- arm.select_set(True)
2922
-
2923
- # Add bones:
2924
-
2925
- # Switch to Edit mode.
2926
- view_layer.objects.active = arm
2927
- is_hidden = arm.hide_viewport
2928
- arm.hide_viewport = False # Can't switch to Edit mode hidden objects...
2929
- bpy.ops.object.mode_set(mode='EDIT')
2930
-
2931
- for child in self.children:
2932
- if child.ignore:
2933
- continue
2934
- if child.is_bone:
2935
- child.build_skeleton(self, Matrix(), settings)
2936
-
2937
- bpy.ops.object.mode_set(mode='OBJECT')
2938
-
2939
- arm.hide_viewport = is_hidden
2940
-
2941
- # Set pose matrix and PoseBone custom properties
2942
- for child in self.children:
2943
- if child.ignore:
2944
- continue
2945
- if child.is_bone:
2946
- child.set_pose_matrix_and_custom_props(self, settings)
2947
-
2948
- # Add bone children:
2949
- for child in self.children:
2950
- if child.ignore:
2951
- continue
2952
- child_obj = child.build_skeleton_children(fbx_tmpl, settings, scene, view_layer)
2953
-
2954
- return arm
2955
- elif self.fbx_elem and not self.is_bone:
2956
- obj = self.build_node_obj(fbx_tmpl, settings)
2957
-
2958
- # walk through children
2959
- for child in self.children:
2960
- child.build_hierarchy(fbx_tmpl, settings, scene, view_layer)
2961
-
2962
- # instance in scene
2963
- view_layer.active_layer_collection.collection.objects.link(obj)
2964
- obj.select_set(True)
2965
-
2966
- return obj
2967
- else:
2968
- for child in self.children:
2969
- child.build_hierarchy(fbx_tmpl, settings, scene, view_layer)
2970
-
2971
- return None
2972
-
2973
- def link_hierarchy(self, fbx_tmpl, settings, scene):
2974
- if self.is_armature:
2975
- arm = self.bl_obj
2976
-
2977
- # Link bone children:
2978
- for child in self.children:
2979
- if child.ignore:
2980
- continue
2981
- child_obj = child.link_skeleton_children(fbx_tmpl, settings, scene)
2982
- if child_obj:
2983
- child_obj.parent = arm
2984
-
2985
- # Add armature modifiers to the meshes
2986
- if self.meshes:
2987
- for mesh in self.meshes:
2988
- (mmat, amat) = mesh.armature_setup[self]
2989
- me_obj = mesh.bl_obj
2990
-
2991
- # bring global armature & mesh matrices into *Blender* global space.
2992
- # Note: Usage of matrix_geom (local 'diff' transform) here is quite brittle.
2993
- # Among other things, why in hell isn't it taken into account by bindpose & co???
2994
- # Probably because org app (max) handles it completely aside from any parenting stuff,
2995
- # which we obviously cannot do in Blender. :/
2996
- if amat is None:
2997
- amat = self.bind_matrix
2998
- amat = settings.global_matrix @ (Matrix() if amat is None else amat)
2999
- if self.matrix_geom:
3000
- amat = amat @ self.matrix_geom
3001
- mmat = settings.global_matrix @ mmat
3002
- if mesh.matrix_geom:
3003
- mmat = mmat @ mesh.matrix_geom
3004
-
3005
- # Now that we have armature and mesh in there (global) bind 'state' (matrix),
3006
- # we can compute inverse parenting matrix of the mesh.
3007
- me_obj.matrix_parent_inverse = amat.inverted_safe() @ mmat @ me_obj.matrix_basis.inverted_safe()
3008
-
3009
- mod = mesh.bl_obj.modifiers.new(arm.name, 'ARMATURE')
3010
- mod.object = arm
3011
-
3012
- # Add bone weights to the deformers
3013
- for child in self.children:
3014
- if child.ignore:
3015
- continue
3016
- if child.is_bone:
3017
- child.set_bone_weights()
3018
-
3019
- return arm
3020
- elif self.bl_obj:
3021
- obj = self.bl_obj
3022
-
3023
- # walk through children
3024
- for child in self.children:
3025
- child_obj = child.link_hierarchy(fbx_tmpl, settings, scene)
3026
- if child_obj:
3027
- child_obj.parent = obj
3028
-
3029
- return obj
3030
- else:
3031
- for child in self.children:
3032
- child.link_hierarchy(fbx_tmpl, settings, scene)
3033
-
3034
- return None
3035
-
3036
-
3037
- def load(operator, context, filepath="",
3038
- use_manual_orientation=False,
3039
- axis_forward='-Z',
3040
- axis_up='Y',
3041
- global_scale=1.0,
3042
- bake_space_transform=False,
3043
- use_custom_normals=True,
3044
- use_image_search=False,
3045
- use_alpha_decals=False,
3046
- decal_offset=0.0,
3047
- use_anim=True,
3048
- anim_offset=1.0,
3049
- use_subsurf=False,
3050
- use_custom_props=True,
3051
- use_custom_props_enum_as_string=True,
3052
- ignore_leaf_bones=False,
3053
- force_connect_children=False,
3054
- automatic_bone_orientation=False,
3055
- primary_bone_axis='Y',
3056
- secondary_bone_axis='X',
3057
- use_prepost_rot=True,
3058
- colors_type='SRGB',
3059
- mtl_name_collision_mode="MAKE_UNIQUE"):
3060
-
3061
- global fbx_elem_nil
3062
- fbx_elem_nil = FBXElem('', (), (), ())
3063
-
3064
- import os
3065
- import time
3066
- from bpy_extras.io_utils import axis_conversion
3067
-
3068
- from . import parse_fbx
3069
- from .fbx_utils import RIGHT_HAND_AXES, FBX_FRAMERATES
3070
-
3071
- start_time_proc = time.process_time()
3072
- start_time_sys = time.time()
3073
-
3074
- perfmon = PerfMon()
3075
- perfmon.level_up()
3076
- perfmon.step("FBX Import: start importing %s" % filepath)
3077
- perfmon.level_up()
3078
-
3079
- # Detect ASCII files.
3080
-
3081
- # Typically it's bad practice to fail silently on any error,
3082
- # however the file may fail to read for many reasons,
3083
- # and this situation is handled later in the code,
3084
- # right now we only want to know if the file successfully reads as ascii.
3085
- try:
3086
- with open(filepath, 'r', encoding="utf-8") as fh:
3087
- fh.read(24)
3088
- is_ascii = True
3089
- except Exception:
3090
- is_ascii = False
3091
-
3092
- if is_ascii:
3093
- operator.report({'ERROR'}, rpt_("ASCII FBX files are not supported %r") % filepath)
3094
- return {'CANCELLED'}
3095
- del is_ascii
3096
- # End ascii detection.
3097
-
3098
- try:
3099
- elem_root, version = parse_fbx.parse(filepath)
3100
- except Exception as e:
3101
- import traceback
3102
- traceback.print_exc()
3103
-
3104
- operator.report({'ERROR'}, rpt_("Couldn't open file %r (%s)") % (filepath, e))
3105
- return {'CANCELLED'}
3106
-
3107
- if version < 7100:
3108
- operator.report({'ERROR'}, rpt_("Version %r unsupported, must be %r or later") % (version, 7100))
3109
- return {'CANCELLED'}
3110
-
3111
- print("FBX version: %r" % version)
3112
-
3113
- if bpy.ops.object.mode_set.poll():
3114
- bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
3115
-
3116
- # deselect all
3117
- if bpy.ops.object.select_all.poll():
3118
- bpy.ops.object.select_all(action='DESELECT')
3119
-
3120
- basedir = os.path.dirname(filepath)
3121
-
3122
- nodal_material_wrap_map = {}
3123
- image_cache = {}
3124
-
3125
- # Tables: (FBX_byte_id -> [FBX_data, None or Blender_datablock])
3126
- fbx_table_nodes = {}
3127
-
3128
- if use_alpha_decals:
3129
- material_decals = set()
3130
- else:
3131
- material_decals = None
3132
-
3133
- scene = context.scene
3134
- view_layer = context.view_layer
3135
-
3136
- # #### Get some info from GlobalSettings.
3137
-
3138
- perfmon.step("FBX import: Prepare...")
3139
-
3140
- fbx_settings = elem_find_first(elem_root, b'GlobalSettings')
3141
- fbx_settings_props = elem_find_first(fbx_settings, b'Properties70')
3142
- if fbx_settings is None or fbx_settings_props is None:
3143
- operator.report({'ERROR'}, rpt_("No 'GlobalSettings' found in file %r") % filepath)
3144
- return {'CANCELLED'}
3145
-
3146
- # FBX default base unit seems to be the centimeter, while raw Blender Unit is equivalent to the meter...
3147
- unit_scale = elem_props_get_number(fbx_settings_props, b'UnitScaleFactor', 1.0)
3148
- unit_scale_org = elem_props_get_number(fbx_settings_props, b'OriginalUnitScaleFactor', 1.0)
3149
- global_scale *= (unit_scale / units_blender_to_fbx_factor(context.scene))
3150
- # Compute global matrix and scale.
3151
- if not use_manual_orientation:
3152
- axis_forward = (elem_props_get_integer(fbx_settings_props, b'FrontAxis', 1),
3153
- elem_props_get_integer(fbx_settings_props, b'FrontAxisSign', 1))
3154
- axis_up = (elem_props_get_integer(fbx_settings_props, b'UpAxis', 2),
3155
- elem_props_get_integer(fbx_settings_props, b'UpAxisSign', 1))
3156
- axis_coord = (elem_props_get_integer(fbx_settings_props, b'CoordAxis', 0),
3157
- elem_props_get_integer(fbx_settings_props, b'CoordAxisSign', 1))
3158
- axis_key = (axis_up, axis_forward, axis_coord)
3159
- axis_up, axis_forward = {v: k for k, v in RIGHT_HAND_AXES.items()}.get(axis_key, ('Z', 'Y'))
3160
- global_matrix = (Matrix.Scale(global_scale, 4) @
3161
- axis_conversion(from_forward=axis_forward, from_up=axis_up).to_4x4())
3162
-
3163
- # To cancel out unwanted rotation/scale on nodes.
3164
- global_matrix_inv = global_matrix.inverted()
3165
- # For transforming mesh normals.
3166
- global_matrix_inv_transposed = global_matrix_inv.transposed()
3167
-
3168
- # Compute bone correction matrix
3169
- bone_correction_matrix = None # None means no correction/identity
3170
- if not automatic_bone_orientation:
3171
- if (primary_bone_axis, secondary_bone_axis) != ('Y', 'X'):
3172
- bone_correction_matrix = axis_conversion(from_forward='X',
3173
- from_up='Y',
3174
- to_forward=secondary_bone_axis,
3175
- to_up=primary_bone_axis,
3176
- ).to_4x4()
3177
-
3178
- # Compute framerate settings.
3179
- custom_fps = elem_props_get_number(fbx_settings_props, b'CustomFrameRate', 25.0)
3180
- time_mode = elem_props_get_enum(fbx_settings_props, b'TimeMode')
3181
- real_fps = {eid: val for val, eid in FBX_FRAMERATES[1:]}.get(time_mode, custom_fps)
3182
- if real_fps <= 0.0:
3183
- real_fps = 25.0
3184
- scene.render.fps = round(real_fps)
3185
- scene.render.fps_base = scene.render.fps / real_fps
3186
-
3187
- # store global settings that need to be accessed during conversion
3188
- settings = FBXImportSettings(
3189
- operator.report, (axis_up, axis_forward), global_matrix, global_scale,
3190
- bake_space_transform, global_matrix_inv, global_matrix_inv_transposed,
3191
- use_custom_normals, use_image_search,
3192
- use_alpha_decals, decal_offset,
3193
- use_anim, anim_offset,
3194
- use_subsurf,
3195
- use_custom_props, use_custom_props_enum_as_string,
3196
- nodal_material_wrap_map, image_cache,
3197
- ignore_leaf_bones, force_connect_children, automatic_bone_orientation, bone_correction_matrix,
3198
- use_prepost_rot, colors_type, mtl_name_collision_mode,
3199
- )
3200
-
3201
- # #### And now, the "real" data.
3202
-
3203
- perfmon.step("FBX import: Templates...")
3204
-
3205
- fbx_defs = elem_find_first(elem_root, b'Definitions') # can be None
3206
- fbx_nodes = elem_find_first(elem_root, b'Objects')
3207
- fbx_connections = elem_find_first(elem_root, b'Connections')
3208
-
3209
- if fbx_nodes is None:
3210
- operator.report({'ERROR'}, rpt_("No 'Objects' found in file %r") % filepath)
3211
- return {'CANCELLED'}
3212
- if fbx_connections is None:
3213
- operator.report({'ERROR'}, rpt_("No 'Connections' found in file %r") % filepath)
3214
- return {'CANCELLED'}
3215
-
3216
- # ----
3217
- # First load property templates
3218
- # Load 'PropertyTemplate' values.
3219
- # Key is a tuple, (ObjectType, FBXNodeType)
3220
- # eg, (b'Texture', b'KFbxFileTexture')
3221
- # (b'Geometry', b'KFbxMesh')
3222
- fbx_templates = {}
3223
-
3224
- def _():
3225
- if fbx_defs is not None:
3226
- for fbx_def in fbx_defs.elems:
3227
- if fbx_def.id == b'ObjectType':
3228
- for fbx_subdef in fbx_def.elems:
3229
- if fbx_subdef.id == b'PropertyTemplate':
3230
- assert(fbx_def.props_type == b'S')
3231
- assert(fbx_subdef.props_type == b'S')
3232
- # (b'Texture', b'KFbxFileTexture') - eg.
3233
- key = fbx_def.props[0], fbx_subdef.props[0]
3234
- fbx_templates[key] = fbx_subdef
3235
- _()
3236
- del _
3237
-
3238
- def fbx_template_get(key):
3239
- ret = fbx_templates.get(key, fbx_elem_nil)
3240
- if ret is fbx_elem_nil:
3241
- # Newest FBX (7.4 and above) use no more 'K' in their type names...
3242
- key = (key[0], key[1][1:])
3243
- return fbx_templates.get(key, fbx_elem_nil)
3244
- return ret
3245
-
3246
- perfmon.step("FBX import: Nodes...")
3247
-
3248
- # ----
3249
- # Build FBX node-table
3250
- def _():
3251
- for fbx_obj in fbx_nodes.elems:
3252
- # TODO, investigate what other items after first 3 may be
3253
- assert(fbx_obj.props_type[:3] == b'LSS')
3254
- fbx_uuid = elem_uuid(fbx_obj)
3255
- fbx_table_nodes[fbx_uuid] = [fbx_obj, None]
3256
- _()
3257
- del _
3258
-
3259
- # ----
3260
- # Load in the data
3261
- # http://download.autodesk.com/us/fbx/20112/FBX_SDK_HELP/index.html?url=
3262
- # WS73099cc142f487551fea285e1221e4f9ff8-7fda.htm,topicNumber=d0e6388
3263
-
3264
- perfmon.step("FBX import: Connections...")
3265
-
3266
- fbx_connection_map = {}
3267
- fbx_connection_map_reverse = {}
3268
-
3269
- def _():
3270
- for fbx_link in fbx_connections.elems:
3271
- c_type = fbx_link.props[0]
3272
- if fbx_link.props_type[1:3] == b'LL':
3273
- c_src, c_dst = fbx_link.props[1:3]
3274
- fbx_connection_map.setdefault(c_src, []).append((c_dst, fbx_link))
3275
- fbx_connection_map_reverse.setdefault(c_dst, []).append((c_src, fbx_link))
3276
- _()
3277
- del _
3278
-
3279
- perfmon.step("FBX import: Meshes...")
3280
-
3281
- # ----
3282
- # Load mesh data
3283
- def _():
3284
- fbx_tmpl = fbx_template_get((b'Geometry', b'KFbxMesh'))
3285
-
3286
- for fbx_uuid, fbx_item in fbx_table_nodes.items():
3287
- fbx_obj, blen_data = fbx_item
3288
- if fbx_obj.id != b'Geometry':
3289
- continue
3290
- if fbx_obj.props[-1] == b'Mesh':
3291
- assert(blen_data is None)
3292
- fbx_item[1] = blen_read_geom(fbx_tmpl, fbx_obj, settings)
3293
- _()
3294
- del _
3295
-
3296
- perfmon.step("FBX import: Materials & Textures...")
3297
-
3298
- # ----
3299
- # Load material data
3300
- def _():
3301
- fbx_tmpl = fbx_template_get((b'Material', b'KFbxSurfacePhong'))
3302
- # b'KFbxSurfaceLambert'
3303
-
3304
- for fbx_uuid, fbx_item in fbx_table_nodes.items():
3305
- fbx_obj, blen_data = fbx_item
3306
- if fbx_obj.id != b'Material':
3307
- continue
3308
- assert(blen_data is None)
3309
- fbx_item[1] = blen_read_material(fbx_tmpl, fbx_obj, settings)
3310
- _()
3311
- del _
3312
-
3313
- # ----
3314
- # Load image & textures data
3315
- def _():
3316
- fbx_tmpl_tex = fbx_template_get((b'Texture', b'KFbxFileTexture'))
3317
- fbx_tmpl_img = fbx_template_get((b'Video', b'KFbxVideo'))
3318
-
3319
- # Important to run all 'Video' ones first, embedded images are stored in those nodes.
3320
- # XXX Note we simplify things here, assuming both matching Video and Texture will use same file path,
3321
- # this may be a bit weak, if issue arise we'll fallback to plain connection stuff...
3322
- for fbx_uuid, fbx_item in fbx_table_nodes.items():
3323
- fbx_obj, blen_data = fbx_item
3324
- if fbx_obj.id != b'Video':
3325
- continue
3326
- fbx_item[1] = blen_read_texture_image(fbx_tmpl_img, fbx_obj, basedir, settings)
3327
- for fbx_uuid, fbx_item in fbx_table_nodes.items():
3328
- fbx_obj, blen_data = fbx_item
3329
- if fbx_obj.id != b'Texture':
3330
- continue
3331
- fbx_item[1] = blen_read_texture_image(fbx_tmpl_tex, fbx_obj, basedir, settings)
3332
- _()
3333
- del _
3334
-
3335
- perfmon.step("FBX import: Cameras & Lamps...")
3336
-
3337
- # ----
3338
- # Load camera data
3339
- def _():
3340
- fbx_tmpl = fbx_template_get((b'NodeAttribute', b'KFbxCamera'))
3341
-
3342
- for fbx_uuid, fbx_item in fbx_table_nodes.items():
3343
- fbx_obj, blen_data = fbx_item
3344
- if fbx_obj.id != b'NodeAttribute':
3345
- continue
3346
- if fbx_obj.props[-1] == b'Camera':
3347
- assert(blen_data is None)
3348
- fbx_item[1] = blen_read_camera(fbx_tmpl, fbx_obj, settings)
3349
- _()
3350
- del _
3351
-
3352
- # ----
3353
- # Load lamp data
3354
- def _():
3355
- fbx_tmpl = fbx_template_get((b'NodeAttribute', b'KFbxLight'))
3356
-
3357
- for fbx_uuid, fbx_item in fbx_table_nodes.items():
3358
- fbx_obj, blen_data = fbx_item
3359
- if fbx_obj.id != b'NodeAttribute':
3360
- continue
3361
- if fbx_obj.props[-1] == b'Light':
3362
- assert(blen_data is None)
3363
- fbx_item[1] = blen_read_light(fbx_tmpl, fbx_obj, settings)
3364
- _()
3365
- del _
3366
-
3367
- # ----
3368
- # Connections
3369
- def connection_filter_ex(fbx_uuid, fbx_id, dct):
3370
- return [(c_found[0], c_found[1], c_type)
3371
- for (c_uuid, c_type) in dct.get(fbx_uuid, ())
3372
- # 0 is used for the root node, which isn't in fbx_table_nodes
3373
- for c_found in (() if c_uuid == 0 else (fbx_table_nodes.get(c_uuid, (None, None)),))
3374
- if (fbx_id is None) or (c_found[0] and c_found[0].id == fbx_id)]
3375
-
3376
- def connection_filter_forward(fbx_uuid, fbx_id):
3377
- return connection_filter_ex(fbx_uuid, fbx_id, fbx_connection_map)
3378
-
3379
- def connection_filter_reverse(fbx_uuid, fbx_id):
3380
- return connection_filter_ex(fbx_uuid, fbx_id, fbx_connection_map_reverse)
3381
-
3382
- perfmon.step("FBX import: Objects & Armatures...")
3383
-
3384
- # -- temporary helper hierarchy to build armatures and objects from
3385
- # lookup from uuid to helper node. Used to build parent-child relations and later to look up animated nodes.
3386
- fbx_helper_nodes = {}
3387
-
3388
- def _():
3389
- # We build an intermediate hierarchy used to:
3390
- # - Calculate and store bone orientation correction matrices. The same matrices will be reused for animation.
3391
- # - Find/insert armature nodes.
3392
- # - Filter leaf bones.
3393
-
3394
- # create scene root
3395
- fbx_helper_nodes[0] = root_helper = FbxImportHelperNode(None, None, None, False)
3396
- root_helper.is_root = True
3397
-
3398
- # add fbx nodes
3399
- fbx_tmpl = fbx_template_get((b'Model', b'KFbxNode'))
3400
- for a_uuid, a_item in fbx_table_nodes.items():
3401
- fbx_obj, bl_data = a_item
3402
- if fbx_obj is None or fbx_obj.id != b'Model':
3403
- continue
3404
-
3405
- fbx_props = (elem_find_first(fbx_obj, b'Properties70'),
3406
- elem_find_first(fbx_tmpl, b'Properties70', fbx_elem_nil))
3407
-
3408
- transform_data = blen_read_object_transform_preprocess(fbx_props, fbx_obj, Matrix(), use_prepost_rot)
3409
- # Note: 'Root' "bones" are handled as (armature) objects.
3410
- # Note: See T46912 for first FBX file I ever saw with 'Limb' bones - thought those were totally deprecated.
3411
- is_bone = fbx_obj.props[2] in {b'LimbNode', b'Limb'}
3412
- fbx_helper_nodes[a_uuid] = FbxImportHelperNode(fbx_obj, bl_data, transform_data, is_bone)
3413
-
3414
- # add parent-child relations and add blender data to the node
3415
- for fbx_link in fbx_connections.elems:
3416
- if fbx_link.props[0] != b'OO':
3417
- continue
3418
- if fbx_link.props_type[1:3] == b'LL':
3419
- c_src, c_dst = fbx_link.props[1:3]
3420
- parent = fbx_helper_nodes.get(c_dst)
3421
- if parent is None:
3422
- continue
3423
-
3424
- child = fbx_helper_nodes.get(c_src)
3425
- if child is None:
3426
- # add blender data (meshes, lights, cameras, etc.) to a helper node
3427
- fbx_sdata, bl_data = p_item = fbx_table_nodes.get(c_src, (None, None))
3428
- if fbx_sdata is None:
3429
- continue
3430
- if fbx_sdata.id not in {b'Geometry', b'NodeAttribute'}:
3431
- continue
3432
- parent.bl_data = bl_data
3433
- if bl_data is None:
3434
- # If there's no bl_data, add the fbx_sdata so that it can be read when creating the bl_data/bone
3435
- parent.fbx_data_elem = fbx_sdata
3436
- else:
3437
- # set parent
3438
- child.parent = parent
3439
-
3440
- # find armatures (either an empty below a bone or a new node inserted at the bone
3441
- root_helper.find_armatures()
3442
-
3443
- # mark nodes that have bone children
3444
- root_helper.find_bone_children()
3445
-
3446
- # mark nodes that need a bone to attach child-bones to
3447
- root_helper.find_fake_bones()
3448
-
3449
- # mark leaf nodes that are only required to mark the end of their parent bone
3450
- if settings.ignore_leaf_bones:
3451
- root_helper.mark_leaf_bones()
3452
-
3453
- # What a mess! Some bones have several BindPoses, some have none, clusters contain a bind pose as well,
3454
- # and you can have several clusters per bone!
3455
- # Maybe some conversion can be applied to put them all into the same frame of reference?
3456
-
3457
- # get the bind pose from pose elements
3458
- for a_uuid, a_item in fbx_table_nodes.items():
3459
- fbx_obj, bl_data = a_item
3460
- if fbx_obj is None:
3461
- continue
3462
- if fbx_obj.id != b'Pose':
3463
- continue
3464
- if fbx_obj.props[2] != b'BindPose':
3465
- continue
3466
- for fbx_pose_node in fbx_obj.elems:
3467
- if fbx_pose_node.id != b'PoseNode':
3468
- continue
3469
- node_elem = elem_find_first(fbx_pose_node, b'Node')
3470
- node = elem_uuid(node_elem)
3471
- matrix_elem = elem_find_first(fbx_pose_node, b'Matrix')
3472
- matrix = array_to_matrix4(matrix_elem.props[0]) if matrix_elem else None
3473
- bone = fbx_helper_nodes.get(node)
3474
- if bone and matrix:
3475
- # Store the matrix in the helper node.
3476
- # There may be several bind pose matrices for the same node, but in tests they seem to be identical.
3477
- bone.bind_matrix = matrix # global space
3478
-
3479
- # get clusters and bind pose
3480
- for helper_uuid, helper_node in fbx_helper_nodes.items():
3481
- if not helper_node.is_bone:
3482
- continue
3483
- for cluster_uuid, cluster_link in fbx_connection_map.get(helper_uuid, ()):
3484
- if cluster_link.props[0] != b'OO':
3485
- continue
3486
- fbx_cluster, _ = fbx_table_nodes.get(cluster_uuid, (None, None))
3487
- if fbx_cluster is None or fbx_cluster.id != b'Deformer' or fbx_cluster.props[2] != b'Cluster':
3488
- continue
3489
-
3490
- # Get the bind pose from the cluster:
3491
- tx_mesh_elem = elem_find_first(fbx_cluster, b'Transform', default=None)
3492
- tx_mesh = array_to_matrix4(tx_mesh_elem.props[0]) if tx_mesh_elem else Matrix()
3493
-
3494
- tx_bone_elem = elem_find_first(fbx_cluster, b'TransformLink', default=None)
3495
- tx_bone = array_to_matrix4(tx_bone_elem.props[0]) if tx_bone_elem else None
3496
-
3497
- tx_arm_elem = elem_find_first(fbx_cluster, b'TransformAssociateModel', default=None)
3498
- tx_arm = array_to_matrix4(tx_arm_elem.props[0]) if tx_arm_elem else None
3499
-
3500
- mesh_matrix = tx_mesh
3501
- armature_matrix = tx_arm
3502
-
3503
- if tx_bone:
3504
- mesh_matrix = tx_bone @ mesh_matrix
3505
- helper_node.bind_matrix = tx_bone # overwrite the bind matrix
3506
-
3507
- # Get the meshes driven by this cluster: (Shouldn't that be only one?)
3508
- meshes = set()
3509
- for skin_uuid, skin_link in fbx_connection_map.get(cluster_uuid):
3510
- if skin_link.props[0] != b'OO':
3511
- continue
3512
- fbx_skin, _ = fbx_table_nodes.get(skin_uuid, (None, None))
3513
- if fbx_skin is None or fbx_skin.id != b'Deformer' or fbx_skin.props[2] != b'Skin':
3514
- continue
3515
- skin_connection = fbx_connection_map.get(skin_uuid)
3516
- if skin_connection is None:
3517
- continue
3518
- for mesh_uuid, mesh_link in skin_connection:
3519
- if mesh_link.props[0] != b'OO':
3520
- continue
3521
- fbx_mesh, _ = fbx_table_nodes.get(mesh_uuid, (None, None))
3522
- if fbx_mesh is None or fbx_mesh.id != b'Geometry' or fbx_mesh.props[2] != b'Mesh':
3523
- continue
3524
- for object_uuid, object_link in fbx_connection_map.get(mesh_uuid):
3525
- if object_link.props[0] != b'OO':
3526
- continue
3527
- mesh_node = fbx_helper_nodes[object_uuid]
3528
- if mesh_node:
3529
- # ----
3530
- # If we get a valid mesh matrix (in bone space), store armature and
3531
- # mesh global matrices, we need them to compute mesh's matrix_parent_inverse
3532
- # when actually binding them via the modifier.
3533
- # Note we assume all bones were bound with the same mesh/armature (global) matrix,
3534
- # we do not support otherwise in Blender anyway!
3535
- mesh_node.armature_setup[helper_node.armature] = (mesh_matrix, armature_matrix)
3536
- meshes.add(mesh_node)
3537
-
3538
- helper_node.clusters.append((fbx_cluster, meshes))
3539
-
3540
- # convert bind poses from global space into local space
3541
- root_helper.make_bind_pose_local()
3542
-
3543
- # collect armature meshes
3544
- root_helper.collect_armature_meshes()
3545
-
3546
- # find the correction matrices to align FBX objects with their Blender equivalent
3547
- root_helper.find_correction_matrix(settings)
3548
-
3549
- # build the Object/Armature/Bone hierarchy
3550
- root_helper.build_hierarchy(fbx_tmpl, settings, scene, view_layer)
3551
-
3552
- # Link the Object/Armature/Bone hierarchy
3553
- root_helper.link_hierarchy(fbx_tmpl, settings, scene)
3554
-
3555
- # root_helper.print_info(0)
3556
- _()
3557
- del _
3558
-
3559
- perfmon.step("FBX import: ShapeKeys...")
3560
-
3561
- # We can handle shapes.
3562
- blend_shape_channels = {} # We do not need Shapes themselves, but keyblocks, for anim.
3563
-
3564
- def _():
3565
- fbx_tmpl = fbx_template_get((b'Geometry', b'KFbxShape'))
3566
-
3567
- # - FBX | - Blender equivalent
3568
- # Mesh | `Mesh`
3569
- # BlendShape | `Key`
3570
- # BlendShapeChannel | `ShapeKey`, but without its `.data`.
3571
- # Shape | `ShapeKey.data`, but also includes normals and the values are relative to the base Mesh
3572
- # | instead of being absolute. The data is sparse, so each Shape has an "Indexes" array too.
3573
- # | FBX 2020 introduced 'Modern Style' Shapes that also support tangents, binormals, vertex
3574
- # | colors and UVs, and can be absolute values instead of relative, but 'Modern Style' Shapes
3575
- # | are not currently supported.
3576
- #
3577
- # The FBX connections between Shapes and Meshes form multiple many-many relationships:
3578
- # Mesh >-< BlendShape >-< BlendShapeChannel >-< Shape
3579
- # In practice, the relationships are almost never many-many and are more typically 1-many or 1-1:
3580
- # Mesh --- BlendShape:
3581
- # usually 1-1 and the FBX SDK might enforce that each BlendShape is connected to at most one Mesh.
3582
- # BlendShape --< BlendShapeChannel:
3583
- # usually 1-many.
3584
- # BlendShapeChannel --- or uncommonly --< Shape:
3585
- # usually 1-1, but 1-many is a documented feature.
3586
-
3587
- def connections_gen(c_src_uuid, fbx_id, fbx_type):
3588
- """Helper to reduce duplicate code"""
3589
- # Rarely, an imported FBX file will have duplicate connections. For Shape Key related connections, FBX
3590
- # appears to ignore the duplicates, or overwrite the existing duplicates such that the end result is the
3591
- # same as ignoring them, so keep a set of the seen connections and ignore any duplicates.
3592
- seen_connections = set()
3593
- for c_dst_uuid, ctype in fbx_connection_map.get(c_src_uuid, ()):
3594
- if ctype.props[0] != b'OO':
3595
- # 'Object-Object' connections only.
3596
- continue
3597
- fbx_data, bl_data = fbx_table_nodes.get(c_dst_uuid, (None, None))
3598
- if fbx_data is None or fbx_data.id != fbx_id or fbx_data.props[2] != fbx_type:
3599
- # Either `c_dst_uuid` doesn't exist, or it has a different id or type.
3600
- continue
3601
- connection_key = (c_src_uuid, c_dst_uuid)
3602
- if connection_key in seen_connections:
3603
- # The connection is a duplicate, skip it.
3604
- continue
3605
- seen_connections.add(connection_key)
3606
- yield c_dst_uuid, fbx_data, bl_data
3607
-
3608
- # XXX - Multiple Shapes can be assigned to a single BlendShapeChannel to create a progressive blend between the
3609
- # base mesh and the assigned Shapes, with the percentage at which each Shape is fully blended being stored
3610
- # in the BlendShapeChannel's FullWeights array. This is also known as 'in-between shapes'.
3611
- # We don't have any support for in-between shapes currently.
3612
- blend_shape_channel_to_shapes = {}
3613
- mesh_to_shapes = {}
3614
- for s_uuid, (fbx_sdata, _bl_sdata) in fbx_table_nodes.items():
3615
- if fbx_sdata is None or fbx_sdata.id != b'Geometry' or fbx_sdata.props[2] != b'Shape':
3616
- continue
3617
-
3618
- # shape -> blendshapechannel -> blendshape -> mesh.
3619
- for bc_uuid, fbx_bcdata, _bl_bcdata in connections_gen(s_uuid, b'Deformer', b'BlendShapeChannel'):
3620
- # Track the Shapes connected to each BlendShapeChannel.
3621
- shapes_assigned_to_channel = blend_shape_channel_to_shapes.setdefault(bc_uuid, [])
3622
- shapes_assigned_to_channel.append(s_uuid)
3623
- for bs_uuid, _fbx_bsdata, _bl_bsdata in connections_gen(bc_uuid, b'Deformer', b'BlendShape'):
3624
- for m_uuid, _fbx_mdata, bl_mdata in connections_gen(bs_uuid, b'Geometry', b'Mesh'):
3625
- # Blenmeshes are assumed already created at that time!
3626
- assert(isinstance(bl_mdata, bpy.types.Mesh))
3627
- # Group shapes by mesh so that each mesh only needs to be processed once for all of its shape
3628
- # keys.
3629
- if bl_mdata not in mesh_to_shapes:
3630
- # And we have to find all objects using this mesh!
3631
- objects = []
3632
- for o_uuid, o_ctype in fbx_connection_map.get(m_uuid, ()):
3633
- if o_ctype.props[0] != b'OO':
3634
- continue
3635
- node = fbx_helper_nodes[o_uuid]
3636
- if node:
3637
- objects.append(node)
3638
- shapes_list = []
3639
- mesh_to_shapes[bl_mdata] = (objects, shapes_list)
3640
- else:
3641
- shapes_list = mesh_to_shapes[bl_mdata][1]
3642
- # Only the number of shapes assigned to each BlendShapeChannel needs to be passed through to
3643
- # `blen_read_shapes`, but that number isn't known until all the connections have been
3644
- # iterated, so pass the `shapes_assigned_to_channel` list instead.
3645
- shapes_list.append((bc_uuid, fbx_sdata, fbx_bcdata, shapes_assigned_to_channel))
3646
- # BlendShape deformers are only here to connect BlendShapeChannels to meshes, nothing else to do.
3647
-
3648
- # Iterate through each mesh and create its shape keys
3649
- for bl_mdata, (objects, shapes) in mesh_to_shapes.items():
3650
- for bc_uuid, keyblocks in blen_read_shapes(fbx_tmpl, shapes, objects, bl_mdata, scene).items():
3651
- # keyblocks is a list of tuples (mesh, keyblock) matching that shape/blendshapechannel, for animation.
3652
- blend_shape_channels.setdefault(bc_uuid, []).extend(keyblocks)
3653
- _()
3654
- del _
3655
-
3656
- if settings.use_subsurf:
3657
- perfmon.step("FBX import: Subdivision surfaces")
3658
-
3659
- # Look through connections for subsurf in meshes and add it to the parent object
3660
- def _():
3661
- for fbx_link in fbx_connections.elems:
3662
- if fbx_link.props[0] != b'OO':
3663
- continue
3664
- if fbx_link.props_type[1:3] == b'LL':
3665
- c_src, c_dst = fbx_link.props[1:3]
3666
- parent = fbx_helper_nodes.get(c_dst)
3667
- if parent is None:
3668
- continue
3669
-
3670
- child = fbx_helper_nodes.get(c_src)
3671
- if child is None:
3672
- fbx_sdata, bl_data = fbx_table_nodes.get(c_src, (None, None))
3673
- if fbx_sdata.id != b'Geometry':
3674
- continue
3675
-
3676
- preview_levels = elem_prop_first(elem_find_first(fbx_sdata, b'PreviewDivisionLevels'))
3677
- render_levels = elem_prop_first(elem_find_first(fbx_sdata, b'RenderDivisionLevels'))
3678
- if isinstance(preview_levels, int) and isinstance(render_levels, int):
3679
- mod = parent.bl_obj.modifiers.new('subsurf', 'SUBSURF')
3680
- mod.levels = preview_levels
3681
- mod.render_levels = render_levels
3682
- boundary_rule = elem_prop_first(elem_find_first(fbx_sdata, b'BoundaryRule'), default=1)
3683
- if boundary_rule == 1:
3684
- mod.boundary_smooth = "PRESERVE_CORNERS"
3685
- else:
3686
- mod.boundary_smooth = "ALL"
3687
-
3688
- _()
3689
- del _
3690
-
3691
- if use_anim:
3692
- perfmon.step("FBX import: Animations...")
3693
-
3694
- # Animation!
3695
- def _():
3696
- # Find the number of "ktimes" per second for this file.
3697
- # Start with the default for this FBX version.
3698
- fbx_ktime = FBX_KTIME_V8 if version >= 8000 else FBX_KTIME_V7
3699
- # Try to find the value of the nested elem_root->'FBXHeaderExtension'->'OtherFlags'->'TCDefinition' element
3700
- # and look up the "ktimes" per second for its value.
3701
- if header := elem_find_first(elem_root, b'FBXHeaderExtension'):
3702
- # The header version that added TCDefinition support is 1004.
3703
- if elem_prop_first(elem_find_first(header, b'FBXHeaderVersion'), default=0) >= 1004:
3704
- if other_flags := elem_find_first(header, b'OtherFlags'):
3705
- if timecode_definition := elem_find_first(other_flags, b'TCDefinition'):
3706
- timecode_definition_value = elem_prop_first(timecode_definition)
3707
- # If its value is unknown or missing, default to FBX_KTIME_V8.
3708
- fbx_ktime = FBX_TIMECODE_DEFINITION_TO_KTIME_PER_SECOND.get(timecode_definition_value,
3709
- FBX_KTIME_V8)
3710
-
3711
- fbx_tmpl_astack = fbx_template_get((b'AnimationStack', b'FbxAnimStack'))
3712
- fbx_tmpl_alayer = fbx_template_get((b'AnimationLayer', b'FbxAnimLayer'))
3713
- stacks = {}
3714
-
3715
- # AnimationStacks.
3716
- for as_uuid, fbx_asitem in fbx_table_nodes.items():
3717
- fbx_asdata, _blen_data = fbx_asitem
3718
- if fbx_asdata.id != b'AnimationStack' or fbx_asdata.props[2] != b'':
3719
- continue
3720
- stacks[as_uuid] = (fbx_asitem, {})
3721
-
3722
- # AnimationLayers
3723
- # (mixing is completely ignored for now, each layer results in an independent set of actions).
3724
- def get_astacks_from_alayer(al_uuid):
3725
- for as_uuid, as_ctype in fbx_connection_map.get(al_uuid, ()):
3726
- if as_ctype.props[0] != b'OO':
3727
- continue
3728
- fbx_asdata, _bl_asdata = fbx_table_nodes.get(as_uuid, (None, None))
3729
- if (fbx_asdata is None or fbx_asdata.id != b'AnimationStack' or
3730
- fbx_asdata.props[2] != b'' or as_uuid not in stacks):
3731
- continue
3732
- yield as_uuid
3733
- for al_uuid, fbx_alitem in fbx_table_nodes.items():
3734
- fbx_aldata, _blen_data = fbx_alitem
3735
- if fbx_aldata.id != b'AnimationLayer' or fbx_aldata.props[2] != b'':
3736
- continue
3737
- for as_uuid in get_astacks_from_alayer(al_uuid):
3738
- _fbx_asitem, alayers = stacks[as_uuid]
3739
- alayers[al_uuid] = (fbx_alitem, {})
3740
-
3741
- # AnimationCurveNodes (also the ones linked to actual animated data!).
3742
- curvenodes = {}
3743
- for acn_uuid, fbx_acnitem in fbx_table_nodes.items():
3744
- fbx_acndata, _blen_data = fbx_acnitem
3745
- if fbx_acndata.id != b'AnimationCurveNode' or fbx_acndata.props[2] != b'':
3746
- continue
3747
- cnode = curvenodes[acn_uuid] = {}
3748
- items = []
3749
- for n_uuid, n_ctype in fbx_connection_map.get(acn_uuid, ()):
3750
- if n_ctype.props[0] != b'OP':
3751
- continue
3752
- lnk_prop = n_ctype.props[3]
3753
- if lnk_prop in {b'Lcl Translation', b'Lcl Rotation', b'Lcl Scaling'}:
3754
- # n_uuid can (????) be linked to root '0' node, instead of a mere object node... See T41712.
3755
- ob = fbx_helper_nodes.get(n_uuid, None)
3756
- if ob is None or ob.is_root:
3757
- continue
3758
- items.append((ob, lnk_prop))
3759
- elif lnk_prop == b'DeformPercent': # Shape keys.
3760
- keyblocks = blend_shape_channels.get(n_uuid, None)
3761
- if keyblocks is None:
3762
- continue
3763
- items += [(kb, lnk_prop) for kb in keyblocks]
3764
- elif lnk_prop == b'FocalLength': # Camera lens.
3765
- from bpy.types import Camera
3766
- fbx_item = fbx_table_nodes.get(n_uuid, None)
3767
- if fbx_item is None or not isinstance(fbx_item[1], Camera):
3768
- continue
3769
- cam = fbx_item[1]
3770
- items.append((cam, lnk_prop))
3771
- elif lnk_prop == b'FocusDistance': # Camera focus.
3772
- from bpy.types import Camera
3773
- fbx_item = fbx_table_nodes.get(n_uuid, None)
3774
- if fbx_item is None or not isinstance(fbx_item[1], Camera):
3775
- continue
3776
- cam = fbx_item[1]
3777
- items.append((cam, lnk_prop))
3778
- elif lnk_prop == b'DiffuseColor':
3779
- from bpy.types import Material
3780
- fbx_item = fbx_table_nodes.get(n_uuid, None)
3781
- if fbx_item is None or not isinstance(fbx_item[1], Material):
3782
- continue
3783
- mat = fbx_item[1]
3784
- items.append((mat, lnk_prop))
3785
- print("WARNING! Importing material's animation is not supported for Nodal materials...")
3786
- for al_uuid, al_ctype in fbx_connection_map.get(acn_uuid, ()):
3787
- if al_ctype.props[0] != b'OO':
3788
- continue
3789
- fbx_aldata, _blen_aldata = fbx_alitem = fbx_table_nodes.get(al_uuid, (None, None))
3790
- if fbx_aldata is None or fbx_aldata.id != b'AnimationLayer' or fbx_aldata.props[2] != b'':
3791
- continue
3792
- for as_uuid in get_astacks_from_alayer(al_uuid):
3793
- _fbx_alitem, anim_items = stacks[as_uuid][1][al_uuid]
3794
- assert(_fbx_alitem == fbx_alitem)
3795
- for item, item_prop in items:
3796
- # No need to keep curvenode FBX data here, contains nothing useful for us.
3797
- anim_items.setdefault(item, {})[acn_uuid] = (cnode, item_prop)
3798
-
3799
- # AnimationCurves (real animation data).
3800
- for ac_uuid, fbx_acitem in fbx_table_nodes.items():
3801
- fbx_acdata, _blen_data = fbx_acitem
3802
- if fbx_acdata.id != b'AnimationCurve' or fbx_acdata.props[2] != b'':
3803
- continue
3804
- for acn_uuid, acn_ctype in fbx_connection_map.get(ac_uuid, ()):
3805
- if acn_ctype.props[0] != b'OP':
3806
- continue
3807
- fbx_acndata, _bl_acndata = fbx_table_nodes.get(acn_uuid, (None, None))
3808
- if (fbx_acndata is None or fbx_acndata.id != b'AnimationCurveNode' or
3809
- fbx_acndata.props[2] != b'' or acn_uuid not in curvenodes):
3810
- continue
3811
- # Note this is an infamous simplification of the compound props stuff,
3812
- # seems to be standard naming but we'll probably have to be smarter to handle more exotic files?
3813
- channel = {
3814
- b'd|X': 0, b'd|Y': 1, b'd|Z': 2,
3815
- b'd|DeformPercent': 0,
3816
- b'd|FocalLength': 0,
3817
- b'd|FocusDistance': 0
3818
- }.get(acn_ctype.props[3], None)
3819
- if channel is None:
3820
- continue
3821
- curvenodes[acn_uuid][ac_uuid] = (fbx_acitem, channel)
3822
-
3823
- # And now that we have sorted all this, apply animations!
3824
- blen_read_animations(fbx_tmpl_astack, fbx_tmpl_alayer, stacks, scene, settings.anim_offset, global_scale,
3825
- fbx_ktime)
3826
-
3827
- _()
3828
- del _
3829
-
3830
- perfmon.step("FBX import: Assign materials...")
3831
-
3832
- def _():
3833
- # link Material's to Geometry (via Model's)
3834
- processed_meshes = set()
3835
- for helper_uuid, helper_node in fbx_helper_nodes.items():
3836
- obj = helper_node.bl_obj
3837
- if not obj or obj.type != 'MESH':
3838
- continue
3839
-
3840
- # Get the Mesh corresponding to the Geometry used by this Model.
3841
- mesh = obj.data
3842
- processed_meshes.add(mesh)
3843
-
3844
- # Get the Materials from the Model's connections.
3845
- material_connections = connection_filter_reverse(helper_uuid, b'Material')
3846
- if not material_connections:
3847
- continue
3848
-
3849
- mesh_mats = mesh.materials
3850
- num_mesh_mats = len(mesh_mats)
3851
-
3852
- if num_mesh_mats == 0:
3853
- # This is the first (or only) model to use this Geometry. This is the most common case when importing.
3854
- # All the Materials can trivially be appended to the Mesh's Materials.
3855
- mats_to_append = material_connections
3856
- mats_to_compare = ()
3857
- elif num_mesh_mats == len(material_connections):
3858
- # Another Model uses the same Geometry and has already appended its Materials to the Mesh. This is the
3859
- # second most common case when importing.
3860
- # It's also possible that a Model could share the same Geometry and have the same number of Materials,
3861
- # but have different Materials, though this is less common.
3862
- # The Model Materials will need to be compared with the Mesh Materials at the same indices to check if
3863
- # they are different.
3864
- mats_to_append = ()
3865
- mats_to_compare = material_connections
3866
- else:
3867
- # Under the assumption that only used Materials are connected to the Model, the number of Materials of
3868
- # each Model using a specific Geometry should be the same, otherwise the Material Indices of the
3869
- # Geometry will be out-of-bounds of the Materials of at least one of the Models using that Geometry.
3870
- # We wouldn't expect this case to happen, but there's nothing to say it can't.
3871
- # We'll handle a differing number of Materials by appending any extra Materials and comparing the rest.
3872
- mats_to_append = material_connections[num_mesh_mats:]
3873
- mats_to_compare = material_connections[:num_mesh_mats]
3874
-
3875
- for _fbx_lnk_material, material, _fbx_lnk_material_type in mats_to_append:
3876
- mesh_mats.append(material)
3877
-
3878
- mats_to_compare_and_slots = zip(mats_to_compare, obj.material_slots)
3879
- for (_fbx_lnk_material, material, _fbx_lnk_material_type), mat_slot in mats_to_compare_and_slots:
3880
- if material != mat_slot.material:
3881
- # Material Slots default to being linked to the Mesh, so a previously processed Object is also using
3882
- # this Mesh, but the Mesh uses a different Material for this Material Slot.
3883
- # To have a different Material for this Material Slot on this Object only, the Material Slot must be
3884
- # linked to the Object rather than the Mesh.
3885
- # TODO: add an option to link all materials to objects in Blender instead?
3886
- mat_slot.link = 'OBJECT'
3887
- mat_slot.material = material
3888
-
3889
- # We have to validate mesh polygons' ma_idx, see #41015!
3890
- # Some FBX seem to have an extra 'default' material which is not defined in FBX file.
3891
- for mesh in processed_meshes:
3892
- if mesh.validate_material_indices():
3893
- print("WARNING: mesh '%s' had invalid material indices, those were reset to first material" % mesh.name)
3894
- _()
3895
- del _
3896
-
3897
- perfmon.step("FBX import: Assign textures...")
3898
-
3899
- def _():
3900
- material_images = {}
3901
-
3902
- fbx_tmpl = fbx_template_get((b'Material', b'KFbxSurfacePhong'))
3903
- # b'KFbxSurfaceLambert'
3904
-
3905
- def texture_mapping_set(fbx_obj, node_texture):
3906
- assert(fbx_obj.id == b'Texture')
3907
-
3908
- fbx_props = (elem_find_first(fbx_obj, b'Properties70'),
3909
- elem_find_first(fbx_tmpl, b'Properties70', fbx_elem_nil))
3910
- loc = elem_props_get_vector_3d(fbx_props, b'Translation', (0.0, 0.0, 0.0))
3911
- rot = tuple(-r for r in elem_props_get_vector_3d(fbx_props, b'Rotation', (0.0, 0.0, 0.0)))
3912
- scale = tuple(((1.0 / s) if s != 0.0 else 1.0)
3913
- for s in elem_props_get_vector_3d(fbx_props, b'Scaling', (1.0, 1.0, 1.0)))
3914
- clamp = (bool(elem_props_get_enum(fbx_props, b'WrapModeU', 0)) or
3915
- bool(elem_props_get_enum(fbx_props, b'WrapModeV', 0)))
3916
-
3917
- if (loc == (0.0, 0.0, 0.0) and
3918
- rot == (0.0, 0.0, 0.0) and
3919
- scale == (1.0, 1.0, 1.0) and
3920
- clamp == False):
3921
- return
3922
-
3923
- node_texture.translation = loc
3924
- node_texture.rotation = rot
3925
- node_texture.scale = scale
3926
- if clamp:
3927
- node_texture.extension = 'EXTEND'
3928
-
3929
- for fbx_uuid, fbx_item in fbx_table_nodes.items():
3930
- fbx_obj, blen_data = fbx_item
3931
- if fbx_obj.id != b'Material':
3932
- continue
3933
-
3934
- material = fbx_table_nodes.get(fbx_uuid, (None, None))[1]
3935
- for (fbx_lnk,
3936
- image,
3937
- fbx_lnk_type) in connection_filter_reverse(fbx_uuid, b'Texture'):
3938
-
3939
- if fbx_lnk_type.props[0] == b'OP':
3940
- lnk_type = fbx_lnk_type.props[3]
3941
-
3942
- ma_wrap = nodal_material_wrap_map[material]
3943
-
3944
- if lnk_type in {b'DiffuseColor', b'3dsMax|maps|texmap_diffuse'}:
3945
- ma_wrap.base_color_texture.image = image
3946
- texture_mapping_set(fbx_lnk, ma_wrap.base_color_texture)
3947
- elif lnk_type in {b'SpecularColor', b'SpecularFactor'}:
3948
- # Intensity actually, not color...
3949
- ma_wrap.specular_texture.image = image
3950
- texture_mapping_set(fbx_lnk, ma_wrap.specular_texture)
3951
- elif lnk_type in {b'ReflectionColor', b'ReflectionFactor', b'3dsMax|maps|texmap_reflection'}:
3952
- # Intensity actually, not color...
3953
- ma_wrap.metallic_texture.image = image
3954
- texture_mapping_set(fbx_lnk, ma_wrap.metallic_texture)
3955
- elif lnk_type in {b'TransparentColor', b'TransparencyFactor'}:
3956
- ma_wrap.alpha_texture.image = image
3957
- texture_mapping_set(fbx_lnk, ma_wrap.alpha_texture)
3958
- if use_alpha_decals:
3959
- material_decals.add(material)
3960
- elif lnk_type == b'ShininessExponent':
3961
- # That is probably reversed compared to expected results? TODO...
3962
- ma_wrap.roughness_texture.image = image
3963
- texture_mapping_set(fbx_lnk, ma_wrap.roughness_texture)
3964
- # XXX, applications abuse bump!
3965
- elif lnk_type in {b'NormalMap', b'Bump', b'3dsMax|maps|texmap_bump'}:
3966
- ma_wrap.normalmap_texture.image = image
3967
- texture_mapping_set(fbx_lnk, ma_wrap.normalmap_texture)
3968
- """
3969
- elif lnk_type == b'Bump':
3970
- # TODO displacement...
3971
- """
3972
- elif lnk_type in {b'EmissiveColor'}:
3973
- ma_wrap.emission_color_texture.image = image
3974
- texture_mapping_set(fbx_lnk, ma_wrap.emission_color_texture)
3975
- elif lnk_type in {b'EmissiveFactor'}:
3976
- ma_wrap.emission_strength_texture.image = image
3977
- texture_mapping_set(fbx_lnk, ma_wrap.emission_strength_texture)
3978
- else:
3979
- print("WARNING: material link %r ignored" % lnk_type)
3980
-
3981
- material_images.setdefault(material, {})[lnk_type] = image
3982
-
3983
- # Check if the diffuse image has an alpha channel,
3984
- # if so, use the alpha channel.
3985
-
3986
- # Note: this could be made optional since images may have alpha but be entirely opaque
3987
- for fbx_uuid, fbx_item in fbx_table_nodes.items():
3988
- fbx_obj, blen_data = fbx_item
3989
- if fbx_obj.id != b'Material':
3990
- continue
3991
- material = fbx_table_nodes.get(fbx_uuid, (None, None))[1]
3992
- image = material_images.get(material, {}).get(b'DiffuseColor', None)
3993
- # do we have alpha?
3994
- if image and image.depth == 32:
3995
- if use_alpha_decals:
3996
- material_decals.add(material)
3997
-
3998
- ma_wrap = nodal_material_wrap_map[material]
3999
- ma_wrap.alpha_texture.use_alpha = True
4000
- ma_wrap.alpha_texture.copy_from(ma_wrap.base_color_texture)
4001
-
4002
- # Propagate mapping from diffuse to all other channels which have none defined.
4003
- # XXX Commenting for now, I do not really understand the logic here, why should diffuse mapping
4004
- # be applied to all others if not defined for them???
4005
- # ~ ma_wrap = nodal_material_wrap_map[material]
4006
- # ~ ma_wrap.mapping_set_from_diffuse()
4007
-
4008
- _()
4009
- del _
4010
-
4011
- perfmon.step("FBX import: Cycles z-offset workaround...")
4012
-
4013
- def _():
4014
- # Annoying workaround for cycles having no z-offset
4015
- if material_decals and use_alpha_decals:
4016
- for fbx_uuid, fbx_item in fbx_table_nodes.items():
4017
- fbx_obj, blen_data = fbx_item
4018
- if fbx_obj.id != b'Geometry':
4019
- continue
4020
- if fbx_obj.props[-1] == b'Mesh':
4021
- mesh = fbx_item[1]
4022
-
4023
- num_verts = len(mesh.vertices)
4024
- if decal_offset != 0.0 and num_verts > 0:
4025
- for material in mesh.materials:
4026
- if material in material_decals:
4027
- blen_norm_dtype = np.single
4028
- vcos = MESH_ATTRIBUTE_POSITION.to_ndarray(mesh.attributes)
4029
- vnorm = np.empty(num_verts * 3, dtype=blen_norm_dtype)
4030
- mesh.vertex_normals.foreach_get("vector", vnorm)
4031
-
4032
- vcos += vnorm * decal_offset
4033
-
4034
- MESH_ATTRIBUTE_POSITION.foreach_set(mesh.attributes, vcos)
4035
- break
4036
-
4037
- for obj in (obj for obj in bpy.data.objects if obj.data == mesh):
4038
- obj.visible_shadow = False
4039
- _()
4040
- del _
4041
-
4042
- perfmon.level_down()
4043
-
4044
- perfmon.level_down("Import finished.")
4045
- return {'FINISHED'}