Cleanup: Small improvements to Hydra mesh and curves export
- Use threadsafe normal computation (will be improved more in #93551) - Copy data directly instead of loops when format is the same - Use bke::CurvesGeometry wrapper and attribute API - Avoid `push_back` when size is known ahead of time
This commit is contained in:
@@ -141,45 +141,41 @@ void CurvesData::write_materials()
|
||||
mat_data_ = get_or_create_material(mat);
|
||||
}
|
||||
|
||||
void CurvesData::write_curves(const Curves *curves)
|
||||
void CurvesData::write_curves(const Curves *curves_id)
|
||||
{
|
||||
curve_vertex_counts_.clear();
|
||||
widths_.clear();
|
||||
vertices_.clear();
|
||||
const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
|
||||
const float *radii = (const float *)CustomData_get_layer_named(
|
||||
&curves->geometry.point_data, CD_PROP_FLOAT, "radius");
|
||||
const float(*positions)[3] = (const float(*)[3])CustomData_get_layer_named(
|
||||
&curves->geometry.point_data, CD_PROP_FLOAT3, "position");
|
||||
curve_vertex_counts_.resize(curves.curves_num());
|
||||
offset_indices::copy_group_sizes(
|
||||
curves.points_by_curve(),
|
||||
curves.curves_range(),
|
||||
MutableSpan(curve_vertex_counts_.data(), curve_vertex_counts_.size()));
|
||||
|
||||
vertices_.reserve(curves->geometry.curve_num);
|
||||
const Span<float3> positions = curves.positions();
|
||||
vertices_.resize(curves.points_num());
|
||||
MutableSpan(vertices_.data(), vertices_.size()).copy_from(positions.cast<pxr::GfVec3f>());
|
||||
|
||||
for (int i = 0; i < curves->geometry.curve_num; i++) {
|
||||
int first_point_index = *(curves->geometry.curve_offsets + i);
|
||||
int num_points = *(curves->geometry.curve_offsets + i + 1) - first_point_index;
|
||||
curve_vertex_counts_.push_back(num_points);
|
||||
|
||||
/* Set radius similar to Cycles if isn't set */
|
||||
for (int j = 0; j < num_points; j++) {
|
||||
int ind = first_point_index + j;
|
||||
widths_.push_back(radii ? radii[ind] * 2 : 0.01f);
|
||||
vertices_.push_back(pxr::GfVec3f(positions[ind][0], positions[ind][1], positions[ind][2]));
|
||||
}
|
||||
const VArray<float> radii = *curves.attributes().lookup_or_default<float>(
|
||||
"radius", ATTR_DOMAIN_POINT, 0.01f);
|
||||
widths_.resize(curves.points_num());
|
||||
for (const int i : curves.points_range()) {
|
||||
widths_[i] = radii[i] * 2.0f;
|
||||
}
|
||||
write_uv_maps(curves);
|
||||
|
||||
write_uv_maps(curves_id);
|
||||
}
|
||||
|
||||
void CurvesData::write_uv_maps(const Curves *curves)
|
||||
void CurvesData::write_uv_maps(const Curves *curves_id)
|
||||
{
|
||||
uvs_.clear();
|
||||
|
||||
const float(*uvs)[2] = (const float(*)[2])CustomData_get_layer_named(
|
||||
&curves->geometry.curve_data, CD_PROP_FLOAT2, "surface_uv_coordinate");
|
||||
if (uvs) {
|
||||
for (int i = 0; i < curves->geometry.curve_num; i++) {
|
||||
uvs_.push_back(pxr::GfVec2f(uvs[i][0], uvs[i][1]));
|
||||
}
|
||||
const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
const Span<float2> surface_uv_coords = curves.surface_uv_coords();
|
||||
if (surface_uv_coords.is_empty()) {
|
||||
uvs_.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
uvs_.resize(curves.curves_num());
|
||||
MutableSpan(uvs_.data(), uvs_.size()).copy_from(surface_uv_coords.cast<pxr::GfVec2f>());
|
||||
}
|
||||
|
||||
} // namespace blender::io::hydra
|
||||
|
||||
@@ -47,8 +47,8 @@ class CurvesData : public ObjectData {
|
||||
void write_materials() override;
|
||||
|
||||
private:
|
||||
void write_curves(const Curves *curves);
|
||||
void write_uv_maps(const Curves *curves);
|
||||
void write_curves(const Curves *curves_id);
|
||||
void write_uv_maps(const Curves *curves_id);
|
||||
};
|
||||
|
||||
} // namespace blender::io::hydra
|
||||
|
||||
@@ -193,7 +193,8 @@ void MeshData::write_materials()
|
||||
const Object *object = (const Object *)id;
|
||||
for (int i = 0; i < submeshes_.size(); ++i) {
|
||||
SubMesh &m = submeshes_[i];
|
||||
Material *mat = BKE_object_material_get_eval(const_cast<Object *>(object), m.mat_index + 1);
|
||||
const Material *mat = BKE_object_material_get_eval(const_cast<Object *>(object),
|
||||
m.mat_index + 1);
|
||||
m.mat_data = get_or_create_material(mat);
|
||||
}
|
||||
}
|
||||
@@ -231,11 +232,14 @@ void MeshData::write_submeshes(const Mesh *mesh)
|
||||
const Span<int> corner_verts = mesh->corner_verts();
|
||||
const Span<MLoopTri> looptris = mesh->looptris();
|
||||
|
||||
BKE_mesh_calc_normals_split(const_cast<Mesh *>(mesh));
|
||||
const float(*lnors)[3] = (float(*)[3])CustomData_get_layer(&mesh->loop_data, CD_NORMAL);
|
||||
const float(*luvs)[2] = (float(*)[2])CustomData_get_layer(&mesh->loop_data, CD_PROP_FLOAT2);
|
||||
Array<float3> corner_normals(mesh->totloop);
|
||||
BKE_mesh_calc_normals_split_ex(
|
||||
mesh, nullptr, reinterpret_cast<float(*)[3]>(corner_normals.data()));
|
||||
|
||||
for (size_t i = 0; i < looptris.size(); ++i) {
|
||||
const float2 *uv_map = static_cast<const float2 *>(
|
||||
CustomData_get_layer(&mesh->loop_data, CD_PROP_FLOAT2));
|
||||
|
||||
for (const int i : looptris.index_range()) {
|
||||
int mat_ind = material_indices ? material_indices[looptri_faces[i]] : 0;
|
||||
const MLoopTri < = looptris[i];
|
||||
SubMesh &sm = submeshes_[mat_ind];
|
||||
@@ -245,16 +249,16 @@ void MeshData::write_submeshes(const Mesh *mesh)
|
||||
sm.face_vertex_indices.push_back(corner_verts[lt.tri[1]]);
|
||||
sm.face_vertex_indices.push_back(corner_verts[lt.tri[2]]);
|
||||
|
||||
if (lnors) {
|
||||
sm.normals.push_back(pxr::GfVec3f(lnors[lt.tri[0]]));
|
||||
sm.normals.push_back(pxr::GfVec3f(lnors[lt.tri[1]]));
|
||||
sm.normals.push_back(pxr::GfVec3f(lnors[lt.tri[2]]));
|
||||
if (!corner_normals.is_empty()) {
|
||||
sm.normals.push_back(pxr::GfVec3f(&corner_normals[lt.tri[0]].x));
|
||||
sm.normals.push_back(pxr::GfVec3f(&corner_normals[lt.tri[1]].x));
|
||||
sm.normals.push_back(pxr::GfVec3f(&corner_normals[lt.tri[2]].x));
|
||||
}
|
||||
|
||||
if (luvs) {
|
||||
sm.uvs.push_back(pxr::GfVec2f(luvs[lt.tri[0]]));
|
||||
sm.uvs.push_back(pxr::GfVec2f(luvs[lt.tri[1]]));
|
||||
sm.uvs.push_back(pxr::GfVec2f(luvs[lt.tri[2]]));
|
||||
if (uv_map) {
|
||||
sm.uvs.push_back(pxr::GfVec2f(&uv_map[lt.tri[0]].x));
|
||||
sm.uvs.push_back(pxr::GfVec2f(&uv_map[lt.tri[1]].x));
|
||||
sm.uvs.push_back(pxr::GfVec2f(&uv_map[lt.tri[2]].x));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,13 +276,9 @@ void MeshData::write_submeshes(const Mesh *mesh)
|
||||
return;
|
||||
}
|
||||
|
||||
/* vertices */
|
||||
const blender::Span<blender::float3> verts = mesh->vert_positions();
|
||||
pxr::VtVec3fArray vertices(mesh->totvert);
|
||||
int i = 0;
|
||||
for (blender::float3 v : verts) {
|
||||
vertices[i++] = pxr::GfVec3f(v.x, v.y, v.z);
|
||||
}
|
||||
const Span<float3> positions = mesh->vert_positions();
|
||||
MutableSpan(vertices.data(), vertices.size()).copy_from(positions.cast<pxr::GfVec3f>());
|
||||
|
||||
if (submeshes_.size() == 1) {
|
||||
submeshes_[0].vertices = std::move(vertices);
|
||||
|
||||
Reference in New Issue
Block a user