diff options
5 files changed, 37 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 d31353c4a76..38163af64b6 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 @@ -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>(); 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 1bbefaee75f..2eb2b66335d 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_io.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_io.hh @@ -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...>}; 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 f97e2575aa2..ecae93f8f7a 100644 --- a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc @@ -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; |