Fix T95360, new 3.1 obj exporter losing nurbs curve "endpoint".

The new wavefront .obj exporter in 3.1 was producing slightly invalid parm line syntax (missing u), and was not setting first/last N params to zeroes and ones for curves with "endpoint" flag properly.
This commit is contained in:
Aras Pranckevicius 2022-02-05 17:51:03 -05:00 committed by Howard Trickey
parent 3a90f93507
commit c24b2cdebf
Notes: blender-bot 2023-02-14 10:37:50 +01:00
Referenced by issue #95360, New 3.1 obj exporter produces invalid "parm" nurbs curve line, resulting in lost "endpoint" curve flag
5 changed files with 37 additions and 4 deletions

View File

@ -352,12 +352,24 @@ void OBJWriter::write_nurbs_curve(const OBJCurve &obj_nurbs_data) const
/**
* In `parm u 0 0.1 ..` line:, (total control points + 2) equidistant numbers in the
* parameter range are inserted.
* parameter range are inserted. However for curves with endpoint flag,
* first degree+1 numbers are zeroes, and last degree+1 numbers are ones
*/
const short flagsu = obj_nurbs_data.get_nurbs_flagu(spline_idx);
const bool cyclic = flagsu & CU_NURB_CYCLIC;
const bool endpoint = !cyclic && (flagsu & CU_NURB_ENDPOINT);
file_handler_->write<eOBJSyntaxElement::nurbs_parameter_begin>();
for (int i = 1; i <= total_control_points + 2; i++) {
file_handler_->write<eOBJSyntaxElement::nurbs_parameters>(1.0f * i /
(total_control_points + 2 + 1));
float parm = 1.0f * i / (total_control_points + 2 + 1);
if (endpoint) {
if (i <= nurbs_degree) {
parm = 0;
}
else if (i > total_control_points + 2 - nurbs_degree) {
parm = 1;
}
}
file_handler_->write<eOBJSyntaxElement::nurbs_parameters>(parm);
}
file_handler_->write<eOBJSyntaxElement::nurbs_parameter_end>();

View File

@ -168,7 +168,7 @@ constexpr FormattingSyntax syntax_elem_to_formatting(const eOBJSyntaxElement key
return {"curv 0.0 1.0", 0, is_type_string_related<T...>};
}
case eOBJSyntaxElement::nurbs_parameter_begin: {
return {"parm 0.0", 0, is_type_string_related<T...>};
return {"parm u 0.0", 0, is_type_string_related<T...>};
}
case eOBJSyntaxElement::nurbs_parameters: {
return {" %f", 1, is_type_float<T...>};

View File

@ -102,4 +102,10 @@ int OBJCurve::get_nurbs_degree(const int spline_index) const
return nurb->orderu - 1;
}
short OBJCurve::get_nurbs_flagu(const int spline_index) const
{
const Nurb *const nurb = static_cast<Nurb *>(BLI_findlink(&export_curve_->nurb, spline_index));
return nurb->flagu;
}
} // namespace blender::io::obj

View File

@ -61,6 +61,10 @@ class OBJCurve : NonCopyable {
* Get the degree of the NURBS spline at the given index.
*/
int get_nurbs_degree(int spline_index) const;
/**
* Get the U flags (CU_NURB_*) of the NURBS spline at the given index.
*/
short get_nurbs_flagu(int spline_index) const;
private:
/**

View File

@ -378,6 +378,17 @@ TEST_F(obj_exporter_regression_test, nurbs_as_nurbs)
"io_tests/blend_geometry/nurbs.blend", "io_tests/obj/nurbs.obj", "", _export.params);
}
TEST_F(obj_exporter_regression_test, nurbs_curves_as_nurbs)
{
OBJExportParamsDefault _export;
_export.params.forward_axis = OBJ_AXIS_Y_FORWARD;
_export.params.up_axis = OBJ_AXIS_Z_UP;
_export.params.export_materials = false;
_export.params.export_curves_as_nurbs = true;
compare_obj_export_to_golden(
"io_tests/blend_geometry/nurbs_curves.blend", "io_tests/obj/nurbs_curves.obj", "", _export.params);
}
TEST_F(obj_exporter_regression_test, nurbs_as_mesh)
{
OBJExportParamsDefault _export;