diff options
5 files changed, 41 insertions, 4 deletions
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc index 4f5321019d5..13d1a4fdde6 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc @@ -369,11 +369,25 @@ void OBJWriter::write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh, /** * 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); fh.write<eOBJSyntaxElement::nurbs_parameter_begin>(); for (int i = 1; i <= total_control_points + 2; i++) { - fh.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; + } + } + fh.write<eOBJSyntaxElement::nurbs_parameters>(parm); } fh.write<eOBJSyntaxElement::nurbs_parameter_end>(); diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_io.hh b/source/blender/io/wavefront_obj/exporter/obj_export_io.hh index 692eb7f5db5..e5b731aa51d 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_io.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_io.hh @@ -177,7 +177,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...>}; diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc b/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc index ec690115115..8a6d3b4b93a 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc @@ -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 diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.hh b/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.hh index 0c71c3cc09d..d831afec0a0 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.hh @@ -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: /** diff --git a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc index ac2ee8d566b..01f201897cf 100644 --- a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc @@ -265,7 +265,7 @@ o abcdef o 012345678901234567890123456789abcd o 123 curv 0.0 1.0 -parm 0.0 +parm u 0.0 )"; ASSERT_EQ(got_string, expected); } @@ -410,6 +410,19 @@ 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; |