Files
test2/source/blender/io/usd/intern/usd_reader_shape.cc

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

348 lines
12 KiB
C++
Raw Normal View History

/* SPDX-FileCopyrightText: 2023 Nvidia. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0-or-later */
Alembic/USD: Use GeometrySets to import data This rewrites the Alembic and USD data importers to work with and output GeometrySets instead of Meshes. The main motivation for this change is to be able to import properly point clouds, which are currently imported as Meshes, and curves data, which suffer from a lot of issues due to limitations of legacy curves structures (fixed by the new curves data-block) and are also converted to Meshes. Further, for Curves, it will allow importing arbitrary attributes. This patch was primarily meant for Alembic, but changes to USD import were necessary as they share the same modifier. For Alembic: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Points are imported as PointClouds For USD: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Note that the current USD importer does not support loading PointClouds, so this patch does not add support for it. For both Alembic and USD, knots arrays are not read anymore, as the new Curves object does not expose the ability to set them. Improvements can be made in the future if and when example assets are provided. This fixes at least the following: #58704: Animated Alembic curves don't update on render #112308: Curves have offset animations (alembic / USD) #118261: wrong motion blur from usd in cycles and reverting to the first frame when disabeling motion blur Co-authored-by: Jesse Yurkovich <jesse.y@gmail.com> Pull Request: https://projects.blender.org/blender/blender/pulls/115623
2024-02-28 03:02:38 +01:00
#include "BKE_geometry_set.hh"
2024-01-15 12:44:04 -05:00
#include "BKE_lib_id.hh"
#include "BKE_mesh.hh"
#include "BKE_object.hh"
#include "BKE_report.hh"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_windowmanager_types.h"
#include "usd_attribute_utils.hh"
#include "usd_mesh_utils.hh"
#include "usd_reader_shape.hh"
#include <pxr/usd/usdGeom/capsule.h>
#include <pxr/usd/usdGeom/capsule_1.h>
#include <pxr/usd/usdGeom/cone.h>
#include <pxr/usd/usdGeom/cube.h>
#include <pxr/usd/usdGeom/cylinder.h>
#include <pxr/usd/usdGeom/cylinder_1.h>
#include <pxr/usd/usdGeom/plane.h>
#include <pxr/usd/usdGeom/sphere.h>
#include <pxr/usdImaging/usdImaging/capsuleAdapter.h>
#include <pxr/usdImaging/usdImaging/coneAdapter.h>
#include <pxr/usdImaging/usdImaging/cubeAdapter.h>
#include <pxr/usdImaging/usdImaging/cylinderAdapter.h>
#include <pxr/usdImaging/usdImaging/planeAdapter.h>
#include <pxr/usdImaging/usdImaging/sphereAdapter.h>
namespace blender::io::usd {
USDShapeReader::USDShapeReader(const pxr::UsdPrim &prim,
const USDImportParams &import_params,
const ImportSettings &settings)
: USDGeomReader(prim, import_params, settings)
{
}
void USDShapeReader::create_object(Main *bmain, double /*motionSampleTime*/)
{
Mesh *mesh = BKE_mesh_add(bmain, name_.c_str());
object_ = BKE_object_add_only_object(bmain, OB_MESH, name_.c_str());
object_->data = mesh;
}
void USDShapeReader::read_object_data(Main *bmain, double motionSampleTime)
{
const USDMeshReadParams params = create_mesh_read_params(motionSampleTime,
import_params_.mesh_read_flag);
Mesh *mesh = (Mesh *)object_->data;
Mesh *read_mesh = this->read_mesh(mesh, params, nullptr);
if (read_mesh != mesh) {
BKE_mesh_nomain_to_mesh(read_mesh, mesh, object_);
if (is_time_varying()) {
USDGeomReader::add_cache_modifier();
}
}
USDXformReader::read_object_data(bmain, motionSampleTime);
}
template<typename Adapter>
void USDShapeReader::read_values(const double motionSampleTime,
pxr::VtVec3fArray &positions,
pxr::VtIntArray &face_indices,
pxr::VtIntArray &face_counts) const
{
Adapter adapter;
pxr::VtValue points_val = adapter.GetPoints(prim_, motionSampleTime);
if (points_val.IsHolding<pxr::VtVec3fArray>()) {
positions = points_val.Get<pxr::VtVec3fArray>();
}
pxr::VtValue topology_val = adapter.GetTopology(prim_, pxr::SdfPath(), motionSampleTime);
if (topology_val.IsHolding<pxr::HdMeshTopology>()) {
const pxr::HdMeshTopology &topology = topology_val.Get<pxr::HdMeshTopology>();
face_counts = topology.GetFaceVertexCounts();
face_indices = topology.GetFaceVertexIndices();
}
}
bool USDShapeReader::read_mesh_values(double motionSampleTime,
pxr::VtVec3fArray &positions,
pxr::VtIntArray &face_indices,
pxr::VtIntArray &face_counts) const
{
if (prim_.IsA<pxr::UsdGeomCapsule>() || prim_.IsA<pxr::UsdGeomCapsule_1>()) {
read_values<pxr::UsdImagingCapsuleAdapter>(
motionSampleTime, positions, face_indices, face_counts);
return true;
}
if (prim_.IsA<pxr::UsdGeomCylinder>() || prim_.IsA<pxr::UsdGeomCylinder_1>()) {
read_values<pxr::UsdImagingCylinderAdapter>(
motionSampleTime, positions, face_indices, face_counts);
return true;
}
if (prim_.IsA<pxr::UsdGeomCone>()) {
read_values<pxr::UsdImagingConeAdapter>(
motionSampleTime, positions, face_indices, face_counts);
return true;
}
if (prim_.IsA<pxr::UsdGeomCube>()) {
read_values<pxr::UsdImagingCubeAdapter>(
motionSampleTime, positions, face_indices, face_counts);
return true;
}
if (prim_.IsA<pxr::UsdGeomSphere>()) {
read_values<pxr::UsdImagingSphereAdapter>(
motionSampleTime, positions, face_indices, face_counts);
return true;
}
if (prim_.IsA<pxr::UsdGeomPlane>()) {
read_values<pxr::UsdImagingPlaneAdapter>(
motionSampleTime, positions, face_indices, face_counts);
return true;
}
BKE_reportf(reports(),
RPT_ERROR,
"Unhandled Gprim type: %s (%s)",
prim_.GetTypeName().GetText(),
prim_.GetPath().GetText());
return false;
}
Mesh *USDShapeReader::read_mesh(Mesh *existing_mesh,
const USDMeshReadParams params,
const char ** /*r_err_str*/)
{
if (!prim_) {
return existing_mesh;
}
pxr::VtIntArray usd_face_indices;
pxr::VtIntArray usd_face_counts;
/* Should have a good set of data by this point-- copy over. */
Mesh *active_mesh = mesh_from_prim(existing_mesh, params, usd_face_indices, usd_face_counts);
if (active_mesh == existing_mesh) {
return existing_mesh;
}
Span<int> face_indices = Span(usd_face_indices.cdata(), usd_face_indices.size());
Span<int> face_counts = Span(usd_face_counts.cdata(), usd_face_counts.size());
MutableSpan<int> face_offsets = active_mesh->face_offsets_for_write();
for (const int i : IndexRange(active_mesh->faces_num)) {
face_offsets[i] = face_counts[i];
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
}
offset_indices::accumulate_counts_to_offsets(face_offsets);
Mesh: Move face shade smooth flag to a generic attribute Currently the shade smooth status for mesh faces is stored as part of `MPoly::flag`. As described in #95967, this moves that information to a separate boolean attribute. It also flips its status, so the attribute is now called `sharp_face`, which mirrors the existing `sharp_edge` attribute. The attribute doesn't need to be allocated when all faces are smooth. Forward compatibility is kept until 4.0 like the other mesh refactors. This will reduce memory bandwidth requirements for some operations, since the array of booleans uses 12 times less memory than `MPoly`. It also allows faces to be stored more efficiently in the future, since the flag is now unused. It's also possible to use generic functions to process the values. For example, finding whether there is a sharp face is just `sharp_faces.contains(true)`. The `shade_smooth` attribute is no longer accessible with geometry nodes. Since there were dedicated accessor nodes for that data, that shouldn't be a problem. That's difficult to version automatically since the named attribute nodes could be used in arbitrary combinations. **Implementation notes:** - The attribute and array variables in the code use the `sharp_faces` term, to be consistent with the user-facing "sharp faces" wording, and to avoid requiring many renames when #101689 is implemented. - Cycles now accesses smooth face status with the generic attribute, to avoid overhead. - Changing the zero-value from "smooth" to "flat" takes some care to make sure defaults are the same. - Versioning for the edge mode extrude node is particularly complex. New nodes are added by versioning to propagate the attribute in its old inverted state. - A lot of access is still done through the `CustomData` API rather than the attribute API because of a few functions. That can be cleaned up easily in the future. - In the future we would benefit from a way to store attributes as a single value for when all faces are sharp. Pull Request: https://projects.blender.org/blender/blender/pulls/104422
2023-03-08 15:36:18 +01:00
/* Don't smooth-shade cubes; we're not worrying about sharpness for Gprims. */
bke::mesh_smooth_set(*active_mesh, !prim_.IsA<pxr::UsdGeomCube>());
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
MutableSpan<int> corner_verts = active_mesh->corner_verts_for_write();
for (const int i : corner_verts.index_range()) {
corner_verts[i] = face_indices[i];
}
bke::mesh_calc_edges(*active_mesh, false, false);
return active_mesh;
}
Alembic/USD: Use GeometrySets to import data This rewrites the Alembic and USD data importers to work with and output GeometrySets instead of Meshes. The main motivation for this change is to be able to import properly point clouds, which are currently imported as Meshes, and curves data, which suffer from a lot of issues due to limitations of legacy curves structures (fixed by the new curves data-block) and are also converted to Meshes. Further, for Curves, it will allow importing arbitrary attributes. This patch was primarily meant for Alembic, but changes to USD import were necessary as they share the same modifier. For Alembic: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Points are imported as PointClouds For USD: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Note that the current USD importer does not support loading PointClouds, so this patch does not add support for it. For both Alembic and USD, knots arrays are not read anymore, as the new Curves object does not expose the ability to set them. Improvements can be made in the future if and when example assets are provided. This fixes at least the following: #58704: Animated Alembic curves don't update on render #112308: Curves have offset animations (alembic / USD) #118261: wrong motion blur from usd in cycles and reverting to the first frame when disabeling motion blur Co-authored-by: Jesse Yurkovich <jesse.y@gmail.com> Pull Request: https://projects.blender.org/blender/blender/pulls/115623
2024-02-28 03:02:38 +01:00
void USDShapeReader::read_geometry(bke::GeometrySet &geometry_set,
USDMeshReadParams params,
const char **r_err_str)
Alembic/USD: Use GeometrySets to import data This rewrites the Alembic and USD data importers to work with and output GeometrySets instead of Meshes. The main motivation for this change is to be able to import properly point clouds, which are currently imported as Meshes, and curves data, which suffer from a lot of issues due to limitations of legacy curves structures (fixed by the new curves data-block) and are also converted to Meshes. Further, for Curves, it will allow importing arbitrary attributes. This patch was primarily meant for Alembic, but changes to USD import were necessary as they share the same modifier. For Alembic: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Points are imported as PointClouds For USD: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Note that the current USD importer does not support loading PointClouds, so this patch does not add support for it. For both Alembic and USD, knots arrays are not read anymore, as the new Curves object does not expose the ability to set them. Improvements can be made in the future if and when example assets are provided. This fixes at least the following: #58704: Animated Alembic curves don't update on render #112308: Curves have offset animations (alembic / USD) #118261: wrong motion blur from usd in cycles and reverting to the first frame when disabeling motion blur Co-authored-by: Jesse Yurkovich <jesse.y@gmail.com> Pull Request: https://projects.blender.org/blender/blender/pulls/115623
2024-02-28 03:02:38 +01:00
{
Mesh *existing_mesh = geometry_set.get_mesh_for_write();
Mesh *new_mesh = read_mesh(existing_mesh, params, r_err_str);
Alembic/USD: Use GeometrySets to import data This rewrites the Alembic and USD data importers to work with and output GeometrySets instead of Meshes. The main motivation for this change is to be able to import properly point clouds, which are currently imported as Meshes, and curves data, which suffer from a lot of issues due to limitations of legacy curves structures (fixed by the new curves data-block) and are also converted to Meshes. Further, for Curves, it will allow importing arbitrary attributes. This patch was primarily meant for Alembic, but changes to USD import were necessary as they share the same modifier. For Alembic: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Points are imported as PointClouds For USD: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Note that the current USD importer does not support loading PointClouds, so this patch does not add support for it. For both Alembic and USD, knots arrays are not read anymore, as the new Curves object does not expose the ability to set them. Improvements can be made in the future if and when example assets are provided. This fixes at least the following: #58704: Animated Alembic curves don't update on render #112308: Curves have offset animations (alembic / USD) #118261: wrong motion blur from usd in cycles and reverting to the first frame when disabeling motion blur Co-authored-by: Jesse Yurkovich <jesse.y@gmail.com> Pull Request: https://projects.blender.org/blender/blender/pulls/115623
2024-02-28 03:02:38 +01:00
if (new_mesh != existing_mesh) {
geometry_set.replace_mesh(new_mesh);
}
}
void USDShapeReader::apply_primvars_to_mesh(Mesh *mesh, const double motionSampleTime) const
{
/* TODO: also handle the displayOpacity primvar. */
if (!mesh || !prim_) {
return;
}
pxr::UsdGeomPrimvarsAPI pv_api = pxr::UsdGeomPrimvarsAPI(prim_);
std::vector<pxr::UsdGeomPrimvar> primvars = pv_api.GetPrimvarsWithValues();
pxr::TfToken active_color_name;
for (const pxr::UsdGeomPrimvar &pv : primvars) {
const pxr::SdfValueTypeName pv_type = pv.GetTypeName();
if (!pv_type.IsArray()) {
continue; /* Skip non-array primvar attributes. */
}
const pxr::TfToken name = pxr::UsdGeomPrimvar::StripPrimvarsName(pv.GetPrimvarName());
/* Skip reading primvars that have been read before and are not time varying. */
if (primvar_time_varying_map_.contains(name) && !primvar_time_varying_map_.lookup(name)) {
continue;
}
const std::optional<eCustomDataType> type = convert_usd_type_to_blender(pv_type);
if (type == CD_PROP_COLOR) {
/* Set the active color name to 'displayColor', if a color primvar
* with this name exists. Otherwise, use the name of the first
* color primvar we find for the active color. */
if (active_color_name.IsEmpty() || name == usdtokens::displayColor) {
active_color_name = name;
}
Fix: USD: Support color attributes on all relevant domains Color primvars/attributes were historically treated as a special case for both import and export. This was mostly done to align with how painting and viewport display works in Blender. Export would generally ignore color attributes except when they were found on a Mesh's Point or FaceCorner domains. And import went out of its way to map incoming color primvars to the FaceCorner domain in more situations than necessary. To facilitate better roundtripping in Blender<=>USD workflows, and to reduce code duplication, this PR teaches the common attribute utilities how to handle color types. The color attributes will now work on all relevant Mesh and Curve domains. There were tests in place for this already but they were set to verify the inverse state, i.e. the technically broken state, until this could be fixed. There remains one special case: "displayColor" primvars and attributes. The "displayColor" is a special primvar in USD and is the de-facto way to set a simple viewport color in that ecosystem. It must also be a color3f type. In order to not regress import, if a "displayColor" primvar is found on the Face domain we will map it to FaceCorner instead so it can be displayed in the viewport; which has been the case for the past several releases. We can drop this special-case if/when Blender can display Face colors through the Viewport Shading "Attribute" color type. Additionally, Blender will export this, and only this, color attribute as a color3f. Note: As was the case prior to this PR, the following 2 discrepancies still prevent "perfect" round-trips: - USD does not have an equivalent to Blender's byte colors; they are treated as float during IO - Blender does not have an equivalent to USD's color3 types; they are treated as color4 during IO Pull Request: https://projects.blender.org/blender/blender/pulls/127784
2024-09-24 19:05:55 +02:00
}
Fix: USD: Support color attributes on all relevant domains Color primvars/attributes were historically treated as a special case for both import and export. This was mostly done to align with how painting and viewport display works in Blender. Export would generally ignore color attributes except when they were found on a Mesh's Point or FaceCorner domains. And import went out of its way to map incoming color primvars to the FaceCorner domain in more situations than necessary. To facilitate better roundtripping in Blender<=>USD workflows, and to reduce code duplication, this PR teaches the common attribute utilities how to handle color types. The color attributes will now work on all relevant Mesh and Curve domains. There were tests in place for this already but they were set to verify the inverse state, i.e. the technically broken state, until this could be fixed. There remains one special case: "displayColor" primvars and attributes. The "displayColor" is a special primvar in USD and is the de-facto way to set a simple viewport color in that ecosystem. It must also be a color3f type. In order to not regress import, if a "displayColor" primvar is found on the Face domain we will map it to FaceCorner instead so it can be displayed in the viewport; which has been the case for the past several releases. We can drop this special-case if/when Blender can display Face colors through the Viewport Shading "Attribute" color type. Additionally, Blender will export this, and only this, color attribute as a color3f. Note: As was the case prior to this PR, the following 2 discrepancies still prevent "perfect" round-trips: - USD does not have an equivalent to Blender's byte colors; they are treated as float during IO - Blender does not have an equivalent to USD's color3 types; they are treated as color4 during IO Pull Request: https://projects.blender.org/blender/blender/pulls/127784
2024-09-24 19:05:55 +02:00
read_generic_mesh_primvar(mesh, pv, motionSampleTime, false);
Fix: USD: Support color attributes on all relevant domains Color primvars/attributes were historically treated as a special case for both import and export. This was mostly done to align with how painting and viewport display works in Blender. Export would generally ignore color attributes except when they were found on a Mesh's Point or FaceCorner domains. And import went out of its way to map incoming color primvars to the FaceCorner domain in more situations than necessary. To facilitate better roundtripping in Blender<=>USD workflows, and to reduce code duplication, this PR teaches the common attribute utilities how to handle color types. The color attributes will now work on all relevant Mesh and Curve domains. There were tests in place for this already but they were set to verify the inverse state, i.e. the technically broken state, until this could be fixed. There remains one special case: "displayColor" primvars and attributes. The "displayColor" is a special primvar in USD and is the de-facto way to set a simple viewport color in that ecosystem. It must also be a color3f type. In order to not regress import, if a "displayColor" primvar is found on the Face domain we will map it to FaceCorner instead so it can be displayed in the viewport; which has been the case for the past several releases. We can drop this special-case if/when Blender can display Face colors through the Viewport Shading "Attribute" color type. Additionally, Blender will export this, and only this, color attribute as a color3f. Note: As was the case prior to this PR, the following 2 discrepancies still prevent "perfect" round-trips: - USD does not have an equivalent to Blender's byte colors; they are treated as float during IO - Blender does not have an equivalent to USD's color3 types; they are treated as color4 during IO Pull Request: https://projects.blender.org/blender/blender/pulls/127784
2024-09-24 19:05:55 +02:00
/* Record whether the primvar attribute might be time varying. */
if (!primvar_time_varying_map_.contains(name)) {
primvar_time_varying_map_.add(name, pv.ValueMightBeTimeVarying());
}
}
if (!active_color_name.IsEmpty()) {
BKE_id_attributes_default_color_set(&mesh->id, active_color_name.GetText());
BKE_id_attributes_active_color_set(&mesh->id, active_color_name.GetText());
}
}
Mesh *USDShapeReader::mesh_from_prim(Mesh *existing_mesh,
const USDMeshReadParams params,
pxr::VtIntArray &face_indices,
pxr::VtIntArray &face_counts) const
{
pxr::VtVec3fArray positions;
if (!read_mesh_values(params.motion_sample_time, positions, face_indices, face_counts)) {
return existing_mesh;
}
const bool poly_counts_match = existing_mesh ? face_counts.size() == existing_mesh->faces_num :
false;
const bool position_counts_match = existing_mesh ? positions.size() == existing_mesh->verts_num :
false;
Mesh *active_mesh = nullptr;
if (!position_counts_match || !poly_counts_match) {
active_mesh = BKE_mesh_new_nomain_from_template(
existing_mesh, positions.size(), 0, face_counts.size(), face_indices.size());
}
else {
active_mesh = existing_mesh;
}
MutableSpan<float3> vert_positions = active_mesh->vert_positions_for_write();
vert_positions.copy_from(Span(positions.cdata(), positions.size()).cast<float3>());
if (params.read_flags & MOD_MESHSEQ_READ_COLOR) {
if (active_mesh != existing_mesh) {
/* Clear the primvar map to force attributes to be reloaded. */
this->primvar_time_varying_map_.clear();
}
apply_primvars_to_mesh(active_mesh, params.motion_sample_time);
}
return active_mesh;
}
bool USDShapeReader::is_time_varying()
{
for (const bool animating_flag : primvar_time_varying_map_.values()) {
if (animating_flag) {
return true;
}
}
if (prim_.IsA<pxr::UsdGeomCapsule>()) {
pxr::UsdGeomCapsule geom(prim_);
return (geom.GetAxisAttr().ValueMightBeTimeVarying() ||
geom.GetHeightAttr().ValueMightBeTimeVarying() ||
geom.GetRadiusAttr().ValueMightBeTimeVarying());
}
if (prim_.IsA<pxr::UsdGeomCapsule_1>()) {
pxr::UsdGeomCapsule_1 geom(prim_);
return (geom.GetAxisAttr().ValueMightBeTimeVarying() ||
geom.GetHeightAttr().ValueMightBeTimeVarying() ||
geom.GetRadiusTopAttr().ValueMightBeTimeVarying() ||
geom.GetRadiusBottomAttr().ValueMightBeTimeVarying());
}
if (prim_.IsA<pxr::UsdGeomCylinder>()) {
pxr::UsdGeomCylinder geom(prim_);
return (geom.GetAxisAttr().ValueMightBeTimeVarying() ||
geom.GetHeightAttr().ValueMightBeTimeVarying() ||
geom.GetRadiusAttr().ValueMightBeTimeVarying());
}
if (prim_.IsA<pxr::UsdGeomCylinder_1>()) {
pxr::UsdGeomCylinder_1 geom(prim_);
return (geom.GetAxisAttr().ValueMightBeTimeVarying() ||
geom.GetHeightAttr().ValueMightBeTimeVarying() ||
geom.GetRadiusTopAttr().ValueMightBeTimeVarying() ||
geom.GetRadiusBottomAttr().ValueMightBeTimeVarying());
}
if (prim_.IsA<pxr::UsdGeomCone>()) {
pxr::UsdGeomCone geom(prim_);
return (geom.GetAxisAttr().ValueMightBeTimeVarying() ||
geom.GetHeightAttr().ValueMightBeTimeVarying() ||
geom.GetRadiusAttr().ValueMightBeTimeVarying());
}
if (prim_.IsA<pxr::UsdGeomCube>()) {
pxr::UsdGeomCube geom(prim_);
return geom.GetSizeAttr().ValueMightBeTimeVarying();
}
if (prim_.IsA<pxr::UsdGeomSphere>()) {
pxr::UsdGeomSphere geom(prim_);
return geom.GetRadiusAttr().ValueMightBeTimeVarying();
}
if (prim_.IsA<pxr::UsdGeomPlane>()) {
pxr::UsdGeomPlane geom(prim_);
return (geom.GetWidthAttr().ValueMightBeTimeVarying() ||
geom.GetLengthAttr().ValueMightBeTimeVarying() ||
geom.GetAxisAttr().ValueMightBeTimeVarying());
}
BKE_reportf(reports(),
RPT_ERROR,
"Unhandled Gprim type: %s (%s)",
prim_.GetTypeName().GetText(),
prim_.GetPath().GetText());
return false;
}
} // namespace blender::io::usd