WIP: USD: add velocity to USD importer #104462

Draft
Sonny Campbell wants to merge 3 commits from SonnyCampbell_Unity/blender:unity/T96182-usd-reader-velocity into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
5 changed files with 44 additions and 2 deletions
Showing only changes of commit e8a396c2a5 - Show all commits

View File

@ -247,6 +247,8 @@ void USDMeshReader::read_object_data(Main *bmain, const double motionSampleTime)
USDMeshReadParams params = {};
params.motion_sample_time = motionSampleTime;
params.read_flags = import_params_.mesh_read_flag;
params.velocity_name = "";
params.velocity_scale = 0.0;
Mesh *read_mesh = this->read_mesh(mesh, params, nullptr);
@ -730,6 +732,31 @@ void USDMeshReader::read_mesh_sample(ImportSettings *settings,
if ((settings->read_flag & MOD_MESHSEQ_READ_COLOR) != 0) {
read_colors(mesh, motionSampleTime);
}
if (!settings->velocity_name.empty() && settings->velocity_scale != 0.0f) {
read_velocities(mesh, motionSampleTime);
}
}
void USDMeshReader::read_velocities(Mesh *mesh, double motionSampleTime)
{
pxr::VtVec3fArray usd_velocities;
mesh_prim_.GetVelocitiesAttr().Get(&usd_velocities, motionSampleTime);
const int num_velocity_vectors = static_cast<int>(usd_velocities.size());
if (num_velocity_vectors != mesh->totvert) {
/* Files containing videogrammetry data may be malformed and export velocity data on missing
* frames (most likely by copying the last valid data). */
return;
}
CustomDataLayer *velocity_layer = BKE_id_attribute_new(
&mesh->id, "velocity", CD_PROP_FLOAT3, ATTR_DOMAIN_POINT, nullptr);
float(*velocity)[3] = (float(*)[3])velocity_layer->data;
for (int vertex_idx = 0, totvert = mesh->totvert; vertex_idx < totvert; ++vertex_idx) {
copy_v3_v3(velocity[vertex_idx], usd_velocities[vertex_idx].data());
}
}
void USDMeshReader::assign_facesets_to_material_indices(double motionSampleTime,
@ -891,6 +918,8 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh,
ImportSettings settings;
settings.read_flag |= params.read_flags;
settings.velocity_name = params.velocity_name;
settings.velocity_scale = params.velocity_scale;
if (topology_changed(existing_mesh, params.motion_sample_time)) {
new_mesh = true;
@ -902,7 +931,8 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh,
}
}
read_mesh_sample(&settings, active_mesh, params.motion_sample_time, new_mesh || is_initial_load_);
read_mesh_sample(
&settings, active_mesh, params.motion_sample_time, new_mesh || is_initial_load_);
if (new_mesh) {
/* Here we assume that the number of materials doesn't change, i.e. that
@ -914,7 +944,8 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh,
bke::MutableAttributeAccessor attributes = active_mesh->attributes_for_write();
bke::SpanAttributeWriter<int> material_indices =
attributes.lookup_or_add_for_write_span<int>("material_index", ATTR_DOMAIN_FACE);
assign_facesets_to_material_indices(params.motion_sample_time, material_indices.span, &mat_map);
assign_facesets_to_material_indices(
params.motion_sample_time, material_indices.span, &mat_map);
material_indices.finish();
}
}

View File

@ -66,6 +66,7 @@ class USDMeshReader : public USDGeomReader {
void read_mpolys(Mesh *mesh);
void read_uvs(Mesh *mesh, double motionSampleTime, bool load_uvs = false);
void read_velocities(Mesh *mesh, double motionSampleTime);
void read_colors(Mesh *mesh, double motionSampleTime);
void read_vertex_creases(Mesh *mesh, double motionSampleTime);

View File

@ -34,6 +34,10 @@ struct ImportSettings {
/* From MeshSeqCacheModifierData.read_flag */
int read_flag;
/* From CacheFile and MeshSeqCacheModifierData */
std::string velocity_name;
float velocity_scale;
bool validate_meshes;
CacheFile *cache_file;
@ -59,6 +63,8 @@ struct ImportSettings {
sequence_len(1),
sequence_offset(0),
read_flag(0),
velocity_name(""),
velocity_scale(1.0f),
validate_meshes(false),
cache_file(NULL)
{

View File

@ -72,6 +72,8 @@ struct USDImportParams {
typedef struct USDMeshReadParams {
double motion_sample_time; /* Read USD TimeCode in frames. */
int read_flags; /* MOD_MESHSEQ_xxx value that is set from MeshSeqCacheModifierData.read_flag. */
const char *velocity_name; /* From CacheFile and MeshSeqCacheModifierData */
float velocity_scale; /* From CacheFile and MeshSeqCacheModifierData */
} USDMeshReadParams;
/* The USD_export takes a as_background_job parameter, and returns a boolean.

View File

@ -250,6 +250,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
USDMeshReadParams params = {};
params.motion_sample_time = time * FPS;
params.read_flags = mcmd->read_flag;
params.velocity_name = mcmd->cache_file->velocity_name;
params.velocity_scale = mcmd->velocity_scale;
result = USD_read_mesh(mcmd->reader, ctx->object, mesh, params, &err_str);
# endif