Blender V5.0
viewer_path.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BKE_lib_query.hh"
6#include "BKE_lib_remap.hh"
7#include "BKE_viewer_path.hh"
8
9#include "BLI_index_range.hh"
10#include "BLI_listbase.h"
11#include "BLI_string.h"
12#include "BLI_string_ref.hh"
13
14#include "MEM_guardedalloc.h"
15
16#include "BLO_read_write.hh"
17
20
22{
23 BLI_listbase_clear(&viewer_path->path);
24}
25
27{
28 LISTBASE_FOREACH_MUTABLE (ViewerPathElem *, elem, &viewer_path->path) {
30 }
31 BLI_listbase_clear(&viewer_path->path);
32}
33
35{
37 LISTBASE_FOREACH (const ViewerPathElem *, src_elem, &src->path) {
38 ViewerPathElem *new_elem = BKE_viewer_path_elem_copy(src_elem);
39 BLI_addtail(&dst->path, new_elem);
40 }
41}
42
44 const ViewerPath *b,
46{
47 const ViewerPathElem *elem_a = static_cast<const ViewerPathElem *>(a->path.first);
48 const ViewerPathElem *elem_b = static_cast<const ViewerPathElem *>(b->path.first);
49
50 while (elem_a != nullptr && elem_b != nullptr) {
51 if (!BKE_viewer_path_elem_equal(elem_a, elem_b, flag)) {
52 return false;
53 }
54 elem_a = elem_a->next;
55 elem_b = elem_b->next;
56 }
57 if (elem_a == nullptr && elem_b == nullptr) {
58 return true;
59 }
60 return false;
61}
62
64{
65 uint64_t hash = 0;
66 LISTBASE_FOREACH (ViewerPathElem *, elem, &viewer_path.path) {
67 const uint64_t elem_hash = BKE_viewer_path_elem_hash(*elem);
69 }
70 return hash;
71}
72
73void BKE_viewer_path_blend_write(BlendWriter *writer, const ViewerPath *viewer_path)
74{
75 LISTBASE_FOREACH (ViewerPathElem *, elem, &viewer_path->path) {
76 switch (ViewerPathElemType(elem->type)) {
78 const auto *typed_elem = reinterpret_cast<IDViewerPathElem *>(elem);
79 BLO_write_struct(writer, IDViewerPathElem, typed_elem);
80 break;
81 }
83 const auto *typed_elem = reinterpret_cast<ModifierViewerPathElem *>(elem);
84 BLO_write_struct(writer, ModifierViewerPathElem, typed_elem);
85 break;
86 }
88 const auto *typed_elem = reinterpret_cast<GroupNodeViewerPathElem *>(elem);
89 BLO_write_struct(writer, GroupNodeViewerPathElem, typed_elem);
90 break;
91 }
93 const auto *typed_elem = reinterpret_cast<SimulationZoneViewerPathElem *>(elem);
95 break;
96 }
98 const auto *typed_elem = reinterpret_cast<ViewerNodeViewerPathElem *>(elem);
99 BLO_write_struct(writer, ViewerNodeViewerPathElem, typed_elem);
100 break;
101 }
103 const auto *typed_elem = reinterpret_cast<RepeatZoneViewerPathElem *>(elem);
104 BLO_write_struct(writer, RepeatZoneViewerPathElem, typed_elem);
105 break;
106 }
108 const auto *typed_elem = reinterpret_cast<ForeachGeometryElementZoneViewerPathElem *>(
109 elem);
111 break;
112 }
114 const auto *typed_elem = reinterpret_cast<EvaluateClosureNodeViewerPathElem *>(elem);
116 break;
117 }
118 }
119 BLO_write_string(writer, elem->ui_name);
120 }
121}
122
142
144{
145 LISTBASE_FOREACH (ViewerPathElem *, elem, &viewer_path->path) {
146 switch (ViewerPathElemType(elem->type)) {
148 auto *typed_elem = reinterpret_cast<IDViewerPathElem *>(elem);
150 break;
151 }
153 auto *typed_elem = reinterpret_cast<EvaluateClosureNodeViewerPathElem *>(elem);
155 data, typed_elem->source_node_tree, IDWALK_CB_DIRECT_WEAK_LINK);
156 break;
157 }
164 break;
165 }
166 }
167 }
168}
169
171 const blender::bke::id::IDRemapper &mappings)
172{
173 LISTBASE_FOREACH (ViewerPathElem *, elem, &viewer_path->path) {
174 switch (ViewerPathElemType(elem->type)) {
176 auto *typed_elem = reinterpret_cast<IDViewerPathElem *>(elem);
177 mappings.apply(&typed_elem->id, ID_REMAP_APPLY_DEFAULT);
178 break;
179 }
187 break;
188 }
189 }
190 }
191}
192
193template<typename T> static T *make_elem(const ViewerPathElemType type)
194{
195 T *elem = MEM_callocN<T>(__func__);
196 elem->base.type = type;
197 return elem;
198}
199
201{
202 switch (type) {
204 return &make_elem<IDViewerPathElem>(type)->base;
205 }
207 return &make_elem<ModifierViewerPathElem>(type)->base;
208 }
210 return &make_elem<GroupNodeViewerPathElem>(type)->base;
211 }
213 return &make_elem<SimulationZoneViewerPathElem>(type)->base;
214 }
216 return &make_elem<ViewerNodeViewerPathElem>(type)->base;
217 }
219 return &make_elem<RepeatZoneViewerPathElem>(type)->base;
220 }
223 }
226 }
227 }
229 return nullptr;
230}
231
236
242
248
254
260
266
272
278
280{
282 if (src->ui_name) {
283 dst->ui_name = BLI_strdup(src->ui_name);
284 }
285 switch (ViewerPathElemType(src->type)) {
287 const auto *old_elem = reinterpret_cast<const IDViewerPathElem *>(src);
288 auto *new_elem = reinterpret_cast<IDViewerPathElem *>(dst);
289 new_elem->id = old_elem->id;
290 break;
291 }
293 const auto *old_elem = reinterpret_cast<const ModifierViewerPathElem *>(src);
294 auto *new_elem = reinterpret_cast<ModifierViewerPathElem *>(dst);
295 new_elem->modifier_uid = old_elem->modifier_uid;
296 break;
297 }
299 const auto *old_elem = reinterpret_cast<const GroupNodeViewerPathElem *>(src);
300 auto *new_elem = reinterpret_cast<GroupNodeViewerPathElem *>(dst);
301 new_elem->node_id = old_elem->node_id;
302 break;
303 }
305 const auto *old_elem = reinterpret_cast<const SimulationZoneViewerPathElem *>(src);
306 auto *new_elem = reinterpret_cast<SimulationZoneViewerPathElem *>(dst);
307 new_elem->sim_output_node_id = old_elem->sim_output_node_id;
308 break;
309 }
311 const auto *old_elem = reinterpret_cast<const ViewerNodeViewerPathElem *>(src);
312 auto *new_elem = reinterpret_cast<ViewerNodeViewerPathElem *>(dst);
313 new_elem->node_id = old_elem->node_id;
314 break;
315 }
317 const auto *old_elem = reinterpret_cast<const RepeatZoneViewerPathElem *>(src);
318 auto *new_elem = reinterpret_cast<RepeatZoneViewerPathElem *>(dst);
319 new_elem->repeat_output_node_id = old_elem->repeat_output_node_id;
320 new_elem->iteration = old_elem->iteration;
321 break;
322 }
324 const auto *old_elem = reinterpret_cast<const ForeachGeometryElementZoneViewerPathElem *>(
325 src);
326 auto *new_elem = reinterpret_cast<ForeachGeometryElementZoneViewerPathElem *>(dst);
327 new_elem->zone_output_node_id = old_elem->zone_output_node_id;
328 new_elem->index = old_elem->index;
329 break;
330 }
332 const auto *old_elem = reinterpret_cast<const EvaluateClosureNodeViewerPathElem *>(src);
333 auto *new_elem = reinterpret_cast<EvaluateClosureNodeViewerPathElem *>(dst);
334 new_elem->source_output_node_id = old_elem->source_output_node_id;
335 new_elem->evaluate_node_id = old_elem->evaluate_node_id;
336 new_elem->source_node_tree = old_elem->source_node_tree;
337 break;
338 }
339 }
340 return dst;
341}
342
344 const ViewerPathElem *b,
346{
347 if (a->type != b->type) {
348 return false;
349 }
351 if (StringRef(a->ui_name) != StringRef(b->ui_name)) {
352 return false;
353 }
354 }
355 switch (ViewerPathElemType(a->type)) {
357 const auto *a_elem = reinterpret_cast<const IDViewerPathElem *>(a);
358 const auto *b_elem = reinterpret_cast<const IDViewerPathElem *>(b);
359 return a_elem->id == b_elem->id;
360 }
362 const auto *a_elem = reinterpret_cast<const ModifierViewerPathElem *>(a);
363 const auto *b_elem = reinterpret_cast<const ModifierViewerPathElem *>(b);
364 return a_elem->modifier_uid == b_elem->modifier_uid;
365 }
367 const auto *a_elem = reinterpret_cast<const GroupNodeViewerPathElem *>(a);
368 const auto *b_elem = reinterpret_cast<const GroupNodeViewerPathElem *>(b);
369 return a_elem->node_id == b_elem->node_id;
370 }
372 const auto *a_elem = reinterpret_cast<const SimulationZoneViewerPathElem *>(a);
373 const auto *b_elem = reinterpret_cast<const SimulationZoneViewerPathElem *>(b);
374 return a_elem->sim_output_node_id == b_elem->sim_output_node_id;
375 }
377 const auto *a_elem = reinterpret_cast<const ViewerNodeViewerPathElem *>(a);
378 const auto *b_elem = reinterpret_cast<const ViewerNodeViewerPathElem *>(b);
379 return a_elem->node_id == b_elem->node_id;
380 }
382 const auto *a_elem = reinterpret_cast<const RepeatZoneViewerPathElem *>(a);
383 const auto *b_elem = reinterpret_cast<const RepeatZoneViewerPathElem *>(b);
384 return a_elem->repeat_output_node_id == b_elem->repeat_output_node_id &&
386 a_elem->iteration == b_elem->iteration);
387 }
389 const auto *a_elem = reinterpret_cast<const ForeachGeometryElementZoneViewerPathElem *>(a);
390 const auto *b_elem = reinterpret_cast<const ForeachGeometryElementZoneViewerPathElem *>(b);
391 return a_elem->zone_output_node_id == b_elem->zone_output_node_id &&
393 a_elem->index == b_elem->index);
394 }
396 const auto *a_elem = reinterpret_cast<const EvaluateClosureNodeViewerPathElem *>(a);
397 const auto *b_elem = reinterpret_cast<const EvaluateClosureNodeViewerPathElem *>(b);
398 return a_elem->source_output_node_id == b_elem->source_output_node_id &&
399 a_elem->evaluate_node_id == b_elem->evaluate_node_id &&
400 a_elem->source_node_tree == b_elem->source_node_tree;
401 }
402 }
403 return false;
404}
405
407{
409 switch (ViewerPathElemType(elem.type)) {
411 const auto &typed_elem = reinterpret_cast<const IDViewerPathElem &>(elem);
412 return get_default_hash(elem.type, typed_elem.id ? typed_elem.id->session_uid : 0);
413 }
415 const auto &typed_elem = reinterpret_cast<const ModifierViewerPathElem &>(elem);
416 return get_default_hash(elem.type, typed_elem.modifier_uid);
417 }
419 const auto &typed_elem = reinterpret_cast<const GroupNodeViewerPathElem &>(elem);
420 return get_default_hash(elem.type, typed_elem.node_id);
421 }
423 const auto &typed_elem = reinterpret_cast<const SimulationZoneViewerPathElem &>(elem);
424 return get_default_hash(elem.type, typed_elem.sim_output_node_id);
425 }
427 const auto &typed_elem = reinterpret_cast<const ViewerNodeViewerPathElem &>(elem);
428 return get_default_hash(elem.type, typed_elem.node_id);
429 }
431 const auto &typed_elem = reinterpret_cast<const RepeatZoneViewerPathElem &>(elem);
432 return get_default_hash(elem.type, typed_elem.repeat_output_node_id, typed_elem.iteration);
433 }
435 const auto &typed_elem = reinterpret_cast<const ForeachGeometryElementZoneViewerPathElem &>(
436 elem);
437 return get_default_hash(elem.type, typed_elem.zone_output_node_id, typed_elem.index);
438 }
440 const auto &typed_elem = reinterpret_cast<const EvaluateClosureNodeViewerPathElem &>(elem);
441 return get_default_hash(
442 elem.type,
443 typed_elem.evaluate_node_id,
444 typed_elem.source_output_node_id,
445 typed_elem.source_node_tree ?
446 reinterpret_cast<const ID *>(typed_elem.source_node_tree)->session_uid :
447 0);
448 }
449 }
450 return 0;
451}
452
@ IDWALK_CB_DIRECT_WEAK_LINK
#define BKE_LIB_FOREACHID_PROCESS_ID(data_, id_, cb_flag_)
@ ID_REMAP_APPLY_DEFAULT
ViewerPathEqualFlag
@ VIEWER_PATH_EQUAL_FLAG_IGNORE_ITERATION
@ VIEWER_PATH_EQUAL_FLAG_CONSIDER_UI_NAME
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.cc:41
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_string(BlendDataReader *reader, char **ptr_p)
Definition readfile.cc:5828
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
#define BLO_read_struct_list(reader, struct_name, list)
@ VIEWER_PATH_ELEM_TYPE_GROUP_NODE
@ VIEWER_PATH_ELEM_TYPE_SIMULATION_ZONE
@ VIEWER_PATH_ELEM_TYPE_FOREACH_GEOMETRY_ELEMENT_ZONE
@ VIEWER_PATH_ELEM_TYPE_VIEWER_NODE
@ VIEWER_PATH_ELEM_TYPE_REPEAT_ZONE
@ VIEWER_PATH_ELEM_TYPE_MODIFIER
@ VIEWER_PATH_ELEM_TYPE_EVALUATE_CLOSURE
@ VIEWER_PATH_ELEM_TYPE_ID
Read Guarded memory(de)allocation.
BMesh const char void * data
unsigned long long int uint64_t
IDRemapperApplyResult apply(ID **r_id_ptr, IDRemapperApplyOptions options, ID *id_self=nullptr) const
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define T
uint64_t get_default_hash(const T &v, const Args &...args)
Definition BLI_hash.hh:233
#define hash
Definition noise_c.cc:154
Definition DNA_ID.h:414
unsigned int session_uid
Definition DNA_ID.h:462
void * first
struct ViewerPathElem * next
void BKE_viewer_path_copy(ViewerPath *dst, const ViewerPath *src)
void BKE_viewer_path_id_remap(ViewerPath *viewer_path, const blender::bke::id::IDRemapper &mappings)
uint64_t BKE_viewer_path_elem_hash(const ViewerPathElem &elem)
EvaluateClosureNodeViewerPathElem * BKE_viewer_path_elem_new_evaluate_closure()
ViewerPathElem * BKE_viewer_path_elem_copy(const ViewerPathElem *src)
ViewerNodeViewerPathElem * BKE_viewer_path_elem_new_viewer_node()
ViewerPathElem * BKE_viewer_path_elem_new(const ViewerPathElemType type)
void BKE_viewer_path_elem_free(ViewerPathElem *elem)
void BKE_viewer_path_foreach_id(LibraryForeachIDData *data, ViewerPath *viewer_path)
void BKE_viewer_path_clear(ViewerPath *viewer_path)
void BKE_viewer_path_init(ViewerPath *viewer_path)
SimulationZoneViewerPathElem * BKE_viewer_path_elem_new_simulation_zone()
ForeachGeometryElementZoneViewerPathElem * BKE_viewer_path_elem_new_foreach_geometry_element_zone()
GroupNodeViewerPathElem * BKE_viewer_path_elem_new_group_node()
static T * make_elem(const ViewerPathElemType type)
IDViewerPathElem * BKE_viewer_path_elem_new_id()
bool BKE_viewer_path_elem_equal(const ViewerPathElem *a, const ViewerPathElem *b, const ViewerPathEqualFlag flag)
ModifierViewerPathElem * BKE_viewer_path_elem_new_modifier()
void BKE_viewer_path_blend_read_data(BlendDataReader *reader, ViewerPath *viewer_path)
uint64_t BKE_viewer_path_hash(const ViewerPath &viewer_path)
bool BKE_viewer_path_equal(const ViewerPath *a, const ViewerPath *b, const ViewerPathEqualFlag flag)
RepeatZoneViewerPathElem * BKE_viewer_path_elem_new_repeat_zone()
void BKE_viewer_path_blend_write(BlendWriter *writer, const ViewerPath *viewer_path)
uint8_t flag
Definition wm_window.cc:145