Blender  V2.93
dupli_persistent_id.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2020 Blender Foundation.
17  * All rights reserved.
18  */
19 
20 #include "dupli_parent_finder.hh"
21 
22 #include <climits>
23 #include <cstring>
24 #include <ostream>
25 #include <sstream>
26 
27 namespace blender::io {
28 
30 {
31  persistent_id_[0] = INT_MAX;
32 }
33 
35 {
36  for (int index = 0; index < array_length_; ++index) {
37  persistent_id_[index] = dupli_ob->persistent_id[index];
38  }
39 }
40 
41 PersistentID::PersistentID(const PIDArray &persistent_id_values)
42 {
43  persistent_id_ = persistent_id_values;
44 }
45 
47 {
48  if (persistent_id_[0] == INT_MAX || other.persistent_id_[0] == INT_MAX) {
49  /* Either one or the other is not instanced at all, so definitely not from the same instancer.
50  */
51  return false;
52  }
53 
54  /* Start at index 1 to skip the first digit. */
55  for (int index = 1; index < array_length_; ++index) {
56  const int pid_digit_a = persistent_id_[index];
57  const int pid_digit_b = other.persistent_id_[index];
58 
59  if (pid_digit_a != pid_digit_b) {
60  return false;
61  }
62 
63  if (pid_digit_a == INT_MAX) {
64  /* Both persistent IDs were identical so far, and this marks the end of the useful data. */
65  break;
66  }
67  }
68  return true;
69 }
70 
72 {
73  if (persistent_id_[0] == INT_MAX) {
74  return PersistentID();
75  }
76 
77  /* Left-shift the entire PID by 1. */
78  PIDArray new_pid_values;
79  int index;
80  for (index = 0; index < array_length_ - 1; ++index) {
81  new_pid_values[index] = persistent_id_[index + 1];
82  }
83  new_pid_values[index] = INT_MAX;
84 
85  return PersistentID(new_pid_values);
86 }
87 
89 {
90  std::stringstream stream;
91 
92  /* Find one past the last index. */
93  int index;
94  for (index = 0; index < array_length_ && persistent_id_[index] < INT_MAX; ++index) {
95  ;
96  }
97 
98  /* Iterate backward to construct the string. */
99  --index;
100  for (; index >= 0; --index) {
101  stream << persistent_id_[index];
102  if (index > 0) {
103  stream << "-";
104  }
105  }
106 
107  return stream.str();
108 }
109 
110 bool operator<(const PersistentID &persistent_id_a, const PersistentID &persistent_id_b)
111 {
112  const PersistentID::PIDArray &pid_a = persistent_id_a.persistent_id_;
113  const PersistentID::PIDArray &pid_b = persistent_id_b.persistent_id_;
114 
115  for (int index = 0; index < PersistentID::array_length_; ++index) {
116  const int pid_digit_a = pid_a[index];
117  const int pid_digit_b = pid_b[index];
118 
119  if (pid_digit_a != pid_digit_b) {
120  return pid_digit_a < pid_digit_b;
121  }
122 
123  if (pid_a[index] == INT_MAX) {
124  break;
125  }
126  }
127  /* Both Persistent IDs were equal, so not less-than. */
128  return false;
129 }
130 
131 bool operator==(const PersistentID &persistent_id_a, const PersistentID &persistent_id_b)
132 {
133  const PersistentID::PIDArray &pid_a = persistent_id_a.persistent_id_;
134  const PersistentID::PIDArray &pid_b = persistent_id_b.persistent_id_;
135 
136  for (int index = 0; index < PersistentID::array_length_; ++index) {
137  const int pid_digit_a = pid_a[index];
138  const int pid_digit_b = pid_b[index];
139 
140  if (pid_digit_a != pid_digit_b) {
141  return false;
142  }
143 
144  if (pid_a[index] == INT_MAX) {
145  break;
146  }
147  }
148  return true;
149 }
150 
151 std::ostream &operator<<(std::ostream &os, const PersistentID &persistent_id)
152 {
153  if (persistent_id.persistent_id_[0] == INT_MAX) {
154  return os;
155  }
156 
157  const PersistentID::PIDArray &pid_array = persistent_id.persistent_id_;
158  for (int index = 0; index < PersistentID::array_length_ && pid_array[index] < INT_MAX; ++index) {
159  if (index > 0) {
160  os << "-";
161  }
162  os << pid_array[index];
163  }
164  return os;
165 }
166 
167 } // namespace blender::io
PersistentID instancer_pid() const
std::string as_object_name_suffix() const
constexpr static int array_length_
bool is_from_same_instancer_as(const PersistentID &other) const
std::array< int, array_length_ > PIDArray
bool operator<(const PersistentID &persistent_id_a, const PersistentID &persistent_id_b)
std::ostream & operator<<(std::ostream &os, const PersistentID &persistent_id)
bool operator==(const PersistentID &persistent_id_a, const PersistentID &persistent_id_b)
int persistent_id[8]
Definition: BKE_duplilist.h:54