Blender V4.3
spreadsheet_data_source_geometry.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 "BLI_math_matrix.hh"
7
8#include "BKE_attribute.hh"
10#include "BKE_context.hh"
11#include "BKE_curves.hh"
12#include "BKE_editmesh.hh"
14#include "BKE_geometry_set.hh"
16#include "BKE_global.hh"
17#include "BKE_grease_pencil.hh"
18#include "BKE_instances.hh"
19#include "BKE_lib_id.hh"
20#include "BKE_mesh.hh"
21#include "BKE_mesh_wrapper.hh"
22#include "BKE_modifier.hh"
24#include "BKE_object_types.hh"
25#include "BKE_volume.hh"
26#include "BKE_volume_grid.hh"
27
28#include "DNA_ID.h"
30#include "DNA_space_types.h"
31#include "DNA_userdef_types.h"
32
34
35#include "ED_curves.hh"
36#include "ED_outliner.hh"
37#include "ED_spreadsheet.hh"
38
41
42#include "BLT_translation.hh"
43
44#include "RNA_access.hh"
45#include "RNA_enum_types.hh"
46
47#include "UI_resources.hh"
48
49#include "bmesh.hh"
50
52#include "spreadsheet_intern.hh"
53
55
57
59 FunctionRef<void(const SpreadsheetColumnID &, bool is_extra)> fn) const
60{
61 for (const auto item : columns_.items()) {
62 SpreadsheetColumnID column_id;
63 column_id.name = (char *)item.key.c_str();
64 fn(column_id, true);
65 }
66}
67
68std::unique_ptr<ColumnValues> ExtraColumns::get_column_values(
69 const SpreadsheetColumnID &column_id) const
70{
71 const GSpan *values = columns_.lookup_ptr(column_id.name);
72 if (values == nullptr) {
73 return {};
74 }
75 return std::make_unique<ColumnValues>(column_id.name, GVArray::ForSpan(*values));
76}
77
79 const Mesh &mesh,
80 const bke::AttrDomain domain,
81 FunctionRef<void(const SpreadsheetColumnID &, bool is_extra)> fn)
82{
83 switch (domain) {
85 if (CustomData_has_layer(&mesh.vert_data, CD_ORIGINDEX)) {
86 fn({(char *)"Original Index"}, false);
87 }
88 break;
90 if (CustomData_has_layer(&mesh.edge_data, CD_ORIGINDEX)) {
91 fn({(char *)"Original Index"}, false);
92 }
93 fn({(char *)"Vertices"}, false);
94 break;
96 if (CustomData_has_layer(&mesh.face_data, CD_ORIGINDEX)) {
97 fn({(char *)"Original Index"}, false);
98 }
99 fn({(char *)"Corner Start"}, false);
100 fn({(char *)"Corner Size"}, false);
101 break;
103 fn({(char *)"Vertex"}, false);
104 fn({(char *)"Edge"}, false);
105 break;
106 default:
108 break;
109 }
110}
111
112static std::unique_ptr<ColumnValues> build_mesh_debug_columns(const Mesh &mesh,
113 const bke::AttrDomain domain,
114 const StringRef name)
115{
116 switch (domain) {
118 if (name == "Original Index") {
119 const int *data = static_cast<const int *>(
121 if (data) {
122 return std::make_unique<ColumnValues>(name,
123 VArray<int>::ForSpan({data, mesh.verts_num}));
124 }
125 }
126 return {};
127 }
129 if (name == "Original Index") {
130 const int *data = static_cast<const int *>(
132 if (data) {
133 return std::make_unique<ColumnValues>(name,
134 VArray<int>::ForSpan({data, mesh.edges_num}));
135 }
136 }
137 if (name == "Vertices") {
138 return std::make_unique<ColumnValues>(name, VArray<int2>::ForSpan(mesh.edges()));
139 }
140 return {};
141 }
143 if (name == "Original Index") {
144 const int *data = static_cast<const int *>(
146 if (data) {
147 return std::make_unique<ColumnValues>(name,
148 VArray<int>::ForSpan({data, mesh.faces_num}));
149 }
150 }
151 if (name == "Corner Start") {
152 return std::make_unique<ColumnValues>(
153 name, VArray<int>::ForSpan(mesh.face_offsets().drop_back(1)));
154 }
155 if (name == "Corner Size") {
156 const OffsetIndices faces = mesh.faces();
157 return std::make_unique<ColumnValues>(
158 name, VArray<int>::ForFunc(faces.size(), [faces](int64_t index) {
159 return faces[index].size();
160 }));
161 }
162 return {};
163 }
165 if (name == "Vertex") {
166 return std::make_unique<ColumnValues>(name, VArray<int>::ForSpan(mesh.corner_verts()));
167 }
168 if (name == "Edge") {
169 return std::make_unique<ColumnValues>(name, VArray<int>::ForSpan(mesh.corner_edges()));
170 }
171 return {};
172 }
173 default:
175 return {};
176 }
177}
178
180 FunctionRef<void(const SpreadsheetColumnID &, bool is_extra)> fn) const
181{
182 std::optional<const bke::AttributeAccessor> attributes = this->get_component_attributes();
183 if (!attributes.has_value()) {
184 return;
185 }
186 if (attributes->domain_size(domain_) == 0) {
187 return;
188 }
189
190 if (component_->type() == bke::GeometryComponent::Type::Instance) {
191 fn({(char *)"Name"}, false);
192 }
193
194 if (component_->type() == bke::GeometryComponent::Type::GreasePencil) {
195 fn({(char *)"Name"}, false);
196 }
197
198 extra_columns_.foreach_default_column_ids(fn);
199
200 attributes->foreach_attribute([&](const bke::AttributeIter &iter) {
201 if (iter.domain != domain_) {
202 return;
203 }
205 return;
206 }
208 return;
209 }
210 if (iter.domain == bke::AttrDomain::Instance && iter.name == "instance_transform") {
211 /* Don't display the instance transform attribute, since matrix visualization in the
212 * spreadsheet isn't helpful. */
213 return;
214 }
215 SpreadsheetColumnID column_id;
216 column_id.name = (char *)iter.name.data();
217 const bool is_front = iter.name == ".viewer";
218 fn(column_id, is_front);
219 });
220
221 if (component_->type() == bke::GeometryComponent::Type::Instance) {
222 fn({(char *)"Position"}, false);
223 fn({(char *)"Rotation"}, false);
224 fn({(char *)"Scale"}, false);
225 }
226 else if (G.debug_value == 4001 && component_->type() == bke::GeometryComponent::Type::Mesh) {
227 const bke::MeshComponent &component = static_cast<const bke::MeshComponent &>(*component_);
228 if (const Mesh *mesh = component.get()) {
230 }
231 }
232}
233
234std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
235 const SpreadsheetColumnID &column_id) const
236{
237 std::optional<const bke::AttributeAccessor> attributes = this->get_component_attributes();
238 if (!attributes.has_value()) {
239 return {};
240 }
241 const int domain_num = attributes->domain_size(domain_);
242 if (domain_num == 0) {
243 return {};
244 }
245
246 std::lock_guard lock{mutex_};
247
248 std::unique_ptr<ColumnValues> extra_column_values = extra_columns_.get_column_values(column_id);
249 if (extra_column_values) {
250 return extra_column_values;
251 }
252
253 if (component_->type() == bke::GeometryComponent::Type::Instance) {
254 if (const bke::Instances *instances =
255 static_cast<const bke::InstancesComponent &>(*component_).get())
256 {
257 if (STREQ(column_id.name, "Name")) {
258 Span<int> reference_handles = instances->reference_handles();
259 Span<bke::InstanceReference> references = instances->references();
260 return std::make_unique<ColumnValues>(
261 column_id.name,
263 domain_num, [reference_handles, references](int64_t index) {
264 return references[reference_handles[index]];
265 }));
266 }
267 Span<float4x4> transforms = instances->transforms();
268 if (STREQ(column_id.name, "Position")) {
269 return std::make_unique<ColumnValues>(
270 column_id.name, VArray<float3>::ForFunc(domain_num, [transforms](int64_t index) {
271 return transforms[index].location();
272 }));
273 }
274 if (STREQ(column_id.name, "Rotation")) {
275 return std::make_unique<ColumnValues>(
276 column_id.name, VArray<float3>::ForFunc(domain_num, [transforms](int64_t index) {
277 return float3(math::to_euler(math::normalize(transforms[index])));
278 }));
279 }
280 if (STREQ(column_id.name, "Scale")) {
281 return std::make_unique<ColumnValues>(
282 column_id.name, VArray<float3>::ForFunc(domain_num, [transforms](int64_t index) {
283 return math::to_scale<true>(transforms[index]);
284 }));
285 }
286 }
287 }
288 else if (component_->type() == bke::GeometryComponent::Type::GreasePencil) {
289 if (const GreasePencil *grease_pencil =
290 static_cast<const bke::GreasePencilComponent &>(*component_).get())
291 {
292 if (domain_ == bke::AttrDomain::Layer && STREQ(column_id.name, "Name")) {
293 const Span<const bke::greasepencil::Layer *> layers = grease_pencil->layers();
294 return std::make_unique<ColumnValues>(
295 column_id.name, VArray<std::string>::ForFunc(domain_num, [layers](int64_t index) {
296 StringRefNull name = layers[index]->name();
297 if (name.is_empty()) {
298 name = IFACE_("(Layer)");
299 }
300 return std::string(name);
301 }));
302 }
303 }
304 }
305 else if (G.debug_value == 4001 && component_->type() == bke::GeometryComponent::Type::Mesh) {
306 const bke::MeshComponent &component = static_cast<const bke::MeshComponent &>(*component_);
307 if (const Mesh *mesh = component.get()) {
308 if (std::unique_ptr<ColumnValues> values = build_mesh_debug_columns(
309 *mesh, domain_, column_id.name))
310 {
311 return values;
312 }
313 }
314 }
315
316 bke::GAttributeReader attribute = attributes->lookup(column_id.name);
317 if (!attribute) {
318 return {};
319 }
320 GVArray varray = std::move(attribute.varray);
321 if (attribute.domain != domain_) {
322 return {};
323 }
324
325 StringRefNull column_display_name = column_id.name;
326 if (column_display_name == ".viewer") {
327 column_display_name = "Viewer";
328 }
329
330 return std::make_unique<ColumnValues>(column_display_name, std::move(varray));
331}
332
334{
335 std::optional<const bke::AttributeAccessor> attributes = this->get_component_attributes();
336 if (!attributes.has_value()) {
337 return {};
338 }
339 return attributes->domain_size(domain_);
340}
341
343{
344 if (!object_orig_) {
345 return false;
346 }
347 switch (component_->type()) {
349 if (object_orig_->type != OB_MESH) {
350 return false;
351 }
352 if (object_orig_->mode != OB_MODE_EDIT) {
353 return false;
354 }
355 return true;
356 }
358 if (object_orig_->type != OB_CURVES) {
359 return false;
360 }
361 if (!ELEM(object_orig_->mode, OB_MODE_SCULPT_CURVES, OB_MODE_EDIT)) {
362 return false;
363 }
364 return true;
365 }
367 if (object_orig_->type != OB_POINTCLOUD) {
368 return false;
369 }
370 if (object_orig_->mode != OB_MODE_EDIT) {
371 return false;
372 }
373 return true;
374 }
375 default:
376 return false;
377 }
378}
379
381{
382 std::lock_guard lock{mutex_};
383 const IndexMask full_range(this->tot_rows());
384 if (full_range.is_empty()) {
385 return full_range;
386 }
387
388 switch (component_->type()) {
390 BLI_assert(object_orig_->type == OB_MESH);
391 BLI_assert(object_orig_->mode == OB_MODE_EDIT);
392 const Mesh *mesh_eval = geometry_set_.get_mesh();
393 const bke::AttributeAccessor attributes_eval = mesh_eval->attributes();
394 Mesh *mesh_orig = (Mesh *)object_orig_->data;
395 BMesh *bm = mesh_orig->runtime->edit_mesh->bm;
397
398 const int *orig_indices = (const int *)CustomData_get_layer(&mesh_eval->vert_data,
400 if (orig_indices != nullptr) {
401 /* Use CD_ORIGINDEX layer if it exists. */
402 VArray<bool> selection = attributes_eval.adapt_domain<bool>(
404 [bm, orig_indices](int vertex_index) -> bool {
405 const int i_orig = orig_indices[vertex_index];
406 if (i_orig < 0) {
407 return false;
408 }
409 if (i_orig >= bm->totvert) {
410 return false;
411 }
412 const BMVert *vert = BM_vert_at_index(bm, i_orig);
413 return BM_elem_flag_test(vert, BM_ELEM_SELECT);
414 }),
416 domain_);
417 return IndexMask::from_bools(selection, memory);
418 }
419
420 if (mesh_eval->verts_num == bm->totvert) {
421 /* Use a simple heuristic to match original vertices to evaluated ones. */
422 VArray<bool> selection = attributes_eval.adapt_domain<bool>(
423 VArray<bool>::ForFunc(mesh_eval->verts_num,
424 [bm](int vertex_index) -> bool {
425 const BMVert *vert = BM_vert_at_index(bm, vertex_index);
426 return BM_elem_flag_test(vert, BM_ELEM_SELECT);
427 }),
429 domain_);
430 return IndexMask::from_bools(selection, memory);
431 }
432
433 return full_range;
434 }
436 BLI_assert(object_orig_->type == OB_CURVES);
437 const bke::CurveComponent &component = static_cast<const bke::CurveComponent &>(*component_);
438 const Curves &curves_id = *component.get();
439 switch (domain_) {
441 return curves::retrieve_selected_points(curves_id, memory);
443 return curves::retrieve_selected_curves(curves_id, memory);
444 default:
446 }
447 return full_range;
448 }
450 BLI_assert(object_orig_->type == OB_POINTCLOUD);
451 const bke::AttributeAccessor attributes = *component_->attributes();
452 const VArray<bool> &selection = *attributes.lookup_or_default(
453 ".selection", bke::AttrDomain::Point, false);
454 return IndexMask::from_bools(selection, memory);
455 }
456 default:
457 return full_range;
458 }
459}
460
461std::optional<const bke::AttributeAccessor> GeometryDataSource::get_component_attributes() const
462{
463 if (component_->type() != bke::GeometryComponent::Type::GreasePencil) {
464 return component_->attributes();
465 }
466 const GreasePencil *grease_pencil = geometry_set_.get_grease_pencil();
467 if (!grease_pencil) {
468 return {};
469 }
470 if (domain_ == bke::AttrDomain::Layer) {
471 return grease_pencil->attributes();
472 }
473 if (layer_index_ >= 0 && layer_index_ < grease_pencil->layers().size()) {
474 if (const bke::greasepencil::Drawing *drawing = grease_pencil->get_eval_drawing(
475 grease_pencil->layer(layer_index_)))
476 {
477 return drawing->strokes().attributes();
478 }
479 }
480 return {};
481}
482
484 FunctionRef<void(const SpreadsheetColumnID &, bool is_extra)> fn) const
485{
486 if (component_->is_empty()) {
487 return;
488 }
489
490 for (const char *name : {"Grid Name", "Data Type", "Class"}) {
491 SpreadsheetColumnID column_id{(char *)name};
492 fn(column_id, false);
493 }
494}
495
496std::unique_ptr<ColumnValues> VolumeDataSource::get_column_values(
497 const SpreadsheetColumnID &column_id) const
498{
499 const Volume *volume = component_->get();
500 if (volume == nullptr) {
501 return {};
502 }
503
504#ifdef WITH_OPENVDB
505 const int size = this->tot_rows();
506 if (STREQ(column_id.name, "Grid Name")) {
507 return std::make_unique<ColumnValues>(
508 IFACE_("Grid Name"), VArray<std::string>::ForFunc(size, [volume](int64_t index) {
509 const bke::VolumeGridData *volume_grid = BKE_volume_grid_get(volume, index);
510 return volume_grid->name();
511 }));
512 }
513 if (STREQ(column_id.name, "Data Type")) {
514 return std::make_unique<ColumnValues>(
515 IFACE_("Data Type"), VArray<std::string>::ForFunc(size, [volume](int64_t index) {
516 const bke::VolumeGridData *volume_grid = BKE_volume_grid_get(volume, index);
517 const VolumeGridType type = volume_grid->grid_type();
518 const char *name = nullptr;
520 return IFACE_(name);
521 }));
522 }
523 if (STREQ(column_id.name, "Class")) {
524 return std::make_unique<ColumnValues>(
525 IFACE_("Class"), VArray<std::string>::ForFunc(size, [volume](int64_t index) {
526 const bke::VolumeGridData *volume_grid = BKE_volume_grid_get(volume, index);
527 openvdb::GridClass grid_class = volume_grid->grid_class();
528 if (grid_class == openvdb::GridClass::GRID_FOG_VOLUME) {
529 return IFACE_("Fog Volume");
530 }
531 if (grid_class == openvdb::GridClass::GRID_LEVEL_SET) {
532 return IFACE_("Level Set");
533 }
534 return IFACE_("Unknown");
535 }));
536 }
537#else
538 UNUSED_VARS(column_id);
539#endif
540
541 return {};
542}
543
545{
546 const Volume *volume = component_->get();
547 if (volume == nullptr) {
548 return 0;
549 }
550 return BKE_volume_num_grids(volume);
551}
552
554{
555 switch (reference.type()) {
557 const Object &object = reference.object();
558 return ED_outliner_icon_from_id(object.id);
559 }
561 return ICON_OUTLINER_COLLECTION;
562 }
564 return ICON_GEOMETRY_SET;
565 }
567 break;
568 }
569 }
570 return ICON_NONE;
571}
572
574 Object *object_eval)
575{
576 bke::GeometrySet geometry_set;
578 const Object *object_orig = DEG_get_original_object(object_eval);
579 if (object_orig->type == OB_MESH) {
580 const Mesh *mesh = static_cast<const Mesh *>(object_orig->data);
581 if (object_orig->mode == OB_MODE_EDIT) {
582 if (const BMEditMesh *em = mesh->runtime->edit_mesh.get()) {
583 Mesh *new_mesh = (Mesh *)BKE_id_new_nomain(ID_ME, nullptr);
584 /* This is a potentially heavy operation to do on every redraw. The best solution here is
585 * to display the data directly from the bmesh without a conversion, which can be
586 * implemented a bit later. */
587 BM_mesh_bm_to_me_for_eval(*em->bm, *new_mesh, nullptr);
588 geometry_set.replace_mesh(new_mesh, bke::GeometryOwnershipType::Owned);
589 }
590 }
591 else {
592 geometry_set.replace_mesh(const_cast<Mesh *>(mesh), bke::GeometryOwnershipType::ReadOnly);
593 }
594 }
595 else if (object_orig->type == OB_POINTCLOUD) {
596 const PointCloud *pointcloud = static_cast<const PointCloud *>(object_orig->data);
597 geometry_set.replace_pointcloud(const_cast<PointCloud *>(pointcloud),
599 }
600 else if (object_orig->type == OB_CURVES) {
601 const Curves &curves_id = *static_cast<const Curves *>(object_orig->data);
602 geometry_set.replace_curves(&const_cast<Curves &>(curves_id),
604 }
605 else if (object_orig->type == OB_GREASE_PENCIL) {
606 const GreasePencil &grease_pencil = *static_cast<const GreasePencil *>(object_orig->data);
607 geometry_set.replace_grease_pencil(&const_cast<GreasePencil &>(grease_pencil),
609 }
610 }
611 else {
612 if (BLI_listbase_is_single(&sspreadsheet->viewer_path.path)) {
613 if (const bke::GeometrySet *geometry_eval = object_eval->runtime->geometry_set_eval) {
614 geometry_set = *geometry_eval;
615 }
616
617 if (object_eval->mode == OB_MODE_EDIT && object_eval->type == OB_MESH) {
621 }
622 }
623 }
624 else {
625 if (const ViewerNodeLog *viewer_log =
627 sspreadsheet->viewer_path))
628 {
629 geometry_set = viewer_log->geometry;
630 }
631 }
632 }
633 return geometry_set;
634}
635
637 const Span<SpreadsheetInstanceID> instance_ids)
638{
639 bke::GeometrySet geometry = root_geometry;
640 for (const SpreadsheetInstanceID &instance_id : instance_ids) {
641 const bke::Instances *instances = geometry.get_instances();
642 if (!instances) {
643 /* Return the best available geometry. */
644 return geometry;
645 }
646 const Span<bke::InstanceReference> references = instances->references();
647 if (instance_id.reference_index < 0 || instance_id.reference_index >= references.size()) {
648 /* Return the best available geometry. */
649 return geometry;
650 }
651 const bke::InstanceReference &reference = references[instance_id.reference_index];
652 bke::GeometrySet reference_geometry;
653 reference.to_geometry_set(reference_geometry);
654 geometry = reference_geometry;
655 }
656 return geometry;
657}
658
659std::unique_ptr<DataSource> data_source_from_geometry(const bContext *C, Object *object_eval)
660{
662
663 const bke::GeometrySet root_geometry_set = spreadsheet_get_display_geometry_set(sspreadsheet,
664 object_eval);
666 root_geometry_set, Span{sspreadsheet->instance_ids, sspreadsheet->instance_ids_num});
667
668 const bke::AttrDomain domain = (bke::AttrDomain)sspreadsheet->attribute_domain;
669 const auto component_type = bke::GeometryComponent::Type(sspreadsheet->geometry_component_type);
670 const int active_layer_index = sspreadsheet->active_layer_index;
671 if (!geometry_set.has(component_type)) {
672 return {};
673 }
674
675 if (component_type == bke::GeometryComponent::Type::Volume) {
676 return std::make_unique<VolumeDataSource>(std::move(geometry_set));
677 }
678 Object *object_orig = sspreadsheet->instance_ids_num == 0 ?
679 DEG_get_original_object(object_eval) :
680 nullptr;
681 return std::make_unique<GeometryDataSource>(
682 object_orig, std::move(geometry_set), component_type, domain, active_layer_index);
683}
684
685} // namespace blender::ed::spreadsheet
SpaceSpreadsheet * CTX_wm_space_spreadsheet(const bContext *C)
Low-level operations for curves.
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
Low-level operations for grease pencil.
void * BKE_id_new_nomain(short type, const char *name)
Definition lib_id.cc:1487
void BKE_mesh_wrapper_ensure_mdata(Mesh *mesh)
Mesh * BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval)
Volume data-block.
int BKE_volume_num_grids(const Volume *volume)
const blender::bke::VolumeGridData * BKE_volume_grid_get(const Volume *volume, int grid_index)
VolumeGridType
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
void void BLI_INLINE bool BLI_listbase_is_single(const struct ListBase *lb)
#define UNUSED_VARS(...)
#define ELEM(...)
#define STREQ(a, b)
#define IFACE_(msgid)
Object * DEG_get_original_object(Object *object)
ID and Library types, which are fundamental for SDNA.
@ ID_ME
@ OB_MODE_EDIT
@ OB_MODE_SCULPT_CURVES
@ OB_GREASE_PENCIL
@ OB_MESH
@ OB_POINTCLOUD
@ OB_CURVES
@ SPREADSHEET_OBJECT_EVAL_STATE_ORIGINAL
int ED_outliner_icon_from_id(const ID &id)
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 Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture 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:29
volatile int lock
@ BM_ELEM_SELECT
#define BM_elem_flag_test(ele, hflag)
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
void BM_mesh_bm_to_me_for_eval(BMesh &bm, Mesh &mesh, const CustomData_MeshMasks *cd_mask_extra)
#define BM_VERT
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
AttributeSet attributes
static GVArray ForSpan(GSpan span)
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
constexpr int64_t size() const
Definition BLI_span.hh:253
constexpr const char * data() const
static VArray ForSpan(Span< T > values)
static VArray ForFunc(const int64_t size, GetFunc get_func)
GVArray adapt_domain(const GVArray &varray, const AttrDomain from_domain, const AttrDomain to_domain) const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
void to_geometry_set(GeometrySet &r_geometry_set) const
Definition instances.cc:85
Span< InstanceReference > references() const
Definition instances.cc:277
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
IndexMask apply_selection_filter(IndexMaskMemory &memory) 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
void foreach_default_column_ids(FunctionRef< void(const SpreadsheetColumnID &, bool is_extra)> fn) const override
std::unique_ptr< ColumnValues > get_column_values(const SpreadsheetColumnID &column_id) const override
static const ViewerNodeLog * find_viewer_node_log_for_path(const ViewerPath &viewer_path)
static char faces[256]
#define G(x, y, z)
bool attribute_name_is_anonymous(const StringRef name)
bool allow_procedural_attribute_access(StringRef attribute_name)
IndexMask retrieve_selected_curves(const bke::CurvesGeometry &curves, IndexMaskMemory &memory)
IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves, IndexMaskMemory &memory)
bke::GeometrySet get_geometry_set_for_instance_ids(const bke::GeometrySet &root_geometry, const Span< SpreadsheetInstanceID > instance_ids)
bke::GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspreadsheet, Object *object_eval)
int get_instance_reference_icon(const bke::InstanceReference &reference)
std::unique_ptr< DataSource > data_source_from_geometry(const bContext *C, Object *object_eval)
static void add_mesh_debug_column_names(const Mesh &mesh, const bke::AttrDomain domain, FunctionRef< void(const SpreadsheetColumnID &, bool is_extra)> fn)
static std::unique_ptr< ColumnValues > build_mesh_debug_columns(const Mesh &mesh, const bke::AttrDomain domain, const StringRef name)
GPU_SHADER_INTERFACE_INFO(overlay_edit_curve_handle_iface, "vert").flat(Type pos vertex_in(1, Type::UINT, "data") .vertex_out(overlay_edit_curve_handle_iface) .geometry_layout(PrimitiveIn Frequency::GEOMETRY storage_buf(1, Qualifier::READ, "uint", "data[]", Frequency::GEOMETRY) .push_constant(Type Frequency::GEOMETRY selection[]
bool RNA_enum_name_from_value(const EnumPropertyItem *item, int value, const char **r_name)
const EnumPropertyItem rna_enum_volume_grid_data_type_items[]
Definition rna_volume.cc:27
__int64 int64_t
Definition stdint.h:89
MeshRuntimeHandle * runtime
CustomData vert_data
int verts_num
ObjectRuntimeHandle * runtime
SpreadsheetInstanceID * instance_ids
uint8_t geometry_component_type
bool has(const GeometryComponent::Type component_type) const
void replace_pointcloud(PointCloud *pointcloud, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
void replace_curves(Curves *curves, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
void replace_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
void replace_grease_pencil(GreasePencil *grease_pencil, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)