Fix: Small changes to USD and Alembic curves import
Make both importers work the same way: first building an array of the new offsets, then comparing the offsets to check if the topology changed. Previously the USD importer incorrectly compared curve offsets to USD point counts. Also: - Don't unnecessarily set the resolution to the incorrect default. The default for the curves system is 12. But it's unnecessary to fill the attribute to the default value anyway. - Use some helper methods to iterate over all curves. - Use float literal instead of integer. - Use cast and `copy_from` for positions copy - Pass Span by value Pull Request: https://projects.blender.org/blender/blender/pulls/118829
This commit is contained in:
@@ -139,18 +139,9 @@ static CurveType get_curve_type(const Alembic::AbcGeom::BasisType basis)
|
||||
static bool curves_topology_changed(const bke::CurvesGeometry &curves,
|
||||
Span<int> preprocessed_offsets)
|
||||
{
|
||||
/* Offsets have an extra element. */
|
||||
if (curves.curve_num != preprocessed_offsets.size() - 1) {
|
||||
if (curves.offsets() != preprocessed_offsets) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const Span<int> offsets = curves.offsets();
|
||||
for (const int i_curve : preprocessed_offsets.index_range()) {
|
||||
if (offsets[i_curve] != preprocessed_offsets[i_curve]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,17 +41,17 @@ static int point_count(int usdCount, CurveType curve_type, bool is_cyclic)
|
||||
return usdCount;
|
||||
}
|
||||
|
||||
/** Return the sum of the values of each element in `usdCounts`. This is used for precomputing the
|
||||
* total number of points for all curves in some curve primitive. */
|
||||
static int accumulate_point_count(const pxr::VtIntArray &usdCounts,
|
||||
CurveType curve_type,
|
||||
bool is_cyclic)
|
||||
static Array<int> calc_curve_offsets(const pxr::VtIntArray &usdCounts,
|
||||
const CurveType curve_type,
|
||||
bool is_cyclic)
|
||||
{
|
||||
int result = 0;
|
||||
for (int v : usdCounts) {
|
||||
result += point_count(v, curve_type, is_cyclic);
|
||||
Array<int> offsets(usdCounts.size() + 1);
|
||||
int offset = 0;
|
||||
for (const int i : offsets.index_range()) {
|
||||
offsets[i] = offset;
|
||||
offset += point_count(usdCounts[i], curve_type, is_cyclic);
|
||||
}
|
||||
return result;
|
||||
return offsets;
|
||||
}
|
||||
|
||||
static void add_bezier_control_point(int cp,
|
||||
@@ -59,7 +59,7 @@ static void add_bezier_control_point(int cp,
|
||||
MutableSpan<float3> positions,
|
||||
MutableSpan<float3> handles_left,
|
||||
MutableSpan<float3> handles_right,
|
||||
const Span<pxr::GfVec3f> &usdPoints)
|
||||
const Span<pxr::GfVec3f> usdPoints)
|
||||
{
|
||||
if (offset == 0) {
|
||||
positions[cp] = to_float3(usdPoints[offset]);
|
||||
@@ -79,27 +79,11 @@ static void add_bezier_control_point(int cp,
|
||||
}
|
||||
|
||||
/** Returns true if the number of curves or the number of curve points in each curve differ. */
|
||||
static bool curves_topology_changed(const bke::CurvesGeometry &curves,
|
||||
const pxr::VtIntArray &usdCounts,
|
||||
CurveType curve_type,
|
||||
int expected_total_point_num,
|
||||
bool is_cyclic)
|
||||
static bool curves_topology_changed(const bke::CurvesGeometry &curves, const Span<int> usd_offsets)
|
||||
{
|
||||
if (curves.curves_num() != usdCounts.size()) {
|
||||
if (curves.offsets() != usd_offsets) {
|
||||
return true;
|
||||
}
|
||||
if (curves.points_num() != expected_total_point_num) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const int curve : curves.curves_range()) {
|
||||
const int expected_curve_point_num = point_count(usdCounts[curve], curve_type, is_cyclic);
|
||||
const int current_curve_point_num = curves.curve_offsets[curve];
|
||||
|
||||
if (current_curve_point_num != expected_curve_point_num) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -175,17 +159,17 @@ void USDCurvesReader::read_curve_sample(Curves *curves_id, const double motionSa
|
||||
|
||||
const CurveType curve_type = get_curve_type(type, basis);
|
||||
const bool is_cyclic = wrap == pxr::UsdGeomTokens->periodic;
|
||||
const int num_subcurves = usdCounts.size();
|
||||
const int num_points = accumulate_point_count(usdCounts, curve_type, is_cyclic);
|
||||
const int default_resolution = 6;
|
||||
const int curves_num = usdCounts.size();
|
||||
const Array<int> new_offsets = calc_curve_offsets(usdCounts, curve_type, is_cyclic);
|
||||
|
||||
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
if (curves_topology_changed(curves, usdCounts, curve_type, num_points, is_cyclic)) {
|
||||
curves.resize(num_points, num_subcurves);
|
||||
if (curves_topology_changed(curves, new_offsets)) {
|
||||
curves.resize(new_offsets.last(), curves_num);
|
||||
}
|
||||
|
||||
curves.offsets_for_write().copy_from(new_offsets);
|
||||
|
||||
curves.fill_curve_types(curve_type);
|
||||
curves.resolution_for_write().fill(default_resolution);
|
||||
|
||||
if (is_cyclic) {
|
||||
curves.cyclic_for_write().fill(true);
|
||||
@@ -196,7 +180,6 @@ void USDCurvesReader::read_curve_sample(Curves *curves_id, const double motionSa
|
||||
curves.nurbs_orders_for_write().fill(curve_order);
|
||||
}
|
||||
|
||||
MutableSpan<int> offsets = curves.offsets_for_write();
|
||||
MutableSpan<float3> positions = curves.positions_for_write();
|
||||
|
||||
/* Bezier curves require care in filing out their left/right handles. */
|
||||
@@ -210,12 +193,10 @@ void USDCurvesReader::read_curve_sample(Curves *curves_id, const double motionSa
|
||||
|
||||
int usd_point_offset = 0;
|
||||
int point_offset = 0;
|
||||
for (const int i : IndexRange(num_subcurves)) {
|
||||
for (const int i : curves.curves_range()) {
|
||||
const int usd_point_count = usdCounts[i];
|
||||
const int point_count = bezier_point_count(usd_point_count, is_cyclic);
|
||||
|
||||
offsets[i] = point_offset;
|
||||
|
||||
int cp_offset = 0;
|
||||
for (const int cp : IndexRange(point_count)) {
|
||||
add_bezier_control_point(cp,
|
||||
@@ -232,16 +213,8 @@ void USDCurvesReader::read_curve_sample(Curves *curves_id, const double motionSa
|
||||
}
|
||||
}
|
||||
else {
|
||||
int offset = 0;
|
||||
for (const int i : IndexRange(num_subcurves)) {
|
||||
const int num_verts = usdCounts[i];
|
||||
offsets[i] = offset;
|
||||
offset += num_verts;
|
||||
}
|
||||
|
||||
for (const int i_point : curves.points_range()) {
|
||||
positions[i_point] = to_float3(usdPoints[i_point]);
|
||||
}
|
||||
static_assert(sizeof(pxr::GfVec3f) == sizeof(float3));
|
||||
positions.copy_from(Span(usdPoints.data(), usdPoints.size()).cast<float3>());
|
||||
}
|
||||
|
||||
if (!usdWidths.empty()) {
|
||||
@@ -251,7 +224,7 @@ void USDCurvesReader::read_curve_sample(Curves *curves_id, const double motionSa
|
||||
|
||||
pxr::TfToken widths_interp = curve_prim_.GetWidthsInterpolation();
|
||||
if (widths_interp == pxr::UsdGeomTokens->constant) {
|
||||
radii.span.fill(usdWidths[0] / 2);
|
||||
radii.span.fill(usdWidths[0] / 2.0f);
|
||||
}
|
||||
else {
|
||||
const bool is_bezier_vertex_interp = (type == pxr::UsdGeomTokens->cubic &&
|
||||
@@ -262,13 +235,13 @@ void USDCurvesReader::read_curve_sample(Curves *curves_id, const double motionSa
|
||||
* Assign the widths as-if it were 'varying' only. */
|
||||
int usd_point_offset = 0;
|
||||
int point_offset = 0;
|
||||
for (const int i : IndexRange(num_subcurves)) {
|
||||
for (const int i : curves.curves_range()) {
|
||||
const int usd_point_count = usdCounts[i];
|
||||
const int point_count = bezier_point_count(usd_point_count, is_cyclic);
|
||||
|
||||
int cp_offset = 0;
|
||||
for (const int cp : IndexRange(point_count)) {
|
||||
radii.span[point_offset + cp] = usdWidths[usd_point_offset + cp_offset] / 2;
|
||||
radii.span[point_offset + cp] = usdWidths[usd_point_offset + cp_offset] / 2.0f;
|
||||
cp_offset += 3;
|
||||
}
|
||||
|
||||
@@ -278,7 +251,7 @@ void USDCurvesReader::read_curve_sample(Curves *curves_id, const double motionSa
|
||||
}
|
||||
else {
|
||||
for (const int i_point : curves.points_range()) {
|
||||
radii.span[i_point] = usdWidths[i_point] / 2;
|
||||
radii.span[i_point] = usdWidths[i_point] / 2.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user