Adds a new USD export test which guards against potential future changes
that impact how and when `AbstractHierarchyWriter` objects are written.
The test has mesh and curves(new) objects which contain no geometry for
frame ranges [1,3] and [7,9] but will contain geometry for frames [4,6].
This validates the exported geometry data is as expected for all frames.
Pull Request: https://projects.blender.org/blender/blender/pulls/163232
Text, metaball, and NURBS surface objects get converted to meshes as
part of depsgraph evaluation and will be detected as a "dupli" which
were then excluded for export; as otherwise we'd get double exports.
However, this exclusion needs to be more selective because such objects
would then be excluded incorrectly if they were inside an instanced
Collection or when instanced through point clouds. Only exclude them if
they are the same original object, preventing duplicate exports but
allowing true instancing to work.
Added new test which instances a Collection of these object types using
both collection instances and point instancing.
Pull Request: https://projects.blender.org/blender/blender/pulls/161710
Support import/export of Matrix4d primvar attribute values.
The changes to io_report.py are currently unused but were implemented
for completeness.
Note: The double-precision 64-bit values from USD are converted to float
32-bit on import.
Pull Request: https://projects.blender.org/blender/blender/pulls/160182
Most game engines use and store normal data per-point. Blender's default
USD export always converts them to face-varying/corner. This PR exports
normals following Blender internal data model (point, corner or face),
thus making import in engines more straightforward for meshes that
already use per-point normals without additional conversion steps.
USD export tests have also been updated to reflect this change.
Pull Request: https://projects.blender.org/blender/blender/pulls/159858
USD export currently only saves to disk at the very end of export. Due
to how USD de-duplicates data, all timeSamples remain in memory until
that time. This is problematic for cases such as #156402 that, due to
their size, quickly exhausts memory.
The solution is to call Stage Save() throughout the export process
instead of waiting until the end. However, it needs to be configurable.
Incremental saves have caused issues in the past for Google Drive
locations and it will be slower to export (slightly). Additionally, it's
not trivial or elegant to estimate the size of the exported data either.
We leave it up to the user to decide how frequently to save.
The new option will be displayed when the Animation option is selected.
Fixes#156402
Pull Request: https://projects.blender.org/blender/blender/pulls/158069
On export, apply the UsdColorSpaceAPI schema to the root prim, materials
lights, color primvras and shader prims for image textures. By default
the root prim would have been enough, but it is possible to export with
out a root prim and this keeps behavior consistent independent of that
setting.
On import, use UsdColorSpaceAPI::ComputeColorSpaceName to resolve
the colorspace for each color attribute through the USD hierarchy,
and convert from that colorspace to scene linear.
Pull Request: projects.blender.org/blender/blender/pulls/157196
Currently after mesh data evaluation finishes evaluating modifiers, it
copies the name of the object's original mesh to the evaluated mesh.
This is problematic for a couple reasons. First is that it's not
necessarily right semantically. The mesh might have been sourced from
another object during evaluation with some method like the object info
node. Second, this requires the final mesh to be mutable. While that
isn't a problem for current code, it gets in the way for #119968, which
optimizes modifier evaluation using implicit sharing though GeometrySet
to avoid copies.
To get the same evaluated mesh naming as before where it makes sense,
this PR makes mesh copy/creation functions copy the name. That way the
original name is propagated through the modifier stack and nodes, similar
to the way the edit mesh pointer is propagated after 839108f623.
This still required a change to the USD export test though, because the
mesh it exports is generated from scratch inside Geometry Nodes; it doesn't
come from the original mesh in any way.
Pull Request: https://projects.blender.org/blender/blender/pulls/155330
In USD primvars can use ':' to namespace their primvar variables. It is
somewhat common, especially with USD files from more established DCCs,
to see primvars like `primvars:ri:attributes:user:MatteID0`.
During Import we would read this in correctly. However, Export would
sanitize the name and convert ':' to '_' unnecessarily. This PR allows
generic primvars, including UVs, to contain ':'.
Pull Request: https://projects.blender.org/blender/blender/pulls/155300
An incorrect scaling vector was used that resulted in the positions of
the incoming and outgoing USD prims not being scaled accordingly.
There was already test coverage in place for the general code paths, but
none tested or verified the positions of the objects when scaling was
required. Added additional test coverage to prevent future regressions.
Pull Request: https://projects.blender.org/blender/blender/pulls/154780
Allow the USD curves writer to export empty curve objects. Notably this
fixes a crash for old-curve objects and allows for animations where some
frames contain splines and some do not.
Because curve objects are just containers for any type of curve,
animated setups where the very first frame contains 0 splines may export
incorrectly. USD needs to know what type of curve it is (catmullRom,
bezier, poly, etc.) when defining the Prim, but if the object contains 0
splines, then we don't know what it should be. For this situation we
have a fallback where old-curves default to bezier and new-curves
default to catmullRom. All subsequent frames must only have curve types
matching the fallback.
Pull Request: https://projects.blender.org/blender/blender/pulls/152752
The UsdPreviewSurface has odd semantics related to its `opacity` input
where it is not only used for translucency/transmission but also for
so-called "alpha cutouts", despite the fact that the UsdPreviewSurface,
and all other USD surfaces, not having an actual Alpha input.
Up until this PR we were only considering the alpha cutout type networks
rather than transmission, which has meant we could never import/export
something like glass. Additionally, `opacity` is the inverse of
`transmission weight`, which is used on all other, modern, material
surfaces, which massively complicates export and import. We have to
invert the opacity <-> transmission values/graphs to properly handle it.
This PR will handle some very simple networks where things are plugged
into our Transmission Weight socket.
Like all other material network support, processing here is limited to
the usage of the Principled BSDF. Direct usage of e.g. a Glass BSDF node
is not supported.
Tests updated to include "constant" opacity values as well as several
texture-based networks (see screenshot).
Ref: #100452
Pull Request: https://projects.blender.org/blender/blender/pulls/152546
Move several tests from manual validation into the compare framework.
This reduces overly verbose and sometimes difficult to understand python
code in exchange for an easier to read textual representation of
everything that was imported.
Only tests where the validation would be the same or better were
considered.
Minor changes to the io_report module were done to support this like
dumping `UDIMTile` information as well as escaping the generated report
data so file paths like `test_grid_<UDIM>.png` would show correctly.
Pull Request: https://projects.blender.org/blender/blender/pulls/151748
ParticleSystem hair was being exported as linear catmullRom rather than
as cubic catmullRom. Found while moving this test from manual validation
to the compare framework (in a separate PR).
Pull Request: https://projects.blender.org/blender/blender/pulls/151645
This change adds support for importing and exporting accessibility
metadata to USD.
Details:
USD supports authoring accessibility metadata via the UsdUIAccessibilityAPI
schema. Two methods for authoring accessibility metadata are supported:
1) An accessibility label and description can be specified directly in
the USD export options via two new string export fields This data will
be set on the default prim of the exported stage and will have a
"standard" priority.
2) Accessibility data can be authored in the Blender object's Custom
Properties which will be written to the corresponding USD prim during
the export. If creating custom properties, the property name must be
defined in the following format:
- accessibility:\<namespace\>:label
- accessibility:\<namespace\>:description
- accessibility:\<namespace\>:priority
Since the AccessibilityAPI is a MultipleApply schema, the namespace
can specify an intended purpose for the accessibility metadata.
Note: Although the AccessibilityAPI schema supports time-samples,
Blender STRING properties are not keyframe-able, so this change only
writes default attribute values without any time-samples.
On import, the accessibility properties are populated back into the
object's Custom Properties.
Authored by Apple: Dan Knowlton
Pull Request: https://projects.blender.org/blender/blender/pulls/149682
These Ids are required for correct in-camera motion blur so read and
write them as appropriate for both point clouds and point instancers.
The incoming USD Ids are 64-bit but Blender only supports 32-bit Ids so
the values will be narrowed. This will potentially produce different or
duplicate Ids depending on how far the value is outside the
[-2147483648, 2147483647] range.
Pull Request: https://projects.blender.org/blender/blender/pulls/149666
This change updates the USD mesh export to write indexed UVs rather
than the previous unindexed (per face vertex) UVs to preserve UV
connectivity information.
Details:
Previously the USD export of mesh UVs was not preserving any
information about the UV connectivity. This meant that importing
the USD into another DCC that relies on indexed UVs for connectivity
would treat each face as a separate UV island.
With this change, the `BKE_mesh_uv_vert_map_create` function is
used to determine the UV connectivity during the USD export and
to write indexed UVs.
Authored by Apple: Dan Knowlton
Co-authored-by: Dan Knowlton <d_knowlton@apple.com>
Pull Request: https://projects.blender.org/blender/blender/pulls/149677
The report in question uncovered two sources of issues. The primary one
being that there was an accidental double-transform from placing the
basis curves prim under the main Xform of the mesh too. This is solved
by considering the inverse of mesh's world transform when writing out
the curve points.
The second was exposed with the new, more correct, viewport drawing of
curves that showed that we were exporting the wrong curve type. This
would manifest as a disappearing curve segment at the beginning and end
of the curve. Fixed by explicitly writing out catmull-rom, pinned,
curves for the hair rather than using bsplines.
As a result the Storm-USD tests now match much closer to the native
Storm-Hydra variants.
Pull Request: https://projects.blender.org/blender/blender/pulls/148543
The motivation is to keep backward compatibility after deprecating
`material.use_nodes()` and `world.use_nodes`. For example the
following script would behave the same way in 4.5 and 5.0:
```python
mat = bpy.data.materials.new("My new mat")
mat.use_nodes = True
```
Pull Request: https://projects.blender.org/blender/blender/pulls/147052
"Use Nodes" was removed in the compositor to simplify the compositing
workflow. This introduced a slight inconsistency with the Shader Node
Editor.
This PR removes "Use Nodes" for object materials.
For Line Style, no changes are planned (not sure how to preserve
compatibility yet).
This simplifies the state of objects; either they have a material or
they don't.
Backward compatibility:
- If Use Nodes is turned Off, new nodes are added to the node tree to
simulate the same material:
- DNA: Only `use_nodes` is marked deprecated
- Python API:
- `material.use_nodes` is marked deprecated and will be removed in
6.0. Reading it always returns `True` and setting it has no effect.
- `material.diffuse_color`, `material.specular` etc.. Are not used by
EEVEE anymore but are kept because they are used by Workbench.
Forward compatibility:
Always enable 'Use Nodes' when writing blend files.
Known Issues:
Some UI tests are failing on macOS
Pull Request: https://projects.blender.org/blender/blender/pulls/141278
Refactor and revamp import and export of `UsdGeomNurbsCurves` prim
objects.
Fixes#130056, among other things.
Summary of changes and enhancements:
- Export:
- Write out `nurb_weight` attribute as the USD `pointWeights` primvar
- Properly write out cyclic NURBS curves data (* see notes)
- Import:
- Import using the new `Curves` datablock rather than the old `Curve`
- Properly read in cyclic NURBS curves data (* see notes)
- Tries harder to match incoming knot vector to standard `knots_mode`,
will use Custom otherwise
- Support import of all custom primvars and data attached to the prim
(for use with Geometry Nodes etc.) (* see notes)
Tests were added which check a variety of point count, order, knot_mode,
and cyclic combinations (generated through Geometry Nodes). A small
number of hand-crafted curves were used to test the Custom knots_mode
support on import. Additionally, the tests cover the case when there are
multiple curves defined for a single object.
Notes:
- Cyclic NURBS support is reliant on the current, under-spec'd, USD
documentation. Changes may be required in the future if/when the USD
spec is clarified: https://github.com/PixarAnimationStudios/OpenUSD/issues/3740
- Some Cyclic x knots_mode combinations are not correct and would
require more research to determine how to properly address.
- Custom attributes are not imported for Cyclic NURBS curves yet. Those
will require additional work to function correctly and are also
reliant on seeing how the USD spec changes.
Pull Request: https://projects.blender.org/blender/blender/pulls/143970
Blender grid rendering interprets voxel transforms in such a way that the voxel
values are located at the center of a voxel. This is inconsistent with OpenVDB
where the values are located at the lower corners for the purpose or sampling
and related algorithms.
While it is possible to offset grids when communicating with the OpenVDB
library, this is also error-prone and does not add any major advantage.
Every time a grid is passed to OpenVDB we currently have to take care to
transform by half a voxel to ensure correct sampling weights are used that match
the density displayed by the viewport rendering.
This patch changes volume grid generation, conversion, and rendering code so
that grid transforms match the corner-located values in OpenVDB.
- The volume primitive cube node aligns the grid transform with the location of
the first value, which is now also the same as min/max bounds input of the
node.
- Mesh<->Grid conversion does no longer require offsetting grid transform and
mesh vertices respectively by 0.5 voxels.
- Texture space for viewport rendering is offset by half a voxel, so that it
covers the same area as before and voxel centers remain at the same texture
space locations.
Co-authored-by: Brecht Van Lommel <brecht@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/138449
Move the existing USDZ export test from C++ to Python for better
validation. The resulting file is now run through the `usdchecker`
system and we also check the contents of the resulting archive for the
expected texture file. This helped uncover a pathing issue in the
resulting archive where the 'textures' directory was misnamed on win32;
though it was still functional.
Pull Request: https://projects.blender.org/blender/blender/pulls/144176
Adds and corrects the extent attributes of USD PointInstancer prims.
Extents are now computed for PointInstancers just before the USD stage
is saved and during the export finalization step. The unit test has been
updated accordingly.
This PR also marks all point instancers' prototypes as over after the
extent calculation is done, including the prototypes used by nested
point instancers. This follows the official USD recommendation to place
prototypes under a point instancer marked as over:
https://openusd.org/docs/api/class_usd_geom_point_instancer.html#:~:text=place%20them%20under%20a%20prim%20that%20is%20just%20an%20%22over%22
Authored by Apple: Zili Zhou (Liz)
Co-authored-by: Zili (Liz) Zhou <zili_zhou@apple.com>
Pull Request: https://projects.blender.org/blender/blender/pulls/141299
Adds a Point Instancing exporter based on the existing
USDPointInstancerReader. Covers both round-trip and Blender-native
workflows. Exports 'Instance on Points' setups as USDGeomPointInstancer,
supporting objects, collections, and nested prototypes.
A warning is shown during export if invalid prototype references are
detected. These would occur if an instancer attempts to instance itself.
This feature is currently gated behind an off-by-default export option
(`use_instancing`) as there are still a few cases which can yield
incorrect results.
Further details in the PR.
Ref: #139758
Authored by Apple: Zili (Liz) Zhou
Pull Request: https://projects.blender.org/blender/blender/pulls/139760
Current NURBS evaluation handles corners or sharp angles poorly. Sharp
edges appear when a knot vector value is repeated `order - 1` times.
Users can make sharp corners by creating NURBS curve with `Bezier` knot
mode or by setting `order` to 2 for legacy curves. The problem occurs
because current algorithm takes all the curve's definition interval,
divides it into equal parts and evaluates at those points, but corners
are exactly on repeated knot's. To hit those, the resolution has to be
increased higher than required for the rest of the curve.
The new algorithm divides non zero length intervals between two adjacent
knots into equal parts. This way corners are hit with a resolution of 1.
This does change the evaluated points of NURBS curves, which is why some
test results have to be updated in this commit.
Pull Request: https://projects.blender.org/blender/blender/pulls/138565
Add support for the UsdPrimvarReader_TYPE templates for both import and
export. These are used by several USD test assets and support here
represents the last major piece of the UsdPreviewSurface spec to be
implemented.
On import these become `Attribute` nodes and on export the `Attribute`
nodes will become `UsdPrimvarReader_TYPE`'s accordingly.
Import:
- `UsdPrimvarReader_float` and `UsdPrimvarReader_int` will use the `Fac`
output
- `UsdPrimvarReader_float3` and `UsdPrimvarReader_float4` will use the
`Color` output
- `UsdPrimvarReader_vector`, `UsdPrimvarReader_normal`, and
`UsdPrimvarReader_point` will use the `Vector` output
Export (only `Geometry` Attribute types are considered):
- `Fac` will use `UsdPrimvarReader_float`
- `Color` will use `UsdPrimvarReader_float3`
- `Vector` will use `UsdPrimvarReader_vector`
- `Alpha` is not considered
MaterialX note:
Hydra-native support is a bit more involved and will have to be done
separately. Hydra w/USD sync is trivial to implement but those changes
have been left out here.
Pull Request: https://projects.blender.org/blender/blender/pulls/135143
Switch from Standard Surface to OpenPBR as the exported MaterialX surface,
since this is the new standard more renderers are adopting and it more closely
matches the Principled BSDF implementation.
Anisotropy support is improved though still not quite the same, as formulas
are different. Nodes are generated to apply anisotropic rotation to the
tangent vector, as there is no corresponding parameter in OpenPBR.
Fixes#138164
Authored by Apple: Lee Kerley
Pull Request: https://projects.blender.org/blender/blender/pulls/138165
We recently pulled in the upstream patch to address the incorrect
validation error we were experiencing. This was the only test which
previously required the validator to be disabled.
Pull Request: https://projects.blender.org/blender/blender/pulls/138289
This change adds MaterialX version information to the exported MaterialX
USD materials.
Details:
In USD 25.02, the MaterialXConfigAPI schema was introduced to allow
recording the MaterialX version used to author a material. When loading
MaterialX documents into USD, this schema is automatically applied and
the associated version attribute is created on the material.
Due to how the MaterialX export works (via copying the composed
MaterialX spec from a temporary stage), the MaterialXConfigAPI needs to
be explicitly applied to the final material being exported.
This change applies this MaterialXConfigAPI schema and copies the
version attribute from the temporary MaterialX stage to the final stage.
Authored by Apple: Dan Knowlton
Co-authored-by: Dan Knowlton <d_knowlton@apple.com>
Pull Request: https://projects.blender.org/blender/blender/pulls/137974
While object names in Blender are already unique, the names themselves
may be "unsafe" for use in the various file formats. During processing
we make the names "safe". However, we did not guarantee that these new
safe names were themselves unique wrt each other. Consider object names
"Test 1" and "Test-1" which both become "Test_1" after being made safe.
These will collide during export; only 1 object would be exported and
it's undefined which object's data would "win".
To rectify this we add another name map to the hierarchy iterator which
is then used to handle collisions as they happen. The map is per-
hierarchy meaning that a name can appear more than once as long as its
under a different hierarchy. E.g.
- `/root/A/X` and another `/root/B/X` is OK
- `/root/A/X` and another `/root/A/X` is NOT OK
Pull Request: https://projects.blender.org/blender/blender/pulls/135418
Unlike the legacy type, the radius isn't included in the bounds for the new
curves type. This hasn't been obvious because the drawing is quite broken
and doesn't use the radius properly.
This commit adds a separate cache for the bounds with the radius, which
is now used by default. The old cache is kept around for backward
compatibility in the bounding box geometry node, where a new
"Use Radius" option accesses the old behavior.
Pull Request: https://projects.blender.org/blender/blender/pulls/135584
In order to better interop with the broader Alembic/USD ecosystem, align
the crease values we export with what we believe is expected by native
OpenSubdiv, a 0-10 range.
On import we will translate the native OpenSubdiv range back into
Blender's 0-1 range.
To account for SubD assets produced by Blender before this change, a
compat check is put in place for both Alembic and USD to use the old
methodology when encountering such files. The compat check makes use
of the Blender version we place inside the format's metadata fields. Old
assets loaded into a new Blender will look ok. New assets loaded into an
old Blender would need to be reworked.
Pull Request: https://projects.blender.org/blender/blender/pulls/132582
- There's only a few unit conversion options, just test all of them
- Use reference instead of pointer when passing export settings struct
- Organize scaling struct fields to keep similar options together
Pull Request: https://projects.blender.org/blender/blender/pulls/133774
Refactored USD instancing export to support instanceable references.
With this change, it's now possible to instance object hierarchies and
geometry types other than meshes (e.g., curves, point clouds, etc.).
No longer marking mesh prims as instances in
USDGenericMeshWriter::write_mesh().
USDTransformWriter::do_write() now marks the Xform as instanceable
with a reference to the prototype's Xform when the Blender object is
an instance.
In USDAbstractWriter::mark_as_instance() the target prim is now marked
as instanceable.
Added AbstractHierarchyIterator virtual functions include_data_writers()
and include_child_writers() to allow pruning children of instanceable Xforms
in AbstractHierarchyIterator::make_writers(). These functions return true
in the base class implementation, so that the iterator behavior for Alembic
exports is unaffected. In the USDHierarchyIterator subclass, these functions
are overridden to return false if instancing is enabled and the objects are
instances.
Added virtual function AbstractHierarchyIterator::should_determine_duplication_references()
which returns true if duplication references should be resolved for children
of a given context. This function is overridden in USDHierarchyIterator to
skip processing children of instances, which is more efficient for USD export,
since children of instances are pruned during traversal for writing. For nested
instances where the original prototype is not included in the export, this also
avoids designating a duplicated object parented to an instance as "the original",
which would cause USD errors since defining a prim under an instance
proxy is not allowed.
Extended logic in `AbstractHierarchyIterator::determine_duplication_references()`
to identify prototypes.
Added new function `HierarchyContext::is_prototype()`.
Disallowing merging with parent for instances and prototypes, since
the Xforms cannot be discarded in those cases.
Extended `USDWriterAbstract::ensure_usd_material()` with special logic
to ensure materials for prototype prims are defined in the subtree of the
prototype. This helps ensure the hierarchical encapsulation requirement
for prototypes and is required by certain renderers (e.g., Houdini's Karma)
for instance materials to render.
Added a new `process_scene_graph_instances()` function to ensure
prototypes are exported as abstract prims.
Added python tests test_export_native_instancing_true and
test_export_native_instancing_false.
Pull Request: https://projects.blender.org/blender/blender/pulls/131707
Makes use of recently added test data to ensure proper handling of child
objects, with animated transform constraints, parented to other objects
who also have animated transform constraints.
Also uses the `colored_print` module to better segment the test output.
Pull Request: https://projects.blender.org/blender/blender/pulls/133600
Cleanup and enhance our export of the USD `extent` attribute.
This does the following:
- The existing `author_extents` function now uses recently added common
code to write out the extents attribute
- A new `author_extents` overload allows the use of Blender's native
bounds for the types that support it. We now use this rather than
asking USD to recompute it for us.
- Meshes will now have their extents correctly written during animations
- Curves will now have their extents written as they were not doing so
prior to this PR
- Hair, Lights, Points, and Volumes make use of the `author_extents`
functions now
Since Curves need their extents tested, this PR also moves the test from
C++ to Python. Python tests allow for faster iteration, are more
straightforward to write, and allow usage of the USD validator.
Pull Request: https://projects.blender.org/blender/blender/pulls/132531
Export
Like we do for Mesh and PointCloud, export any "velocity" attribute on
the Point domain as native USD "velocities". While testing, a few
additional blender-internal attributes were discovered being exported
which are now excluded during export.
Import
Add the cache modifier as appropriate when we detect that UsdBasisCurve
data is animated. This includes time-varying positions, widths,
velocities, and general attribute values. Before this PR, only the
positions were considered. And like Export, the native USD "velocities"
attribute is now processed.
Adds test coverage as well.
Pull Request: https://projects.blender.org/blender/blender/pulls/133027
This rescales the whole scene by its root transform to match the same
visual size while not forcing the user to wait for scale to be applied to
each object.
This is requested by studios whose main applications / USD scenes are
in CM, because referencing and payloading scenes from disparate scales
can cause issues at resolution time.
If "Apply Unit Scale Conversion" is unchecked on import, the user now
has the ability to bring the objects in with a scale factor of 1.0, so that the
objects may be edited as if Blender's scene units matches the imported
stage's.
At export time, a "Stage Meters Per Unit" value can be chosen from a list
of common measurements, as well as setting a custom value.
Co-authored-by: kiki <charles@skeletalstudios.com>
Co-authored-by: Michael Kowalski <makowalski@nvidia.com>
Pull Request: https://projects.blender.org/blender/blender/pulls/122804