Commit Graph

251 Commits

Author SHA1 Message Date
d05b2aeec3 Fix #105298: Import FBX: TypeError - 'NoneType' is not iterable
Continue if skin connection map is None
Avoid Assertion Error
Fixes #105298
2024-04-28 12:50:28 +02:00
1de247676d FBX IO: Fix performance regression setting keyframe_point interpolation
Blender is built with char as unsigned and `Keyframe.interpolation` has
the #PROP_RAW_CHAR raw type. foreach_get/foreach_set used to incorrectly
consider `signed char` buffers to be compatible. This was fixed in
blender/blender@992ec6487b such that `unsigned char` buffers are now
considered compatible instead.

This patch updates the keyframe_point interpolation array's dtype to
`unsigned char` to restore the faster access with foreach_set when the
buffer is considered compatible.

Setting the interpolation values of 100 fcurves with 1000 keyframes each
goes from about 5.5ms to about 0.3ms for me.
2024-03-28 13:56:57 +00:00
689081bcbb Fix #105217: FBX Force Connect Children transforms Objects parented to Bones
Force Connect Children can change the length and rotation of imported
bones, which was affecting Objects parented to bones.

This patch updates the correction matrix for child Objects attached to
bones to account for any changes made by forcing children bones to
connect to their parents.

Meshes rigged to bones weren't affected because it was only the rest
pose that was changed.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/105249
2024-03-22 13:53:52 +01:00
a99528adb0 FBX IO: Use the new ShapeKey.points with faster foreach_get/set
Added to Blender 4.1.0 in blender/blender@7d77caab9b, ShapeKey.points
gives optimized access to shape key points data (meshes/lattices) when
accessed with #foreach_get and #foreach_set.

FBX 'shape keys' (Shape Geometry) are sparse data, but Blender shape
keys have one coordinate for every vertex in the mesh, which means that
importing a large mesh with many small shape keys can result in writing
a very large amount of Shape Key data compared to what was stored in the
.fbx file.

This patch updates FBX IO to use ShapeKey.points, noticeably speeding up
imports and exports of larger meshes with many shape keys.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/105133
2024-01-24 05:06:48 +01:00
2cdfe9e591 Fix #105088: FBX Camera Focus Distance is interpreted as millimeters
FBX IO has been converting the Camera `FocusDistance` property from
millimeters on import and to millimeters on export, however, this
appears to have been incorrect because `FocusDistance` appears to be
in meters instead.

The FBX SDK used to have deprecated `SetSpecificDistance()` and
`GetSpecificDistance()` functions that were documented as accessing
Camera Focus Distance in millimeters.

The documentation of these functions appears to have been incorrectly
attributed to the Camera Focus Distance property itself, which could be
accessed directly without the deprecated functions, and appears to be
stored in meters.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/105124
2024-01-16 21:48:20 +01:00
f21b90cbab Fix #105045: Error importing FBX custom properties on placeholder PoseBones
Caused by not understanding an uncommon import case in 716702b97e where
a bone can be created without an FBX Node to import custom properties
from.

A bone in Blender is always created from an FBX Node, so it seemed like
all bones should have an FBX Node that custom properties can be imported
from. However, FBX allows bone and non-bone Nodes to be parented to one
another, which Blender cannot represent exactly due to Armatures only
containing bones. In such cases, the non-bone Node is imported as an
Object, but a bone with the same name is also created (which the Object
is parented to). The newly created bone doesn't have a Node to import
custom properties from because the Node belongs to the imported Object
instead.
2023-12-09 01:49:56 +00:00
86bcdbd5c4 FBX IO: Update for new meshes being smooth by default
Blender 3.6 changed newly created meshes to be smooth by default,
therefore, it is no longer necessary to remove the "sharp_face"
attribute if face smoothing was not set when importing a mesh.

The only time when "sharp_face" needs to be removed is if we create the
attribute when attempting to set face smoothing, but setting face
smoothing fails.

No changes to the import of .fbx files are expected with this patch.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/105039
2023-12-05 03:41:01 +01:00
791b042c3a FBX IO: Export normals with IndexToDirect reference mode
The FBX SDK documentation says that normals should be IndexToDirect
mapped. 9 years ago, we didn't export with IndexToDirect mode because
apps at the time didn't support it well.

9 years is a long time and the apps I've tried all work with
IndexToDirect, so the export of normals has been updated to use the
IndexToDirect mode, using the already existing, but disabled code.

This will slightly increase export times, and will slightly increase
exported file size in cases that don't have lots of duplicate normals.

In the worst case scenario of exporting only geometry with the 'CORNER'
normals domain and nothing else, exports can be about 1.28 times slower
and result in a about a 1.08 times larger file size.

The FBX importer was not previously set up to handle the import of
ByVertice-IndexToDirect normals, so this has been added to ensure that
the normals of FBX IO exported .fbx files are imported correctly.

If older versions of FBX IO attempt to import ByVertice-IndexToDirect
normals, a warning will be printed to the System Console that the
mapping type and ref type are not supported and custom normals will not
be set. However, the normals of the imported mesh will still match the
expected imported normals because they are the same as the imported
mesh's vertex normals. This is only applicable to ByVertice normals
exported by FBX IO, because they are only exported when
`Mesh.normals_domain` is `'POINT'`, which requires no sharp edges, no
sharp faces and no custom normals.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/105020
2023-12-02 02:08:18 +01:00
a850ed1e38 FBX IO: Fix animation import when the newer opt-in FBX_KTIME is used
FBX 2019.5 (file version 7700) introduced a new number of "ktimes" per
second to more accurately support some animation frame rates. The new
value is an opt-in until FBX version 8000, where it should then become
the default.

The importer will now look for new the header version and flag
specifying to opt in to the new FBX_KTIME value.

The exporter is unaffected because it always writes an FBX version 7400
binary.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/105019
2023-12-01 01:00:24 +01:00
2c32cc163f FBX IO: Fix import of shape key animations without any keyframes
Attempting to import a shape key animation without any animation curves
or with only empty animation curves would result in attempting to get
the min/max of an empty list or array.

The animation curve values array is now checked for being non-empty
before attempting to get its minimum and maximum values.

The list of animated shape key deform values is now only created when
there are values to add to it, thus ensuring it is never empty.
2023-11-26 18:14:04 +00:00
0ceb884d1f FBX IO: Fix error importing BlendShapeChannels with extraneous FullWeights
Fixes a rare cause of #84111, but does not fix the main issue.

Aside from Shape Keys with Vertex Groups exported by Blender, rarely, a
BlendShapeChannel can have more FullWeights than Shapes assigned to it,
which would fail an assertion that the number of FullWeights equals the
number of vertices moved by the Shape with an allowed exception of when
there is only a single FullWeight.

This assertion was not correct because each FullWeight is the
deformation percentage of the BlendShapeChannel that fully activates
each Shape assigned to the BlendShapeChannel.

This patch keeps track of the Shapes assigned to each BlendShapeChannel
so that the number of FullWeights can be correctly compared against the
number of Shapes. FBX appears to ignore any excess FullWeights, so the
updated assertion allows this too.

Blender exported Shape Keys with Vertex Groups are then handled
separately by initially checking if the number of FullWeights equals the
number of vertices moved by the imported Shape.

The main cause of #84111 is when there is more than one Shape assigned
to a BlendShapeChannel. This is still not supported because it requires
larger changes and allowing it now would cause more issues. Because the
assertion is no longer sufficient to cause an error when there is more
than one Shape, an explicitly thrown RuntimeException has been added to
fulfil the same role.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104956
2023-11-05 10:16:54 +01:00
d532e47c3a Merge branch 'blender-v4.0-release'
# Conflicts:
#	io_scene_fbx/__init__.py
2023-10-30 17:28:46 +00:00
c9d8698a1a FBX IO: Fix missing conversion to radians of initial rotation in animation import
My own mistake in e7b1962893.

The incorrect rotation could be noticed if the initial rotation was
non-zero and an imported transformation animation only animated scaling
and/or translation.

Several addon patch versions have been skipped because they were
mistakenly used by the main branch. See 5713746637.
2023-10-30 17:25:11 +00:00
519cd4ae63 FBX IO: Update missed MeshLoop.vertex_index to the corner vert attribute
This use of MeshLoop.vertex_index was missed in d17ed07832.
2023-10-27 23:43:09 +01:00
b0f8406b72 FBX IO: Fix import of per-face normals
Small mistake of not updating the foreach attributes in b1fbf73a08.

It turns out that the import of per-vertex normals was unaffected
because blen_read_geom_array_mapped_polyloop currently covers all
supported import cases covered by blen_read_geom_array_mapped_vert,
making the mistake in the per-vertex code unreachable.

We should probably add ByVertice-IndexToDirect support to
blen_read_geom_array_mapped_vert in the future, so the currently
unreachable code has been left as-is and a comment has been added.
2023-10-27 22:56:48 +01:00
b1fbf73a08 Mesh: Update addons for auto smooth removal
See https://projects.blender.org/blender/blender/pulls/108014

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104609
2023-10-20 16:53:43 +02:00
1edbfe9249 Fix duplicate shape key import when the FBX connections are duplicated
Rarely, FBX files with duplicate ShapeKey-related connections are
encountered. The FBX IO addon would add a ShapeKey for each duplicate,
however external software appears to ignore the duplicates, or
overwrite the existing duplicates such that the same effect as ignoring
new duplicates is achieved.

This patch modifies the FBX importer to skip all duplicate ShapeKey-
related connections when finding the ShapeKeys to add to each Mesh.

While it is unclear if they are ever encountered, importing multi-user
Shapes/BlendShapeChannels/etc. as single-users remains supported, e.g.
a Mesh with a BlendShape with two different BlendShapeChannels that both
have the same Shape will still import that Shape as two separate
ShapeKeys.

The code needed for iterating through each type of connection was
duplicated and was getting rather large with the newly added code, so
it has been refactored into calling a generator helper function.

The outermost loop had an unnecessary line of code that would re-get
values from `fbx_table_nodes`, this has been removed.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104954
2023-10-18 17:24:34 +02:00
25697d80c2 Fix incorrect merged weights from ignored bones in FBX import
Given a chain of bones A -> B -> C and a vertex weighted to all three
bones: When C is ignored and its weight is to be merged into its parent
B, the sum of the weights that are not A should remain the same as
before the merge. The current code is instead setting the B weight to
the average of the B and C weights, which does not maintain the sum of
the weights. The division that was creating the average has been
removed, so now the weights in C to be merged into B are added directly
to the B weight.

Because the maximum value a weight can be set to is 1.0, this poses a
problem when the weights to be added together exceed 1.0. Re-normalizing
all the weights on the vertex in this case sounds like it could work,
but unfortunately, we only have access to all the weights for one bone
at a time with the current implementation. Re-normalizing the weights
after adding all the weights to each vertex is too late because the
weights exceeding 1.0 would already have been clamped to 1.0. A comment
has been added to indicate that this is a known issue.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104928
2023-10-06 05:25:38 +02:00
2b8d9bf2b8 FBX IO: Add support for armature data custom properties
Armature data custom properties are now imported from and exported to
the NodeAttribute connected to the Armature's Node.

This implements part of #104677.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104888
2023-09-19 01:53:43 +02:00
e7b1962893 FBX IO: Speed up transformation animation import
This patch speeds up the conversion from animated FBX lcl
translation/rotation/scale to Blender translation/rotation/scale.

An FBX file containing an armature with 65 bones and a single animation
with 1523 frames (each one keyframed) animating 47 bones (144 animated
channels in the FBX file) goes from a 1.01s import to a 0.38s import for
me with this patch. This patch should provide better baselines to
compare future performance improvements against.

Animated rotations are now converted to radians in advance using NumPy.

The non-animated matrices are now calculated once in advance and
combined into as few matrices as possible using the associative property
of matrix multiplication, reducing the amount of matrix multiplication
required to calculate the final matrix for each imported keyframe.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104870
2023-09-11 13:53:10 +02:00
bf0e7c8d6e FBX IO: Only import the first animation curve per channel
FBX's default animation system only uses the first animation curve
assigned to a channel.

This patch changes the FBX Importer to also only use the first animation
curve assigned to a channel.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104866
2023-09-08 00:33:36 +02:00
7362631fa4 FBX IO: Fix error importing transformation animations with a single channel
The second return value of _combine_curve_keyframe_times is supposed to
be a list of arrays, but when there was only a single input array, that
array was being returned directly, without putting it in a list.

This fixes an unreported mistake in abab1c9343.
2023-09-06 22:56:51 +01:00
abab1c9343 FBX IO: Speed up animation import using NumPy
This patch updates much of the animation import code to replace
iteration with NumPy vectorized functions and can result in a
significant speedup for files that are mostly animation.

An FBX file containing an armature with 65 bones and a single animation
with 1523 frames (each one keyframed) animating 47 bones (144 animated
channels in the FBX file) goes from a 1.96s import to a 1.01s import for
me with this patch.

The majority of the remaining animation import time after this patch is
spent converting FBX transformation animations to Blender transformation
animations. Much of this can also be sped up with NumPy, but that will
be submitted separately once it is finished. For this reason, the new
`_transformation_curves_gen` function is only intended as an interim to
facilitate this patch until the transformation animation conversion is
also updated to use NumPy.

# Changes to the import of valid animations:
Previously, all imported animation curves for a single Action would
interpolate the keyframes of every other animation curve imported for
that action. This is needed for imported Object/PoseBone transformation
animations, but is unnecessary for other imported animations.

This was unlikely to be noticed because it only affected material color
animations and animations that affected both the `lens` and
`focus_distance` properties of a camera.

Now with this patch, only the transformation animation curves
interpolate the keyframes of every other transform animation curve.

This change is a requirement to be able to support importing other
animation curves in the future, such as those for custom properties.

# Changes to the import of questionably valid animations:
FBX's default animation system only uses the first animation curve
assigned to a property's channel, but the specification does allow for
more than one curve per channel.

Previously, Blender would combine these curves together, but in such a
way that each additional imported curve would replace all the values of
prior imported curves at times less than the maximum keyframe time of
the additional imported curve (interpolating values for the keyframes
that don't exist in the additional imported curve).

Now when there are multiple animation curves assigned to a channel, the
additional imported curves only replace values at their keyframe times,
no interpolation for other keyframe times takes place.

# Changes to the import of invalid animations:
An animation curve is invalid if its keyframe times are not strictly
increasing. Some imported invalid curves result in extrapolating values.
These extrapolated values are still discarded with this patch, but
previously they would be replaced with a default value. With this patch,
the extrapolated values and their keyframe times are discarded entirely.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104856
2023-09-04 22:07:43 +02:00
30b697938c Fix #104820: FBX import error due to removed light distance property 2023-08-08 17:47:29 +02:00
9254557d0b Fix #104773: FBX import fails when custom property name matches an expected non-custom property
The importer expects some named properties to have specific types
because they are usually FBX-defined properties, but the importer was
also accepting user-defined properties with the same name, which could
have any type, causing an error to be raised when checking the
property's type.

This patch changes the importer to ignore custom properties when finding
specific properties by name.

The import of custom properties is unchanged by this patch.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104821
2023-08-08 16:14:41 +02:00
89bd09391a Fix #104706: Imported FBX shape key values outside the 0.0 to 1.0 range are clamped
This patch changes the FBX import of shape keys by decreasing/increasing
their slider_min/slider_max to fit the imported Value (DeformPercent in
FBX). If the imported Value already fits within the slider range, no
changes are made.

To fit the imported Value, the slider_min/slider_max is set to double
the imported Value if that would fit it within the slider range,
otherwise the slider_min/slider_max is decreased/increased by double the
distance from the imported Value to the current slider_min/slider_max.

Expanded slider_min/slider_max values are rounded down/up to the nearest
integer to produce a more visually pleasing result.

The animated values of shape keys are also checked when animations are
imported and decrease/increase slider_min/slider_max in the same way.

Blender has a hard minimum of -10.0 for slider_min and hard max of 10.0
for slider_max (the importer gets these values from the ShapeKey type's
bl_rna rather than being hardcoded). If a shape key's current or
animated value goes outside that range, a warning is printed to the
system console.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104740
2023-07-24 15:20:04 +02:00
d17ed07832 FBX IO: Corner vert/edge and edge verts access with attributes
Blender 3.6 moved corner (loop) vertex index and edge index, and edge
vertices to generic attributes. The old API still works for now, but is
slower and may be removed in 4.0, so this patch updates FBX IO to use
the new ".corner_vert", ".corner_edge" and ".edge_verts" attributes.

numpy.astype() with copy=False does not create a new view in the desired
dtype when the original dtype is the same kind, itemsize and byteorder,
but has a different character code, e.g. 'i' and 'l'. This is
problematic because Blender can be picky about the character code. The
astype_view_signedness() utility function has been updated to create
such views instead of falling back to numpy.astype().

This patch makes no changes to the import or export of FBX files.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104648
2023-06-26 17:43:23 +02:00
39a012ca07 FBX IO: Vertex position access with attributes
Blender 3.5 moved vertex positions to a generic attribute. The old API
still works for now, but is slower and may be removed in 4.0, so this
patch updates FBX IO to use the new "position" attribute.

This patch makes no changes to the import or export of FBX files.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104647
2023-06-26 17:42:47 +02:00
eb2bfdcaf1 FBX IO: Edge/face sharp access with attributes
Blender 3.5 moved edge sharp to a generic attribute and 3.6 moved face
smooth to a generic attribute. The old API still works for now, but is
slower and may be removed in 4.0, so this patch updates FBX IO to use
the new "sharp_edge" and "sharp_face" attributes.

Because the old API was face smooth, not sharp, the logic for working
with "sharp_face" is inverted compared to before.

When the "sharp_edge" or "sharp_face" attributes do not exist, all edges
or faces can be assumed to not be marked sharp, reducing necessary work.

A comment comparing the speed of calculating polygon sides from `t_ls`
vs getting polygon sides from polygon "loop_total" has been updated to
reflect the change that "loop_total" is not stored internally as of 3.6
and is now slower to access.

This patch makes a minor change to the import of FBX files, whereby code
that used to set every face to smooth now removes the "sharp_face"
attribute instead.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104649
2023-06-26 15:46:39 +02:00
5d72f0e881 FBX IO: Vertex normals access with new vertex_normals property
Blender 3.1 moved vertex normals to a separate array. The old API still
works for now, but is slower and may be removed in 4.0, so this patch
updates FBX IO to use the new `vertex_normals` property.

This patch makes no changes to the import or export of FBX files.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104651
2023-06-26 15:36:56 +02:00
204a6ef7b5 FBX IO: UVs access with new uv property
Blender 3.5 moved UV layers to a generic attribute also accessible from
the new `uv` property of the UV layer. The old API still works for now,
but is slower and may be removed in 4.0, so this patch updates FBX IO to
use the new `uv` property.

There is no performance difference between accessing the UVs through the
foreach_get/set functions of the attribute and the `uv` property.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104650
2023-06-26 15:35:50 +02:00
670406d0a5 FBX IO: Material index access with attributes
Blender 3.4 moved material indices to a generic attribute. The old API
still works for now, but is slower and may be removed in 4.0, so this
patch updates FBX IO to use the new "material_index" attribute.

This patch changes the export of meshes that have multiple materials,
but where all the polygons are assigned to the first material (so there
is no "material_index" attribute) to export using the "AllSame" type.
Material indices exported in this way export in negligible constant
time.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104646
2023-06-26 13:05:45 +02:00
eba777ca9a FBX IO: Add attributes utility functions
These are used by subsequent patches to update mesh data access to use
attributes.

The ability to specify the foreach_get/set Python attribute in attribute
utility functions is not currently used, but is to facilitate color
attributes which might want to by accessed with "color_srgb" instead of
the default of "color".

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104645
2023-06-26 13:01:24 +02:00
28814d62ec Merge branch 'blender-v3.6-release' 2023-06-21 16:17:04 +02:00
716702b97e Fix disparity of FBX custom properties import and export
Light, camera, bone and pose bone properties are now imported to match
the exporter behaviour.

Image custom properties are now exported to match the importer
behaviour, except for Image custom properties that are rarely imported
from a Texture Node instead of a Video Node, which are always exported
to a Video Node.

This resolves one of the issues in #104677.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104702
2023-06-21 15:52:56 +02:00
fde8af8659 Fix #104707: FBX edge creases fail to be imported/exported
The MeshEdge.crease API has been removed in 4.0, replaced with the
"crease_edge" attribute and the Python defined
Mesh.edge_creases/edge_creases_ensure()/edge_creases_remove().

This patch replaces use of the old MeshEdge.crease API with accessing
the "crease_edge" attribute with the Python defined property and
function.

The intention of this patch is not to perform any functional changes
compared to when the older MeshEdge.crease API was used, so while it may
be possible to skip exporting creases when there aren't any, this has
been left as a "todo" comment for now.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104709
2023-06-21 15:46:49 +02:00
e8da6131fd License headers: use SPDX-FileCopyrightText for all addons
Move copyright text to SPDX-FileCopyrightText or set to the
Blender Foundation so "make check_licenses" now runs without warnings.
2023-06-15 16:54:05 +10:00
096470d98f Merge branch 'blender-v3.6-release' 2023-06-09 17:48:51 +02:00
80db34b208 Fix #104669: Incorrect material assignment of imported FBX with duplicate materials
The initial fix made for #103976 incorrectly identified the issue as
being part of the exporter and changed the exporter to work with the
bugged behaviour of the importer. This patch fixes the issue on the
importer side.

Unlike Blender, Materials always belong to the FBX Model (Object
equivalent), whereas Blender defaults to the Materials belonging to the
Mesh (FBX Geometry equivalent). When a Mesh was used by multiple
Objects, to prevent appending the Materials of each FBX Model to the
Mesh, a set of already used Materials was kept and non-unique Materials
would be skipped. However, skipping non-unique Materials would mean the
material indices of a Mesh no longer match its Materials, causing the
material indices to appear offset or invalid.

This patch changes the import of Meshes containing duplicate Materials.
The duplicates are now added to the Mesh in their original order
instead of being skipped.

This patch changes the import of Meshes used by more than one Object
whereby the imported Objects have different Materials. After the
Materials from the first imported Object are appended to the Mesh, any
different Materials from other imported Objects at the same indices have
their Material Slot linked to the Object with the differing Material set
in that Material Slot. If other imported Objects have more Materials
than the number of existing materials on the Mesh, the additional
Materials are appended to the Mesh. Previously, Materials that were
already present in the Mesh would be skipped and new Materials would be
appended to the end of the Mesh's Materials.

Meshes containing duplicate materials that were exported by Blender 3.5
and earlier would export duplicate materials despite only one of the
duplicates being used by the exported mesh (fixed in #104667). All the
duplicates in these FBX files are now imported with this change.

Due to the previous incorrect attempt fix for #103976, FBX with
duplicate materials exported by Blender 3.5 have incorrect material
indices (fixed in #104667). The importer issue fixed by this patch
combined with the exporter issue would cause such incorrectly exported
FBX files to import as if they had been exported correctly in the first
place. Now that the importer issue is fixed, this is no longer the case
and the importer will now show that those Blender 3.5 exported FBX with
duplicate materials have incorrect material indices.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104683
2023-06-09 17:46:16 +02:00
ce2dbbb841 Update add-ons for removed Mesh.calc_normals() 2023-05-23 13:04:12 +10:00
8e37176dcd FBX Import: Fix pre-, post- and geometric rotations
The pre-, post- and geometric rotations were using the rotation order of
the transform, but it's only the rotation that uses the rotation order
of the transform.

The post-rotation used in calculating the WorldTransform was being used
as-is, this seems to have been an error in the FBX 2011 documentation
because since FBX 2012, the documentation has specified that the inverse
of post-rotation is used and there is no mention of this change in the
FBX 2012 changes. Additionally, given files in FBX 2011 format, the
post-rotation works the same as in FBX 2012 and newer.

The pre-, post- and geometric rotations have been changed to always use
XYZ order.

The post-rotation is now inverted when calculating each WorldTransform.

Fixes the import of .fbx that have non-zero post-rotation.
Fixes the import of .fbx that have pre-/post-/geometric rotation and
have non-XYZ rotation order.

Cases where the "Use Pre/Post Rotation" option of the FBX Importer had
to be disabled to get a working import are likely to now work with the
option enabled.

Fixes #45176: Incorrect rotation of imported Cameras and Lights

Note: no update is required to exporter code, as Blender never defines any pre/geometrical/post rotation for its data.

----

The recent claim to having fixed #45176 in https://projects.blender.org/blender/blender-addons/pulls/104500 had me wondering what the actual problem with imported camera rotations was. Some other open-source FBX importers have had and fixed similar issues. It appears that there were two issues at play, I've tried to explain them here.

### post-rotation inversion
Initially I figured out that post-rotation needed to be inverted by setting up an .fbx with post-rotation on a camera on all three axes (.fbx files in reported issues tend to have only a single non-zero axis) and importing it into Unity and then manually brute-forcing the rotation order and sign of components in Blender's FBX importer until Blender matched.
Later, I found that since FBX 2012, [the documentation](https://download.autodesk.com/global/docs/fbxsdk2012/en_us/files/GUID-10CDD63C-79C1-4F2D-BB28-AD2BE65A02E-50.htm) actually specifies that the inverse of the post-rotation is used. There was no mention of post-rotation changing in the FBX 2012 change notes and it just so happened that the [ecp020_shotcam1_2011_v001.fbx](https://archive.blender.org/developer/F197080/ecp020_shotcam1_2011_v001.fbx) attached in https://projects.blender.org/blender/blender-addons/issues/45176 was a 2011 format FBX, so I could inspect its post-rotation and convert it to a newer FBX format using FBX Converter 2013. By observing that both the original 2011 version and the converted 2013 version had identical post-rotation, both displayed the same in the FBX Viewer in FBX Converter and both imported correctly into Blender when using the inverse of post-rotation, I deduced that the FBX 2011 documentation must have been incorrect as opposed to the FBX format having changed in this regard in FBX 2012.

ufbx inverts post-rotation: 70d5526256/ufbx.c (L19152)
assimp inverts post-rotation: b1afa41047/code/AssetLib/FBX/FBXConverter.cpp (L820)
I also found a thread on the autodesk forums from 2010 where the user managed to figure out that post-rotation needed to be inverted, despite it not being in the documentation: https://forums.autodesk.com/t5/fbx-forum/maya-quot-rotate-axis-quot-vs-fbx-quot-postrotation-quot/td-p/4168814?profile.language=en

### pre-/post-/geometric rotation order
The [FBX documentation](http://download.autodesk.com/us/fbx/20112/FBX_SDK_HELP/index.html?url=WS1a9193826455f5ff1f92379812724681e696651.htm,topicNumber=d0e7429) only actually specifies that the `R` rotation matrix takes into account the rotation order of the transform, it seems to have been a mistake to also apply the rotation order to the other rotation matrices.
The example code under "Pivot Management" at https://download.autodesk.com/us/fbx/20112/FBX_SDK_HELP/SDKRef/a00209.html actually has a comment that states "// Rotation order don't affect post rotation, so just use the default `XYZ` order", so that at least makes it clear that post-rotation is not affected by rotation order.
assimp had the same issue of not having pre-/post-rotation in `XYZ` order: 9444935ce8
ufbx also uses `XYZ` order for pre-/post-rotation: 70d5526256/ufbx.c (L19165)

Geometric rotation I couldn't tell whether to use 'XYZ' or the rotation order of the transform so figured it out myself by modifying the `Road_signs_v1.FBX` from https://projects.blender.org/blender/blender-addons/issues/104558 so that the first sign Model had a geometric rotation of `(-90, -20, 15)` and so that all the models in the file had `ZXY` rotation order. By opening the modified .fbx in Unity and FBX Review, I could see that geometric rotation had to also always be `XYZ` otherwise blender would import the rotation of the modified first sign Model incorrectly.

### Tested files now importing with expected rotation with this patch
The FBX Viewer in FBX Converter 2013 is very useful for showing the expected import where users have not provided screenshots in the issues though it tends to crash opening manually modified .fbx files and can't open some newer .fbx files since it's only designed to support up to FBX 2013. FBX Review is also useful for the same purpose and is much more recent and resilient to manually modified and broken .fbx files, but it's very basic and doesn't show cameras or lights as objects in the scene which makes it less useful since a lot of the reports are about camera rotations specifically.
I found that a lot of the imported .fbx import really tiny with default settings, so you may need to zoom in or scale up imported Objects to see them better in Blender.
* [ecp020_shotcam1_2011_v001.fbx](https://archive.blender.org/developer/F197080/ecp020_shotcam1_2011_v001.fbx) from https://projects.blender.org/blender/blender-addons/issues/45176#issue-5995
  * ![image](/attachments/ffa400cc-3345-4150-8f42-3d34ea6dc443)
  * ![image](/attachments/f57d2ee3-91c8-44bd-b042-a3fd47527940)
* [T1v2.fbx](https://archive.blender.org/developer/F512439/T1v2.fbx) from https://projects.blender.org/blender/blender-addons/issues/45176#issuecomment-55477
  * ![image](/attachments/adf77195-de10-4529-864e-7956b24cc34e)
* [fontan new.fbx](https://archive.blender.org/developer/F8959054/fontan_new.fbx) from https://projects.blender.org/blender/blender-addons/issues/81444#issuecomment-24398
  * Note that this .fbx also sets the `Shift X` and `Shift Y` of the camera in the import, so to get parity with other software, both shift values may need to be set to zero.
  * ![image](/attachments/e7aec455-8c28-4d7c-8322-b03e2203a53f)
* [g2f_nolimits.fbx](https://drive.google.com/file/d/12e2DtFcy8fqVmhOsq4DSuth7U4wmbbkH/view?usp=sharing) from https://projects.blender.org/blender/blender-addons/issues/88272#issue-2434
  * This patch does not solve the linked issue, but rather fixes the fact that importing older DAZ3D FBX would have incorrect rotations unless `Use Pre/Post rotations` was disabled in the importer (this is a common step to find in older tutorials for importing from DAZ Studio to Blender). With this patch, disabling `Use Pre/Post rotations` appears to now be unnecessary, though I was unable to find an older animated DAZ3D FBX to determine if animations would also work. Newer versions of DAZ Studio appear to not use pre- and post-rotations in their FBX exports anymore, so the `Use Pre/Post rotations` option of the importer is irrelevant for newer DAZ3D produced .fbx files.
  * ![image](/attachments/2753508d-f743-4b96-a7ec-1394fabc3c6d)
* [MayaLightCameraOutputTest_20201012.fbx](https://archive.blender.org/developer/F8982408/MayaLightCameraOutputTest_20201012.fbx) from https://projects.blender.org/blender/blender-addons/issues/81647
  * ![image](/attachments/b7c2670b-2b32-4fd3-b29f-3ccfc618ae0e)
* [Road_signs_v1_underground_parking_geometric_rotation_modified.fbx](/attachments/f853909f-7dcb-4943-b949-e1628797da89)
  * This is the .fbx I modified so that the first sign has a geometric rotation of `(-90, -20, 15)` and so that all the objects have `ZXY` rotation order.
  * ![image](/attachments/13be9877-7572-479e-9807-139298e22601)
  * ![image](/attachments/5f9d895a-b87f-4c79-8018-df49fdca1a83)

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104561
2023-04-28 17:21:48 +02:00
bb76a94d06 Cleanup: Remove setting polygon loop total
This property is not editable after blender/blender/7966cd16d6dc4e66d01,
though doing so didn't seem to give an error. It doesn't have
to be set anymore, since the data is redundant with the
"loop_start" anyway.
2023-04-12 08:46:40 -04:00
2438ae5c27 FBX Import: Speed up geometry with numpy
Use buffers matching the C data types with foreach_set to avoid iterating and casting each element in foreach_set's C code.
Use numpy vectorized operations.
Replace _vcos_transformed_gen with numpy version, vcos_transformed.

Testing with verts/edges/polys arrays created from subdivided default cubes:
~8-45 times faster for about 1000 to 100_000 loops (len(fbx_polys)) then starts reducing at a reducing rate down to about 35 times faster after 6 million loops.
The speedup for setting smoothing is small, within the range of about 1-1.4 times.
The speedup for setting split normals is negligible since most of the time is spent on Mesh.normals_split_custom_set which runs in the same time as before.

Changes made to the import of malformed .fbx files:
.fbx that have edges, but no polygon-vertex-indices will now ignore the edges, print an error and continue the import, resulting in a mesh containing only vertices. Beforehand, an IndexError would be raised when an attempt would be made to index the empty fbx_polys array.
.fbx that have a verts array with a number of elements that isn't divisible by 3 will now have the remainder stripped from the end and an error will be printed. Beforehand, a RuntimeError would be raised by mesh.vertices.foreach_set("co", fbx_verts) because fbx_verts would not contain the number of elements exactly 3 times the number of vertices.
2023-04-03 14:55:09 +02:00
9859e253b5 FBX Import: Speed up geometry layers with foreach_set and numpy
Replace per-element xform functions with numpy vectorized functions.

Setting a stride larger than item_size remains supported despite being unused.
Setting a stride smaller than item_size is not implemented.

The only specific change to a geometry layer is that vertex and polygon normals are now expanded to loop normals using numpy and foreach_set.

The overall speedup will vary depending on what layers are being imported, how many and which mapping is being used for each layer.
This can result in a large speedup for imports that have many layers, especially larger layers such as UVs and vertex colors.

Since this patch uses foreach_set it does mean that the new functions are limited to importing into blender data that is exposed to the Python API as bpy_prop_collection instances.
All existing imported geometry layers meet this criterion.
2023-04-03 14:50:14 +02:00
66390ced12 FBX Import: Speed up shape keys with numpy
Move vg.add outside the hot loop when adding vertex groups for shape key weights. This will also slightly speed up the import of bone weights since that uses the same function.

Group shape keys by mesh so that each mesh only needs to be processed once. This is important for the new code, since it has an upfront cost per mesh. Without the grouping, the same individual cost would be per shape key instead.

The greater the percentage of the mesh that a shape key moves, the greater this patch's speedup.
If the number of indices of an imported shape key is less than about 2% the number of vertices of the mesh, this patch can end up slower due to every vertex in the shape key being set, not only those moved by the imported shape key.
For many shape keys that move only a small portion of the mesh, e.g. character models with shape keys for facial animations, the speedup is often only around 1-3 times and can be slightly slower in some cases.
It's possible to modify the original code to iterate more efficiently, at which point the threshold would change to being less than about 7% the number of vertices.
2023-04-03 14:43:22 +02:00
5da3d41c27 FBX Import: Speed up cycles decal workaround with numpy
Replace iteration with foreach_get/set and numpy vectorized operations

An issue introduced in Blender 3.3 makes the original code very slow:
https://projects.blender.org/blender/blender/issues/105909
So this results in about a 1500 times speedup at 6000 vertices and 3500 times at 25000 vertices.

In Blender 3.2 the new code would run about 40-60 times faster for 1000-25000+ vertices.
2023-04-03 14:41:45 +02:00
47da0ad56b FBX Import: Base patch for numpy and foreach_set speedup
This is a base patch that the other separate numpy and foreach_set patches to the FBX importer rely on.

Add imports used by the other patches.
Add utility function for converting Python arrays to numpy ndarrays that share the same memory.
2023-04-03 14:40:56 +02:00
14b248aac0 Cleanup: fix a few issues in UI messages
- Replace "UV's" by "UVs"
  The apostrophe is not a mark of plural but of possessive in English.
- "generic [coordinate] values"
  Likely a copy / paste mistake
2023-02-23 16:42:37 +01:00
7d80f2f971 Fix T104326: FBX Import: material link b'TransparencyFactor' ignored. 2023-02-06 17:03:37 +01:00
b83a135675 Fix T102810: Error for import FBX ASCII
The import script was broken in rBA27ee43296585, because I forgot an
import for i18n. ASCII FBX is still not supported, but at least the
erro reporting won't crash.

Reported by Evan Wilson in D16373.
2022-11-29 22:24:54 +01:00