Blender V4.5
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_listbase.h"
6#include "BLI_math_matrix.hh"
8
9#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"
23#include "BKE_object_types.hh"
24#include "BKE_volume.hh"
25#include "BKE_volume_grid.hh"
26
28#include "DNA_space_types.h"
29
31
32#include "ED_curves.hh"
33#include "ED_outliner.hh"
34
36
37#include "BLT_translation.hh"
38
39#include "RNA_access.hh"
40#include "RNA_enum_types.hh"
41
42#include "UI_resources.hh"
43
44#include "bmesh.hh"
45
47#include "spreadsheet_intern.hh"
48
50
51uint64_t SpreadsheetInstanceID::hash() const
52{
54}
55
57{
58 return a.reference_index == b.reference_index;
59}
60
62{
63 return !(a == b);
64}
65
67
69 const Mesh &mesh,
70 const bke::AttrDomain domain,
71 FunctionRef<void(const SpreadsheetColumnID &, bool is_extra)> fn)
72{
73 switch (domain) {
75 if (CustomData_has_layer(&mesh.vert_data, CD_ORIGINDEX)) {
76 fn({(char *)"Original Index"}, false);
77 }
78 break;
80 if (CustomData_has_layer(&mesh.edge_data, CD_ORIGINDEX)) {
81 fn({(char *)"Original Index"}, false);
82 }
83 break;
85 if (CustomData_has_layer(&mesh.face_data, CD_ORIGINDEX)) {
86 fn({(char *)"Original Index"}, false);
87 }
88 fn({(char *)"Corner Start"}, false);
89 fn({(char *)"Corner Size"}, false);
90 break;
92 break;
93 default:
95 break;
96 }
97}
98
99static std::unique_ptr<ColumnValues> build_mesh_debug_columns(const Mesh &mesh,
100 const bke::AttrDomain domain,
101 const StringRef name)
102{
103 switch (domain) {
105 if (name == "Original Index") {
106 const int *data = static_cast<const int *>(
108 if (data) {
109 return std::make_unique<ColumnValues>(name,
110 VArray<int>::ForSpan({data, mesh.verts_num}));
111 }
112 }
113 return {};
114 }
116 if (name == "Original Index") {
117 const int *data = static_cast<const int *>(
119 if (data) {
120 return std::make_unique<ColumnValues>(name,
121 VArray<int>::ForSpan({data, mesh.edges_num}));
122 }
123 }
124 return {};
125 }
127 if (name == "Original Index") {
128 const int *data = static_cast<const int *>(
130 if (data) {
131 return std::make_unique<ColumnValues>(name,
132 VArray<int>::ForSpan({data, mesh.faces_num}));
133 }
134 }
135 if (name == "Corner Start") {
136 return std::make_unique<ColumnValues>(
137 name, VArray<int>::ForSpan(mesh.face_offsets().drop_back(1)));
138 }
139 if (name == "Corner Size") {
140 const OffsetIndices faces = mesh.faces();
141 return std::make_unique<ColumnValues>(
142 name, VArray<int>::ForFunc(faces.size(), [faces](int64_t index) {
143 return faces[index].size();
144 }));
145 }
146 return {};
147 }
149 return {};
150 }
151 default:
153 return {};
154 }
155}
156
157bool GeometryDataSource::display_attribute(const StringRef name,
158 const bke::AttrDomain domain) const
159{
161 return false;
162 }
163 if (!show_internal_attributes_) {
165 return false;
166 }
167 if (domain == bke::AttrDomain::Instance && name == "instance_transform") {
168 /* Don't display the instance transform attribute, since matrix visualization in the
169 * spreadsheet isn't helpful. */
170 return false;
171 }
172 }
173 return true;
174}
175
177 FunctionRef<void(const SpreadsheetColumnID &, bool is_extra)> fn) const
178{
179 std::optional<const bke::AttributeAccessor> attributes = this->get_component_attributes();
180 if (!attributes.has_value()) {
181 return;
182 }
183 if (attributes->domain_size(domain_) == 0) {
184 return;
185 }
186
187 if (component_->type() == bke::GeometryComponent::Type::Instance) {
188 fn({(char *)"Name"}, false);
189 }
190
191 if (component_->type() == bke::GeometryComponent::Type::GreasePencil) {
192 fn({(char *)"Name"}, false);
193 }
194
195 attributes->foreach_attribute([&](const bke::AttributeIter &iter) {
196 if (iter.domain != domain_) {
197 return;
198 }
199 if (!display_attribute(iter.name, iter.domain)) {
200 return;
201 }
202 SpreadsheetColumnID column_id;
203 column_id.name = (char *)iter.name.data();
204 const bool is_front = iter.name == ".viewer";
205 fn(column_id, is_front);
206 });
207
208 if (component_->type() == bke::GeometryComponent::Type::Instance) {
209 fn({(char *)"Position"}, false);
210 fn({(char *)"Rotation"}, false);
211 fn({(char *)"Scale"}, false);
212 }
213 else if (G.debug_value == 4001 && component_->type() == bke::GeometryComponent::Type::Mesh) {
214 const bke::MeshComponent &component = static_cast<const bke::MeshComponent &>(*component_);
215 if (const Mesh *mesh = component.get()) {
217 }
218 }
219}
220
221std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
222 const SpreadsheetColumnID &column_id) const
223{
224 std::optional<const bke::AttributeAccessor> attributes = this->get_component_attributes();
225 if (!attributes.has_value()) {
226 return {};
227 }
228 const int domain_num = attributes->domain_size(domain_);
229 if (domain_num == 0) {
230 return {};
231 }
232 if (!display_attribute(column_id.name, domain_)) {
233 return {};
234 }
235
236 std::lock_guard lock{mutex_};
237
238 if (component_->type() == bke::GeometryComponent::Type::Instance) {
239 if (const bke::Instances *instances =
240 static_cast<const bke::InstancesComponent &>(*component_).get())
241 {
242 if (STREQ(column_id.name, "Name")) {
243 Span<int> reference_handles = instances->reference_handles();
244 Span<bke::InstanceReference> references = instances->references();
245 return std::make_unique<ColumnValues>(
246 column_id.name,
248 domain_num, [reference_handles, references](int64_t index) {
249 return references[reference_handles[index]];
250 }));
251 }
252 Span<float4x4> transforms = instances->transforms();
253 if (STREQ(column_id.name, "Position")) {
254 return std::make_unique<ColumnValues>(
255 column_id.name, VArray<float3>::ForFunc(domain_num, [transforms](int64_t index) {
256 return transforms[index].location();
257 }));
258 }
259 if (STREQ(column_id.name, "Rotation")) {
260 return std::make_unique<ColumnValues>(
261 column_id.name, VArray<float3>::ForFunc(domain_num, [transforms](int64_t index) {
262 return float3(math::to_euler(math::normalize(transforms[index])));
263 }));
264 }
265 if (STREQ(column_id.name, "Scale")) {
266 return std::make_unique<ColumnValues>(
267 column_id.name, VArray<float3>::ForFunc(domain_num, [transforms](int64_t index) {
268 return math::to_scale<true>(transforms[index]);
269 }));
270 }
271 }
272 }
273 else if (component_->type() == bke::GeometryComponent::Type::GreasePencil) {
274 if (const GreasePencil *grease_pencil =
275 static_cast<const bke::GreasePencilComponent &>(*component_).get())
276 {
277 if (domain_ == bke::AttrDomain::Layer && STREQ(column_id.name, "Name")) {
278 const Span<const bke::greasepencil::Layer *> layers = grease_pencil->layers();
279 return std::make_unique<ColumnValues>(
280 column_id.name, VArray<std::string>::ForFunc(domain_num, [layers](int64_t index) {
281 StringRefNull name = layers[index]->name();
282 if (name.is_empty()) {
283 name = IFACE_("(Layer)");
284 }
285 return std::string(name);
286 }));
287 }
288 }
289 }
290 else if (G.debug_value == 4001 && component_->type() == bke::GeometryComponent::Type::Mesh) {
291 const bke::MeshComponent &component = static_cast<const bke::MeshComponent &>(*component_);
292 if (const Mesh *mesh = component.get()) {
293 if (std::unique_ptr<ColumnValues> values = build_mesh_debug_columns(
294 *mesh, domain_, column_id.name))
295 {
296 return values;
297 }
298 }
299 }
300
301 bke::GAttributeReader attribute = attributes->lookup(column_id.name);
302 if (!attribute) {
303 return {};
304 }
305 GVArray varray = std::move(attribute.varray);
306 if (attribute.domain != domain_) {
307 return {};
308 }
309
310 StringRefNull column_display_name = column_id.name;
311 if (column_display_name == ".viewer") {
312 column_display_name = "Viewer";
313 }
314
315 return std::make_unique<ColumnValues>(column_display_name, std::move(varray));
316}
317
319{
320 std::optional<const bke::AttributeAccessor> attributes = this->get_component_attributes();
321 if (!attributes.has_value()) {
322 return {};
323 }
324 return attributes->domain_size(domain_);
325}
326
328{
329 if (!object_orig_) {
330 return false;
331 }
332 switch (component_->type()) {
334 if (object_orig_->type != OB_MESH) {
335 return false;
336 }
337 if (object_orig_->mode != OB_MODE_EDIT) {
338 return false;
339 }
340 return true;
341 }
343 if (object_orig_->type != OB_CURVES) {
344 return false;
345 }
346 if (!ELEM(object_orig_->mode, OB_MODE_SCULPT_CURVES, OB_MODE_EDIT)) {
347 return false;
348 }
349 return true;
350 }
352 if (object_orig_->type != OB_POINTCLOUD) {
353 return false;
354 }
355 if (object_orig_->mode != OB_MODE_EDIT) {
356 return false;
357 }
358 return true;
359 }
360 default:
361 return false;
362 }
363}
364
366 const Mesh &mesh_orig,
367 IndexMaskMemory &memory)
368{
369 const bke::AttributeAccessor attributes_eval = mesh_eval.attributes();
370 const IndexRange range(attributes_eval.domain_size(bke::AttrDomain::Face));
371 BMesh *bm = mesh_orig.runtime->edit_mesh->bm;
372
374 if (mesh_eval.faces_num == bm->totface) {
375 return IndexMask::from_predicate(range, GrainSize(4096), memory, [&](const int i) {
376 const BMFace *face = BM_face_at_index(bm, i);
378 });
379 }
380 if (const int *orig_indices = static_cast<const int *>(
382 {
383 return IndexMask::from_predicate(range, GrainSize(2048), memory, [&](const int i) {
384 const int orig = orig_indices[i];
385 if (orig == -1) {
386 return false;
387 }
388 const BMFace *face = BM_face_at_index(bm, orig);
390 });
391 }
392 return range;
393}
394
396 const Mesh &mesh_orig,
397 const bke::AttrDomain domain,
398 IndexMaskMemory &memory)
399{
400 const bke::AttributeAccessor attributes_eval = mesh_eval.attributes();
401 const IndexRange range(attributes_eval.domain_size(domain));
402 BMesh *bm = mesh_orig.runtime->edit_mesh->bm;
403
404 switch (domain) {
407 if (mesh_eval.verts_num == bm->totvert) {
408 return IndexMask::from_predicate(range, GrainSize(4096), memory, [&](const int i) {
409 const BMVert *vert = BM_vert_at_index(bm, i);
411 });
412 }
413 if (const int *orig_indices = static_cast<const int *>(
415 {
416 return IndexMask::from_predicate(range, GrainSize(2048), memory, [&](const int i) {
417 const int orig = orig_indices[i];
418 if (orig == -1) {
419 return false;
420 }
421 const BMVert *vert = BM_vert_at_index(bm, orig);
423 });
424 }
425 return range;
426 }
429 if (mesh_eval.edges_num == bm->totedge) {
430 return IndexMask::from_predicate(range, GrainSize(4096), memory, [&](const int i) {
431 const BMEdge *edge = BM_edge_at_index(bm, i);
433 });
434 }
435 if (const int *orig_indices = static_cast<const int *>(
437 {
438 return IndexMask::from_predicate(range, GrainSize(2048), memory, [&](const int i) {
439 const int orig = orig_indices[i];
440 if (orig == -1) {
441 return false;
442 }
443 const BMEdge *edge = BM_edge_at_index(bm, orig);
445 });
446 }
447 return range;
448 }
450 return calc_mesh_selection_mask_faces(mesh_eval, mesh_orig, memory);
451 }
453 IndexMaskMemory face_memory;
455 mesh_eval, mesh_orig, face_memory);
456 if (face_mask.is_empty()) {
457 return {};
458 }
459 if (face_mask.size() == range.size()) {
460 return range;
461 }
462
463 Array<bool> face_selection(range.size(), false);
464 face_mask.to_bools(face_selection);
465
466 const VArray<bool> corner_selection = attributes_eval.adapt_domain<bool>(
468 return IndexMask::from_bools(corner_selection, memory);
469 }
470 default:
472 return range;
473 }
474}
475
477{
478 std::lock_guard lock{mutex_};
479 const IndexMask full_range(this->tot_rows());
480 if (full_range.is_empty()) {
481 return full_range;
482 }
483
484 switch (component_->type()) {
486 BLI_assert(object_orig_->type == OB_MESH);
487 BLI_assert(object_orig_->mode == OB_MODE_EDIT);
488 const Mesh *mesh_eval = geometry_set_.get_mesh();
489 const Mesh *mesh_orig = static_cast<const Mesh *>(object_orig_->data);
490 return calc_mesh_selection_mask(*mesh_eval, *mesh_orig, domain_, memory);
491 }
493 BLI_assert(object_orig_->type == OB_CURVES);
494 const bke::CurveComponent &component = static_cast<const bke::CurveComponent &>(*component_);
495 const Curves &curves_id = *component.get();
496 switch (domain_) {
498 return curves::retrieve_selected_points(curves_id, memory);
500 return curves::retrieve_selected_curves(curves_id, memory);
501 default:
503 }
504 return full_range;
505 }
507 BLI_assert(object_orig_->type == OB_POINTCLOUD);
508 const bke::AttributeAccessor attributes = *component_->attributes();
509 const VArray<bool> selection = *attributes.lookup_or_default(
510 ".selection", bke::AttrDomain::Point, true);
511 return IndexMask::from_bools(selection, memory);
512 }
513 default:
514 return full_range;
515 }
516}
517
518std::optional<const bke::AttributeAccessor> GeometryDataSource::get_component_attributes() const
519{
520 if (component_->type() != bke::GeometryComponent::Type::GreasePencil) {
521 return component_->attributes();
522 }
523 const GreasePencil *grease_pencil = geometry_set_.get_grease_pencil();
524 if (!grease_pencil) {
525 return {};
526 }
527 if (domain_ == bke::AttrDomain::Layer) {
528 return grease_pencil->attributes();
529 }
530 if (layer_index_ >= 0 && layer_index_ < grease_pencil->layers().size()) {
531 if (const bke::greasepencil::Drawing *drawing = grease_pencil->get_eval_drawing(
532 grease_pencil->layer(layer_index_)))
533 {
534 return drawing->strokes().attributes();
535 }
536 }
537 return {};
538}
539
541 FunctionRef<void(const SpreadsheetColumnID &, bool is_extra)> fn) const
542{
543 if (component_->is_empty()) {
544 return;
545 }
546
547 for (const char *name : {"Grid Name", "Data Type", "Class"}) {
548 SpreadsheetColumnID column_id{(char *)name};
549 fn(column_id, false);
550 }
551}
552
553std::unique_ptr<ColumnValues> VolumeDataSource::get_column_values(
554 const SpreadsheetColumnID &column_id) const
555{
556 const Volume *volume = component_->get();
557 if (volume == nullptr) {
558 return {};
559 }
560
561#ifdef WITH_OPENVDB
562 const int size = this->tot_rows();
563 if (STREQ(column_id.name, "Grid Name")) {
564 return std::make_unique<ColumnValues>(
565 IFACE_("Grid Name"), VArray<std::string>::ForFunc(size, [volume](int64_t index) {
566 const bke::VolumeGridData *volume_grid = BKE_volume_grid_get(volume, index);
567 return volume_grid->name();
568 }));
569 }
570 if (STREQ(column_id.name, "Data Type")) {
571 return std::make_unique<ColumnValues>(
572 IFACE_("Data Type"), VArray<std::string>::ForFunc(size, [volume](int64_t index) {
573 const bke::VolumeGridData *volume_grid = BKE_volume_grid_get(volume, index);
574 const VolumeGridType type = volume_grid->grid_type();
575 const char *name = nullptr;
577 return IFACE_(name);
578 }));
579 }
580 if (STREQ(column_id.name, "Class")) {
581 return std::make_unique<ColumnValues>(
582 IFACE_("Class"), VArray<std::string>::ForFunc(size, [volume](int64_t index) {
583 const bke::VolumeGridData *volume_grid = BKE_volume_grid_get(volume, index);
584 openvdb::GridClass grid_class = volume_grid->grid_class();
585 if (grid_class == openvdb::GridClass::GRID_FOG_VOLUME) {
586 return IFACE_("Fog Volume");
587 }
588 if (grid_class == openvdb::GridClass::GRID_LEVEL_SET) {
589 return IFACE_("Level Set");
590 }
591 return IFACE_("Unknown");
592 }));
593 }
594#else
595 UNUSED_VARS(column_id);
596#endif
597
598 return {};
599}
600
602{
603 const Volume *volume = component_->get();
604 if (volume == nullptr) {
605 return 0;
606 }
607 return BKE_volume_num_grids(volume);
608}
609
611{
612 switch (reference.type()) {
614 const Object &object = reference.object();
615 return ED_outliner_icon_from_id(object.id);
616 }
618 return ICON_OUTLINER_COLLECTION;
619 }
621 return ICON_GEOMETRY_SET;
622 }
624 break;
625 }
626 }
627 return ICON_NONE;
628}
629
631 Object *object_eval)
632{
633 bke::GeometrySet geometry_set;
635 const Object *object_orig = DEG_get_original(object_eval);
636 if (object_orig->type == OB_MESH) {
637 const Mesh *mesh = static_cast<const Mesh *>(object_orig->data);
638 if (object_orig->mode == OB_MODE_EDIT) {
639 if (const BMEditMesh *em = mesh->runtime->edit_mesh.get()) {
640 Mesh *new_mesh = BKE_id_new_nomain<Mesh>(nullptr);
641 /* This is a potentially heavy operation to do on every redraw. The best solution here is
642 * to display the data directly from the bmesh without a conversion, which can be
643 * implemented a bit later. */
644 BM_mesh_bm_to_me_for_eval(*em->bm, *new_mesh, nullptr);
645 geometry_set.replace_mesh(new_mesh, bke::GeometryOwnershipType::Owned);
646 }
647 }
648 else {
649 geometry_set.replace_mesh(const_cast<Mesh *>(mesh), bke::GeometryOwnershipType::ReadOnly);
650 }
651 }
652 else if (object_orig->type == OB_POINTCLOUD) {
653 const PointCloud *pointcloud = static_cast<const PointCloud *>(object_orig->data);
654 geometry_set.replace_pointcloud(const_cast<PointCloud *>(pointcloud),
656 }
657 else if (object_orig->type == OB_CURVES) {
658 const Curves &curves_id = *static_cast<const Curves *>(object_orig->data);
659 geometry_set.replace_curves(&const_cast<Curves &>(curves_id),
661 }
662 else if (object_orig->type == OB_GREASE_PENCIL) {
663 const GreasePencil &grease_pencil = *static_cast<const GreasePencil *>(object_orig->data);
664 geometry_set.replace_grease_pencil(&const_cast<GreasePencil &>(grease_pencil),
666 }
667 }
668 else {
670 geometry_set = bke::object_get_evaluated_geometry_set(*object_eval);
671 }
672 else {
673 if (const ViewerNodeLog *viewer_log =
675 sspreadsheet->geometry_id.viewer_path))
676 {
677 geometry_set = viewer_log->geometry;
678 }
679 }
680 }
681 return geometry_set;
682}
683
685 const Span<SpreadsheetInstanceID> instance_ids)
686{
687 bke::GeometrySet geometry = root_geometry;
688 for (const SpreadsheetInstanceID &instance_id : instance_ids) {
689 const bke::Instances *instances = geometry.get_instances();
690 if (!instances) {
691 /* Return the best available geometry. */
692 return geometry;
693 }
694 const Span<bke::InstanceReference> references = instances->references();
695 if (instance_id.reference_index < 0 || instance_id.reference_index >= references.size()) {
696 /* Return the best available geometry. */
697 return geometry;
698 }
699 const bke::InstanceReference &reference = references[instance_id.reference_index];
700 bke::GeometrySet reference_geometry;
701 reference.to_geometry_set(reference_geometry);
702 geometry = reference_geometry;
703 }
704 return geometry;
705}
706
707std::unique_ptr<DataSource> data_source_from_geometry(const bContext *C, Object *object_eval)
708{
710
711 const bke::GeometrySet root_geometry_set = spreadsheet_get_display_geometry_set(sspreadsheet,
712 object_eval);
714 root_geometry_set,
715 Span{sspreadsheet->geometry_id.instance_ids, sspreadsheet->geometry_id.instance_ids_num});
716
717 const bke::AttrDomain domain = (bke::AttrDomain)sspreadsheet->geometry_id.attribute_domain;
718 const auto component_type = bke::GeometryComponent::Type(
720 const int layer_index = sspreadsheet->geometry_id.layer_index;
721 if (!geometry_set.has(component_type)) {
722 return {};
723 }
724
725 if (component_type == bke::GeometryComponent::Type::Volume) {
726 return std::make_unique<VolumeDataSource>(std::move(geometry_set));
727 }
728 Object *object_orig = sspreadsheet->geometry_id.instance_ids_num == 0 ?
729 DEG_get_original(object_eval) :
730 nullptr;
731 return std::make_unique<GeometryDataSource>(object_orig,
732 std::move(geometry_set),
733 component_type,
734 domain,
735 sspreadsheet->flag &
737 layer_index);
738}
739
740} // 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:1500
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:93
#define BLI_assert(a)
Definition BLI_assert.h:46
void void BLI_INLINE bool BLI_listbase_is_single(const ListBase *lb)
#define UNUSED_VARS(...)
#define ELEM(...)
#define STREQ(a, b)
#define IFACE_(msgid)
T * DEG_get_original(T *id)
@ OB_MODE_EDIT
@ OB_MODE_SCULPT_CURVES
@ OB_GREASE_PENCIL
@ OB_MESH
@ OB_POINTCLOUD
@ OB_CURVES
@ SPREADSHEET_OBJECT_EVAL_STATE_ORIGINAL
@ SPREADSHEET_FLAG_SHOW_INTERNAL_ATTRIBUTES
int ED_outliner_icon_from_id(const ID &id)
#define C
Definition RandGen.cpp:29
volatile int lock
@ BM_ELEM_SELECT
#define BM_elem_flag_test_bool(ele, hflag)
BMesh const char void * data
BMesh * bm
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
BLI_INLINE BMEdge * BM_edge_at_index(BMesh *bm, const int index)
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
BLI_INLINE BMFace * BM_face_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_FACE
#define BM_EDGE
#define BM_VERT
long long int int64_t
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
AttributeSet attributes
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
constexpr int64_t size() const
constexpr int64_t size() const
Definition BLI_span.hh:252
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
int domain_size(const AttrDomain domain) const
void to_geometry_set(GeometrySet &r_geometry_set) const
Definition instances.cc:93
Span< InstanceReference > references() const
Definition instances.cc:285
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
void to_bools(MutableSpan< bool > r_bools) const
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)
GeometrySet object_get_evaluated_geometry_set(const Object &object, bool apply_subdiv=true)
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)
static IndexMask calc_mesh_selection_mask_faces(const Mesh &mesh_eval, const Mesh &mesh_orig, IndexMaskMemory &memory)
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 IndexMask calc_mesh_selection_mask(const Mesh &mesh_eval, const Mesh &mesh_orig, const bke::AttrDomain domain, IndexMaskMemory &memory)
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)
uint64_t get_default_hash(const T &v, const Args &...args)
Definition BLI_hash.hh:233
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:25
bool operator!=(const SpreadsheetInstanceID &a, const SpreadsheetInstanceID &b)
bool operator==(const SpreadsheetInstanceID &a, const SpreadsheetInstanceID &b)
CustomData edge_data
int edges_num
MeshRuntimeHandle * runtime
CustomData face_data
CustomData vert_data
int faces_num
int verts_num
SpreadsheetTableIDGeometry geometry_id
SpreadsheetInstanceID * instance_ids
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)
i
Definition text_draw.cc:230