WIP: Geometry Nodes: A Modeling Approach of Gizmo #108744

Closed
Iliya Katushenock wants to merge 29 commits from mod_moder:gizmos_bke_component into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
14 changed files with 163 additions and 66 deletions
Showing only changes of commit 998fb19c41 - Show all commits

View File

@ -620,6 +620,17 @@ class NODE_MT_category_GEO_VOLUME(Menu):
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_category_GEO_GIZMOS(Menu):
bl_idname = "NODE_MT_category_GEO_GIZMOS"
bl_label = "Gizmos"
bl_translation_context = i18n_contexts.id_id
def draw(self, context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeArrowGizmo")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_category_GEO_GROUP(Menu):
bl_idname = "NODE_MT_category_GEO_GROUP"
bl_label = "Group"
@ -658,6 +669,7 @@ class NODE_MT_geometry_node_add_all(Menu):
layout.menu("NODE_MT_geometry_node_GEO_MESH")
layout.menu("NODE_MT_category_GEO_POINT")
layout.menu("NODE_MT_category_GEO_VOLUME")
layout.menu("NODE_MT_category_GEO_GIZMOS")
layout.separator()
layout.menu("NODE_MT_category_simulation")
layout.separator()
@ -702,6 +714,7 @@ classes = (
NODE_MT_category_GEO_POINT,
NODE_MT_category_simulation,
NODE_MT_category_GEO_VOLUME,
NODE_MT_category_GEO_GIZMOS,
NODE_MT_geometry_node_GEO_MATERIAL,
NODE_MT_category_GEO_TEXTURE,
NODE_MT_category_GEO_UTILITIES,

View File

@ -39,6 +39,7 @@ namespace blender::bke {
class ComponentAttributeProviders;
class CurvesEditHints;
class Instances;
class GizmosGeometry;
} // namespace blender::bke
class GeometryComponent;
@ -243,6 +244,10 @@ struct GeometrySet {
*/
static GeometrySet create_with_pointcloud(
PointCloud *pointcloud, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
static GeometrySet create_with_gizmos(
blender::bke::GizmosGeometry *gizmos,
GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
/**
* Create a new geometry set that only contains the given curves.
*/
@ -651,7 +656,8 @@ class GeometryComponentEditData final : public GeometryComponent {
/**
* A geometry component that stores a gizmo points.
*
* This component is taked at the finishing of modifier evaluation and storend in COW object runtime.
* This component is taked at the finishing of modifier evaluation and storend in COW object
* runtime.
*/
class GizmosComponent : public GeometryComponent {
private:
@ -661,11 +667,14 @@ class GizmosComponent : public GeometryComponent {
public:
GizmosComponent();
~GizmosComponent();
GizmosComponent *copy() const override;
GeometryComponent *copy() const final;
void clear() override;
bool has_gizmos() const;
void replace(blender::bke::GizmosGeometry *gizmos,
GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
const blender::bke::GizmosGeometry *get_for_read() const;
blender::bke::GizmosGeometry *get_for_write();

View File

@ -4,6 +4,8 @@
#pragma once
#include "BLI_vector_set.hh"
#include "BKE_attribute.hh"
namespace blender::bke {
@ -17,8 +19,9 @@ class GizmosGeometry {
public:
GizmosGeometry() = default;
//GizmosGeometry(int pathes, int gizmos);
//GizmosGeometry(const GizmosGeometry &other);
GizmosGeometry(std::string);
// GizmosGeometry(int pathes, int gizmos);
// GizmosGeometry(const GizmosGeometry &other);
GizmosGeometry *copy() const;
@ -28,7 +31,8 @@ class GizmosGeometry {
int gizmos_num() const;
/**
* Remove the indices that are not contained in the mask input, and remove unused pathes afterwards.
* Remove the indices that are not contained in the mask input, and remove unused pathes
* afterwards.
*/
void remove(const blender::IndexMask &mask,
const blender::bke::AnonymousAttributePropagationInfo &propagation_info);
@ -40,4 +44,14 @@ class GizmosGeometry {
const CustomDataAttributes &custom_data_attributes() const;
};
inline CustomDataAttributes &GizmosGeometry::custom_data_attributes()
{
return attributes_;
}
inline const CustomDataAttributes &GizmosGeometry::custom_data_attributes() const
{
return attributes_;
}
} // namespace blender::bke

View File

@ -142,9 +142,11 @@ set(SRC
intern/geometry_component_mesh.cc
intern/geometry_component_pointcloud.cc
intern/geometry_component_volume.cc
intern/geometry_component_gizmos.cc
intern/geometry_fields.cc
intern/geometry_set.cc
intern/geometry_set_instances.cc
intern/gizmos.cc
intern/gpencil_curve_legacy.c
intern/gpencil_geom_legacy.cc
intern/gpencil_legacy.c

View File

@ -2,6 +2,13 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BKE_geometry_set.hh"
#include "attribute_access_intern.hh"
/* -------------------------------------------------------------------- */
/** \name Geometry Component Implementation
* \{ */
GizmosComponent::GizmosComponent() : GeometryComponent(GEO_COMPONENT_TYPE_GIZMO) {}
GizmosComponent::~GizmosComponent()
@ -29,18 +36,26 @@ void GizmosComponent::clear()
gizmos_ = nullptr;
}
}
void GizmosComponent::replace(blender::bke::GizmosGeometry *gizmos,
GeometryOwnershipType ownership)
{
BLI_assert(this->is_mutable());
this->clear();
gizmos_ = gizmos;
ownership_ = ownership;
}
bool GizmosComponent::has_gizmos() const
{
return gizmos_ != nullptr;
}
const PointCloud *GizmosComponent::get_for_read() const
const blender::bke::GizmosGeometry *GizmosComponent::get_for_read() const
{
return pointcloud_;
return gizmos_;
}
PointCloud *GizmosComponent::get_for_write()
blender::bke::GizmosGeometry *GizmosComponent::get_for_write()
{
BLI_assert(this->is_mutable());
if (ownership_ == GeometryOwnershipType::ReadOnly) {
@ -77,36 +92,20 @@ void GizmosComponent::ensure_owns_direct_data()
namespace blender::bke {
static void tag_component_positions_changed(void *owner)
static ComponentAttributeProviders create_attribute_providers_for_gizmos()
{
PointCloud &points = *static_cast<PointCloud *>(owner);
points.tag_positions_changed();
}
static void tag_component_radius_changed(void *owner)
{
PointCloud &points = *static_cast<PointCloud *>(owner);
points.tag_radii_changed();
}
/**
* In this function all the attribute providers for a point cloud component are created. Most data
* in this function is statically allocated, because it does not change over time.
*/
static ComponentAttributeProviders create_attribute_providers_for_point_cloud()
{
static CustomDataAccessInfo point_access = {
static CustomDataAccessInfo gizmos_access = {
[](void *owner) -> CustomData * {
PointCloud *pointcloud = static_cast<PointCloud *>(owner);
return &pointcloud->pdata;
GizmosGeometry *gizmos = static_cast<GizmosGeometry *>(owner);
return &gizmos->custom_data_attributes().data;
},
[](const void *owner) -> const CustomData * {
const PointCloud *pointcloud = static_cast<const PointCloud *>(owner);
return &pointcloud->pdata;
const GizmosGeometry *gizmos = static_cast<const GizmosGeometry *>(owner);
return &gizmos->custom_data_attributes().data;
},
[](const void *owner) -> int {
const PointCloud *pointcloud = static_cast<const PointCloud *>(owner);
return pointcloud->totpoint;
const GizmosGeometry *gizmos = static_cast<const GizmosGeometry *>(owner);
return gizmos->gizmos_num();
}};
static BuiltinCustomDataLayerProvider position("position",
@ -115,42 +114,33 @@ static ComponentAttributeProviders create_attribute_providers_for_point_cloud()
CD_PROP_FLOAT3,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::NonDeletable,
point_access,
tag_component_positions_changed);
static BuiltinCustomDataLayerProvider radius("radius",
ATTR_DOMAIN_POINT,
CD_PROP_FLOAT,
CD_PROP_FLOAT,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
point_access,
tag_component_radius_changed);
gizmos_access,
nullptr);
static BuiltinCustomDataLayerProvider id("id",
ATTR_DOMAIN_POINT,
CD_PROP_INT32,
CD_PROP_INT32,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
point_access,
gizmos_access,
nullptr);
static CustomDataAttributeProvider point_custom_data(ATTR_DOMAIN_POINT, point_access);
return ComponentAttributeProviders({&position, &radius, &id}, {&point_custom_data});
static CustomDataAttributeProvider gizmos_custom_data(ATTR_DOMAIN_POINT, gizmos_access);
return ComponentAttributeProviders({&position, &id}, {&gizmos_custom_data});
}
static AttributeAccessorFunctions get_pointcloud_accessor_functions()
static AttributeAccessorFunctions get_gizmos_accessor_functions()
{
static const ComponentAttributeProviders providers =
create_attribute_providers_for_point_cloud();
static const ComponentAttributeProviders providers = create_attribute_providers_for_gizmos();
AttributeAccessorFunctions fn =
attribute_accessor_functions::accessor_functions_for_providers<providers>();
fn.domain_size = [](const void *owner, const eAttrDomain domain) {
if (owner == nullptr) {
return 0;
}
const PointCloud &pointcloud = *static_cast<const PointCloud *>(owner);
const GizmosGeometry &gizmos = *static_cast<const GizmosGeometry *>(owner);
switch (domain) {
case ATTR_DOMAIN_POINT:
return pointcloud.totpoint;
return gizmos.gizmos_num();
default:
return 0;
}
@ -170,37 +160,36 @@ static AttributeAccessorFunctions get_pointcloud_accessor_functions()
return fn;
}
static const AttributeAccessorFunctions &get_pointcloud_accessor_functions_ref()
static const AttributeAccessorFunctions &get_gizmos_accessor_functions_ref()
{
static const AttributeAccessorFunctions fn = get_pointcloud_accessor_functions();
static const AttributeAccessorFunctions fn = get_gizmos_accessor_functions();
return fn;
}
} // namespace blender::bke
blender::bke::AttributeAccessor PointCloud::attributes() const
blender::bke::AttributeAccessor blender::bke::GizmosGeometry::attributes() const
{
return blender::bke::AttributeAccessor(this,
blender::bke::get_pointcloud_accessor_functions_ref());
return blender::bke::AttributeAccessor(this, blender::bke::get_gizmos_accessor_functions_ref());
}
blender::bke::MutableAttributeAccessor PointCloud::attributes_for_write()
blender::bke::MutableAttributeAccessor blender::bke::GizmosGeometry::attributes_for_write()
{
return blender::bke::MutableAttributeAccessor(
this, blender::bke::get_pointcloud_accessor_functions_ref());
return blender::bke::MutableAttributeAccessor(this,
blender::bke::get_gizmos_accessor_functions_ref());
}
std::optional<blender::bke::AttributeAccessor> PointCloudComponent::attributes() const
std::optional<blender::bke::AttributeAccessor> GizmosComponent::attributes() const
{
return blender::bke::AttributeAccessor(pointcloud_,
blender::bke::get_pointcloud_accessor_functions_ref());
return blender::bke::AttributeAccessor(gizmos_,
blender::bke::get_gizmos_accessor_functions_ref());
}
std::optional<blender::bke::MutableAttributeAccessor> PointCloudComponent::attributes_for_write()
std::optional<blender::bke::MutableAttributeAccessor> GizmosComponent::attributes_for_write()
{
PointCloud *pointcloud = this->get_for_write();
return blender::bke::MutableAttributeAccessor(
pointcloud, blender::bke::get_pointcloud_accessor_functions_ref());
blender::bke::GizmosGeometry *gizmos = this->get_for_write();
return blender::bke::MutableAttributeAccessor(gizmos,
blender::bke::get_gizmos_accessor_functions_ref());
}
/** \} */

View File

@ -58,6 +58,8 @@ GeometryComponentPtr GeometryComponent::create(GeometryComponentType component_t
return new CurveComponent();
case GEO_COMPONENT_TYPE_EDIT:
return new GeometryComponentEditData();
case GEO_COMPONENT_TYPE_GIZMO:
return new GizmosComponent();
}
BLI_assert_unreachable();
return {};
@ -420,6 +422,17 @@ GeometrySet GeometrySet::create_with_pointcloud(PointCloud *pointcloud,
return geometry_set;
}
GeometrySet GeometrySet::create_with_gizmos(blender::bke::GizmosGeometry *gizmos,
GeometryOwnershipType ownership)
{
GeometrySet geometry_set;
if (gizmos != nullptr) {
GizmosComponent &component = geometry_set.get_component_for_write<GizmosComponent>();
component.replace(gizmos, ownership);
}
return geometry_set;
}
GeometrySet GeometrySet::create_with_curves(Curves *curves, GeometryOwnershipType ownership)
{
GeometrySet geometry_set;

View File

@ -2,8 +2,24 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BKE_gizmos.hh"
namespace blender::bke {
GizmosGeometry::GizmosGeometry(std::string path) : paths_{std::move(path)}, mapping(1, 0)
{
attributes_.reallocate(1);
}
GizmosGeometry *GizmosGeometry::copy() const
{
GizmosGeometry *gizmos = new GizmosGeometry;
gizmos->paths_ = paths_;
gizmos->mapping = mapping;
gizmos->attributes_ = attributes_;
return gizmos;
}
int GizmosGeometry::pathes_num() const
{
return paths_.size();

View File

@ -956,6 +956,8 @@ static bool modifier_apply_obdata(
{
const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md_eval->type);
// GizmosComponent *overlay_gizmo = ob->runtime->overlay_gizmo;
if (mti->isDisabled && mti->isDisabled(scene, md_eval, false)) {
BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
return false;

View File

@ -160,6 +160,9 @@ typedef struct Object_Runtime {
*/
struct GeometrySet *geometry_set_eval;
/* Evaluated object only runtime. */
// GizmosComponent *overlay_gizmo
/**
* Mesh structure created during object evaluation.
* It has deformation only modifiers applied on it.

View File

@ -445,7 +445,7 @@ DefNode(GeometryNode, GEO_NODE_VOLUME_TO_MESH, def_geo_volume_to_mesh, "VOLUME_T
DefNode(GeometryNode, GEO_NODE_INTERPOLATE_CURVES, 0, "INTERPOLATE_CURVES", InterpolateCurves, "Interpolate Curves", "Generate new curves on points by interpolating between existing curves")
//DefNode(GeometryNode, GEO_NODE_ARROW_GIZMO, 0, "ARROW_GIZMO", ArrowGizmo, "Arrow Gizmo", "")
DefNode(GeometryNode, GEO_NODE_ARROW_GIZMO, 0, "ARROW_GIZMO", ArrowGizmo, "Arrow Gizmo", "")
/* undefine macros */
#undef DefNode

View File

@ -28,6 +28,7 @@ set(INC
set(SRC
nodes/node_geo_accumulate_field.cc
nodes/node_geo_arrow_gizmos.cc
nodes/node_geo_attribute_capture.cc
nodes/node_geo_attribute_domain_size.cc
nodes/node_geo_attribute_statistic.cc

View File

@ -16,6 +16,7 @@ void register_geometry_nodes()
register_node_type_geo_attribute_capture();
register_node_type_geo_attribute_domain_size();
register_node_type_geo_attribute_statistic();
register_node_type_geo_arrow_gizmo();
register_node_type_geo_blur_attribute();
register_node_type_geo_boolean();
register_node_type_geo_bounding_box();

View File

@ -13,6 +13,7 @@ void register_node_type_geo_attribute_capture();
void register_node_type_geo_attribute_domain_size();
void register_node_type_geo_attribute_separate_xyz();
void register_node_type_geo_attribute_statistic();
void register_node_type_geo_arrow_gizmo();
void register_node_type_geo_blur_attribute();
void register_node_type_geo_boolean();
void register_node_type_geo_bounding_box();

View File

@ -0,0 +1,33 @@
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BKE_gizmos.hh"
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_arrow_gizmo_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Geometry>("Gizmo");
}
static void node_geo_exec(GeoNodeExecParams params)
{
bke::GizmosGeometry *gizmo = new bke::GizmosGeometry("path!");
params.set_output("Gizmo", GeometrySet::create_with_gizmos(gizmo));
}
} // namespace blender::nodes::node_geo_arrow_gizmo_cc
void register_node_type_geo_arrow_gizmo()
{
namespace file_ns = blender::nodes::node_geo_arrow_gizmo_cc;
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_ARROW_GIZMO, "Arrow Gizmo", NODE_CLASS_GEOMETRY);
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.declare = file_ns::node_declare;
nodeRegisterType(&ntype);
}