Blender  V3.3
cycles/blender/util.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #ifndef __BLENDER_UTIL_H__
5 #define __BLENDER_UTIL_H__
6 
7 #include "scene/mesh.h"
8 #include "scene/scene.h"
9 
10 #include "util/algorithm.h"
11 #include "util/array.h"
12 #include "util/map.h"
13 #include "util/path.h"
14 #include "util/set.h"
15 #include "util/transform.h"
16 #include "util/types.h"
17 #include "util/vector.h"
18 
19 /* Hacks to hook into Blender API
20  * todo: clean this up ... */
21 
22 extern "C" {
23 void BKE_image_user_frame_calc(void *ima, void *iuser, int cfra);
25  void *bmain, void *iuser, void *ima, char *path, bool resolve_udim, bool resolve_multiview);
26 unsigned char *BKE_image_get_pixels_for_frame(void *image, int frame, int tile);
27 float *BKE_image_get_float_pixels_for_frame(void *image, int frame, int tile);
28 }
29 
31 
32 struct BObjectInfo {
33  /* Object directly provided by the depsgraph iterator. This object is only valid during one
34  * iteration and must not be accessed afterwards. Transforms and visibility should be checked on
35  * this object. */
37 
38  /* This object remains alive even after the object iterator is done. It corresponds to one
39  * original object. It is the object that owns the object data below. */
41 
42  /* The object-data referenced by the iter object. This is still valid after the depsgraph
43  * iterator is done. It might have a different type compared to real_object.data(). */
45 
46  /* True when the current geometry is the data of the referenced object. False when it is a
47  * geometry instance that does not have a 1-to-1 relationship with an object. */
48  bool is_real_object_data() const
49  {
50  return const_cast<BL::Object &>(real_object).data() == object_data;
51  }
52 };
53 
54 typedef BL::ShaderNodeAttribute::attribute_type_enum BlenderAttributeType;
55 BlenderAttributeType blender_attribute_name_split_type(ustring name, string *r_real_name);
56 
57 void python_thread_state_save(void **python_thread_state);
58 void python_thread_state_restore(void **python_thread_state);
59 
60 static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/,
61  BObjectInfo &b_ob_info,
62  BL::Depsgraph & /*depsgraph*/,
63  bool /*calc_undeformed*/,
64  Mesh::SubdivisionType subdivision_type)
65 {
66  /* TODO: make this work with copy-on-write, modifiers are already evaluated. */
67 #if 0
68  bool subsurf_mod_show_render = false;
69  bool subsurf_mod_show_viewport = false;
70 
71  if (subdivision_type != Mesh::SUBDIVISION_NONE) {
72  BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length() - 1];
73 
74  subsurf_mod_show_render = subsurf_mod.show_render();
75  subsurf_mod_show_viewport = subsurf_mod.show_viewport();
76 
77  subsurf_mod.show_render(false);
78  subsurf_mod.show_viewport(false);
79  }
80 #endif
81 
82  BL::Mesh mesh = (b_ob_info.object_data.is_a(&RNA_Mesh)) ? BL::Mesh(b_ob_info.object_data) :
84 
85  if (b_ob_info.is_real_object_data()) {
86  if (mesh) {
87  /* Make a copy to split faces if we use autosmooth, otherwise not needed.
88  * Also in edit mode do we need to make a copy, to ensure data layers like
89  * UV are not empty. */
90  if (mesh.is_editmode() ||
91  (mesh.use_auto_smooth() && subdivision_type == Mesh::SUBDIVISION_NONE)) {
93  mesh = b_ob_info.real_object.to_mesh(false, depsgraph);
94  }
95  }
96  else {
98  mesh = b_ob_info.real_object.to_mesh(false, depsgraph);
99  }
100  }
101  else {
102  /* TODO: what to do about non-mesh geometry instances? */
103  }
104 
105 #if 0
106  if (subdivision_type != Mesh::SUBDIVISION_NONE) {
107  BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length() - 1];
108 
109  subsurf_mod.show_render(subsurf_mod_show_render);
110  subsurf_mod.show_viewport(subsurf_mod_show_viewport);
111  }
112 #endif
113 
114  if ((bool)mesh && subdivision_type == Mesh::SUBDIVISION_NONE) {
115  if (mesh.use_auto_smooth()) {
116  mesh.split_faces(false);
117  }
118 
119  mesh.calc_loop_triangles();
120  }
121 
122  return mesh;
123 }
124 
125 static inline void free_object_to_mesh(BL::BlendData & /*data*/,
126  BObjectInfo &b_ob_info,
127  BL::Mesh &mesh)
128 {
129  if (!b_ob_info.is_real_object_data()) {
130  return;
131  }
132  /* Free mesh if we didn't just use the existing one. */
133  BL::Object object = b_ob_info.real_object;
134  if (object.data().ptr.data != mesh.ptr.data) {
135  object.to_mesh_clear();
136  }
137 }
138 
139 static inline void colorramp_to_array(BL::ColorRamp &ramp,
140  array<float3> &ramp_color,
141  array<float> &ramp_alpha,
142  int size)
143 {
144  ramp_color.resize(size);
145  ramp_alpha.resize(size);
146 
147  for (int i = 0; i < size; i++) {
148  float color[4];
149 
150  ramp.evaluate((float)i / (float)(size - 1), color);
151  ramp_color[i] = make_float3(color[0], color[1], color[2]);
152  ramp_alpha[i] = color[3];
153  }
154 }
155 
156 static inline void curvemap_minmax_curve(/*const*/ BL::CurveMap &curve, float *min_x, float *max_x)
157 {
158  *min_x = min(*min_x, curve.points[0].location()[0]);
159  *max_x = max(*max_x, curve.points[curve.points.length() - 1].location()[0]);
160 }
161 
162 static inline void curvemapping_minmax(/*const*/ BL::CurveMapping &cumap,
163  int num_curves,
164  float *min_x,
165  float *max_x)
166 {
167  // const int num_curves = cumap.curves.length(); /* Gives linking error so far. */
168  *min_x = FLT_MAX;
169  *max_x = -FLT_MAX;
170  for (int i = 0; i < num_curves; ++i) {
171  BL::CurveMap map(cumap.curves[i]);
172  curvemap_minmax_curve(map, min_x, max_x);
173  }
174 }
175 
177 {
178  cumap.update();
179  BL::CurveMap curve = cumap.curves[0];
180  data.resize(size);
181  for (int i = 0; i < size; i++) {
182  float t = (float)i / (float)(size - 1);
183  data[i] = cumap.evaluate(curve, t);
184  }
185 }
186 
189  int size)
190 {
191  float min = 0.0f, max = 1.0f;
192 
193  curvemapping_minmax(cumap, 1, &min, &max);
194 
195  const float range = max - min;
196 
197  cumap.update();
198 
199  BL::CurveMap map = cumap.curves[0];
200 
201  data.resize(size);
202 
203  for (int i = 0; i < size; i++) {
204  float t = min + (float)i / (float)(size - 1) * range;
205  data[i] = cumap.evaluate(map, t);
206  }
207 }
208 
211  int size,
212  bool rgb_curve)
213 {
214  float min_x = 0.0f, max_x = 1.0f;
215 
216  /* TODO(sergey): There is no easy way to automatically guess what is
217  * the range to be used here for the case when mapping is applied on
218  * top of another mapping (i.e. R curve applied on top of common
219  * one).
220  *
221  * Using largest possible range form all curves works correct for the
222  * cases like vector curves and should be good enough heuristic for
223  * the color curves as well.
224  *
225  * There might be some better estimations here tho.
226  */
227  const int num_curves = rgb_curve ? 4 : 3;
228  curvemapping_minmax(cumap, num_curves, &min_x, &max_x);
229 
230  const float range_x = max_x - min_x;
231 
232  cumap.update();
233 
234  BL::CurveMap mapR = cumap.curves[0];
235  BL::CurveMap mapG = cumap.curves[1];
236  BL::CurveMap mapB = cumap.curves[2];
237 
238  data.resize(size);
239 
240  if (rgb_curve) {
241  BL::CurveMap mapI = cumap.curves[3];
242  for (int i = 0; i < size; i++) {
243  const float t = min_x + (float)i / (float)(size - 1) * range_x;
244  data[i] = make_float3(cumap.evaluate(mapR, cumap.evaluate(mapI, t)),
245  cumap.evaluate(mapG, cumap.evaluate(mapI, t)),
246  cumap.evaluate(mapB, cumap.evaluate(mapI, t)));
247  }
248  }
249  else {
250  for (int i = 0; i < size; i++) {
251  float t = min_x + (float)i / (float)(size - 1) * range_x;
252  data[i] = make_float3(
253  cumap.evaluate(mapR, t), cumap.evaluate(mapG, t), cumap.evaluate(mapB, t));
254  }
255  }
256 }
257 
258 static inline bool BKE_object_is_modified(BL::Object &self, BL::Scene &scene, bool preview)
259 {
260  return self.is_modified(scene, (preview) ? (1 << 0) : (1 << 1)) ? true : false;
261 }
262 
264 {
265  if (!self.is_real_object_data()) {
266  /* Comes from geometry nodes, can't use heuristic to guess if it's animated. */
267  return true;
268  }
269 
270  /* Use heuristic to quickly check if object is potentially animated. */
271  return self.real_object.is_deform_modified(scene, (preview) ? (1 << 0) : (1 << 1)) ? true :
272  false;
273 }
274 
275 static inline int render_resolution_x(BL::RenderSettings &b_render)
276 {
277  return b_render.resolution_x() * b_render.resolution_percentage() / 100;
278 }
279 
280 static inline int render_resolution_y(BL::RenderSettings &b_render)
281 {
282  return b_render.resolution_y() * b_render.resolution_percentage() / 100;
283 }
284 
285 static inline string image_user_file_path(BL::BlendData &data,
286  BL::ImageUser &iuser,
287  BL::Image &ima,
288  int cfra)
289 {
290  char filepath[1024];
291  iuser.tile(0);
292  BKE_image_user_frame_calc(ima.ptr.data, iuser.ptr.data, cfra);
293  BKE_image_user_file_path_ex(data.ptr.data, iuser.ptr.data, ima.ptr.data, filepath, false, true);
294 
295  return string(filepath);
296 }
297 
298 static inline int image_user_frame_number(BL::ImageUser &iuser, BL::Image &ima, int cfra)
299 {
300  BKE_image_user_frame_calc(ima.ptr.data, iuser.ptr.data, cfra);
301  return iuser.frame_current();
302 }
303 
304 static inline unsigned char *image_get_pixels_for_frame(BL::Image &image, int frame, int tile)
305 {
306  return BKE_image_get_pixels_for_frame(image.ptr.data, frame, tile);
307 }
308 
309 static inline float *image_get_float_pixels_for_frame(BL::Image &image, int frame, int tile)
310 {
311  return BKE_image_get_float_pixels_for_frame(image.ptr.data, frame, tile);
312 }
313 
314 static inline void render_add_metadata(BL::RenderResult &b_rr, string name, string value)
315 {
316  b_rr.stamp_data_add_field(name.c_str(), value.c_str());
317 }
318 
319 /* Utilities */
320 
321 static inline Transform get_transform(const BL::Array<float, 16> &array)
322 {
323  ProjectionTransform projection;
324 
325  /* We assume both types to be just 16 floats, and transpose because blender
326  * use column major matrix order while we use row major. */
327  memcpy((void *)&projection, &array, sizeof(float) * 16);
328  projection = projection_transpose(projection);
329 
330  /* Drop last row, matrix is assumed to be affine transform. */
331  return projection_to_transform(projection);
332 }
333 
334 static inline float2 get_float2(const BL::Array<float, 2> &array)
335 {
336  return make_float2(array[0], array[1]);
337 }
338 
339 static inline float3 get_float3(const BL::Array<float, 2> &array)
340 {
341  return make_float3(array[0], array[1], 0.0f);
342 }
343 
344 static inline float3 get_float3(const BL::Array<float, 3> &array)
345 {
346  return make_float3(array[0], array[1], array[2]);
347 }
348 
349 static inline float3 get_float3(const BL::Array<float, 4> &array)
350 {
351  return make_float3(array[0], array[1], array[2]);
352 }
353 
354 static inline float4 get_float4(const BL::Array<float, 4> &array)
355 {
356  return make_float4(array[0], array[1], array[2], array[3]);
357 }
358 
359 static inline int3 get_int3(const BL::Array<int, 3> &array)
360 {
361  return make_int3(array[0], array[1], array[2]);
362 }
363 
364 static inline int4 get_int4(const BL::Array<int, 4> &array)
365 {
366  return make_int4(array[0], array[1], array[2], array[3]);
367 }
368 
369 static inline float3 get_float3(PointerRNA &ptr, const char *name)
370 {
371  float3 f;
372  RNA_float_get_array(&ptr, name, &f.x);
373  return f;
374 }
375 
376 static inline void set_float3(PointerRNA &ptr, const char *name, float3 value)
377 {
378  RNA_float_set_array(&ptr, name, &value.x);
379 }
380 
381 static inline float4 get_float4(PointerRNA &ptr, const char *name)
382 {
383  float4 f;
384  RNA_float_get_array(&ptr, name, &f.x);
385  return f;
386 }
387 
388 static inline void set_float4(PointerRNA &ptr, const char *name, float4 value)
389 {
390  RNA_float_set_array(&ptr, name, &value.x);
391 }
392 
393 static inline bool get_boolean(PointerRNA &ptr, const char *name)
394 {
395  return RNA_boolean_get(&ptr, name) ? true : false;
396 }
397 
398 static inline void set_boolean(PointerRNA &ptr, const char *name, bool value)
399 {
400  RNA_boolean_set(&ptr, name, (int)value);
401 }
402 
403 static inline float get_float(PointerRNA &ptr, const char *name)
404 {
405  return RNA_float_get(&ptr, name);
406 }
407 
408 static inline void set_float(PointerRNA &ptr, const char *name, float value)
409 {
410  RNA_float_set(&ptr, name, value);
411 }
412 
413 static inline int get_int(PointerRNA &ptr, const char *name)
414 {
415  return RNA_int_get(&ptr, name);
416 }
417 
418 static inline void set_int(PointerRNA &ptr, const char *name, int value)
419 {
420  RNA_int_set(&ptr, name, value);
421 }
422 
423 /* Get a RNA enum value with sanity check: if the RNA value is above num_values
424  * the function will return a fallback default value.
425  *
426  * NOTE: This function assumes that RNA enum values are a continuous sequence
427  * from 0 to num_values-1. Be careful to use it with enums where some values are
428  * deprecated!
429  */
430 static inline int get_enum(PointerRNA &ptr,
431  const char *name,
432  int num_values = -1,
433  int default_value = -1)
434 {
435  int value = RNA_enum_get(&ptr, name);
436  if (num_values != -1 && value >= num_values) {
437  assert(default_value != -1);
438  value = default_value;
439  }
440  return value;
441 }
442 
443 static inline string get_enum_identifier(PointerRNA &ptr, const char *name)
444 {
445  PropertyRNA *prop = RNA_struct_find_property(&ptr, name);
446  const char *identifier = "";
447  int value = RNA_property_enum_get(&ptr, prop);
448 
449  RNA_property_enum_identifier(NULL, &ptr, prop, value, &identifier);
450 
451  return string(identifier);
452 }
453 
454 static inline void set_enum(PointerRNA &ptr, const char *name, int value)
455 {
456  RNA_enum_set(&ptr, name, value);
457 }
458 
459 static inline void set_enum(PointerRNA &ptr, const char *name, const string &identifier)
460 {
461  RNA_enum_set_identifier(NULL, &ptr, name, identifier.c_str());
462 }
463 
464 static inline string get_string(PointerRNA &ptr, const char *name)
465 {
466  char cstrbuf[1024];
467  char *cstr = RNA_string_get_alloc(&ptr, name, cstrbuf, sizeof(cstrbuf), NULL);
468  string str(cstr);
469  if (cstr != cstrbuf)
470  MEM_freeN(cstr);
471 
472  return str;
473 }
474 
475 static inline void set_string(PointerRNA &ptr, const char *name, const string &value)
476 {
477  RNA_string_set(&ptr, name, value.c_str());
478 }
479 
480 /* Relative Paths */
481 
482 static inline string blender_absolute_path(BL::BlendData &b_data, BL::ID &b_id, const string &path)
483 {
484  if (path.size() >= 2 && path[0] == '/' && path[1] == '/') {
485  string dirname;
486 
487  if (b_id.library()) {
488  BL::ID b_library_id(b_id.library());
489  dirname = blender_absolute_path(b_data, b_library_id, b_id.library().filepath());
490  }
491  else
492  dirname = b_data.filepath();
493 
494  return path_join(path_dirname(dirname), path.substr(2));
495  }
496 
497  return path;
498 }
499 
500 static inline string get_text_datablock_content(const PointerRNA &ptr)
501 {
502  if (ptr.data == NULL) {
503  return "";
504  }
505 
506  string content;
507  BL::Text::lines_iterator iter;
508  for (iter.begin(ptr); iter; ++iter) {
509  content += iter->body() + "\n";
510  }
511 
512  return content;
513 }
514 
515 /* Texture Space */
516 
517 static inline void mesh_texture_space(BL::Mesh &b_mesh, float3 &loc, float3 &size)
518 {
519  loc = get_float3(b_mesh.texspace_location());
520  size = get_float3(b_mesh.texspace_size());
521 
522  if (size.x != 0.0f)
523  size.x = 0.5f / size.x;
524  if (size.y != 0.0f)
525  size.y = 0.5f / size.y;
526  if (size.z != 0.0f)
527  size.z = 0.5f / size.z;
528 
529  loc = loc * size - make_float3(0.5f, 0.5f, 0.5f);
530 }
531 
532 /* Object motion steps, returns 0 if no motion blur needed. */
533 static inline uint object_motion_steps(BL::Object &b_parent,
534  BL::Object &b_ob,
535  const int max_steps = INT_MAX)
536 {
537  /* Get motion enabled and steps from object itself. */
538  PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
539  bool use_motion = get_boolean(cobject, "use_motion_blur");
540  if (!use_motion) {
541  return 0;
542  }
543 
544  int steps = max(1, get_int(cobject, "motion_steps"));
545 
546  /* Also check parent object, so motion blur and steps can be
547  * controlled by dupligroup duplicator for linked groups. */
548  if (b_parent.ptr.data != b_ob.ptr.data) {
549  PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
550  use_motion &= get_boolean(parent_cobject, "use_motion_blur");
551 
552  if (!use_motion) {
553  return 0;
554  }
555 
556  steps = max(steps, get_int(parent_cobject, "motion_steps"));
557  }
558 
559  /* Use uneven number of steps so we get one keyframe at the current frame,
560  * and use 2^(steps - 1) so objects with more/fewer steps still have samples
561  * at the same times, to avoid sampling at many different times. */
562  return min((2 << (steps - 1)) + 1, max_steps);
563 }
564 
565 /* object uses deformation motion blur */
566 static inline bool object_use_deform_motion(BL::Object &b_parent, BL::Object &b_ob)
567 {
568  PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
569  bool use_deform_motion = get_boolean(cobject, "use_deform_motion");
570  /* If motion blur is enabled for the object we also check
571  * whether it's enabled for the parent object as well.
572  *
573  * This way we can control motion blur from the dupligroup
574  * duplicator much easier.
575  */
576  if (use_deform_motion && b_parent.ptr.data != b_ob.ptr.data) {
577  PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
578  use_deform_motion &= get_boolean(parent_cobject, "use_deform_motion");
579  }
580  return use_deform_motion;
581 }
582 
584 {
585  for (BL::Modifier &b_mod : b_ob.modifiers) {
586  if (b_mod.is_a(&RNA_FluidModifier)) {
587  BL::FluidModifier b_mmd(b_mod);
588 
589  if (b_mmd.fluid_type() == BL::FluidModifier::fluid_type_DOMAIN &&
590  b_mmd.domain_settings().domain_type() == BL::FluidDomainSettings::domain_type_GAS) {
591  return b_mmd.domain_settings();
592  }
593  }
594  }
595 
597 }
598 
599 static inline BL::MeshSequenceCacheModifier object_mesh_cache_find(BL::Object &b_ob,
600  bool *has_subdivision_modifier)
601 {
602  for (int i = b_ob.modifiers.length() - 1; i >= 0; --i) {
603  BL::Modifier b_mod = b_ob.modifiers[i];
604 
605  if (b_mod.type() == BL::Modifier::type_MESH_SEQUENCE_CACHE) {
606  BL::MeshSequenceCacheModifier mesh_cache = BL::MeshSequenceCacheModifier(b_mod);
607  return mesh_cache;
608  }
609 
610  /* Skip possible particles system modifiers as they do not modify the geometry. */
611  if (b_mod.type() == BL::Modifier::type_PARTICLE_SYSTEM) {
612  continue;
613  }
614 
615  if (b_mod.type() == BL::Modifier::type_SUBSURF) {
616  if (has_subdivision_modifier) {
617  *has_subdivision_modifier = true;
618  }
619  continue;
620  }
621 
622  break;
623  }
624 
625  return BL::MeshSequenceCacheModifier(PointerRNA_NULL);
626 }
627 
629  bool preview,
630  bool experimental)
631 {
632  PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
633 
634  if (cobj.data && !b_ob.modifiers.empty() && experimental) {
635  BL::Modifier mod = b_ob.modifiers[b_ob.modifiers.length() - 1];
636  bool enabled = preview ? mod.show_viewport() : mod.show_render();
637 
638  if (enabled && mod.type() == BL::Modifier::type_SUBSURF &&
639  RNA_boolean_get(&cobj, "use_adaptive_subdivision")) {
640  BL::SubsurfModifier subsurf(mod);
641 
642  if (subsurf.subdivision_type() == BL::SubsurfModifier::subdivision_type_CATMULL_CLARK) {
644  }
645  else {
647  }
648  }
649  }
650 
651  return Mesh::SUBDIVISION_NONE;
652 }
653 
655 {
656  uint flag = 0;
657 
658  flag |= b_ob.visible_camera() ? PATH_RAY_CAMERA : 0;
659  flag |= b_ob.visible_diffuse() ? PATH_RAY_DIFFUSE : 0;
660  flag |= b_ob.visible_glossy() ? PATH_RAY_GLOSSY : 0;
661  flag |= b_ob.visible_transmission() ? PATH_RAY_TRANSMIT : 0;
662  flag |= b_ob.visible_shadow() ? PATH_RAY_SHADOW : 0;
663  flag |= b_ob.visible_volume_scatter() ? PATH_RAY_VOLUME_SCATTER : 0;
664 
665  return flag;
666 }
667 
668 /* Check whether some of "built-in" motion-related attributes are needed to be exported (includes
669  * things like velocity from cache modifier, fluid simulation).
670  *
671  * NOTE: This code is run prior to object motion blur initialization. so can not access properties
672  * set by `sync_object_motion_init()`. */
673 static inline bool object_need_motion_attribute(BObjectInfo &b_ob_info, Scene *scene)
674 {
675  const Scene::MotionType need_motion = scene->need_motion();
676  if (need_motion == Scene::MOTION_NONE) {
677  /* Simple case: neither motion pass nor motion blur is needed, no need in the motion related
678  * attributes. */
679  return false;
680  }
681 
682  if (need_motion == Scene::MOTION_BLUR) {
683  /* A bit tricky and implicit case:
684  * - Motion blur is enabled in the scene, which implies specific number of time steps for
685  * objects.
686  * - If the object has motion blur disabled on it, it will have 0 time steps.
687  * - Motion attribute expects non-zero time steps.
688  *
689  * Avoid adding motion attributes if the motion blur will enforce 0 motion steps. */
690  PointerRNA cobject = RNA_pointer_get(&b_ob_info.real_object.ptr, "cycles");
691  const bool use_motion = get_boolean(cobject, "use_motion_blur");
692  if (!use_motion) {
693  return false;
694  }
695  }
696 
697  /* Motion pass which implies 3 motion steps, or motion blur which is not disabled on object
698  * level. */
699  return true;
700 }
701 
702 class EdgeMap {
703  public:
705  {
706  }
707 
708  void clear()
709  {
710  edges_.clear();
711  }
712 
713  void insert(int v0, int v1)
714  {
715  get_sorted_verts(v0, v1);
716  edges_.insert(std::pair<int, int>(v0, v1));
717  }
718 
719  bool exists(int v0, int v1)
720  {
721  get_sorted_verts(v0, v1);
722  return edges_.find(std::pair<int, int>(v0, v1)) != edges_.end();
723  }
724 
725  protected:
726  void get_sorted_verts(int &v0, int &v1)
727  {
728  if (v0 > v1) {
729  swap(v0, v1);
730  }
731  }
732 
733  set<std::pair<int, int>> edges_;
734 };
735 
737 
738 #endif /* __BLENDER_UTIL_H__ */
typedef float(TangentPoint)[2]
unsigned int uint
Definition: BLI_sys_types.h:67
const char * dirname(char *path)
void swap(T &a, T &b)
Definition: Common.h:19
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
struct ID ID
struct CurveMapping CurveMapping
struct CurveMap CurveMap
struct FluidDomainSettings FluidDomainSettings
struct ImageUser ImageUser
struct Image Image
struct Mesh Mesh
struct Object Object
struct Scene Scene
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
float float4[4]
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
struct RenderResult RenderResult
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
set< std::pair< int, int > > edges_
void insert(int v0, int v1)
bool exists(int v0, int v1)
void get_sorted_verts(int &v0, int &v1)
T * resize(size_t newsize)
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
static string image_user_file_path(BL::BlendData &data, BL::ImageUser &iuser, BL::Image &ima, int cfra)
static uint object_ray_visibility(BL::Object &b_ob)
static float4 get_float4(const BL::Array< float, 4 > &array)
float * BKE_image_get_float_pixels_for_frame(void *image, int frame, int tile)
static uint object_motion_steps(BL::Object &b_parent, BL::Object &b_ob, const int max_steps=INT_MAX)
static int render_resolution_x(BL::RenderSettings &b_render)
static float get_float(PointerRNA &ptr, const char *name)
static void curvemapping_float_to_array(BL::CurveMapping &cumap, array< float > &data, int size)
void python_thread_state_restore(void **python_thread_state)
Definition: python.cpp:93
static void set_boolean(PointerRNA &ptr, const char *name, bool value)
static bool get_boolean(PointerRNA &ptr, const char *name)
static void set_float3(PointerRNA &ptr, const char *name, float3 value)
static unsigned char * image_get_pixels_for_frame(BL::Image &image, int frame, int tile)
static bool BKE_object_is_modified(BL::Object &self, BL::Scene &scene, bool preview)
unsigned char * BKE_image_get_pixels_for_frame(void *image, int frame, int tile)
static int get_int(PointerRNA &ptr, const char *name)
static void free_object_to_mesh(BL::BlendData &, BObjectInfo &b_ob_info, BL::Mesh &mesh)
static string get_enum_identifier(PointerRNA &ptr, const char *name)
static BL::Mesh object_to_mesh(BL::BlendData &, BObjectInfo &b_ob_info, BL::Depsgraph &, bool, Mesh::SubdivisionType subdivision_type)
static string get_text_datablock_content(const PointerRNA &ptr)
static void colorramp_to_array(BL::ColorRamp &ramp, array< float3 > &ramp_color, array< float > &ramp_alpha, int size)
static void curvemapping_to_array(BL::CurveMapping &cumap, array< float > &data, int size)
static float3 get_float3(const BL::Array< float, 2 > &array)
static int render_resolution_y(BL::RenderSettings &b_render)
static bool object_need_motion_attribute(BObjectInfo &b_ob_info, Scene *scene)
static int get_enum(PointerRNA &ptr, const char *name, int num_values=-1, int default_value=-1)
void BKE_image_user_file_path_ex(void *bmain, void *iuser, void *ima, char *path, bool resolve_udim, bool resolve_multiview)
static void set_enum(PointerRNA &ptr, const char *name, int value)
static void render_add_metadata(BL::RenderResult &b_rr, string name, string value)
BlenderAttributeType blender_attribute_name_split_type(ustring name, string *r_real_name)
static void set_float4(PointerRNA &ptr, const char *name, float4 value)
static bool BKE_object_is_deform_modified(BObjectInfo &self, BL::Scene &scene, bool preview)
static int4 get_int4(const BL::Array< int, 4 > &array)
static void curvemapping_color_to_array(BL::CurveMapping &cumap, array< float3 > &data, int size, bool rgb_curve)
static string blender_absolute_path(BL::BlendData &b_data, BL::ID &b_id, const string &path)
static int3 get_int3(const BL::Array< int, 3 > &array)
static float2 get_float2(const BL::Array< float, 2 > &array)
static Mesh::SubdivisionType object_subdivision_type(BL::Object &b_ob, bool preview, bool experimental)
void BKE_image_user_frame_calc(void *ima, void *iuser, int cfra)
static void set_int(PointerRNA &ptr, const char *name, int value)
static BL::FluidDomainSettings object_fluid_gas_domain_find(BL::Object &b_ob)
void python_thread_state_save(void **python_thread_state)
Definition: python.cpp:88
static void curvemap_minmax_curve(BL::CurveMap &curve, float *min_x, float *max_x)
static string get_string(PointerRNA &ptr, const char *name)
static void set_float(PointerRNA &ptr, const char *name, float value)
static Transform get_transform(const BL::Array< float, 16 > &array)
static void curvemapping_minmax(BL::CurveMapping &cumap, int num_curves, float *min_x, float *max_x)
static BL::MeshSequenceCacheModifier object_mesh_cache_find(BL::Object &b_ob, bool *has_subdivision_modifier)
static bool object_use_deform_motion(BL::Object &b_parent, BL::Object &b_ob)
static void mesh_texture_space(BL::Mesh &b_mesh, float3 &loc, float3 &size)
static void set_string(PointerRNA &ptr, const char *name, const string &value)
BL::ShaderNodeAttribute::attribute_type_enum BlenderAttributeType
static int image_user_frame_number(BL::ImageUser &iuser, BL::Image &ima, int cfra)
static float * image_get_float_pixels_for_frame(BL::Image &image, int frame, int tile)
ccl_device_inline Transform projection_to_transform(const ProjectionTransform &a)
ccl_device_inline ProjectionTransform projection_transpose(const ProjectionTransform &a)
Scene scene
Curve curve
const Depsgraph * depsgraph
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx in_weight_img image(1, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D_ARRAY, "out_weight_img") .image(3
#define str(s)
bool enabled
ccl_gpu_kernel_postfix ccl_global int ccl_global int int num_values
ccl_global const KernelWorkTile * tile
@ PATH_RAY_SHADOW
Definition: kernel/types.h:206
@ PATH_RAY_TRANSMIT
Definition: kernel/types.h:196
@ PATH_RAY_VOLUME_SCATTER
Definition: kernel/types.h:201
@ PATH_RAY_GLOSSY
Definition: kernel/types.h:198
@ PATH_RAY_DIFFUSE
Definition: kernel/types.h:197
@ PATH_RAY_CAMERA
Definition: kernel/types.h:194
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
#define make_int4(x, y, z, w)
Definition: metal/compat.h:208
#define make_float2(x, y)
Definition: metal/compat.h:203
#define make_float4(x, y, z, w)
Definition: metal/compat.h:205
#define make_int3(x, y, z)
Definition: metal/compat.h:207
#define make_float3(x, y, z)
Definition: metal/compat.h:204
static const pxr::TfToken preview("preview", pxr::TfToken::Immortal)
SocketIndexByIdentifierMap * map
string path_dirname(const string &path)
Definition: path.cpp:399
string path_join(const string &dir, const string &file)
Definition: path.cpp:413
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
Definition: rna_access.c:5155
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5167
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
Definition: rna_access.c:4874
const PointerRNA PointerRNA_NULL
Definition: rna_access.c:61
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:4921
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
Definition: rna_access.c:4980
void RNA_enum_set_identifier(bContext *C, PointerRNA *ptr, const char *name, const char *id)
Definition: rna_access.c:5027
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4910
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4957
bool RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
Definition: rna_access.c:1759
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
Definition: rna_access.c:4968
char * RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen, int *r_len)
Definition: rna_access.c:5129
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3402
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:5015
void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
Definition: rna_access.c:4992
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
static const int steps
Definition: sky_nishita.cpp:19
#define min(a, b)
Definition: sort.c:35
BL::Object real_object
BL::Object iter_object
bool is_real_object_data() const
SubdivisionType
Definition: scene/mesh.h:119
@ SUBDIVISION_NONE
Definition: scene/mesh.h:120
@ SUBDIVISION_LINEAR
Definition: scene/mesh.h:121
@ SUBDIVISION_CATMULL_CLARK
Definition: scene/mesh.h:122
void * data
Definition: RNA_types.h:38
MotionType need_motion() const
Definition: scene.cpp:387
MotionType
Definition: scene.h:259
@ MOTION_NONE
Definition: scene.h:259
@ MOTION_BLUR
Definition: scene.h:259
float x
float max
ccl_device_inline int mod(int x, int m)
Definition: util/math.h:490
PointerRNA * ptr
Definition: wm_files.c:3480