From c233955ef9e911cf63ed6c2985f9d45f204e3a31 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 4 Mar 2025 23:58:02 +0100 Subject: [PATCH] Geometry Nodes: support custom delimiter in Import CSV node Previously, only `,` was a valid delimiter, but it's also common to have e.g. tab or semicolon. Only single characters are supported as delimiters. A few characters are not allowed because they have other meanings: `\n`, `\r`, `"`, `\\`. Note: The best way to get a tab character is the use the Special Characters node currently. Pull Request: https://projects.blender.org/blender/blender/pulls/135468 --- source/blender/io/csv/IO_csv.hh | 1 + source/blender/io/csv/importer/csv_reader.cc | 1 + .../nodes/geometry/nodes/node_geo_import_csv.cc | 14 ++++++++++++++ 3 files changed, 16 insertions(+) diff --git a/source/blender/io/csv/IO_csv.hh b/source/blender/io/csv/IO_csv.hh index 918d67210ed..44e888e89e2 100644 --- a/source/blender/io/csv/IO_csv.hh +++ b/source/blender/io/csv/IO_csv.hh @@ -18,6 +18,7 @@ namespace blender::io::csv { struct CSVImportParams { /** Full path to the source CSV file to import. */ char filepath[FILE_MAX]; + char delimiter = ','; ReportList *reports = nullptr; }; diff --git a/source/blender/io/csv/importer/csv_reader.cc b/source/blender/io/csv/importer/csv_reader.cc index 4020046ea76..af8dec6078f 100644 --- a/source/blender/io/csv/importer/csv_reader.cc +++ b/source/blender/io/csv/importer/csv_reader.cc @@ -281,6 +281,7 @@ PointCloud *import_csv_as_pointcloud(const CSVImportParams &import_params) LinearAllocator<> allocator; Array columns_info; csv_parse::CsvParseOptions parse_options; + parse_options.delimiter = import_params.delimiter; const auto parse_header = [&](const csv_parse::CsvRecord &record) { columns_info.reinitialize(record.size()); diff --git a/source/blender/nodes/geometry/nodes/node_geo_import_csv.cc b/source/blender/nodes/geometry/nodes/node_geo_import_csv.cc index 0db0ac3b2f6..b1bd98be115 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_import_csv.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_import_csv.cc @@ -20,6 +20,7 @@ static void node_declare(NodeDeclarationBuilder &b) .path_filter("*.csv") .hide_label() .description("Path to a CSV file"); + b.add_input("Delimiter").default_value(","); b.add_output("Point Cloud"); } @@ -33,8 +34,21 @@ static void node_geo_exec(GeoNodeExecParams params) params.set_default_remaining_outputs(); return; } + const std::string delimiter = params.extract_input("Delimiter"); + if (delimiter.size() != 1) { + params.error_message_add(NodeWarningType::Error, TIP_("Delimiter must be a single character")); + params.set_default_remaining_outputs(); + return; + } + if (ELEM(delimiter[0], '\n', '\r', '"', '\\')) { + params.error_message_add(NodeWarningType::Error, + TIP_("Delimiter must not be \\n, \\r, \" or \\")); + params.set_default_remaining_outputs(); + return; + } blender::io::csv::CSVImportParams import_params{}; + import_params.delimiter = delimiter[0]; STRNCPY(import_params.filepath, path->c_str()); ReportList reports;