Cleanup: various non-functional changes when reading usd attribute data

- Use `lookup_or_add_for_write_only_span` in more places
- Use `copy_from` when reading in positions for the few readers where
  this wasn't already being done
- Remove manual memory management when processing corner normals

Pull Request: https://projects.blender.org/blender/blender/pulls/128043
This commit is contained in:
Jesse Yurkovich
2024-09-23 21:16:44 +02:00
committed by Jesse Yurkovich
parent bd841a92e2
commit e1a44ad129
5 changed files with 26 additions and 53 deletions

View File

@@ -244,7 +244,7 @@ void USDCurvesReader::read_curve_sample(Curves *curves_id, const double motionSa
if (!usdWidths.empty()) {
bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
bke::SpanAttributeWriter<float> radii = attributes.lookup_or_add_for_write_span<float>(
bke::SpanAttributeWriter<float> radii = attributes.lookup_or_add_for_write_only_span<float>(
"radius", bke::AttrDomain::Point);
pxr::TfToken widths_interp = curve_prim_.GetWidthsInterpolation();

View File

@@ -22,6 +22,7 @@
#include "BKE_object.hh"
#include "BKE_report.hh"
#include "BLI_array.hh"
#include "BLI_map.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_span.hh"
@@ -32,8 +33,6 @@
#include "DNA_object_types.h"
#include "DNA_windowmanager_types.h"
#include "MEM_guardedalloc.h"
#include <pxr/base/gf/matrix4f.h>
#include <pxr/base/vt/array.h>
#include <pxr/base/vt/types.h>
@@ -436,7 +435,7 @@ void USDMeshReader::read_vertex_creases(Mesh *mesh, const double motionSampleTim
}
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
bke::SpanAttributeWriter creases = attributes.lookup_or_add_for_write_span<float>(
bke::SpanAttributeWriter creases = attributes.lookup_or_add_for_write_only_span<float>(
"crease_vert", bke::AttrDomain::Point);
for (size_t i = 0; i < corner_indices.size(); i++) {
@@ -452,28 +451,23 @@ void USDMeshReader::read_velocities(Mesh *mesh, const double motionSampleTime)
if (!velocities.empty()) {
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
bke::GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span(
"velocity", bke::AttrDomain::Point, CD_PROP_FLOAT3);
bke::SpanAttributeWriter<float3> velocity =
attributes.lookup_or_add_for_write_only_span<float3>("velocity", bke::AttrDomain::Point);
Span<pxr::GfVec3f> usd_data(velocities.data(), velocities.size());
attribute.span.typed<float3>().copy_from(usd_data.cast<float3>());
attribute.finish();
velocity.span.copy_from(usd_data.cast<float3>());
velocity.finish();
}
}
void USDMeshReader::process_normals_vertex_varying(Mesh *mesh)
{
if (!mesh) {
return;
}
if (normals_.empty()) {
return;
}
if (normals_.size() != mesh->verts_num) {
CLOG_WARN(&LOG, "Vertex varying normals count mismatch for mesh %s", prim_path_.c_str());
CLOG_WARN(&LOG, "Vertex varying normals count mismatch for mesh '%s'", prim_path_.c_str());
return;
}
@@ -490,20 +484,17 @@ void USDMeshReader::process_normals_face_varying(Mesh *mesh) const
/* Check for normals count mismatches to prevent crashes. */
if (normals_.size() != mesh->corners_num) {
CLOG_WARN(&LOG, "Loop normal count mismatch for mesh %s", mesh->id.name);
CLOG_WARN(&LOG, "Loop normal count mismatch for mesh '%s'", prim_path_.c_str());
return;
}
long int loop_count = normals_.size();
float(*lnors)[3] = static_cast<float(*)[3]>(
MEM_malloc_arrayN(loop_count, sizeof(float[3]), "USD::FaceNormals"));
Array<float3> corner_normals(mesh->corners_num);
const OffsetIndices faces = mesh->faces();
for (const int i : faces.index_range()) {
const IndexRange face = faces[i];
for (int j : face.index_range()) {
int blender_index = face.start() + j;
const int corner = face.start() + j;
int usd_index = face.start();
if (is_left_handed_) {
@@ -513,14 +504,11 @@ void USDMeshReader::process_normals_face_varying(Mesh *mesh) const
usd_index += j;
}
lnors[blender_index][0] = normals_[usd_index][0];
lnors[blender_index][1] = normals_[usd_index][1];
lnors[blender_index][2] = normals_[usd_index][2];
corner_normals[corner] = detail::convert_value<pxr::GfVec3f, float3>(normals_[usd_index]);
}
}
BKE_mesh_set_custom_normals(mesh, lnors);
MEM_freeN(lnors);
BKE_mesh_set_custom_normals(mesh, reinterpret_cast<float(*)[3]>(corner_normals.data()));
}
void USDMeshReader::process_normals_uniform(Mesh *mesh) const
@@ -531,25 +519,20 @@ void USDMeshReader::process_normals_uniform(Mesh *mesh) const
/* Check for normals count mismatches to prevent crashes. */
if (normals_.size() != mesh->faces_num) {
CLOG_WARN(&LOG, "Uniform normal count mismatch for mesh %s", mesh->id.name);
CLOG_WARN(&LOG, "Uniform normal count mismatch for mesh '%s'", prim_path_.c_str());
return;
}
float(*lnors)[3] = static_cast<float(*)[3]>(
MEM_malloc_arrayN(mesh->corners_num, sizeof(float[3]), "USD::FaceNormals"));
Array<float3> corner_normals(mesh->corners_num);
const OffsetIndices faces = mesh->faces();
for (const int i : faces.index_range()) {
for (const int corner : faces[i]) {
lnors[corner][0] = normals_[i][0];
lnors[corner][1] = normals_[i][1];
lnors[corner][2] = normals_[i][2];
corner_normals[corner] = detail::convert_value<pxr::GfVec3f, float3>(normals_[i]);
}
}
BKE_mesh_set_custom_normals(mesh, lnors);
MEM_freeN(lnors);
BKE_mesh_set_custom_normals(mesh, reinterpret_cast<float(*)[3]>(corner_normals.data()));
}
void USDMeshReader::read_mesh_sample(ImportSettings *settings,
@@ -563,9 +546,7 @@ void USDMeshReader::read_mesh_sample(ImportSettings *settings,
if (new_mesh || (settings->read_flag & MOD_MESHSEQ_READ_VERT) != 0) {
MutableSpan<float3> vert_positions = mesh->vert_positions_for_write();
for (int i = 0; i < positions_.size(); i++) {
vert_positions[i] = {positions_[i][0], positions_[i][1], positions_[i][2]};
}
vert_positions.copy_from(Span(positions_.data(), positions_.size()).cast<float3>());
mesh->tag_positions_changed();
read_vertex_creases(mesh, motionSampleTime);

View File

@@ -88,11 +88,8 @@ void USDPointInstancerReader::read_object_data(Main *bmain, const double motionS
PointCloud *point_cloud = BKE_pointcloud_new_nomain(positions.size());
MutableSpan<float3> positions_span = point_cloud->positions_for_write();
for (int i = 0; i < positions.size(); ++i) {
positions_span[i] = float3(positions[i][0], positions[i][1], positions[i][2]);
}
MutableSpan<float3> point_positions = point_cloud->positions_for_write();
point_positions.copy_from(Span(positions.data(), positions.size()).cast<float3>());
bke::MutableAttributeAccessor attributes = point_cloud->attributes_for_write();

View File

@@ -102,7 +102,7 @@ void USDPointsReader::read_geometry(bke::GeometrySet &geometry_set,
if (!usd_widths.empty()) {
bke::MutableAttributeAccessor attributes = point_cloud->attributes_for_write();
bke::SpanAttributeWriter<float> radii = attributes.lookup_or_add_for_write_span<float>(
bke::SpanAttributeWriter<float> radii = attributes.lookup_or_add_for_write_only_span<float>(
"radius", bke::AttrDomain::Point);
const pxr::TfToken widths_interp = points_prim_.GetWidthsInterpolation();
@@ -135,12 +135,12 @@ void USDPointsReader::read_velocities(PointCloud *point_cloud, const double moti
if (!velocities.empty()) {
bke::MutableAttributeAccessor attributes = point_cloud->attributes_for_write();
bke::GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span(
"velocity", bke::AttrDomain::Point, CD_PROP_FLOAT3);
bke::SpanAttributeWriter<float3> velocity =
attributes.lookup_or_add_for_write_only_span<float3>("velocity", bke::AttrDomain::Point);
Span<pxr::GfVec3f> usd_data(velocities.data(), velocities.size());
attribute.span.typed<float3>().copy_from(usd_data.cast<float3>());
attribute.finish();
velocity.span.copy_from(usd_data.cast<float3>());
velocity.finish();
}
}

View File

@@ -265,12 +265,7 @@ Mesh *USDShapeReader::mesh_from_prim(Mesh *existing_mesh,
}
MutableSpan<float3> vert_positions = active_mesh->vert_positions_for_write();
for (int i = 0; i < positions.size(); i++) {
vert_positions[i][0] = positions[i][0];
vert_positions[i][1] = positions[i][1];
vert_positions[i][2] = positions[i][2];
}
vert_positions.copy_from(Span(positions.data(), positions.size()).cast<float3>());
if (params.read_flags & MOD_MESHSEQ_READ_COLOR) {
if (active_mesh != existing_mesh) {