Spreadsheet: Display geometry volume component grids
This shows a geometry's volume grids in the spreadsheet. Three columns are displayed: - Name: The text name of each grid - Data type: Float, Vector, etc. - Class: Fog volume, Level Set, or unkown In the future, values of the voxels themselves could be displayed, but that is a much more complex problem, with important performance implications, etc. Differential Revision: https://developer.blender.org/D13049
This commit is contained in:
parent
4e5537d841
commit
ccead2ed9c
Notes:
blender-bot
2023-02-14 07:39:44 +01:00
Referenced by commit 978ef093db
, Cleanup: fix compiler warnings
Referenced by issue #92950, spreadsheet showing 0 instances when there are instances:
|
@ -67,4 +67,14 @@ set(SRC
|
|||
set(LIB
|
||||
)
|
||||
|
||||
if(WITH_OPENVDB)
|
||||
list(APPEND INC_SYS
|
||||
${OPENVDB_INCLUDE_DIRS}
|
||||
)
|
||||
list(APPEND LIB
|
||||
${OPENVDB_LIBRARIES}
|
||||
)
|
||||
add_definitions(-DWITH_OPENVDB ${OPENVDB_DEFINITIONS})
|
||||
endif()
|
||||
|
||||
blender_add_lib(bf_editor_space_spreadsheet "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
|
|
@ -58,6 +58,7 @@ class CellValue {
|
|||
std::optional<ObjectCellValue> value_object;
|
||||
std::optional<CollectionCellValue> value_collection;
|
||||
std::optional<GeometrySetCellValue> value_geometry_set;
|
||||
std::optional<std::string> value_string;
|
||||
};
|
||||
|
||||
} // namespace blender::ed::spreadsheet
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh_wrapper.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_volume.h"
|
||||
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
|
@ -33,6 +34,11 @@
|
|||
|
||||
#include "NOD_geometry_nodes_eval_log.hh"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_enum_types.h"
|
||||
|
||||
#include "FN_field_cpp_type.hh"
|
||||
|
||||
#include "bmesh.h"
|
||||
|
@ -112,6 +118,9 @@ std::unique_ptr<ColumnValues> ExtraColumns::get_column_values(
|
|||
r_cell_value.value_color = *(
|
||||
const ColorGeometry4f *)value;
|
||||
break;
|
||||
case SPREADSHEET_VALUE_TYPE_STRING:
|
||||
r_cell_value.value_string = *(const std::string *)value;
|
||||
break;
|
||||
case SPREADSHEET_VALUE_TYPE_INSTANCES:
|
||||
break;
|
||||
}
|
||||
|
@ -487,6 +496,89 @@ int InstancesDataSource::tot_rows() const
|
|||
return component_->instances_amount();
|
||||
}
|
||||
|
||||
void VolumeDataSource::foreach_default_column_ids(
|
||||
FunctionRef<void(const SpreadsheetColumnID &, bool is_extra)> fn) const
|
||||
{
|
||||
if (component_->is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const char *name : {"Grid Name", "Data Type", "Class"}) {
|
||||
SpreadsheetColumnID column_id{(char *)name};
|
||||
fn(column_id, false);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<ColumnValues> VolumeDataSource::get_column_values(
|
||||
const SpreadsheetColumnID &column_id) const
|
||||
{
|
||||
const Volume *volume = component_->get_for_read();
|
||||
if (volume == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
const int size = this->tot_rows();
|
||||
if (STREQ(column_id.name, "Grid Name")) {
|
||||
return column_values_from_function(
|
||||
SPREADSHEET_VALUE_TYPE_STRING,
|
||||
IFACE_("Grid Name"),
|
||||
size,
|
||||
[volume](int index, CellValue &r_cell_value) {
|
||||
const VolumeGrid *volume_grid = BKE_volume_grid_get_for_read(volume, index);
|
||||
r_cell_value.value_string = BKE_volume_grid_name(volume_grid);
|
||||
},
|
||||
6.0f);
|
||||
}
|
||||
if (STREQ(column_id.name, "Data Type")) {
|
||||
return column_values_from_function(
|
||||
SPREADSHEET_VALUE_TYPE_STRING,
|
||||
IFACE_("Type"),
|
||||
size,
|
||||
[volume](int index, CellValue &r_cell_value) {
|
||||
const VolumeGrid *volume_grid = BKE_volume_grid_get_for_read(volume, index);
|
||||
const VolumeGridType type = BKE_volume_grid_type(volume_grid);
|
||||
const char *name = nullptr;
|
||||
RNA_enum_name_from_value(rna_enum_volume_grid_data_type_items, type, &name);
|
||||
r_cell_value.value_string = IFACE_(name);
|
||||
},
|
||||
5.0f);
|
||||
}
|
||||
if (STREQ(column_id.name, "Class")) {
|
||||
return column_values_from_function(
|
||||
SPREADSHEET_VALUE_TYPE_STRING,
|
||||
IFACE_("Class"),
|
||||
size,
|
||||
[volume](int index, CellValue &r_cell_value) {
|
||||
const VolumeGrid *volume_grid = BKE_volume_grid_get_for_read(volume, index);
|
||||
openvdb::GridBase::ConstPtr grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
|
||||
openvdb::GridClass grid_class = grid->getGridClass();
|
||||
if (grid_class == openvdb::GridClass::GRID_FOG_VOLUME) {
|
||||
r_cell_value.value_string = IFACE_("Fog Volume");
|
||||
}
|
||||
else if (grid_class == openvdb::GridClass::GRID_LEVEL_SET) {
|
||||
r_cell_value.value_string = IFACE_("Level Set");
|
||||
}
|
||||
else {
|
||||
r_cell_value.value_string = IFACE_("Unkown");
|
||||
}
|
||||
},
|
||||
5.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
int VolumeDataSource::tot_rows() const
|
||||
{
|
||||
const Volume *volume = component_->get_for_read();
|
||||
if (volume == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return BKE_volume_num_grids(volume);
|
||||
}
|
||||
|
||||
GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspreadsheet,
|
||||
Object *object_eval,
|
||||
const GeometryComponentType used_component_type)
|
||||
|
@ -682,6 +774,9 @@ std::unique_ptr<DataSource> data_source_from_geometry(const bContext *C, Object
|
|||
if (component_type == GEO_COMPONENT_TYPE_INSTANCES) {
|
||||
return std::make_unique<InstancesDataSource>(geometry_set, std::move(extra_columns));
|
||||
}
|
||||
if (component_type == GEO_COMPONENT_TYPE_VOLUME) {
|
||||
return std::make_unique<VolumeDataSource>(geometry_set);
|
||||
}
|
||||
return std::make_unique<GeometryDataSource>(
|
||||
object_eval, geometry_set, component_type, domain, std::move(extra_columns));
|
||||
}
|
||||
|
|
|
@ -116,6 +116,26 @@ class InstancesDataSource : public DataSource {
|
|||
int tot_rows() const override;
|
||||
};
|
||||
|
||||
class VolumeDataSource : public DataSource {
|
||||
const GeometrySet geometry_set_;
|
||||
const VolumeComponent *component_;
|
||||
|
||||
public:
|
||||
VolumeDataSource(GeometrySet geometry_set)
|
||||
: geometry_set_(std::move(geometry_set)),
|
||||
component_(geometry_set_.get_component_for_read<VolumeComponent>())
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
int tot_rows() const override;
|
||||
};
|
||||
|
||||
std::unique_ptr<DataSource> data_source_from_geometry(const bContext *C, Object *object_eval);
|
||||
|
||||
} // namespace blender::ed::spreadsheet
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_volume.h"
|
||||
|
||||
#include "BLF_api.h"
|
||||
|
||||
|
@ -48,7 +49,7 @@ static int is_component_row_selected(struct uiBut *but, const void *arg)
|
|||
const bool is_domain_selected = (AttributeDomain)sspreadsheet->attribute_domain == domain;
|
||||
bool is_selected = is_component_selected && is_domain_selected;
|
||||
|
||||
if (component == GEO_COMPONENT_TYPE_INSTANCES) {
|
||||
if (ELEM(component, GEO_COMPONENT_TYPE_VOLUME, GEO_COMPONENT_TYPE_INSTANCES)) {
|
||||
is_selected = is_component_selected;
|
||||
}
|
||||
|
||||
|
@ -141,6 +142,14 @@ static int element_count_from_instances(const GeometrySet &geometry_set)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int element_count_from_volume(const GeometrySet &geometry_set)
|
||||
{
|
||||
if (const Volume *volume = geometry_set.get_volume_for_read()) {
|
||||
return BKE_volume_num_grids(volume);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int element_count_from_component_domain(const GeometrySet &geometry_set,
|
||||
GeometryComponentType component,
|
||||
AttributeDomain domain)
|
||||
|
@ -191,6 +200,10 @@ void DatasetRegionDrawer::draw_dataset_row(const int indentation,
|
|||
BLI_str_format_attribute_domain_size(
|
||||
element_count, element_count_from_instances(draw_context.current_geometry_set));
|
||||
}
|
||||
if (component == GEO_COMPONENT_TYPE_VOLUME) {
|
||||
BLI_str_format_attribute_domain_size(
|
||||
element_count, element_count_from_volume(draw_context.current_geometry_set));
|
||||
}
|
||||
else {
|
||||
BLI_str_format_attribute_domain_size(
|
||||
element_count,
|
||||
|
@ -237,7 +250,7 @@ void DatasetRegionDrawer::draw_dataset_row(const int indentation,
|
|||
|
||||
void DatasetRegionDrawer::draw_component_row(const DatasetComponentLayoutInfo &component_info)
|
||||
{
|
||||
if (component_info.type == GEO_COMPONENT_TYPE_INSTANCES) {
|
||||
if (ELEM(component_info.type, GEO_COMPONENT_TYPE_VOLUME, GEO_COMPONENT_TYPE_INSTANCES)) {
|
||||
draw_dataset_row(
|
||||
0, component_info.type, std::nullopt, component_info.icon, component_info.label, true);
|
||||
}
|
||||
|
|
|
@ -74,6 +74,12 @@ constexpr DatasetComponentLayoutInfo DATASET_layout_hierarchy[] = {
|
|||
ATTR_INFO(ATTR_DOMAIN_POINT, N_("Point"), ICON_PARTICLE_POINT),
|
||||
},
|
||||
},
|
||||
{
|
||||
GEO_COMPONENT_TYPE_VOLUME,
|
||||
N_("Volume Grids"),
|
||||
ICON_VOLUME_DATA,
|
||||
{},
|
||||
},
|
||||
{
|
||||
GEO_COMPONENT_TYPE_INSTANCES,
|
||||
N_("Instances"),
|
||||
|
|
|
@ -228,6 +228,23 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer {
|
|||
0,
|
||||
nullptr);
|
||||
}
|
||||
else if (cell_value.value_string.has_value()) {
|
||||
uiDefIconTextBut(params.block,
|
||||
UI_BTYPE_LABEL,
|
||||
0,
|
||||
ICON_NONE,
|
||||
cell_value.value_string->c_str(),
|
||||
params.xmin,
|
||||
params.ymin,
|
||||
params.width,
|
||||
params.height,
|
||||
nullptr,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_float_vector(const CellDrawParams ¶ms, const Span<float> values) const
|
||||
|
|
|
@ -2006,6 +2006,7 @@ typedef enum eSpreadsheetColumnValueType {
|
|||
SPREADSHEET_VALUE_TYPE_FLOAT3 = 4,
|
||||
SPREADSHEET_VALUE_TYPE_COLOR = 5,
|
||||
SPREADSHEET_VALUE_TYPE_INSTANCES = 6,
|
||||
SPREADSHEET_VALUE_TYPE_STRING = 7,
|
||||
} eSpreadsheetColumnValueType;
|
||||
|
||||
/**
|
||||
|
|
|
@ -211,6 +211,8 @@ DEF_ENUM(rna_enum_attribute_domain_items)
|
|||
DEF_ENUM(rna_enum_attribute_domain_without_corner_items)
|
||||
DEF_ENUM(rna_enum_attribute_domain_with_auto_items)
|
||||
|
||||
DEF_ENUM(rna_enum_volume_grid_data_type_items)
|
||||
|
||||
DEF_ENUM(rna_enum_collection_color_items)
|
||||
DEF_ENUM(rna_enum_strip_color_items)
|
||||
|
||||
|
|
|
@ -33,6 +33,26 @@
|
|||
|
||||
#include "BLI_math_base.h"
|
||||
|
||||
const EnumPropertyItem rna_enum_volume_grid_data_type_items[] = {
|
||||
{VOLUME_GRID_BOOLEAN, "BOOLEAN", 0, "Boolean", "Boolean"},
|
||||
{VOLUME_GRID_FLOAT, "FLOAT", 0, "Float", "Single precision float"},
|
||||
{VOLUME_GRID_DOUBLE, "DOUBLE", 0, "Double", "Double precision"},
|
||||
{VOLUME_GRID_INT, "INT", 0, "Integer", "32-bit integer"},
|
||||
{VOLUME_GRID_INT64, "INT64", 0, "Integer 64-bit", "64-bit integer"},
|
||||
{VOLUME_GRID_MASK, "MASK", 0, "Mask", "No data, boolean mask of active voxels"},
|
||||
{VOLUME_GRID_STRING, "STRING", 0, "String", "Text string"},
|
||||
{VOLUME_GRID_VECTOR_FLOAT, "VECTOR_FLOAT", 0, "Float Vector", "3D float vector"},
|
||||
{VOLUME_GRID_VECTOR_DOUBLE, "VECTOR_DOUBLE", 0, "Double Vector", "3D double vector"},
|
||||
{VOLUME_GRID_VECTOR_INT, "VECTOR_INT", 0, "Integer Vector", "3D integer vector"},
|
||||
{VOLUME_GRID_POINTS,
|
||||
"POINTS",
|
||||
0,
|
||||
"Points (Unsupported)",
|
||||
"Points grid, currently unsupported by volume objects"},
|
||||
{VOLUME_GRID_UNKNOWN, "UNKNOWN", 0, "Unknown", "Unsupported data type"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
# include "DEG_depsgraph.h"
|
||||
|
@ -244,30 +264,10 @@ static void rna_def_volume_grid(BlenderRNA *brna)
|
|||
prop, "rna_VolumeGrid_name_get", "rna_VolumeGrid_name_length", NULL);
|
||||
RNA_def_property_ui_text(prop, "Name", "Volume grid name");
|
||||
|
||||
static const EnumPropertyItem data_type_items[] = {
|
||||
{VOLUME_GRID_BOOLEAN, "BOOLEAN", 0, "Boolean", "Boolean"},
|
||||
{VOLUME_GRID_FLOAT, "FLOAT", 0, "Float", "Single precision float"},
|
||||
{VOLUME_GRID_DOUBLE, "DOUBLE", 0, "Double", "Double precision"},
|
||||
{VOLUME_GRID_INT, "INT", 0, "Integer", "32-bit integer"},
|
||||
{VOLUME_GRID_INT64, "INT64", 0, "Integer 64-bit", "64-bit integer"},
|
||||
{VOLUME_GRID_MASK, "MASK", 0, "Mask", "No data, boolean mask of active voxels"},
|
||||
{VOLUME_GRID_STRING, "STRING", 0, "String", "Text string"},
|
||||
{VOLUME_GRID_VECTOR_FLOAT, "VECTOR_FLOAT", 0, "Float Vector", "3D float vector"},
|
||||
{VOLUME_GRID_VECTOR_DOUBLE, "VECTOR_DOUBLE", 0, "Double Vector", "3D double vector"},
|
||||
{VOLUME_GRID_VECTOR_INT, "VECTOR_INT", 0, "Integer Vector", "3D integer vector"},
|
||||
{VOLUME_GRID_POINTS,
|
||||
"POINTS",
|
||||
0,
|
||||
"Points (Unsupported)",
|
||||
"Points grid, currently unsupported by volume objects"},
|
||||
{VOLUME_GRID_UNKNOWN, "UNKNOWN", 0, "Unknown", "Unsupported data type"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_enum_funcs(prop, "rna_VolumeGrid_data_type_get", NULL, NULL);
|
||||
RNA_def_property_enum_items(prop, data_type_items);
|
||||
RNA_def_property_enum_items(prop, rna_enum_volume_grid_data_type_items);
|
||||
RNA_def_property_ui_text(prop, "Data Type", "Data type of voxel values");
|
||||
|
||||
prop = RNA_def_property(srna, "channels", PROP_INT, PROP_UNSIGNED);
|
||||
|
|
Loading…
Reference in New Issue