Blender V5.0
dupli_persistent_id.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2020 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6
7#include <climits>
8
9#include <fmt/format.h>
10
11namespace blender::io {
12
14{
15 persistent_id_[0] = INT_MAX;
16}
17
19{
20 for (int index = 0; index < array_length_; ++index) {
21 persistent_id_[index] = dupli_ob->persistent_id[index];
22 }
23}
24
25PersistentID::PersistentID(const PIDArray &persistent_id_values)
26{
27 persistent_id_ = persistent_id_values;
28}
29
31{
32 if (persistent_id_[0] == INT_MAX || other.persistent_id_[0] == INT_MAX) {
33 /* Either one or the other is not instanced at all, so definitely not from the same instancer.
34 */
35 return false;
36 }
37
38 /* Start at index 1 to skip the first digit. */
39 for (int index = 1; index < array_length_; ++index) {
40 const int pid_digit_a = persistent_id_[index];
41 const int pid_digit_b = other.persistent_id_[index];
42
43 if (pid_digit_a != pid_digit_b) {
44 return false;
45 }
46
47 if (pid_digit_a == INT_MAX) {
48 /* Both persistent IDs were identical so far, and this marks the end of the useful data. */
49 break;
50 }
51 }
52 return true;
53}
54
56{
57 if (persistent_id_[0] == INT_MAX) {
58 return PersistentID();
59 }
60
61 /* Left-shift the entire PID by 1. */
62 PIDArray new_pid_values;
63 int index;
64 for (index = 0; index < array_length_ - 1; ++index) {
65 new_pid_values[index] = persistent_id_[index + 1];
66 }
67 new_pid_values[index] = INT_MAX;
68
69 return PersistentID(new_pid_values);
70}
71
73{
74 fmt::basic_memory_buffer<char, 64> buf;
75
76 /* Find one past the last index. */
77 int index;
78 for (index = 0; index < array_length_ && persistent_id_[index] < INT_MAX; ++index) {
79 ;
80 }
81
82 /* Iterate backward to construct the string. */
83 --index;
84 for (; index >= 0; --index) {
85 fmt::format_to(fmt::appender(buf), "{}", persistent_id_[index]);
86 if (index > 0) {
87 fmt::format_to(fmt::appender(buf), "-");
88 }
89 }
90
91 return fmt::to_string(buf);
92}
93
95{
96 uint64_t hash = 5381;
97 for (const int value : persistent_id_) {
98 if (value == INT_MAX) {
99 break;
100 }
101 hash = hash * 33 ^ uint64_t(value);
102 }
103 return hash;
104}
105
106bool operator==(const PersistentID &persistent_id_a, const PersistentID &persistent_id_b)
107{
108 const PersistentID::PIDArray &pid_a = persistent_id_a.persistent_id_;
109 const PersistentID::PIDArray &pid_b = persistent_id_b.persistent_id_;
110
111 for (int index = 0; index < PersistentID::array_length_; ++index) {
112 const int pid_digit_a = pid_a[index];
113 const int pid_digit_b = pid_b[index];
114
115 if (pid_digit_a != pid_digit_b) {
116 return false;
117 }
118
119 if (pid_a[index] == INT_MAX) {
120 break;
121 }
122 }
123 return true;
124}
125
126} // namespace blender::io
unsigned long long int uint64_t
PersistentID(const PIDArray &persistent_id_values)
std::array< int, array_length_ > PIDArray
PersistentID instancer_pid() const
std::string as_object_name_suffix() const
bool is_from_same_instancer_as(const PersistentID &other) const
bool operator==(const PersistentID &persistent_id_a, const PersistentID &persistent_id_b)
int persistent_id[MAX_DUPLI_RECUR]