Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAras Pranckevicius <aras@nesnausk.org>2022-05-10 18:59:46 +0300
committerAras Pranckevicius <aras@nesnausk.org>2022-05-10 19:12:02 +0300
commit6f7959f55fd2b3d291f63f0601d179bf581c5b28 (patch)
treed62268f86f09840cfa29a7dd3f8231fee32032e7 /source/blender/io/common
parent9c2613d1b6d034b4d80367df06ec4cd08d9bbbaa (diff)
parent3bc037a7eb8d214aac9d755f8b2dd0e04cdf3a85 (diff)
Merge branch 'blender-v3.2-release'
Diffstat (limited to 'source/blender/io/common')
-rw-r--r--source/blender/io/common/CMakeLists.txt5
-rw-r--r--source/blender/io/common/IO_path_util.hh29
-rw-r--r--source/blender/io/common/IO_path_util_types.h18
-rw-r--r--source/blender/io/common/intern/path_util.cc81
4 files changed, 133 insertions, 0 deletions
diff --git a/source/blender/io/common/CMakeLists.txt b/source/blender/io/common/CMakeLists.txt
index 02bd5b2b81f..95ffbe19ada 100644
--- a/source/blender/io/common/CMakeLists.txt
+++ b/source/blender/io/common/CMakeLists.txt
@@ -7,6 +7,8 @@ set(INC
../../blenlib
../../depsgraph
../../makesdna
+ ../../../../intern/guardedalloc
+
)
set(INC_SYS
@@ -17,9 +19,12 @@ set(SRC
intern/dupli_parent_finder.cc
intern/dupli_persistent_id.cc
intern/object_identifier.cc
+ intern/path_util.cc
IO_abstract_hierarchy_iterator.h
IO_dupli_persistent_id.hh
+ IO_path_util.hh
+ IO_path_util_types.h
IO_types.h
intern/dupli_parent_finder.hh
)
diff --git a/source/blender/io/common/IO_path_util.hh b/source/blender/io/common/IO_path_util.hh
new file mode 100644
index 00000000000..ac2f935523e
--- /dev/null
+++ b/source/blender/io/common/IO_path_util.hh
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#pragma once
+
+#include "BLI_string_ref.hh"
+#include "BLI_set.hh"
+
+#include "IO_path_util_types.h"
+
+namespace blender::io {
+
+/**
+ * Return a filepath relative to a destination directory, for use with
+ * exporters.
+ *
+ * When PATH_REFERENCE_COPY mode is used, the file path pair (source
+ * path, destination path) is added to the `copy_set`.
+ *
+ * Equivalent of bpy_extras.io_utils.path_reference.
+ */
+std::string path_reference(StringRefNull filepath,
+ StringRefNull base_src,
+ StringRefNull base_dst,
+ ePathReferenceMode mode,
+ Set<std::pair<std::string, std::string>> *copy_set = nullptr);
+
+/** Execute copying files of path_reference. */
+void path_reference_copy(const Set<std::pair<std::string, std::string>> &copy_set);
+
+} // namespace blender::io
diff --git a/source/blender/io/common/IO_path_util_types.h b/source/blender/io/common/IO_path_util_types.h
new file mode 100644
index 00000000000..0233f601a81
--- /dev/null
+++ b/source/blender/io/common/IO_path_util_types.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#pragma once
+
+/** Method used to reference paths. Equivalent of bpy_extras.io_utils.path_reference_mode. */
+typedef enum {
+ /** Use Relative paths with subdirectories only. */
+ PATH_REFERENCE_AUTO = 0,
+ /** Always write absolute paths. */
+ PATH_REFERENCE_ABSOLUTE = 1,
+ /** Write relative paths where possible. */
+ PATH_REFERENCE_RELATIVE = 2,
+ /** Match Absolute/Relative setting with input path. */
+ PATH_REFERENCE_MATCH = 3,
+ /** Filename only. */
+ PATH_REFERENCE_STRIP = 4,
+ /** Copy the file to the destination path. */
+ PATH_REFERENCE_COPY = 5,
+} ePathReferenceMode;
diff --git a/source/blender/io/common/intern/path_util.cc b/source/blender/io/common/intern/path_util.cc
new file mode 100644
index 00000000000..2b9a1d67b44
--- /dev/null
+++ b/source/blender/io/common/intern/path_util.cc
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "IO_path_util.hh"
+
+#include "BLI_fileops.h"
+#include "BLI_path_util.h"
+
+namespace blender::io {
+
+std::string path_reference(StringRefNull filepath,
+ StringRefNull base_src,
+ StringRefNull base_dst,
+ ePathReferenceMode mode,
+ Set<std::pair<std::string, std::string>> *copy_set)
+{
+ const bool is_relative = BLI_path_is_rel(filepath.c_str());
+ char filepath_abs[PATH_MAX];
+ BLI_strncpy(filepath_abs, filepath.c_str(), PATH_MAX);
+ BLI_path_abs(filepath_abs, base_src.c_str());
+ BLI_path_normalize(nullptr, filepath_abs);
+
+ /* Figure out final mode to be used. */
+ if (mode == PATH_REFERENCE_MATCH) {
+ mode = is_relative ? PATH_REFERENCE_RELATIVE : PATH_REFERENCE_ABSOLUTE;
+ }
+ else if (mode == PATH_REFERENCE_AUTO) {
+ mode = BLI_path_contains(base_dst.c_str(), filepath_abs) ? PATH_REFERENCE_RELATIVE :
+ PATH_REFERENCE_ABSOLUTE;
+ }
+ else if (mode == PATH_REFERENCE_COPY) {
+ char filepath_cpy[PATH_MAX];
+ BLI_path_join(filepath_cpy, PATH_MAX, base_dst.c_str(), BLI_path_basename(filepath_abs), nullptr);
+ copy_set->add(std::make_pair(filepath_abs, filepath_cpy));
+ BLI_strncpy(filepath_abs, filepath_cpy, PATH_MAX);
+ mode = PATH_REFERENCE_RELATIVE;
+ }
+
+ /* Now we know the final path mode. */
+ if (mode == PATH_REFERENCE_ABSOLUTE) {
+ return filepath_abs;
+ }
+ else if (mode == PATH_REFERENCE_RELATIVE) {
+ char rel_path[PATH_MAX];
+ BLI_strncpy(rel_path, filepath_abs, PATH_MAX);
+ BLI_path_rel(rel_path, base_dst.c_str());
+ /* Can't always find relative path (e.g. between different drives). */
+ if (!BLI_path_is_rel(rel_path)) {
+ return filepath_abs;
+ }
+ return rel_path + 2; /* Skip blender's internal "//" prefix. */
+ }
+ else if (mode == PATH_REFERENCE_STRIP) {
+ return BLI_path_basename(filepath_abs);
+ }
+ BLI_assert_msg(false, "Invalid path reference mode");
+ return filepath_abs;
+}
+
+void path_reference_copy(const Set<std::pair<std::string, std::string>> &copy_set)
+{
+ for (const auto &copy : copy_set) {
+ const char *src = copy.first.c_str();
+ const char *dst = copy.second.c_str();
+ if (!BLI_exists(src)) {
+ fprintf(stderr, "Missing source file '%s', not copying\n", src);
+ continue;
+ }
+ if (0 == BLI_path_cmp_normalized(src, dst)) {
+ continue; /* Source and dest are the same. */
+ }
+ if (!BLI_make_existing_file(dst)) {
+ fprintf(stderr, "Can't make directory for '%s', not copying\n", dst);
+ continue;
+ }
+ if (!BLI_copy(src, dst)) {
+ fprintf(stderr, "Can't copy '%s' to '%s'\n", src, dst);
+ continue;
+ }
+ }
+}
+
+} // namespace blender::io