Blender  V3.3
spreadsheet_data_source_geometry.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include "BLI_index_mask_ops.hh"
4 #include "BLI_virtual_array.hh"
5 
6 #include "BKE_attribute.hh"
7 #include "BKE_context.h"
8 #include "BKE_curves.hh"
9 #include "BKE_editmesh.h"
10 #include "BKE_geometry_fields.hh"
11 #include "BKE_global.h"
12 #include "BKE_lib_id.h"
13 #include "BKE_mesh.h"
14 #include "BKE_mesh_wrapper.h"
15 #include "BKE_modifier.h"
16 #include "BKE_volume.h"
17 
18 #include "DNA_ID.h"
19 #include "DNA_mesh_types.h"
20 #include "DNA_meshdata_types.h"
21 #include "DNA_space_types.h"
22 #include "DNA_userdef_types.h"
23 
24 #include "DEG_depsgraph_query.h"
25 
26 #include "ED_curves_sculpt.h"
27 #include "ED_spreadsheet.h"
28 
30 
31 #include "BLT_translation.h"
32 
33 #include "RNA_access.h"
34 #include "RNA_enum_types.h"
35 
36 #include "FN_field_cpp_type.hh"
37 
38 #include "bmesh.h"
39 
41 #include "spreadsheet_intern.hh"
42 
45 
46 namespace blender::ed::spreadsheet {
47 
49  FunctionRef<void(const SpreadsheetColumnID &, bool is_extra)> fn) const
50 {
51  for (const auto item : columns_.items()) {
52  SpreadsheetColumnID column_id;
53  column_id.name = (char *)item.key.c_str();
54  fn(column_id, true);
55  }
56 }
57 
58 std::unique_ptr<ColumnValues> ExtraColumns::get_column_values(
59  const SpreadsheetColumnID &column_id) const
60 {
61  const GSpan *values = columns_.lookup_ptr(column_id.name);
62  if (values == nullptr) {
63  return {};
64  }
65  return std::make_unique<ColumnValues>(column_id.name, GVArray::ForSpan(*values));
66 }
67 
69  FunctionRef<void(const SpreadsheetColumnID &, bool is_extra)> fn) const
70 {
71  if (!component_->attributes().has_value()) {
72  return;
73  }
74  const bke::AttributeAccessor attributes = *component_->attributes();
75 
76  if (attributes.domain_size(domain_) == 0) {
77  return;
78  }
79 
80  if (component_->type() == GEO_COMPONENT_TYPE_INSTANCES) {
81  fn({(char *)"Name"}, false);
82  }
83 
84  extra_columns_.foreach_default_column_ids(fn);
85 
86  attributes.for_all(
87  [&](const bke::AttributeIDRef &attribute_id, const bke::AttributeMetaData &meta_data) {
88  if (meta_data.domain != domain_) {
89  return true;
90  }
91  if (attribute_id.is_anonymous()) {
92  return true;
93  }
94  if (!bke::allow_procedural_attribute_access(attribute_id.name())) {
95  return true;
96  }
97  SpreadsheetColumnID column_id;
98  column_id.name = (char *)attribute_id.name().data();
99  fn(column_id, false);
100  return true;
101  });
102 
103  if (component_->type() == GEO_COMPONENT_TYPE_INSTANCES) {
104  fn({(char *)"Rotation"}, false);
105  fn({(char *)"Scale"}, false);
106  }
107  else if (G.debug_value == 4001 && component_->type() == GEO_COMPONENT_TYPE_MESH) {
108  if (domain_ == ATTR_DOMAIN_EDGE) {
109  fn({(char *)"Vertex 1"}, false);
110  fn({(char *)"Vertex 2"}, false);
111  }
112  else if (domain_ == ATTR_DOMAIN_FACE) {
113  fn({(char *)"Corner Start"}, false);
114  fn({(char *)"Corner Size"}, false);
115  }
116  else if (domain_ == ATTR_DOMAIN_CORNER) {
117  fn({(char *)"Vertex"}, false);
118  fn({(char *)"Edge"}, false);
119  }
120  }
121 }
122 
123 std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
124  const SpreadsheetColumnID &column_id) const
125 {
126  if (!component_->attributes().has_value()) {
127  return {};
128  }
129  const bke::AttributeAccessor attributes = *component_->attributes();
130  const int domain_num = attributes.domain_size(domain_);
131  if (domain_num == 0) {
132  return {};
133  }
134 
135  std::lock_guard lock{mutex_};
136 
137  std::unique_ptr<ColumnValues> extra_column_values = extra_columns_.get_column_values(column_id);
138  if (extra_column_values) {
139  return extra_column_values;
140  }
141 
142  if (component_->type() == GEO_COMPONENT_TYPE_INSTANCES) {
143  const InstancesComponent &instances = static_cast<const InstancesComponent &>(*component_);
144  if (STREQ(column_id.name, "Name")) {
145  Span<int> reference_handles = instances.instance_reference_handles();
146  Span<InstanceReference> references = instances.references();
147  return std::make_unique<ColumnValues>(
148  column_id.name,
150  [reference_handles, references](int64_t index) {
151  return references[reference_handles[index]];
152  }));
153  }
154  Span<float4x4> transforms = instances.instance_transforms();
155  if (STREQ(column_id.name, "Rotation")) {
156  return std::make_unique<ColumnValues>(
157  column_id.name, VArray<float3>::ForFunc(domain_num, [transforms](int64_t index) {
158  return transforms[index].to_euler();
159  }));
160  }
161  if (STREQ(column_id.name, "Scale")) {
162  return std::make_unique<ColumnValues>(
163  column_id.name, VArray<float3>::ForFunc(domain_num, [transforms](int64_t index) {
164  return transforms[index].scale();
165  }));
166  }
167  }
168  else if (G.debug_value == 4001 && component_->type() == GEO_COMPONENT_TYPE_MESH) {
169  const MeshComponent &component = static_cast<const MeshComponent &>(*component_);
170  if (const Mesh *mesh = component.get_for_read()) {
171  if (domain_ == ATTR_DOMAIN_EDGE) {
172  if (STREQ(column_id.name, "Vertex 1")) {
173  return std::make_unique<ColumnValues>(
174  column_id.name, VArray<int>::ForFunc(mesh->totedge, [mesh](int64_t index) {
175  return mesh->medge[index].v1;
176  }));
177  }
178  if (STREQ(column_id.name, "Vertex 2")) {
179  return std::make_unique<ColumnValues>(
180  column_id.name, VArray<int>::ForFunc(mesh->totedge, [mesh](int64_t index) {
181  return mesh->medge[index].v2;
182  }));
183  }
184  }
185  else if (domain_ == ATTR_DOMAIN_FACE) {
186  if (STREQ(column_id.name, "Corner Start")) {
187  return std::make_unique<ColumnValues>(
188  column_id.name, VArray<int>::ForFunc(mesh->totpoly, [mesh](int64_t index) {
189  return mesh->mpoly[index].loopstart;
190  }));
191  }
192  if (STREQ(column_id.name, "Corner Size")) {
193  return std::make_unique<ColumnValues>(
194  column_id.name, VArray<int>::ForFunc(mesh->totpoly, [mesh](int64_t index) {
195  return mesh->mpoly[index].totloop;
196  }));
197  }
198  }
199  else if (domain_ == ATTR_DOMAIN_CORNER) {
200  if (STREQ(column_id.name, "Vertex")) {
201  return std::make_unique<ColumnValues>(
202  column_id.name, VArray<int>::ForFunc(mesh->totloop, [mesh](int64_t index) {
203  return mesh->mloop[index].v;
204  }));
205  }
206  if (STREQ(column_id.name, "Edge")) {
207  return std::make_unique<ColumnValues>(
208  column_id.name, VArray<int>::ForFunc(mesh->totloop, [mesh](int64_t index) {
209  return mesh->mloop[index].e;
210  }));
211  }
212  }
213  }
214  }
215 
216  bke::GAttributeReader attribute = attributes.lookup(column_id.name);
217  if (!attribute) {
218  return {};
219  }
220  GVArray varray = std::move(attribute.varray);
221  if (attribute.domain != domain_) {
222  return {};
223  }
224 
225  return std::make_unique<ColumnValues>(column_id.name, std::move(varray));
226 }
227 
229 {
230  if (!component_->attributes().has_value()) {
231  return {};
232  }
233  const bke::AttributeAccessor attributes = *component_->attributes();
234  return attributes.domain_size(domain_);
235 }
236 
238 {
239  Object *object_orig = DEG_get_original_object(object_eval_);
240  switch (component_->type()) {
242  if (object_orig->type != OB_MESH) {
243  return false;
244  }
245  if (object_orig->mode != OB_MODE_EDIT) {
246  return false;
247  }
248  return true;
249  }
251  if (object_orig->type != OB_CURVES) {
252  return false;
253  }
254  if (object_orig->mode != OB_MODE_SCULPT_CURVES) {
255  return false;
256  }
257  return true;
258  }
259  default:
260  return false;
261  }
262 }
263 
265 {
266  std::lock_guard lock{mutex_};
267  const IndexMask full_range(this->tot_rows());
268  if (full_range.is_empty()) {
269  return full_range;
270  }
271 
272  switch (component_->type()) {
274  BLI_assert(object_eval_->type == OB_MESH);
275  BLI_assert(object_eval_->mode == OB_MODE_EDIT);
276  Object *object_orig = DEG_get_original_object(object_eval_);
277  const Mesh *mesh_eval = geometry_set_.get_mesh_for_read();
278  const bke::AttributeAccessor attributes_eval = bke::mesh_attributes(*mesh_eval);
279  Mesh *mesh_orig = (Mesh *)object_orig->data;
280  BMesh *bm = mesh_orig->edit_mesh->bm;
282 
283  const int *orig_indices = (int *)CustomData_get_layer(&mesh_eval->vdata, CD_ORIGINDEX);
284  if (orig_indices != nullptr) {
285  /* Use CD_ORIGINDEX layer if it exists. */
286  VArray<bool> selection = attributes_eval.adapt_domain<bool>(
287  VArray<bool>::ForFunc(mesh_eval->totvert,
288  [bm, orig_indices](int vertex_index) -> bool {
289  const int i_orig = orig_indices[vertex_index];
290  if (i_orig < 0) {
291  return false;
292  }
293  if (i_orig >= bm->totvert) {
294  return false;
295  }
296  const BMVert *vert = BM_vert_at_index(bm, i_orig);
297  return BM_elem_flag_test(vert, BM_ELEM_SELECT);
298  }),
300  domain_);
302  full_range, selection, 1024, indices);
303  }
304 
305  if (mesh_eval->totvert == bm->totvert) {
306  /* Use a simple heuristic to match original vertices to evaluated ones. */
307  VArray<bool> selection = attributes_eval.adapt_domain<bool>(
308  VArray<bool>::ForFunc(mesh_eval->totvert,
309  [bm](int vertex_index) -> bool {
310  const BMVert *vert = BM_vert_at_index(bm, vertex_index);
311  return BM_elem_flag_test(vert, BM_ELEM_SELECT);
312  }),
314  domain_);
316  full_range, selection, 2048, indices);
317  }
318 
319  return full_range;
320  }
322  BLI_assert(object_eval_->type == OB_CURVES);
323  BLI_assert(object_eval_->mode == OB_MODE_SCULPT_CURVES);
324  const CurveComponent &component = static_cast<const CurveComponent &>(*component_);
325  const Curves &curves_id = *component.get_for_read();
326  switch (domain_) {
327  case ATTR_DOMAIN_POINT:
329  case ATTR_DOMAIN_CURVE:
331  default:
333  }
334  return full_range;
335  }
336  default:
337  return full_range;
338  }
339 }
340 
341 void VolumeDataSource::foreach_default_column_ids(
342  FunctionRef<void(const SpreadsheetColumnID &, bool is_extra)> fn) const
343 {
344  if (component_->is_empty()) {
345  return;
346  }
347 
348  for (const char *name : {"Grid Name", "Data Type", "Class"}) {
349  SpreadsheetColumnID column_id{(char *)name};
350  fn(column_id, false);
351  }
352 }
353 
354 std::unique_ptr<ColumnValues> VolumeDataSource::get_column_values(
355  const SpreadsheetColumnID &column_id) const
356 {
357  const Volume *volume = component_->get_for_read();
358  if (volume == nullptr) {
359  return {};
360  }
361 
362 #ifdef WITH_OPENVDB
363  const int size = this->tot_rows();
364  if (STREQ(column_id.name, "Grid Name")) {
365  return std::make_unique<ColumnValues>(
366  IFACE_("Grid Name"), VArray<std::string>::ForFunc(size, [volume](int64_t index) {
367  const VolumeGrid *volume_grid = BKE_volume_grid_get_for_read(volume, index);
368  return BKE_volume_grid_name(volume_grid);
369  }));
370  }
371  if (STREQ(column_id.name, "Data Type")) {
372  return std::make_unique<ColumnValues>(
373  IFACE_("Data Type"), VArray<std::string>::ForFunc(size, [volume](int64_t index) {
374  const VolumeGrid *volume_grid = BKE_volume_grid_get_for_read(volume, index);
375  const VolumeGridType type = BKE_volume_grid_type(volume_grid);
376  const char *name = nullptr;
378  return IFACE_(name);
379  }));
380  }
381  if (STREQ(column_id.name, "Class")) {
382  return std::make_unique<ColumnValues>(
383  IFACE_("Class"), VArray<std::string>::ForFunc(size, [volume](int64_t index) {
384  const VolumeGrid *volume_grid = BKE_volume_grid_get_for_read(volume, index);
385  openvdb::GridBase::ConstPtr grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
386  openvdb::GridClass grid_class = grid->getGridClass();
387  if (grid_class == openvdb::GridClass::GRID_FOG_VOLUME) {
388  return IFACE_("Fog Volume");
389  }
390  if (grid_class == openvdb::GridClass::GRID_LEVEL_SET) {
391  return IFACE_("Level Set");
392  }
393  return IFACE_("Unknown");
394  }));
395  }
396 #else
397  UNUSED_VARS(column_id);
398 #endif
399 
400  return {};
401 }
402 
403 int VolumeDataSource::tot_rows() const
404 {
405  const Volume *volume = component_->get_for_read();
406  if (volume == nullptr) {
407  return 0;
408  }
409  return BKE_volume_num_grids(volume);
410 }
411 
413  Object *object_eval)
414 {
415  GeometrySet geometry_set;
417  Object *object_orig = DEG_get_original_object(object_eval);
418  if (object_orig->type == OB_MESH) {
419  MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
420  if (object_orig->mode == OB_MODE_EDIT) {
421  Mesh *mesh = (Mesh *)object_orig->data;
422  BMEditMesh *em = mesh->edit_mesh;
423  if (em != nullptr) {
424  Mesh *new_mesh = (Mesh *)BKE_id_new_nomain(ID_ME, nullptr);
425  /* This is a potentially heavy operation to do on every redraw. The best solution here is
426  * to display the data directly from the bmesh without a conversion, which can be
427  * implemented a bit later. */
428  BM_mesh_bm_to_me_for_eval(em->bm, new_mesh, nullptr);
429  mesh_component.replace(new_mesh, GeometryOwnershipType::Owned);
430  }
431  }
432  else {
433  Mesh *mesh = (Mesh *)object_orig->data;
435  }
436  }
437  else if (object_orig->type == OB_POINTCLOUD) {
438  PointCloud *pointcloud = (PointCloud *)object_orig->data;
439  PointCloudComponent &pointcloud_component =
441  pointcloud_component.replace(pointcloud, GeometryOwnershipType::ReadOnly);
442  }
443  else if (object_orig->type == OB_CURVES) {
444  const Curves &curves_id = *(const Curves *)object_orig->data;
445  CurveComponent &curve_component = geometry_set.get_component_for_write<CurveComponent>();
446  curve_component.replace(&const_cast<Curves &>(curves_id), GeometryOwnershipType::ReadOnly);
447  }
448  }
449  else {
450  if (object_eval->mode == OB_MODE_EDIT && object_eval->type == OB_MESH) {
452  if (mesh == nullptr) {
453  return geometry_set;
454  }
456  MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
458  }
459  else {
460  if (BLI_listbase_count(&sspreadsheet->context_path) == 1) {
461  /* Use final evaluated object. */
462  if (object_eval->runtime.geometry_set_eval != nullptr) {
463  geometry_set = *object_eval->runtime.geometry_set_eval;
464  }
465  }
466  else {
467  const geo_log::NodeLog *node_log =
469  if (node_log != nullptr) {
470  for (const geo_log::SocketLog &input_log : node_log->input_logs()) {
471  if (const geo_log::GeometryValueLog *geo_value_log =
472  dynamic_cast<const geo_log::GeometryValueLog *>(input_log.value())) {
473  const GeometrySet *full_geometry = geo_value_log->full_geometry();
474  if (full_geometry != nullptr) {
475  geometry_set = *full_geometry;
476  break;
477  }
478  }
479  }
480  }
481  }
482  }
483  }
484  return geometry_set;
485 }
486 
487 static void find_fields_to_evaluate(const SpaceSpreadsheet *sspreadsheet,
488  Map<std::string, GField> &r_fields)
489 {
491  return;
492  }
493  if (BLI_listbase_count(&sspreadsheet->context_path) <= 1) {
494  /* No viewer is currently referenced by the context path. */
495  return;
496  }
498  *sspreadsheet);
499  if (node_log == nullptr) {
500  return;
501  }
502  for (const geo_log::SocketLog &socket_log : node_log->input_logs()) {
503  const geo_log::ValueLog *value_log = socket_log.value();
504  if (value_log == nullptr) {
505  continue;
506  }
507  if (const geo_log::GFieldValueLog *field_value_log =
508  dynamic_cast<const geo_log::GFieldValueLog *>(value_log)) {
509  const GField &field = field_value_log->field();
510  if (field) {
511  r_fields.add("Viewer", std::move(field));
512  }
513  }
514  if (const geo_log::GenericValueLog *generic_value_log =
515  dynamic_cast<const geo_log::GenericValueLog *>(value_log)) {
516  GPointer value = generic_value_log->value();
517  r_fields.add("Viewer", fn::make_constant_field(*value.type(), value.get()));
518  }
519  }
520 }
521 
523  public:
524  /* Use the pointer to the geometry component as a key to detect when the geometry changed. */
526 
528  {
529  }
530 
531  uint64_t hash() const override
532  {
533  return get_default_hash(this->component);
534  }
535 
536  bool is_equal_to(const Key &other) const override
537  {
538  if (const GeometryComponentCacheKey *other_geo =
539  dynamic_cast<const GeometryComponentCacheKey *>(&other)) {
540  return this->component == other_geo->component;
541  }
542  return false;
543  }
544 };
545 
547  public:
548  /* Stores the result of fields evaluated on a geometry component. Without this, fields would have
549  * to be reevaluated on every redraw. */
551 };
552 
555  ExtraColumns &r_extra_columns)
556 {
557  Map<std::string, GField> fields_to_show;
558  find_fields_to_evaluate(sspreadsheet, fields_to_show);
559 
562  std::make_unique<GeometryComponentCacheKey>(component));
563 
564  const eAttrDomain domain = (eAttrDomain)sspreadsheet->attribute_domain;
565  const int domain_num = component.attribute_domain_size(domain);
566  for (const auto item : fields_to_show.items()) {
567  const StringRef name = item.key;
568  const GField &field = item.value;
569 
570  /* Use the cached evaluated array if it exists, otherwise evaluate the field now. */
571  GArray<> &evaluated_array = cache.arrays.lookup_or_add_cb({domain, field}, [&]() {
572  GArray<> evaluated_array(field.cpp_type(), domain_num);
573 
574  bke::GeometryComponentFieldContext field_context{component, domain};
575  fn::FieldEvaluator field_evaluator{field_context, domain_num};
576  field_evaluator.add_with_destination(field, evaluated_array);
577  field_evaluator.evaluate();
578  return evaluated_array;
579  });
580 
581  r_extra_columns.add(name, evaluated_array.as_span());
582  }
583 }
584 
585 std::unique_ptr<DataSource> data_source_from_geometry(const bContext *C, Object *object_eval)
586 {
588  const eAttrDomain domain = (eAttrDomain)sspreadsheet->attribute_domain;
589  const GeometryComponentType component_type = GeometryComponentType(
590  sspreadsheet->geometry_component_type);
591  GeometrySet geometry_set = spreadsheet_get_display_geometry_set(sspreadsheet, object_eval);
592  if (!geometry_set.has(component_type)) {
593  return {};
594  }
595 
596  const GeometryComponent &component = *geometry_set.get_component_for_read(component_type);
597  ExtraColumns extra_columns;
598  add_fields_as_extra_columns(sspreadsheet, component, extra_columns);
599 
600  if (component_type == GEO_COMPONENT_TYPE_VOLUME) {
601  return std::make_unique<VolumeDataSource>(std::move(geometry_set));
602  }
603  return std::make_unique<GeometryDataSource>(
604  object_eval, std::move(geometry_set), component_type, domain, std::move(extra_columns));
605 }
606 
607 } // namespace blender::ed::spreadsheet
eAttrDomain
Definition: BKE_attribute.h:25
@ ATTR_DOMAIN_CURVE
Definition: BKE_attribute.h:31
@ ATTR_DOMAIN_POINT
Definition: BKE_attribute.h:27
@ ATTR_DOMAIN_FACE
Definition: BKE_attribute.h:29
@ ATTR_DOMAIN_CORNER
Definition: BKE_attribute.h:30
@ ATTR_DOMAIN_EDGE
Definition: BKE_attribute.h:28
struct SpaceSpreadsheet * CTX_wm_space_spreadsheet(const bContext *C)
Definition: context.c:941
Low-level operations for curves.
void * CustomData_get_layer(const struct CustomData *data, int type)
GeometryComponentType
@ GEO_COMPONENT_TYPE_MESH
@ GEO_COMPONENT_TYPE_INSTANCES
@ GEO_COMPONENT_TYPE_CURVE
@ GEO_COMPONENT_TYPE_VOLUME
void * BKE_id_new_nomain(short type, const char *name)
Definition: lib_id.c:1173
void BKE_mesh_wrapper_ensure_mdata(struct Mesh *me)
Definition: mesh_wrapper.cc:94
struct Mesh * BKE_modifier_get_evaluated_mesh_from_evaluated_object(struct Object *ob_eval)
Volume data-block.
const VolumeGrid * BKE_volume_grid_get_for_read(const struct Volume *volume, int grid_index)
VolumeGridType BKE_volume_grid_type(const struct VolumeGrid *grid)
VolumeGridType
Definition: BKE_volume.h:90
const char * BKE_volume_grid_name(const struct VolumeGrid *grid)
int BKE_volume_num_grids(const struct Volume *volume)
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define BLI_assert(a)
Definition: BLI_assert.h:46
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define UNUSED_VARS(...)
#define STREQ(a, b)
#define IFACE_(msgid)
static uint8 component(Color32 c, uint i)
Definition: ColorBlock.cpp:108
struct Object * DEG_get_original_object(struct Object *object)
ID and Library types, which are fundamental for sdna.
@ ID_ME
Definition: DNA_ID_enums.h:48
@ CD_ORIGINDEX
@ OB_MODE_EDIT
@ OB_MODE_SCULPT_CURVES
@ OB_MESH
@ OB_POINTCLOUD
@ OB_CURVES
@ SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE
@ SPREADSHEET_OBJECT_EVAL_STATE_ORIGINAL
_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 type
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
#define C
Definition: RandGen.cpp:25
volatile int lock
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_ELEM_SELECT
Definition: bmesh_class.h:471
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:12
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
Definition: bmesh_mesh.cc:558
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
Definition: bmesh_mesh.h:103
void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *cd_mask_extra)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
void replace(Curves *curve, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
virtual std::optional< blender::bke::AttributeAccessor > attributes() const
Definition: geometry_set.cc:75
GeometryComponentType type() const
blender::Span< int > instance_reference_handles() const
blender::Span< InstanceReference > references() const
blender::MutableSpan< blender::float4x4 > instance_transforms()
void replace(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
void replace(PointCloud *pointcloud, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
GSpan as_span() const
const void * get() const
const CPPType * type() const
static GVArray ForSpan(GSpan span)
bool is_empty() const
bool add(const Key &key, const Value &value)
Definition: BLI_map.hh:250
ItemIterator items() const
Definition: BLI_map.hh:859
constexpr const char * data() const
static VArray ForFunc(const int64_t size, GetFunc get_func)
GVArray adapt_domain(const GVArray &varray, const eAttrDomain from_domain, const eAttrDomain to_domain) const
int domain_size(const eAttrDomain domain) const
GAttributeReader lookup(const AttributeIDRef &attribute_id) const
bool for_all(const AttributeForeachCallback fn) const
std::unique_ptr< ColumnValues > get_column_values(const SpreadsheetColumnID &column_id) const
void foreach_default_column_ids(FunctionRef< void(const SpreadsheetColumnID &, bool is_extra)> fn) const
Map< std::pair< eAttrDomain, GField >, GArray<> > arrays
IndexMask apply_selection_filter(Vector< int64_t > &indices) const
std::unique_ptr< ColumnValues > get_column_values(const SpreadsheetColumnID &column_id) const override
void foreach_default_column_ids(FunctionRef< void(const SpreadsheetColumnID &, bool is_extra)> fn) const override
Value & lookup_or_add(std::unique_ptr< Key > key, FunctionRef< std::unique_ptr< Value >()> create_value)
const CPPType & cpp_type() const
Definition: FN_field.hh:122
static const NodeLog * find_node_by_spreadsheet_editor_context(const SpaceSpreadsheet &sspreadsheet)
ccl_gpu_kernel_postfix int ccl_global int * indices
#define G(x, y, z)
static int domain_num(const CurvesGeometry &curves, const eAttrDomain domain)
bool allow_procedural_attribute_access(StringRef attribute_name)
AttributeAccessor mesh_attributes(const Mesh &mesh)
static IndexMask retrieve_selected_points(const CurvesGeometry &curves, const eAttrDomain domain, Vector< int64_t > &r_indices)
static IndexMask retrieve_selected_curves(const CurvesGeometry &curves, const eAttrDomain domain, Vector< int64_t > &r_indices)
GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspreadsheet, Object *object_eval)
std::unique_ptr< DataSource > data_source_from_geometry(const bContext *C, Object *object_eval)
static void find_fields_to_evaluate(const SpaceSpreadsheet *sspreadsheet, Map< std::string, GField > &r_fields)
static void add_fields_as_extra_columns(SpaceSpreadsheet *sspreadsheet, const GeometryComponent &component, ExtraColumns &r_extra_columns)
GField make_constant_field(const CPPType &type, const void *value)
Definition: field.cc:529
IndexMask find_indices_from_virtual_array(IndexMask indices_to_check, const VArray< bool > &virtual_array, int64_t parallel_grain_size, Vector< int64_t > &r_indices)
Definition: index_mask.cc:201
uint64_t get_default_hash(const T &v)
Definition: BLI_hash.hh:218
bool RNA_enum_name_from_value(const EnumPropertyItem *item, int value, const char **r_name)
Definition: rna_access.c:5106
const EnumPropertyItem rna_enum_volume_grid_data_type_items[]
Definition: rna_volume.c:22
__int64 int64_t
Definition: stdint.h:89
unsigned __int64 uint64_t
Definition: stdint.h:90
struct BMesh * bm
Definition: BKE_editmesh.h:40
int totvert
Definition: bmesh_class.h:297
GeometryComponent & get_component_for_write(GeometryComponentType component_type)
bool has(const GeometryComponentType component_type) const
const GeometryComponent * get_component_for_read(GeometryComponentType component_type) const
const Mesh * get_mesh_for_read() const
struct BMEditMesh * edit_mesh
CustomData vdata
int totedge
int totvert
int totpoly
int totloop
struct GeometrySet * geometry_set_eval
Object_Runtime runtime
void * data
blender::ed::spreadsheet::SpreadsheetCache cache
uint8_t geometry_component_type
SpaceSpreadsheet_Runtime * runtime