1
1

Compare commits

...

3 Commits

Author SHA1 Message Date
e8e9ad92ed Add position, rotation, scale attributes to instances 2021-03-16 22:41:37 -04:00
8390ffc155 Merge branch 'master' into temp-geometry-nodes-instances-attributes 2021-03-16 21:58:36 -04:00
ea47e50017 WIP: Add instances data to spreadsheets
This commit does not currently compile, I'm pushing it so I can
continue work on another computer.
2021-03-16 17:21:47 -04:00
4 changed files with 167 additions and 1 deletions

View File

@@ -452,7 +452,12 @@ class InstancesComponent : public GeometryComponent {
bool is_empty() const final;
int attribute_domain_size(const AttributeDomain domain) const final;
static constexpr inline GeometryComponentType static_type = GEO_COMPONENT_TYPE_INSTANCES;
private:
const blender::bke::ComponentAttributeProviders *get_attribute_providers() const final;
};
/** A geometry component that stores volume grids. */

View File

@@ -14,6 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "BLI_float3.hh"
#include "BLI_float4x4.hh"
#include "BLI_map.hh"
#include "BLI_rand.hh"
@@ -23,13 +24,18 @@
#include "DNA_collection_types.h"
#include "BKE_attribute_access.hh"
#include "BKE_geometry_set.hh"
#include "attribute_access_intern.hh"
using blender::float3;
using blender::float4x4;
using blender::Map;
using blender::MutableSpan;
using blender::Set;
using blender::Span;
using blender::bke::ReadAttributePtr;
/* -------------------------------------------------------------------- */
/** \name Geometry Component Implementation
@@ -171,3 +177,132 @@ blender::Span<int> InstancesComponent::almost_unique_ids() const
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Attribute Access
* \{ */
int InstancesComponent::attribute_domain_size(const AttributeDomain domain) const
{
BLI_assert(this->attribute_domain_supported(domain));
switch (domain) {
case ATTR_DOMAIN_POINT:
return this->instances_amount();
default:
BLI_assert(false);
break;
}
return 0;
}
namespace blender::bke {
static float3 get_matrix_position(const float4x4 &matrix)
{
return matrix.translation();
}
static void set_matrix_position(float4x4 &matrix, const float3 &translation)
{
copy_v3_v3(matrix.ptr()[3], translation);
}
static float3 get_matrix_rotation(const float4x4 &matrix)
{
return matrix.to_euler();
}
static void set_matrix_rotation(float4x4 &matrix, const float3 &rotation)
{
float4x4 rotation_matrix;
loc_eul_size_to_mat4(rotation_matrix.values, float3(0), rotation, float3(1));
matrix = matrix * rotation_matrix;
}
static float3 get_matrix_scale(const float4x4 &matrix)
{
return matrix.scale();
}
static void set_matrix_scale(float4x4 &matrix, const float3 &scale)
{
float4x4 scale_matrix;
size_to_mat4(scale_matrix.values, scale);
matrix = matrix * scale_matrix;
}
template<float3 (*GetFunc)(const float4x4 &), void (*SetFunc)(float4x4 &, const float3 &)>
class Float4x4AttributeProvider final : public BuiltinAttributeProvider {
public:
Float4x4AttributeProvider(std::string attribute_name)
: BuiltinAttributeProvider(std::move(attribute_name),
ATTR_DOMAIN_POINT,
CD_PROP_FLOAT3,
NonCreatable,
Writable,
NonDeletable)
{
}
ReadAttributePtr try_get_for_read(const GeometryComponent &component) const final
{
const InstancesComponent &instances_component = static_cast<const InstancesComponent &>(
component);
if (instances_component.instances_amount() == 0) {
return {};
}
return std::make_unique<DerivedArrayReadAttribute<float4x4, float3, GetFunc>>(
ATTR_DOMAIN_POINT, instances_component.transforms());
}
WriteAttributePtr try_get_for_write(GeometryComponent &component) const final
{
InstancesComponent &instances_component = static_cast<InstancesComponent &>(component);
if (instances_component.instances_amount() == 0) {
return {};
}
return std::make_unique<DerivedArrayWriteAttribute<float4x4, float3, GetFunc, SetFunc>>(
ATTR_DOMAIN_POINT, instances_component.transforms());
}
bool try_delete(GeometryComponent &UNUSED(component)) const final
{
return false;
}
bool try_create(GeometryComponent &UNUSED(component)) const final
{
return false;
}
bool exists(const GeometryComponent &component) const final
{
return component.attribute_domain_size(ATTR_DOMAIN_POINT) != 0;
}
};
/**
* In this function all the attribute providers for the instances component are created. Most data
* in this function is statically allocated, because it does not change over time.
*/
static ComponentAttributeProviders create_attribute_providers_for_instances()
{
static Float4x4AttributeProvider<get_matrix_position, set_matrix_position> position("position");
static Float4x4AttributeProvider<get_matrix_rotation, set_matrix_rotation> rotation("rotation");
static Float4x4AttributeProvider<get_matrix_scale, set_matrix_scale> scale("scale");
return ComponentAttributeProviders({&position, &rotation, &scale}, {});
}
} // namespace blender::bke
const blender::bke::ComponentAttributeProviders *InstancesComponent::get_attribute_providers()
const
{
static blender::bke::ComponentAttributeProviders providers =
blender::bke::create_attribute_providers_for_instances();
return &providers;
}
/** \} */

View File

@@ -79,6 +79,25 @@ struct float4x4 {
return m * float3(v);
}
float3 translation() const
{
return float3(values[3]);
}
float3 to_euler() const
{
float3 euler;
mat4_to_eul(euler, values);
return euler;
}
float3 scale() const
{
float3 scale;
mat4_to_size(scale, values);
return scale;
}
float4x4 inverted() const
{
float4x4 result;

View File

@@ -3044,7 +3044,9 @@ static void rna_SpaceSpreadsheet_geometry_component_type_update(Main *UNUSED(bma
PointerRNA *ptr)
{
SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)ptr->data;
if (sspreadsheet->geometry_component_type == GEO_COMPONENT_TYPE_POINT_CLOUD) {
if (ELEM(sspreadsheet->geometry_component_type,
GEO_COMPONENT_TYPE_POINT_CLOUD,
GEO_COMPONENT_TYPE_INSTANCES)) {
sspreadsheet->attribute_domain = ATTR_DOMAIN_POINT;
}
}
@@ -7320,6 +7322,11 @@ static void rna_def_space_spreadsheet(BlenderRNA *brna)
ICON_POINTCLOUD_DATA,
"Point Cloud",
"Point cloud component containing only point data"},
{GEO_COMPONENT_TYPE_INSTANCES,
"INSTANCES",
ICON_EMPTY_AXIS,
"Instances",
"Instances of objects or collections"},
{0, NULL, 0, NULL, NULL},
};