Curves: Enhance tesselation of NURBS with corners
Current NURBS evaluation handles corners or sharp angles poorly. Sharp edges appear when a knot vector value is repeated `order - 1` times. Users can make sharp corners by creating NURBS curve with `Bezier` knot mode or by setting `order` to 2 for legacy curves. The problem occurs because current algorithm takes all the curve's definition interval, divides it into equal parts and evaluates at those points, but corners are exactly on repeated knot's. To hit those, the resolution has to be increased higher than required for the rest of the curve. The new algorithm divides non zero length intervals between two adjacent knots into equal parts. This way corners are hit with a resolution of 1. This does change the evaluated points of NURBS curves, which is why some test results have to be updated in this commit. Pull Request: https://projects.blender.org/blender/blender/pulls/138565
This commit is contained in:
parent
e9bb58e6df
commit
3c407ebeaa
@ -854,8 +854,12 @@ bool check_valid_num_and_order(int points_num, int8_t order, bool cyclic, KnotsM
|
|||||||
* for predictability and so that cached basis weights of NURBS curves with these properties can be
|
* for predictability and so that cached basis weights of NURBS curves with these properties can be
|
||||||
* shared.
|
* shared.
|
||||||
*/
|
*/
|
||||||
int calculate_evaluated_num(
|
int calculate_evaluated_num(int points_num,
|
||||||
int points_num, int8_t order, bool cyclic, int resolution, KnotsMode knots_mode);
|
int8_t order,
|
||||||
|
bool cyclic,
|
||||||
|
int resolution,
|
||||||
|
KnotsMode knots_mode,
|
||||||
|
Span<float> knots);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the length of the knot vector for a NURBS curve with the given properties.
|
* Calculate the length of the knot vector for a NURBS curve with the given properties.
|
||||||
@ -906,6 +910,7 @@ Vector<int> calculate_multiplicity_sequence(Span<float> knots);
|
|||||||
void calculate_basis_cache(int points_num,
|
void calculate_basis_cache(int points_num,
|
||||||
int evaluated_num,
|
int evaluated_num,
|
||||||
int8_t order,
|
int8_t order,
|
||||||
|
int resolution,
|
||||||
bool cyclic,
|
bool cyclic,
|
||||||
Span<float> knots,
|
Span<float> knots,
|
||||||
BasisCache &basis_cache);
|
BasisCache &basis_cache);
|
||||||
|
@ -32,16 +32,57 @@ bool check_valid_num_and_order(const int points_num,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int calc_nonzero_knot_spans(const int points_num,
|
||||||
|
const KnotsMode mode,
|
||||||
|
const int8_t order,
|
||||||
|
const bool cyclic)
|
||||||
|
{
|
||||||
|
const bool is_bezier = ELEM(mode, NURBS_KNOT_MODE_BEZIER, NURBS_KNOT_MODE_ENDPOINT_BEZIER);
|
||||||
|
const bool is_end_point = ELEM(mode, NURBS_KNOT_MODE_ENDPOINT, NURBS_KNOT_MODE_ENDPOINT_BEZIER);
|
||||||
|
/* Inner knots are always repeated once except on Bezier case. */
|
||||||
|
const int repeat_inner = is_bezier ? order - 1 : 1;
|
||||||
|
/* For non endpoint Bezier repeated knots are shifted by one. */
|
||||||
|
const int knots_before_geometry = order + int(is_bezier && !is_end_point && order > 2);
|
||||||
|
const int knots_after_geometry = order - 1 +
|
||||||
|
(cyclic && mode == NURBS_KNOT_MODE_ENDPOINT ? order - 2 : 0);
|
||||||
|
|
||||||
|
const int knots_total = knots_num(points_num, order, cyclic);
|
||||||
|
/* On these knots as parameters actual geometry is generated. */
|
||||||
|
const int geometry_knots = knots_total - knots_before_geometry - knots_after_geometry;
|
||||||
|
/* `repeat_inner - 1` is added to `ceil`. */
|
||||||
|
const int non_zero_knots = (geometry_knots + repeat_inner - 1) / repeat_inner;
|
||||||
|
return non_zero_knots;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int count_nonzero_knot_spans(const int points_num,
|
||||||
|
const int order,
|
||||||
|
const bool cyclic,
|
||||||
|
const Span<float> knots)
|
||||||
|
{
|
||||||
|
BLI_assert(points_num > 0);
|
||||||
|
const int degree = order - 1;
|
||||||
|
int span_num = 0;
|
||||||
|
for (const int knot_span : IndexRange::from_begin_end(cyclic ? 0 : degree, points_num)) {
|
||||||
|
span_num += (knots[knot_span + 1] - knots[knot_span]) > 0.0f;
|
||||||
|
}
|
||||||
|
return span_num;
|
||||||
|
}
|
||||||
|
|
||||||
int calculate_evaluated_num(const int points_num,
|
int calculate_evaluated_num(const int points_num,
|
||||||
const int8_t order,
|
const int8_t order,
|
||||||
const bool cyclic,
|
const bool cyclic,
|
||||||
const int resolution,
|
const int resolution,
|
||||||
const KnotsMode knots_mode)
|
const KnotsMode knots_mode,
|
||||||
|
const Span<float> knots)
|
||||||
{
|
{
|
||||||
if (!check_valid_num_and_order(points_num, order, cyclic, knots_mode)) {
|
if (!check_valid_num_and_order(points_num, order, cyclic, knots_mode)) {
|
||||||
return points_num;
|
return points_num;
|
||||||
}
|
}
|
||||||
return resolution * segments_num(points_num, cyclic);
|
const int nonzero_span_num = knots_mode == KnotsMode::NURBS_KNOT_MODE_CUSTOM &&
|
||||||
|
!knots.is_empty() ?
|
||||||
|
count_nonzero_knot_spans(points_num, order, cyclic, knots) :
|
||||||
|
calc_nonzero_knot_spans(points_num, knots_mode, order, cyclic);
|
||||||
|
return resolution * nonzero_span_num + int(!cyclic);
|
||||||
}
|
}
|
||||||
|
|
||||||
int knots_num(const int points_num, const int8_t order, const bool cyclic)
|
int knots_num(const int points_num, const int8_t order, const bool cyclic)
|
||||||
@ -206,6 +247,7 @@ static void calculate_basis_for_point(const float parameter,
|
|||||||
void calculate_basis_cache(const int points_num,
|
void calculate_basis_cache(const int points_num,
|
||||||
const int evaluated_num,
|
const int evaluated_num,
|
||||||
const int8_t order,
|
const int8_t order,
|
||||||
|
const int resolution,
|
||||||
const bool cyclic,
|
const bool cyclic,
|
||||||
const Span<float> knots,
|
const Span<float> knots,
|
||||||
BasisCache &basis_cache)
|
BasisCache &basis_cache)
|
||||||
@ -225,19 +267,34 @@ void calculate_basis_cache(const int points_num,
|
|||||||
MutableSpan<int> basis_start_indices(basis_cache.start_indices);
|
MutableSpan<int> basis_start_indices(basis_cache.start_indices);
|
||||||
|
|
||||||
const int last_control_point_index = cyclic ? points_num + degree : points_num;
|
const int last_control_point_index = cyclic ? points_num + degree : points_num;
|
||||||
const int evaluated_segment_num = segments_num(evaluated_num, cyclic);
|
|
||||||
|
|
||||||
const float start = knots[degree];
|
int eval_point = 0;
|
||||||
const float end = knots[last_control_point_index];
|
|
||||||
const float step = (end - start) / evaluated_segment_num;
|
|
||||||
for (const int i : IndexRange(evaluated_num)) {
|
|
||||||
/* Clamp parameter due to floating point inaccuracy. */
|
|
||||||
const float parameter = std::clamp(start + step * i, knots[0], knots[points_num + degree]);
|
|
||||||
|
|
||||||
MutableSpan<float> point_weights = basis_weights.slice(i * order, order);
|
for (const int knot_span : IndexRange::from_begin_end(degree, last_control_point_index)) {
|
||||||
|
const float start = knots[knot_span];
|
||||||
calculate_basis_for_point(
|
const float end = knots[knot_span + 1];
|
||||||
parameter, last_control_point_index, degree, knots, point_weights, basis_start_indices[i]);
|
if (start == end) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const float step_width = (end - start) / resolution;
|
||||||
|
for (const int step : IndexRange::from_begin_size(0, resolution)) {
|
||||||
|
const float parameter = start + step * step_width;
|
||||||
|
calculate_basis_for_point(parameter,
|
||||||
|
last_control_point_index,
|
||||||
|
degree,
|
||||||
|
knots,
|
||||||
|
basis_weights.slice(eval_point * order, order),
|
||||||
|
basis_start_indices[eval_point]);
|
||||||
|
eval_point++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!cyclic) {
|
||||||
|
calculate_basis_for_point(knots[last_control_point_index],
|
||||||
|
last_control_point_index,
|
||||||
|
degree,
|
||||||
|
knots,
|
||||||
|
basis_weights.slice(eval_point * order, order),
|
||||||
|
basis_start_indices[eval_point]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,7 +501,10 @@ static void build_mesh_positions(const CurvesInfo &curves_info,
|
|||||||
const bool ignore_profile_position = profile_positions.size() == 1 &&
|
const bool ignore_profile_position = profile_positions.size() == 1 &&
|
||||||
math::is_equal(profile_positions.first(), float3(0.0f));
|
math::is_equal(profile_positions.first(), float3(0.0f));
|
||||||
if (ignore_profile_position) {
|
if (ignore_profile_position) {
|
||||||
if (mesh.verts_num == curves_info.main.points_num()) {
|
if (mesh.verts_num == curves_info.main.points_num() &&
|
||||||
|
/* NURBS can have equal evaluated and positions sizes, but different coords. */
|
||||||
|
!curves_info.main.has_curve_with_type(CURVE_TYPE_NURBS))
|
||||||
|
{
|
||||||
const GAttributeReader src = curves_info.main.attributes().lookup("position");
|
const GAttributeReader src = curves_info.main.attributes().lookup("position");
|
||||||
if (src.sharing_info && src.varray.is_span()) {
|
if (src.sharing_info && src.varray.is_span()) {
|
||||||
const AttributeInitShared init(src.varray.get_internal_span().data(), *src.sharing_info);
|
const AttributeInitShared init(src.varray.get_internal_span().data(), *src.sharing_info);
|
||||||
|
@ -657,6 +657,8 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves,
|
|||||||
|
|
||||||
const VArray<int8_t> nurbs_orders = curves.nurbs_orders();
|
const VArray<int8_t> nurbs_orders = curves.nurbs_orders();
|
||||||
const VArray<int8_t> nurbs_knots_modes = curves.nurbs_knots_modes();
|
const VArray<int8_t> nurbs_knots_modes = curves.nurbs_knots_modes();
|
||||||
|
const OffsetIndices<int> custom_knots_by_curve = curves.nurbs_custom_knots_by_curve();
|
||||||
|
const Span<float> all_custom_knots = curves.nurbs_custom_knots();
|
||||||
|
|
||||||
build_offsets(offsets, [&](const int curve_index) -> int {
|
build_offsets(offsets, [&](const int curve_index) -> int {
|
||||||
const IndexRange points = points_by_curve[curve_index];
|
const IndexRange points = points_by_curve[curve_index];
|
||||||
@ -676,11 +678,17 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves,
|
|||||||
return all_bezier_offsets[offsets.last()];
|
return all_bezier_offsets[offsets.last()];
|
||||||
}
|
}
|
||||||
case CURVE_TYPE_NURBS:
|
case CURVE_TYPE_NURBS:
|
||||||
return curves::nurbs::calculate_evaluated_num(points.size(),
|
const bool is_cyclic = cyclic[curve_index];
|
||||||
nurbs_orders[curve_index],
|
const int8_t order = nurbs_orders[curve_index];
|
||||||
cyclic[curve_index],
|
const KnotsMode knots_mode = KnotsMode(nurbs_knots_modes[curve_index]);
|
||||||
resolution[curve_index],
|
const IndexRange custom_knots_range = custom_knots_by_curve[curve_index];
|
||||||
KnotsMode(nurbs_knots_modes[curve_index]));
|
const Span<float> custom_knots = knots_mode == NURBS_KNOT_MODE_CUSTOM &&
|
||||||
|
!all_custom_knots.is_empty() &&
|
||||||
|
!custom_knots_range.is_empty() ?
|
||||||
|
all_custom_knots.slice(custom_knots_range) :
|
||||||
|
Span<float>();
|
||||||
|
return curves::nurbs::calculate_evaluated_num(
|
||||||
|
points.size(), order, is_cyclic, resolution[curve_index], knots_mode, custom_knots);
|
||||||
}
|
}
|
||||||
BLI_assert_unreachable();
|
BLI_assert_unreachable();
|
||||||
return 0;
|
return 0;
|
||||||
@ -755,6 +763,7 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const
|
|||||||
const OffsetIndices<int> custom_knots_by_curve = this->nurbs_custom_knots_by_curve();
|
const OffsetIndices<int> custom_knots_by_curve = this->nurbs_custom_knots_by_curve();
|
||||||
const VArray<bool> cyclic = this->cyclic();
|
const VArray<bool> cyclic = this->cyclic();
|
||||||
const VArray<int8_t> orders = this->nurbs_orders();
|
const VArray<int8_t> orders = this->nurbs_orders();
|
||||||
|
const VArray<int> resolutions = this->resolution();
|
||||||
const VArray<int8_t> knots_modes = this->nurbs_knots_modes();
|
const VArray<int8_t> knots_modes = this->nurbs_knots_modes();
|
||||||
const Span<float> custom_knots = this->nurbs_custom_knots();
|
const Span<float> custom_knots = this->nurbs_custom_knots();
|
||||||
|
|
||||||
@ -765,6 +774,7 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const
|
|||||||
const IndexRange evaluated_points = evaluated_points_by_curve[curve_index];
|
const IndexRange evaluated_points = evaluated_points_by_curve[curve_index];
|
||||||
|
|
||||||
const int8_t order = orders[curve_index];
|
const int8_t order = orders[curve_index];
|
||||||
|
const int resolution = resolutions[curve_index];
|
||||||
const bool is_cyclic = cyclic[curve_index];
|
const bool is_cyclic = cyclic[curve_index];
|
||||||
const KnotsMode mode = KnotsMode(knots_modes[curve_index]);
|
const KnotsMode mode = KnotsMode(knots_modes[curve_index]);
|
||||||
|
|
||||||
@ -782,8 +792,13 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const
|
|||||||
custom_knots,
|
custom_knots,
|
||||||
knots);
|
knots);
|
||||||
|
|
||||||
curves::nurbs::calculate_basis_cache(
|
curves::nurbs::calculate_basis_cache(points.size(),
|
||||||
points.size(), evaluated_points.size(), order, is_cyclic, knots, r_data[curve_index]);
|
evaluated_points.size(),
|
||||||
|
order,
|
||||||
|
resolution,
|
||||||
|
is_cyclic,
|
||||||
|
knots,
|
||||||
|
r_data[curve_index]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -329,16 +329,17 @@ TEST(curves_geometry, NURBSEvaluation)
|
|||||||
|
|
||||||
Span<float3> evaluated_positions = curves.evaluated_positions();
|
Span<float3> evaluated_positions = curves.evaluated_positions();
|
||||||
static const Array<float3> result_1{{
|
static const Array<float3> result_1{{
|
||||||
{0.166667, 0.833333, 0}, {0.150006, 0.815511, 0}, {0.134453, 0.796582, 0},
|
{0.166667, 0.833333, 0},
|
||||||
{0.119924, 0.776627, 0}, {0.106339, 0.75573, 0}, {0.0936146, 0.733972, 0},
|
{0.121333, 0.778667, 0},
|
||||||
{0.0816693, 0.711434, 0}, {0.0704211, 0.6882, 0}, {0.0597879, 0.66435, 0},
|
{0.084, 0.716, 0},
|
||||||
{0.0496877, 0.639968, 0}, {0.0400385, 0.615134, 0}, {0.0307584, 0.589931, 0},
|
{0.0526667, 0.647333, 0},
|
||||||
{0.0217653, 0.564442, 0}, {0.0129772, 0.538747, 0}, {0.00431208, 0.512929, 0},
|
{0.0253333, 0.574667, 0},
|
||||||
{-0.00431208, 0.487071, 0}, {-0.0129772, 0.461253, 0}, {-0.0217653, 0.435558, 0},
|
{0, 0.5, 0},
|
||||||
{-0.0307584, 0.410069, 0}, {-0.0400385, 0.384866, 0}, {-0.0496877, 0.360032, 0},
|
{-0.0253333, 0.425333, 0},
|
||||||
{-0.0597878, 0.33565, 0}, {-0.0704211, 0.3118, 0}, {-0.0816693, 0.288566, 0},
|
{-0.0526667, 0.352667, 0},
|
||||||
{-0.0936146, 0.266028, 0}, {-0.106339, 0.24427, 0}, {-0.119924, 0.223373, 0},
|
{-0.084, 0.284, 0},
|
||||||
{-0.134453, 0.203418, 0}, {-0.150006, 0.184489, 0}, {-0.166667, 0.166667, 0},
|
{-0.121333, 0.221333, 0},
|
||||||
|
{-0.166667, 0.166667, 0},
|
||||||
}};
|
}};
|
||||||
for (const int i : evaluated_positions.index_range()) {
|
for (const int i : evaluated_positions.index_range()) {
|
||||||
EXPECT_V3_NEAR(evaluated_positions[i], result_1[i], 1e-5f);
|
EXPECT_V3_NEAR(evaluated_positions[i], result_1[i], 1e-5f);
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:5b265d844db7a6f84520e6c01987eec91eab20bd4eeb3e061e83e6b4a35d4323
|
oid sha256:550fa013ce1c048e889087fcbda18c8043456cca3759375064e1b4c8111308be
|
||||||
size 8652
|
size 7531
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:72b89d5470bb42af366946d1d32cc653001facae1266ea6342f1609a190e55a9
|
oid sha256:c2098e5dce32abb74d49e49f71479ecdd7a9acfe4f86b699e36584c4103fc4ba
|
||||||
size 6709
|
size 6709
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:5d11c9cb2b0299b3d425864f1f583a7de2f4152306d7ed886cdcffb829bf93a8
|
oid sha256:f3cc276cb772ecef16c332de06fce6c5bfc577fabdea07a8d3b6293f8727bdfe
|
||||||
size 321069
|
size 321069
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:be872ec81f8cbb50121b40c5de90cb3ca7e19ff1eb1421ba8ad27fa4681473f6
|
oid sha256:c3a4e24475815b526f6fc180c9d0016a482434e822a3270846ecda9e103a60c7
|
||||||
size 321239
|
size 321239
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:7da3b2cb989d0fe71a95a4e32b302b538a7baf406d2728d7b5d2265c49cd8c04
|
oid sha256:98389651f47f3d6b2f5eca34716d8151a7c6a033e379a9cdc03219514fe034f8
|
||||||
size 4213
|
size 4213
|
||||||
|
@ -65,37 +65,34 @@
|
|||||||
- (11.193, 0.000, 0.969)
|
- (11.193, 0.000, 0.969)
|
||||||
- (10.989, 0.000, 0.883)
|
- (10.989, 0.000, 0.883)
|
||||||
|
|
||||||
- Mesh 'NurbsCurve' vtx:9 face:0 loop:0 edge:8
|
- Mesh 'NurbsCurve' vtx:4 face:0 loop:0 edge:3
|
||||||
- 0/1 1/2 2/3 3/4 4/5 5/6 6/7 7/8
|
- 0/1 1/2 2/3
|
||||||
- attr 'position' FLOAT_VECTOR POINT
|
- attr 'position' FLOAT_VECTOR POINT
|
||||||
- (7.730, 0.000, -0.375)
|
- (7.730, 0.000, -0.375)
|
||||||
- (7.886, 0.000, -0.581)
|
- (8.189, 0.000, -0.809)
|
||||||
- (8.063, 0.000, -0.734)
|
- (8.717, 0.000, -0.927)
|
||||||
...
|
|
||||||
- (8.846, 0.000, -0.920)
|
|
||||||
- (9.030, 0.000, -0.887)
|
|
||||||
- (9.197, 0.000, -0.833)
|
- (9.197, 0.000, -0.833)
|
||||||
|
|
||||||
- Mesh 'NurbsCurve2' vtx:24 face:0 loop:0 edge:23
|
- Mesh 'NurbsCurve2' vtx:17 face:0 loop:0 edge:16
|
||||||
- 0/1 1/2 2/3 3/4 4/5 ... 18/19 19/20 20/21 21/22 22/23
|
- 0/1 1/2 2/3 3/4 4/5 ... 11/12 12/13 13/14 14/15 15/16
|
||||||
- attr 'position' FLOAT_VECTOR POINT
|
- attr 'position' FLOAT_VECTOR POINT
|
||||||
- (5.857, 0.000, 5.211)
|
- (5.857, 0.000, 5.211)
|
||||||
- (5.883, 0.000, 4.843)
|
- (5.921, 0.000, 4.685)
|
||||||
- (5.990, 0.000, 4.491)
|
- (6.135, 0.000, 4.218)
|
||||||
...
|
...
|
||||||
- (9.419, 0.000, 3.357)
|
- (9.283, 0.000, 3.248)
|
||||||
- (9.557, 0.000, 3.570)
|
- (9.500, 0.000, 3.465)
|
||||||
- (9.665, 0.000, 3.871)
|
- (9.665, 0.000, 3.871)
|
||||||
|
|
||||||
- Mesh 'NurbsPathCurve' vtx:31 face:0 loop:0 edge:29
|
- Mesh 'NurbsPathCurve' vtx:15 face:0 loop:0 edge:13
|
||||||
- 0/1 1/2 2/3 3/4 4/5 ... 25/26 26/27 27/28 28/29 29/30
|
- 0/1 1/2 2/3 3/4 4/5 ... 9/10 10/11 11/12 12/13 13/14
|
||||||
- attr 'position' FLOAT_VECTOR POINT
|
- attr 'position' FLOAT_VECTOR POINT
|
||||||
- (13.691, 0.000, 0.000)
|
- (13.691, 0.000, 0.000)
|
||||||
- (14.059, 0.000, 0.419)
|
- (14.345, 0.000, 0.646)
|
||||||
- (14.383, 0.000, 0.670)
|
- (14.865, 0.000, 0.823)
|
||||||
...
|
...
|
||||||
- (16.242, 0.000, -0.671)
|
- (15.852, 0.000, -0.877)
|
||||||
- (16.339, 0.000, -0.583)
|
- (16.160, 0.000, -0.732)
|
||||||
- (16.430, 0.000, -0.479)
|
- (16.430, 0.000, -0.479)
|
||||||
|
|
||||||
- Mesh 'PolyCircle' vtx:4 face:0 loop:0 edge:4
|
- Mesh 'PolyCircle' vtx:4 face:0 loop:0 edge:4
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:5a8eda24804f2c3ac01e93af91af20b45ccbf57fee6bf16b81abc47ce781eb99
|
oid sha256:6393161f668410636448320997eabecaff0d2174bcbec6e2b580cac62487b8f1
|
||||||
size 145664
|
size 1603172
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:19a9d325f95220e8ddc3a787a02d18a78480a6a43ad7177d128f069bc6163dbf
|
oid sha256:fc4ccfecbac1c16487705e4d62137f40874df01f1606a2912d25d01f38fba768
|
||||||
size 150542
|
size 991954
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:81af832bacc4e62ad28785a998d1b3a09b555058466553481ce30434b041d402
|
oid sha256:14b15a0a23f21cfefa67b3b437ae68615464a1275c354ca9b6c92b98f388d584
|
||||||
size 89539
|
size 642331
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:6346756e7672b3330f0564518c98419d2616ab5d221e0afa4066397e733db118
|
oid sha256:8bdd3fb883c784f7dfe59ab11315596f577f537cb429ca23a7229f1ef5bd0cbb
|
||||||
size 135396
|
size 1014822
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:4ed3a58f5c685a7dbae64b7cfaee3170b90eced80ea77061ef790f5e9c7b94dd
|
oid sha256:5bca0f399a4a8eab1d3e9ace766c1acc55f8b1b5c542020a84b7cd3db5876f12
|
||||||
size 124628
|
size 1060327
|
||||||
|
@ -936,7 +936,7 @@ class USDExportTest(AbstractUSDTest):
|
|||||||
|
|
||||||
# Contains 2 NURBS curves
|
# Contains 2 NURBS curves
|
||||||
curve = UsdGeom.NurbsCurves(stage.GetPrimAtPath("/root/NurbsCurve/NurbsCurve"))
|
curve = UsdGeom.NurbsCurves(stage.GetPrimAtPath("/root/NurbsCurve/NurbsCurve"))
|
||||||
check_nurbs_curve(curve, False, [4, 4], [6, 6], 10, [[-1.75, -2.6898, -1.0117], [3.0896, 1.9583, 1.0293]])
|
check_nurbs_curve(curve, False, [4, 4], [6, 6], 10, [[-1.75, -2.6891, -1.0117], [3.0896, 1.9583, 1.0293]])
|
||||||
|
|
||||||
# Contains 1 NURBS curve
|
# Contains 1 NURBS curve
|
||||||
curve = UsdGeom.NurbsCurves(stage.GetPrimAtPath("/root/NurbsCircle/NurbsCircle"))
|
curve = UsdGeom.NurbsCurves(stage.GetPrimAtPath("/root/NurbsCircle/NurbsCircle"))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user