Fix #121720: OBJ does not import some curves properly

If a curve was not using U parameter range of 0..1, the importer
did not properly detect whether the "U endpoint" flag should
be set on it. Fixed that, along with test coverage for the case.
This commit is contained in:
Aras Pranckevicius 2024-05-13 11:45:20 +03:00
parent b998697d4f
commit 39150096d8
5 changed files with 43 additions and 6 deletions

@ -358,9 +358,8 @@ static void geom_add_curve_vertex_indices(Geometry *geom,
const char *end,
const GlobalVertices &global_vertices)
{
/* Curve lines always have "0.0" and "1.0", skip over them. */
float dummy[2];
p = parse_floats(p, end, 0, dummy, 2);
/* Parse curve parameter range. */
p = parse_floats(p, end, 0, geom->nurbs_element_.range, 2);
/* Parse indices. */
while (p < end) {
int index;

@ -78,16 +78,21 @@ void CurveFromGeometry::create_nurbs(Curve *curve)
}
BKE_nurb_knot_calc_u(nurb);
/* Figure out whether curve should have U endpoint flag set:
* the parameters should have at least (degree+1) values on each end,
* and their values should match curve range. */
bool do_endpoints = false;
int deg1 = nurbs_geometry.degree + 1;
if (nurbs_geometry.parm.size() >= deg1 * 2) {
do_endpoints = true;
const float2 range = nurbs_geometry.range;
for (int i = 0; i < deg1; ++i) {
if (abs(nurbs_geometry.parm[i]) > 0.0001f) {
if (abs(nurbs_geometry.parm[i] - range.x) > 0.0001f) {
do_endpoints = false;
break;
}
if (abs(nurbs_geometry.parm[nurbs_geometry.parm.size() - 1 - i] - 1.0f) > 0.0001f) {
if (abs(nurbs_geometry.parm[nurbs_geometry.parm.size() - 1 - i] - range.y) > 0.0001f) {
do_endpoints = false;
break;
}

@ -69,6 +69,7 @@ struct NurbsElement {
*/
std::string group_;
int degree = 0;
float2 range{0.0f, 1.0f};
/**
* Indices into the global list of vertex coordinates. Must be non-negative.
*/

@ -316,6 +316,38 @@ TEST_F(OBJImportTest, import_nurbs_cyclic)
import_and_check("nurbs_cyclic.obj", expect, std::size(expect), 0);
}
TEST_F(OBJImportTest, import_nurbs_endpoint)
{
Expectation expect[] = {
{"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
{"OBCurveEndpointRange01",
OB_CURVES_LEGACY,
15,
1,
4,
0,
float3(0.29f, 0, -0.11f),
float3(22.17f, 0, -5.31f)},
{"OBCurveEndpointRangeNon01",
OB_CURVES_LEGACY,
15,
1,
4,
0,
float3(0.29f, 0, -0.11f),
float3(22.17f, 0, -5.31f)},
{"OBCurveNoEndpointRange01",
OB_CURVES_LEGACY,
15,
0,
4,
0,
float3(0.29f, 0, -0.11f),
float3(22.17f, 0, -5.31f)},
};
import_and_check("nurbs_endpoint.obj", expect, std::size(expect), 0);
}
TEST_F(OBJImportTest, import_nurbs_manual)
{
Expectation expect[] = {

@ -1 +1 @@
Subproject commit d8d9c4c5fbca4e11c72fc7247b50655b8c9c7914
Subproject commit 71e05fc367d26218dede9a97f4a0577a3b72a8c8