diff options
author | Hans Goudey <h.goudey@me.com> | 2022-08-30 19:18:40 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-08-30 19:18:40 +0300 |
commit | abe6c640990962735f6f34d26a401c9e506baee3 (patch) | |
tree | 89fcc951de5a3f6c82a9de9f466241f5b94a0168 /source | |
parent | fa8957e0599cf2be06c4822d9a5c0231320d2077 (diff) | |
parent | 82a46ea6f8829fc40205d0d3cabf4017eb738d9a (diff) |
Merge branch 'master' into refactor-mesh-material-index-generic
Diffstat (limited to 'source')
112 files changed, 1701 insertions, 1573 deletions
diff --git a/source/blender/blenkernel/BKE_attribute.hh b/source/blender/blenkernel/BKE_attribute.hh index d29c60a7373..c2f65c93cbe 100644 --- a/source/blender/blenkernel/BKE_attribute.hh +++ b/source/blender/blenkernel/BKE_attribute.hh @@ -2,6 +2,8 @@ #pragma once +#include <optional> + #include "BLI_color.hh" #include "BLI_function_ref.hh" #include "BLI_generic_span.hh" diff --git a/source/blender/blenkernel/BKE_geometry_fields.hh b/source/blender/blenkernel/BKE_geometry_fields.hh index 7c504826044..0e9bf700320 100644 --- a/source/blender/blenkernel/BKE_geometry_fields.hh +++ b/source/blender/blenkernel/BKE_geometry_fields.hh @@ -12,43 +12,181 @@ #include "FN_field.hh" +struct Mesh; +struct PointCloud; + namespace blender::bke { -class GeometryComponentFieldContext : public fn::FieldContext { +struct CurvesGeometry; +class GeometryFieldInput; + +class MeshFieldContext : public fn::FieldContext { + private: + const Mesh &mesh_; + const eAttrDomain domain_; + + public: + MeshFieldContext(const Mesh &mesh, const eAttrDomain domain); + const Mesh &mesh() const + { + return mesh_; + } + + eAttrDomain domain() const + { + return domain_; + } +}; + +class CurvesFieldContext : public fn::FieldContext { + private: + const CurvesGeometry &curves_; + const eAttrDomain domain_; + + public: + CurvesFieldContext(const CurvesGeometry &curves, const eAttrDomain domain); + + const CurvesGeometry &curves() const + { + return curves_; + } + + eAttrDomain domain() const + { + return domain_; + } +}; + +class PointCloudFieldContext : public fn::FieldContext { + private: + const PointCloud &pointcloud_; + + public: + PointCloudFieldContext(const PointCloud &pointcloud) : pointcloud_(pointcloud) + { + } + + const PointCloud &pointcloud() const + { + return pointcloud_; + } +}; + +class InstancesFieldContext : public fn::FieldContext { + private: + const InstancesComponent &instances_; + + public: + InstancesFieldContext(const InstancesComponent &instances) : instances_(instances) + { + } + + const InstancesComponent &instances() const + { + return instances_; + } +}; + +/** + * A field context that can represent meshes, curves, point clouds, or instances, + * used for field inputs that can work for multiple geometry types. + */ +class GeometryFieldContext : public fn::FieldContext { private: - const GeometryComponent &component_; + /** + * Store the geometry as a void pointer instead of a #GeometryComponent to allow referencing data + * that doesn't correspond directly to a geometry component type, in this case #CurvesGeometry + * instead of #Curves. + */ + const void *geometry_; + const GeometryComponentType type_; const eAttrDomain domain_; + friend GeometryFieldInput; + public: - GeometryComponentFieldContext(const GeometryComponent &component, const eAttrDomain domain) - : component_(component), domain_(domain) + GeometryFieldContext(const GeometryComponent &component, eAttrDomain domain); + GeometryFieldContext(const void *geometry, GeometryComponentType type, eAttrDomain domain); + + const void *geometry() const { + return geometry_; } - const GeometryComponent &geometry_component() const + GeometryComponentType type() const { - return component_; + return type_; } eAttrDomain domain() const { return domain_; } + + std::optional<AttributeAccessor> attributes() const; + const Mesh *mesh() const; + const CurvesGeometry *curves() const; + const PointCloud *pointcloud() const; + const InstancesComponent *instances() const; + + private: + GeometryFieldContext(const Mesh &mesh, eAttrDomain domain); + GeometryFieldContext(const CurvesGeometry &curves, eAttrDomain domain); + GeometryFieldContext(const PointCloud &points); + GeometryFieldContext(const InstancesComponent &instances); }; class GeometryFieldInput : public fn::FieldInput { public: using fn::FieldInput::FieldInput; + GVArray get_varray_for_context(const fn::FieldContext &context, + IndexMask mask, + ResourceScope &scope) const override; + virtual GVArray get_varray_for_context(const GeometryFieldContext &context, + IndexMask mask) const = 0; +}; +class MeshFieldInput : public fn::FieldInput { + public: + using fn::FieldInput::FieldInput; GVArray get_varray_for_context(const fn::FieldContext &context, IndexMask mask, ResourceScope &scope) const override; + virtual GVArray get_varray_for_context(const Mesh &mesh, + eAttrDomain domain, + IndexMask mask) const = 0; +}; - virtual GVArray get_varray_for_context(const GeometryComponent &component, +class CurvesFieldInput : public fn::FieldInput { + public: + using fn::FieldInput::FieldInput; + GVArray get_varray_for_context(const fn::FieldContext &context, + IndexMask mask, + ResourceScope &scope) const override; + virtual GVArray get_varray_for_context(const CurvesGeometry &curves, eAttrDomain domain, IndexMask mask) const = 0; }; +class PointCloudFieldInput : public fn::FieldInput { + public: + using fn::FieldInput::FieldInput; + GVArray get_varray_for_context(const fn::FieldContext &context, + IndexMask mask, + ResourceScope &scope) const override; + virtual GVArray get_varray_for_context(const PointCloud &pointcloud, IndexMask mask) const = 0; +}; + +class InstancesFieldInput : public fn::FieldInput { + public: + using fn::FieldInput::FieldInput; + GVArray get_varray_for_context(const fn::FieldContext &context, + IndexMask mask, + ResourceScope &scope) const override; + virtual GVArray get_varray_for_context(const InstancesComponent &instances, + IndexMask mask) const = 0; +}; + class AttributeFieldInput : public GeometryFieldInput { private: std::string name_; @@ -72,8 +210,7 @@ class AttributeFieldInput : public GeometryFieldInput { return name_; } - GVArray get_varray_for_context(const GeometryComponent &component, - eAttrDomain domain, + GVArray get_varray_for_context(const GeometryFieldContext &context, IndexMask mask) const override; std::string socket_inspection_name() const override; @@ -89,8 +226,7 @@ class IDAttributeFieldInput : public GeometryFieldInput { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, - eAttrDomain domain, + GVArray get_varray_for_context(const GeometryFieldContext &context, IndexMask mask) const override; std::string socket_inspection_name() const override; @@ -99,12 +235,9 @@ class IDAttributeFieldInput : public GeometryFieldInput { bool is_equal_to(const fn::FieldNode &other) const override; }; -VArray<float3> curve_normals_varray(const CurveComponent &component, const eAttrDomain domain); +VArray<float3> curve_normals_varray(const CurvesGeometry &curves, const eAttrDomain domain); -VArray<float3> mesh_normals_varray(const MeshComponent &mesh_component, - const Mesh &mesh, - const IndexMask mask, - eAttrDomain domain); +VArray<float3> mesh_normals_varray(const Mesh &mesh, const IndexMask mask, eAttrDomain domain); class NormalFieldInput : public GeometryFieldInput { public: @@ -113,8 +246,7 @@ class NormalFieldInput : public GeometryFieldInput { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, - const eAttrDomain domain, + GVArray get_varray_for_context(const GeometryFieldContext &context, IndexMask mask) const override; std::string socket_inspection_name() const override; @@ -152,8 +284,7 @@ class AnonymousAttributeFieldInput : public GeometryFieldInput { return fn::Field<T>{field_input}; } - GVArray get_varray_for_context(const GeometryComponent &component, - eAttrDomain domain, + GVArray get_varray_for_context(const GeometryFieldContext &context, IndexMask mask) const override; std::string socket_inspection_name() const override; @@ -162,10 +293,10 @@ class AnonymousAttributeFieldInput : public GeometryFieldInput { bool is_equal_to(const fn::FieldNode &other) const override; }; -class CurveLengthFieldInput final : public GeometryFieldInput { +class CurveLengthFieldInput final : public CurvesFieldInput { public: CurveLengthFieldInput(); - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const CurvesGeometry &curves, eAttrDomain domain, IndexMask mask) const final; uint64_t hash() const override; diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h index ad3b1971ca9..39ef738c631 100644 --- a/source/blender/blenkernel/BKE_gpencil_geom.h +++ b/source/blender/blenkernel/BKE_gpencil_geom.h @@ -488,7 +488,8 @@ struct bGPDstroke *BKE_gpencil_stroke_perimeter_from_view(struct RegionView3D *r const struct bGPDlayer *gpl, struct bGPDstroke *gps, int subdivisions, - const float diff_mat[4][4]); + const float diff_mat[4][4], + const float thickness_chg); /** * Get average pressure. */ diff --git a/source/blender/blenkernel/BKE_mesh_remesh_voxel.h b/source/blender/blenkernel/BKE_mesh_remesh_voxel.h index dff17bd6575..d9f5a75ca61 100644 --- a/source/blender/blenkernel/BKE_mesh_remesh_voxel.h +++ b/source/blender/blenkernel/BKE_mesh_remesh_voxel.h @@ -28,9 +28,9 @@ struct Mesh *BKE_mesh_remesh_quadriflow(const struct Mesh *mesh, void *update_cb_data); /* Data reprojection functions */ -void BKE_mesh_remesh_reproject_paint_mask(struct Mesh *target, struct Mesh *source); +void BKE_mesh_remesh_reproject_paint_mask(struct Mesh *target, const struct Mesh *source); void BKE_remesh_reproject_vertex_paint(struct Mesh *target, const struct Mesh *source); -void BKE_remesh_reproject_sculpt_face_sets(struct Mesh *target, struct Mesh *source); +void BKE_remesh_reproject_sculpt_face_sets(struct Mesh *target, const struct Mesh *source); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h index 4215cad5858..8549cd14b3c 100644 --- a/source/blender/blenkernel/BKE_volume.h +++ b/source/blender/blenkernel/BKE_volume.h @@ -135,7 +135,7 @@ struct VolumeGrid *BKE_volume_grid_add(struct Volume *volume, void BKE_volume_grid_remove(struct Volume *volume, struct VolumeGrid *grid); /** - * Openvdb crashes when the determinant of the transform matrix becomes too small. + * OpenVDB crashes when the determinant of the transform matrix becomes too small. */ bool BKE_volume_grid_determinant_valid(double determinant); diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 8b7fbc4938f..465573745ec 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -143,6 +143,7 @@ set(SRC intern/geometry_component_mesh.cc intern/geometry_component_pointcloud.cc intern/geometry_component_volume.cc + intern/geometry_fields.cc intern/geometry_set.cc intern/geometry_set_instances.cc intern/gpencil.c diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc index 495a2c82332..ccaa6e56f08 100644 --- a/source/blender/blenkernel/intern/attribute.cc +++ b/source/blender/blenkernel/intern/attribute.cc @@ -187,9 +187,9 @@ static bool unique_name_cb(void *arg, const char *name) continue; } - CustomData *cdata = info[domain].customdata; + const CustomData *cdata = info[domain].customdata; for (int i = 0; i < cdata->totlayer; i++) { - CustomDataLayer *layer = cdata->layers + i; + const CustomDataLayer *layer = cdata->layers + i; if (STREQ(layer->name, name)) { return true; @@ -493,10 +493,10 @@ void BKE_id_attributes_active_set(ID *id, CustomDataLayer *active_layer) int index = 0; for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) { - CustomData *customdata = info[domain].customdata; + const CustomData *customdata = info[domain].customdata; if (customdata) { for (int i = 0; i < customdata->totlayer; i++) { - CustomDataLayer *layer = &customdata->layers[i]; + const CustomDataLayer *layer = &customdata->layers[i]; if (layer == active_layer) { *BKE_id_attributes_active_index_p(id) = index; return; diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index b9995796a21..313e6a172ac 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -5,7 +5,6 @@ #include "BKE_attribute_math.hh" #include "BKE_customdata.h" #include "BKE_deform.h" -#include "BKE_geometry_fields.hh" #include "BKE_geometry_set.hh" #include "BKE_mesh.h" #include "BKE_pointcloud.h" @@ -794,7 +793,7 @@ void CustomDataAttributes::reorder(Span<AttributeIDRef> new_order) } /* -------------------------------------------------------------------- */ -/** \name Geometry Component +/** \name Attribute API * \{ */ static blender::GVArray try_adapt_data_type(blender::GVArray varray, @@ -805,123 +804,6 @@ static blender::GVArray try_adapt_data_type(blender::GVArray varray, return conversions.try_convert(std::move(varray), to_type); } -GVArray GeometryFieldInput::get_varray_for_context(const fn::FieldContext &context, - IndexMask mask, - ResourceScope &UNUSED(scope)) const -{ - if (const GeometryComponentFieldContext *geometry_context = - dynamic_cast<const GeometryComponentFieldContext *>(&context)) { - const GeometryComponent &component = geometry_context->geometry_component(); - const eAttrDomain domain = geometry_context->domain(); - return this->get_varray_for_context(component, domain, mask); - } - return {}; -} - -GVArray AttributeFieldInput::get_varray_for_context(const GeometryComponent &component, - const eAttrDomain domain, - IndexMask UNUSED(mask)) const -{ - const eCustomDataType data_type = cpp_type_to_custom_data_type(*type_); - if (auto attributes = component.attributes()) { - return attributes->lookup(name_, domain, data_type); - } - return {}; -} - -std::string AttributeFieldInput::socket_inspection_name() const -{ - std::stringstream ss; - ss << '"' << name_ << '"' << TIP_(" attribute from geometry"); - return ss.str(); -} - -uint64_t AttributeFieldInput::hash() const -{ - return get_default_hash_2(name_, type_); -} - -bool AttributeFieldInput::is_equal_to(const fn::FieldNode &other) const -{ - if (const AttributeFieldInput *other_typed = dynamic_cast<const AttributeFieldInput *>(&other)) { - return name_ == other_typed->name_ && type_ == other_typed->type_; - } - return false; -} - -static StringRef get_random_id_attribute_name(const eAttrDomain domain) -{ - switch (domain) { - case ATTR_DOMAIN_POINT: - case ATTR_DOMAIN_INSTANCE: - return "id"; - default: - return ""; - } -} - -GVArray IDAttributeFieldInput::get_varray_for_context(const GeometryComponent &component, - const eAttrDomain domain, - IndexMask mask) const -{ - - const StringRef name = get_random_id_attribute_name(domain); - if (auto attributes = component.attributes()) { - if (GVArray attribute = attributes->lookup(name, domain, CD_PROP_INT32)) { - return attribute; - } - } - - /* Use the index as the fallback if no random ID attribute exists. */ - return fn::IndexFieldInput::get_index_varray(mask); -} - -std::string IDAttributeFieldInput::socket_inspection_name() const -{ - return TIP_("ID / Index"); -} - -uint64_t IDAttributeFieldInput::hash() const -{ - /* All random ID attribute inputs are the same within the same evaluation context. */ - return 92386459827; -} - -bool IDAttributeFieldInput::is_equal_to(const fn::FieldNode &other) const -{ - /* All random ID attribute inputs are the same within the same evaluation context. */ - return dynamic_cast<const IDAttributeFieldInput *>(&other) != nullptr; -} - -GVArray AnonymousAttributeFieldInput::get_varray_for_context(const GeometryComponent &component, - const eAttrDomain domain, - IndexMask UNUSED(mask)) const -{ - const eCustomDataType data_type = cpp_type_to_custom_data_type(*type_); - return component.attributes()->lookup(anonymous_id_.get(), domain, data_type); -} - -std::string AnonymousAttributeFieldInput::socket_inspection_name() const -{ - std::stringstream ss; - ss << '"' << debug_name_ << '"' << TIP_(" from ") << producer_name_; - return ss.str(); -} - -uint64_t AnonymousAttributeFieldInput::hash() const -{ - return get_default_hash_2(anonymous_id_.get(), type_); -} - -bool AnonymousAttributeFieldInput::is_equal_to(const fn::FieldNode &other) const -{ - if (const AnonymousAttributeFieldInput *other_typed = - dynamic_cast<const AnonymousAttributeFieldInput *>(&other)) { - return anonymous_id_.get() == other_typed->anonymous_id_.get() && type_ == other_typed->type_; - } - return false; -} - GVArray AttributeAccessor::lookup(const AttributeIDRef &attribute_id, const std::optional<eAttrDomain> domain, const std::optional<eCustomDataType> data_type) const diff --git a/source/blender/blenkernel/intern/geometry_component_curves.cc b/source/blender/blenkernel/intern/geometry_component_curves.cc index 2714c78e381..596c8e0bfc7 100644 --- a/source/blender/blenkernel/intern/geometry_component_curves.cc +++ b/source/blender/blenkernel/intern/geometry_component_curves.cc @@ -206,18 +206,11 @@ static Array<float3> curve_normal_point_domain(const bke::CurvesGeometry &curves return results; } -VArray<float3> curve_normals_varray(const CurveComponent &component, const eAttrDomain domain) +VArray<float3> curve_normals_varray(const CurvesGeometry &curves, const eAttrDomain domain) { - if (!component.has_curves()) { - return {}; - } - - const Curves &curves_id = *component.get_for_read(); - const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); - const VArray<int8_t> types = curves.curve_types(); if (curves.is_single_type(CURVE_TYPE_POLY)) { - return component.attributes()->adapt_domain<float3>( + return curves.adapt_domain<float3>( VArray<float3>::ForSpan(curves.evaluated_normals()), ATTR_DOMAIN_POINT, domain); } @@ -228,7 +221,7 @@ VArray<float3> curve_normals_varray(const CurveComponent &component, const eAttr } if (domain == ATTR_DOMAIN_CURVE) { - return component.attributes()->adapt_domain<float3>( + return curves.adapt_domain<float3>( VArray<float3>::ForContainer(std::move(normals)), ATTR_DOMAIN_POINT, ATTR_DOMAIN_CURVE); } @@ -241,15 +234,9 @@ VArray<float3> curve_normals_varray(const CurveComponent &component, const eAttr /** \name Curve Length Field Input * \{ */ -static VArray<float> construct_curve_length_gvarray(const CurveComponent &component, +static VArray<float> construct_curve_length_gvarray(const CurvesGeometry &curves, const eAttrDomain domain) { - if (!component.has_curves()) { - return {}; - } - const Curves &curves_id = *component.get_for_read(); - const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); - curves.ensure_evaluated_lengths(); VArray<bool> cyclic = curves.cyclic(); @@ -263,28 +250,23 @@ static VArray<float> construct_curve_length_gvarray(const CurveComponent &compon } if (domain == ATTR_DOMAIN_POINT) { - return component.attributes()->adapt_domain<float>( - std::move(lengths), ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT); + return curves.adapt_domain<float>(std::move(lengths), ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT); } return {}; } CurveLengthFieldInput::CurveLengthFieldInput() - : GeometryFieldInput(CPPType::get<float>(), "Spline Length node") + : CurvesFieldInput(CPPType::get<float>(), "Spline Length node") { category_ = Category::Generated; } -GVArray CurveLengthFieldInput::get_varray_for_context(const GeometryComponent &component, +GVArray CurveLengthFieldInput::get_varray_for_context(const CurvesGeometry &curves, const eAttrDomain domain, IndexMask UNUSED(mask)) const { - if (component.type() == GEO_COMPONENT_TYPE_CURVE) { - const CurveComponent &curve_component = static_cast<const CurveComponent &>(component); - return construct_curve_length_gvarray(curve_component, domain); - } - return {}; + return construct_curve_length_gvarray(curves, domain); } uint64_t CurveLengthFieldInput::hash() const diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index 351af04ceba..ff55409d5fc 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -115,8 +115,7 @@ void MeshComponent::ensure_owns_direct_data() namespace blender::bke { -VArray<float3> mesh_normals_varray(const MeshComponent &mesh_component, - const Mesh &mesh, +VArray<float3> mesh_normals_varray(const Mesh &mesh, const IndexMask mask, const eAttrDomain domain) { @@ -150,7 +149,7 @@ VArray<float3> mesh_normals_varray(const MeshComponent &mesh_component, * array and copy the face normal for each of its corners. In this case using the mesh * component's generic domain interpolation is fine, the data will still be normalized, * since the face normal is just copied to every corner. */ - return mesh_component.attributes()->adapt_domain( + return mesh_attributes(mesh).adapt_domain( VArray<float3>::ForSpan({(float3 *)BKE_mesh_poly_normals_ensure(&mesh), mesh.totpoly}), ATTR_DOMAIN_FACE, ATTR_DOMAIN_CORNER); diff --git a/source/blender/blenkernel/intern/geometry_fields.cc b/source/blender/blenkernel/intern/geometry_fields.cc new file mode 100644 index 00000000000..a52ffb6496b --- /dev/null +++ b/source/blender/blenkernel/intern/geometry_fields.cc @@ -0,0 +1,365 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BKE_attribute.hh" +#include "BKE_curves.hh" +#include "BKE_geometry_fields.hh" +#include "BKE_geometry_set.hh" +#include "BKE_mesh.h" +#include "BKE_pointcloud.h" +#include "BKE_type_conversions.hh" + +#include "DNA_mesh_types.h" +#include "DNA_pointcloud_types.h" + +#include "BLT_translation.h" + +namespace blender::bke { + +MeshFieldContext::MeshFieldContext(const Mesh &mesh, const eAttrDomain domain) + : mesh_(mesh), domain_(domain) +{ + BLI_assert(mesh_attributes(mesh).domain_supported(domain_)); +} + +CurvesFieldContext::CurvesFieldContext(const CurvesGeometry &curves, const eAttrDomain domain) + : curves_(curves), domain_(domain) +{ + BLI_assert(curves.attributes().domain_supported(domain)); +} + +GeometryFieldContext::GeometryFieldContext(const void *geometry, + const GeometryComponentType type, + const eAttrDomain domain) + : geometry_(geometry), type_(type), domain_(domain) +{ + BLI_assert(ELEM(type, + GEO_COMPONENT_TYPE_MESH, + GEO_COMPONENT_TYPE_CURVE, + GEO_COMPONENT_TYPE_POINT_CLOUD, + GEO_COMPONENT_TYPE_INSTANCES)); +} + +GeometryFieldContext::GeometryFieldContext(const GeometryComponent &component, + const eAttrDomain domain) + : type_(component.type()), domain_(domain) +{ + switch (component.type()) { + case GEO_COMPONENT_TYPE_MESH: { + const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); + geometry_ = mesh_component.get_for_read(); + break; + } + case GEO_COMPONENT_TYPE_CURVE: { + const CurveComponent &curve_component = static_cast<const CurveComponent &>(component); + const Curves *curves = curve_component.get_for_read(); + geometry_ = curves ? &CurvesGeometry::wrap(curves->geometry) : nullptr; + break; + } + case GEO_COMPONENT_TYPE_POINT_CLOUD: { + const PointCloudComponent &pointcloud_component = static_cast<const PointCloudComponent &>( + component); + geometry_ = pointcloud_component.get_for_read(); + break; + } + case GEO_COMPONENT_TYPE_INSTANCES: { + const InstancesComponent &instances_component = static_cast<const InstancesComponent &>( + component); + geometry_ = &instances_component; + break; + } + case GEO_COMPONENT_TYPE_VOLUME: + case GEO_COMPONENT_TYPE_EDIT: + BLI_assert_unreachable(); + break; + } +} + +GeometryFieldContext::GeometryFieldContext(const Mesh &mesh, eAttrDomain domain) + : geometry_(&mesh), type_(GEO_COMPONENT_TYPE_MESH), domain_(domain) +{ +} +GeometryFieldContext::GeometryFieldContext(const CurvesGeometry &curves, eAttrDomain domain) + : geometry_(&curves), type_(GEO_COMPONENT_TYPE_CURVE), domain_(domain) +{ +} +GeometryFieldContext::GeometryFieldContext(const PointCloud &points) + : geometry_(&points), type_(GEO_COMPONENT_TYPE_POINT_CLOUD), domain_(ATTR_DOMAIN_POINT) +{ +} +GeometryFieldContext::GeometryFieldContext(const InstancesComponent &instances) + : geometry_(&instances), type_(GEO_COMPONENT_TYPE_INSTANCES), domain_(ATTR_DOMAIN_INSTANCE) +{ +} + +std::optional<AttributeAccessor> GeometryFieldContext::attributes() const +{ + if (const Mesh *mesh = this->mesh()) { + return mesh_attributes(*mesh); + } + if (const CurvesGeometry *curves = this->curves()) { + return curves->attributes(); + } + if (const PointCloud *pointcloud = this->pointcloud()) { + return pointcloud_attributes(*pointcloud); + } + if (const InstancesComponent *instances = this->instances()) { + return instances->attributes(); + } + return {}; +} + +const Mesh *GeometryFieldContext::mesh() const +{ + return this->type() == GEO_COMPONENT_TYPE_MESH ? static_cast<const Mesh *>(geometry_) : nullptr; +} +const CurvesGeometry *GeometryFieldContext::curves() const +{ + return this->type() == GEO_COMPONENT_TYPE_CURVE ? + static_cast<const CurvesGeometry *>(geometry_) : + nullptr; +} +const PointCloud *GeometryFieldContext::pointcloud() const +{ + return this->type() == GEO_COMPONENT_TYPE_POINT_CLOUD ? + static_cast<const PointCloud *>(geometry_) : + nullptr; +} +const InstancesComponent *GeometryFieldContext::instances() const +{ + return this->type() == GEO_COMPONENT_TYPE_INSTANCES ? + static_cast<const InstancesComponent *>(geometry_) : + nullptr; +} + +GVArray GeometryFieldInput::get_varray_for_context(const fn::FieldContext &context, + const IndexMask mask, + ResourceScope & /*scope*/) const +{ + if (const GeometryFieldContext *geometry_context = dynamic_cast<const GeometryFieldContext *>( + &context)) { + return this->get_varray_for_context(*geometry_context, mask); + } + if (const MeshFieldContext *mesh_context = dynamic_cast<const MeshFieldContext *>(&context)) { + return this->get_varray_for_context({mesh_context->mesh(), mesh_context->domain()}, mask); + } + if (const CurvesFieldContext *curve_context = dynamic_cast<const CurvesFieldContext *>( + &context)) { + return this->get_varray_for_context({curve_context->curves(), curve_context->domain()}, mask); + } + if (const PointCloudFieldContext *point_context = dynamic_cast<const PointCloudFieldContext *>( + &context)) { + return this->get_varray_for_context({point_context->pointcloud()}, mask); + } + if (const InstancesFieldContext *instances_context = dynamic_cast<const InstancesFieldContext *>( + &context)) { + return this->get_varray_for_context({instances_context->instances()}, mask); + } + return {}; +} + +GVArray MeshFieldInput::get_varray_for_context(const fn::FieldContext &context, + const IndexMask mask, + ResourceScope & /*scope*/) const +{ + if (const GeometryFieldContext *geometry_context = dynamic_cast<const GeometryFieldContext *>( + &context)) { + if (const Mesh *mesh = geometry_context->mesh()) { + return this->get_varray_for_context(*mesh, geometry_context->domain(), mask); + } + } + if (const MeshFieldContext *mesh_context = dynamic_cast<const MeshFieldContext *>(&context)) { + return this->get_varray_for_context(mesh_context->mesh(), mesh_context->domain(), mask); + } + return {}; +} + +GVArray CurvesFieldInput::get_varray_for_context(const fn::FieldContext &context, + IndexMask mask, + ResourceScope & /*scope*/) const +{ + if (const GeometryFieldContext *geometry_context = dynamic_cast<const GeometryFieldContext *>( + &context)) { + if (const CurvesGeometry *curves = geometry_context->curves()) { + return this->get_varray_for_context(*curves, geometry_context->domain(), mask); + } + } + if (const CurvesFieldContext *curves_context = dynamic_cast<const CurvesFieldContext *>( + &context)) { + return this->get_varray_for_context(curves_context->curves(), curves_context->domain(), mask); + } + return {}; +} + +GVArray PointCloudFieldInput::get_varray_for_context(const fn::FieldContext &context, + IndexMask mask, + ResourceScope & /*scope*/) const +{ + if (const GeometryFieldContext *geometry_context = dynamic_cast<const GeometryFieldContext *>( + &context)) { + if (const PointCloud *pointcloud = geometry_context->pointcloud()) { + return this->get_varray_for_context(*pointcloud, mask); + } + } + if (const PointCloudFieldContext *point_context = dynamic_cast<const PointCloudFieldContext *>( + &context)) { + return this->get_varray_for_context(point_context->pointcloud(), mask); + } + return {}; +} + +GVArray InstancesFieldInput::get_varray_for_context(const fn::FieldContext &context, + IndexMask mask, + ResourceScope & /*scope*/) const +{ + if (const GeometryFieldContext *geometry_context = dynamic_cast<const GeometryFieldContext *>( + &context)) { + if (const InstancesComponent *instances = geometry_context->instances()) { + return this->get_varray_for_context(*instances, mask); + } + } + if (const InstancesFieldContext *instances_context = dynamic_cast<const InstancesFieldContext *>( + &context)) { + return this->get_varray_for_context(instances_context->instances(), mask); + } + return {}; +} + +GVArray AttributeFieldInput::get_varray_for_context(const GeometryFieldContext &context, + IndexMask UNUSED(mask)) const +{ + const eCustomDataType data_type = cpp_type_to_custom_data_type(*type_); + if (auto attributes = context.attributes()) { + return attributes->lookup(name_, context.domain(), data_type); + } + return {}; +} + +std::string AttributeFieldInput::socket_inspection_name() const +{ + std::stringstream ss; + ss << '"' << name_ << '"' << TIP_(" attribute from geometry"); + return ss.str(); +} + +uint64_t AttributeFieldInput::hash() const +{ + return get_default_hash_2(name_, type_); +} + +bool AttributeFieldInput::is_equal_to(const fn::FieldNode &other) const +{ + if (const AttributeFieldInput *other_typed = dynamic_cast<const AttributeFieldInput *>(&other)) { + return name_ == other_typed->name_ && type_ == other_typed->type_; + } + return false; +} + +static StringRef get_random_id_attribute_name(const eAttrDomain domain) +{ + switch (domain) { + case ATTR_DOMAIN_POINT: + case ATTR_DOMAIN_INSTANCE: + return "id"; + default: + return ""; + } +} + +GVArray IDAttributeFieldInput::get_varray_for_context(const GeometryFieldContext &context, + const IndexMask mask) const +{ + + const StringRef name = get_random_id_attribute_name(context.domain()); + if (auto attributes = context.attributes()) { + if (GVArray attribute = attributes->lookup(name, context.domain(), CD_PROP_INT32)) { + return attribute; + } + } + + /* Use the index as the fallback if no random ID attribute exists. */ + return fn::IndexFieldInput::get_index_varray(mask); +} + +std::string IDAttributeFieldInput::socket_inspection_name() const +{ + return TIP_("ID / Index"); +} + +uint64_t IDAttributeFieldInput::hash() const +{ + /* All random ID attribute inputs are the same within the same evaluation context. */ + return 92386459827; +} + +bool IDAttributeFieldInput::is_equal_to(const fn::FieldNode &other) const +{ + /* All random ID attribute inputs are the same within the same evaluation context. */ + return dynamic_cast<const IDAttributeFieldInput *>(&other) != nullptr; +} + +GVArray AnonymousAttributeFieldInput::get_varray_for_context(const GeometryFieldContext &context, + const IndexMask /*mask*/) const +{ + const eCustomDataType data_type = cpp_type_to_custom_data_type(*type_); + return context.attributes()->lookup(anonymous_id_.get(), context.domain(), data_type); +} + +std::string AnonymousAttributeFieldInput::socket_inspection_name() const +{ + std::stringstream ss; + ss << '"' << debug_name_ << '"' << TIP_(" from ") << producer_name_; + return ss.str(); +} + +uint64_t AnonymousAttributeFieldInput::hash() const +{ + return get_default_hash_2(anonymous_id_.get(), type_); +} + +bool AnonymousAttributeFieldInput::is_equal_to(const fn::FieldNode &other) const +{ + if (const AnonymousAttributeFieldInput *other_typed = + dynamic_cast<const AnonymousAttributeFieldInput *>(&other)) { + return anonymous_id_.get() == other_typed->anonymous_id_.get() && type_ == other_typed->type_; + } + return false; +} + +} // namespace blender::bke + +/* -------------------------------------------------------------------- */ +/** \name Mesh and Curve Normals Field Input + * \{ */ + +namespace blender::bke { + +GVArray NormalFieldInput::get_varray_for_context(const GeometryFieldContext &context, + const IndexMask mask) const +{ + if (const Mesh *mesh = context.mesh()) { + return mesh_normals_varray(*mesh, mask, context.domain()); + } + if (const CurvesGeometry *curves = context.curves()) { + return curve_normals_varray(*curves, context.domain()); + } + return {}; +} + +std::string NormalFieldInput::socket_inspection_name() const +{ + return TIP_("Normal"); +} + +uint64_t NormalFieldInput::hash() const +{ + return 213980475983; +} + +bool NormalFieldInput::is_equal_to(const fn::FieldNode &other) const +{ + return dynamic_cast<const NormalFieldInput *>(&other) != nullptr; +} + +} // namespace blender::bke + +/** \} */ diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc index 1a0ce4f0893..633d9ad8c49 100644 --- a/source/blender/blenkernel/intern/geometry_set.cc +++ b/source/blender/blenkernel/intern/geometry_set.cc @@ -8,7 +8,6 @@ #include "BKE_attribute.h" #include "BKE_curves.hh" -#include "BKE_geometry_fields.hh" #include "BKE_geometry_set.hh" #include "BKE_lib_id.h" #include "BKE_mesh.h" @@ -634,48 +633,6 @@ void GeometrySet::modify_geometry_sets(ForeachSubGeometryCallback callback) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Mesh and Curve Normals Field Input - * \{ */ - -namespace blender::bke { - -GVArray NormalFieldInput::get_varray_for_context(const GeometryComponent &component, - const eAttrDomain domain, - IndexMask mask) const -{ - if (component.type() == GEO_COMPONENT_TYPE_MESH) { - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - if (const Mesh *mesh = mesh_component.get_for_read()) { - return mesh_normals_varray(mesh_component, *mesh, mask, domain); - } - } - else if (component.type() == GEO_COMPONENT_TYPE_CURVE) { - const CurveComponent &curve_component = static_cast<const CurveComponent &>(component); - return curve_normals_varray(curve_component, domain); - } - return {}; -} - -std::string NormalFieldInput::socket_inspection_name() const -{ - return TIP_("Normal"); -} - -uint64_t NormalFieldInput::hash() const -{ - return 213980475983; -} - -bool NormalFieldInput::is_equal_to(const fn::FieldNode &other) const -{ - return dynamic_cast<const NormalFieldInput *>(&other) != nullptr; -} - -} // namespace blender::bke - -/** \} */ - -/* -------------------------------------------------------------------- */ /** \name C API * \{ */ diff --git a/source/blender/blenkernel/intern/gpencil_geom.cc b/source/blender/blenkernel/intern/gpencil_geom.cc index 85ff81ba80e..ce2e106c664 100644 --- a/source/blender/blenkernel/intern/gpencil_geom.cc +++ b/source/blender/blenkernel/intern/gpencil_geom.cc @@ -3966,6 +3966,7 @@ static ListBase *gpencil_stroke_perimeter_ex(const bGPdata *gpd, const bGPDlayer *gpl, const bGPDstroke *gps, int subdivisions, + const float thickness_chg, int *r_num_perimeter_points) { /* sanity check */ @@ -3974,7 +3975,9 @@ static ListBase *gpencil_stroke_perimeter_ex(const bGPdata *gpd, } float defaultpixsize = 1000.0f / gpd->pixfactor; + float ovr_radius = thickness_chg / defaultpixsize / 2.0f; float stroke_radius = ((gps->thickness + gpl->line_change) / defaultpixsize) / 2.0f; + stroke_radius = max_ff(stroke_radius - ovr_radius, 0.0f); ListBase *perimeter_right_side = MEM_cnew<ListBase>(__func__); ListBase *perimeter_left_side = MEM_cnew<ListBase>(__func__); @@ -4208,7 +4211,8 @@ bGPDstroke *BKE_gpencil_stroke_perimeter_from_view(struct RegionView3D *rv3d, const bGPDlayer *gpl, bGPDstroke *gps, const int subdivisions, - const float diff_mat[4][4]) + const float diff_mat[4][4], + const float thickness_chg) { if (gps->totpoints == 0) { return nullptr; @@ -4240,7 +4244,7 @@ bGPDstroke *BKE_gpencil_stroke_perimeter_from_view(struct RegionView3D *rv3d, BKE_gpencil_stroke_to_view_space(rv3d, gps_temp, diff_mat); int num_perimeter_points = 0; ListBase *perimeter_points = gpencil_stroke_perimeter_ex( - gpd, gpl, gps_temp, subdivisions, &num_perimeter_points); + gpd, gpl, gps_temp, subdivisions, thickness_chg, &num_perimeter_points); if (num_perimeter_points == 0) { return nullptr; diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc index 03ad4b1cd5f..29f8b26c296 100644 --- a/source/blender/blenkernel/intern/lib_override.cc +++ b/source/blender/blenkernel/intern/lib_override.cc @@ -1802,6 +1802,10 @@ static bool lib_override_library_resync(Main *bmain, lib_override_hierarchy_dependencies_recursive_tag(&data); FOREACH_MAIN_ID_BEGIN (bmain, id) { + if ((id->lib != id_root->lib) || !ID_IS_OVERRIDE_LIBRARY(id)) { + continue; + } + /* IDs that get fully removed from linked data remain as local overrides (using place-holder * linked IDs as reference), but they are often not reachable from any current valid local * override hierarchy anymore. This will ensure they get properly deleted at the end of this @@ -1815,69 +1819,67 @@ static bool lib_override_library_resync(Main *bmain, id->tag |= LIB_TAG_MISSING; } - if ((id->lib == id_root->lib) && ID_IS_OVERRIDE_LIBRARY(id)) { - /* While this should not happen in typical cases (and won't be properly supported here), - * user is free to do all kind of very bad things, including having different local - * overrides of a same linked ID in a same hierarchy. */ - IDOverrideLibrary *id_override_library = BKE_lib_override_library_get( - bmain, id, nullptr, nullptr); + /* While this should not happen in typical cases (and won't be properly supported here), + * user is free to do all kind of very bad things, including having different local + * overrides of a same linked ID in a same hierarchy. */ + IDOverrideLibrary *id_override_library = BKE_lib_override_library_get( + bmain, id, nullptr, nullptr); - if (id_override_library->hierarchy_root != id_root->override_library->hierarchy_root) { - continue; - } + if (id_override_library->hierarchy_root != id_root->override_library->hierarchy_root) { + continue; + } - ID *reference_id = id_override_library->reference; - if (GS(reference_id->name) != GS(id->name)) { - switch (GS(id->name)) { - case ID_KE: - reference_id = reinterpret_cast<ID *>(BKE_key_from_id(reference_id)); - break; - case ID_GR: - BLI_assert(GS(reference_id->name) == ID_SCE); - reference_id = reinterpret_cast<ID *>( - reinterpret_cast<Scene *>(reference_id)->master_collection); - break; - case ID_NT: - reference_id = reinterpret_cast<ID *>(ntreeFromID(id)); - break; - default: - break; - } + ID *reference_id = id_override_library->reference; + if (GS(reference_id->name) != GS(id->name)) { + switch (GS(id->name)) { + case ID_KE: + reference_id = reinterpret_cast<ID *>(BKE_key_from_id(reference_id)); + break; + case ID_GR: + BLI_assert(GS(reference_id->name) == ID_SCE); + reference_id = reinterpret_cast<ID *>( + reinterpret_cast<Scene *>(reference_id)->master_collection); + break; + case ID_NT: + reference_id = reinterpret_cast<ID *>(ntreeFromID(id)); + break; + default: + break; } - if (reference_id == nullptr) { - /* Can happen e.g. when there is a local override of a shapekey, but the matching linked - * obdata (mesh etc.) does not have any shapekey anymore. */ + } + if (reference_id == nullptr) { + /* Can happen e.g. when there is a local override of a shapekey, but the matching linked + * obdata (mesh etc.) does not have any shapekey anymore. */ + continue; + } + BLI_assert(GS(reference_id->name) == GS(id->name)); + + if (!BLI_ghash_haskey(linkedref_to_old_override, reference_id)) { + BLI_ghash_insert(linkedref_to_old_override, reference_id, id); + if (!ID_IS_OVERRIDE_LIBRARY_REAL(id) || (id->tag & LIB_TAG_DOIT) == 0) { continue; } - BLI_assert(GS(reference_id->name) == GS(id->name)); + if ((id->override_library->reference->tag & LIB_TAG_DOIT) == 0) { + /* We have an override, but now it does not seem to be necessary to override that ID + * anymore. Check if there are some actual overrides from the user, otherwise assume + * that we can get rid of this local override. */ + LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &id->override_library->properties) { + if (!ELEM(op->rna_prop_type, PROP_POINTER, PROP_COLLECTION)) { + id->override_library->reference->tag |= LIB_TAG_DOIT; + break; + } - if (!BLI_ghash_haskey(linkedref_to_old_override, reference_id)) { - BLI_ghash_insert(linkedref_to_old_override, reference_id, id); - if (!ID_IS_OVERRIDE_LIBRARY_REAL(id) || (id->tag & LIB_TAG_DOIT) == 0) { - continue; - } - if ((id->override_library->reference->tag & LIB_TAG_DOIT) == 0) { - /* We have an override, but now it does not seem to be necessary to override that ID - * anymore. Check if there are some actual overrides from the user, otherwise assume - * that we can get rid of this local override. */ - LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &id->override_library->properties) { - if (!ELEM(op->rna_prop_type, PROP_POINTER, PROP_COLLECTION)) { + bool do_break = false; + LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) { + if ((opop->flag & IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) == 0) { id->override_library->reference->tag |= LIB_TAG_DOIT; - break; - } - - bool do_break = false; - LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) { - if ((opop->flag & IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) == 0) { - id->override_library->reference->tag |= LIB_TAG_DOIT; - do_break = true; - break; - } - } - if (do_break) { + do_break = true; break; } } + if (do_break) { + break; + } } } } @@ -1919,60 +1921,62 @@ static bool lib_override_library_resync(Main *bmain, ListBase *lb; FOREACH_MAIN_LISTBASE_BEGIN (bmain, lb) { FOREACH_MAIN_LISTBASE_ID_BEGIN (lb, id) { - if (id->tag & LIB_TAG_DOIT && id->newid != nullptr && id->lib == id_root_reference->lib) { - ID *id_override_new = id->newid; - ID *id_override_old = static_cast<ID *>(BLI_ghash_lookup(linkedref_to_old_override, id)); + if ((id->tag & LIB_TAG_DOIT) == 0 || id->newid == nullptr || + id->lib != id_root_reference->lib) { + continue; + } + ID *id_override_new = id->newid; + ID *id_override_old = static_cast<ID *>(BLI_ghash_lookup(linkedref_to_old_override, id)); - BLI_assert((id_override_new->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0); - - /* We need to 'move back' newly created override into its proper library (since it was - * duplicated from the reference ID with 'no main' option, it should currently be the same - * as the reference ID one). */ - BLI_assert(/*!ID_IS_LINKED(id_override_new) || */ id_override_new->lib == id->lib); - BLI_assert(id_override_old == nullptr || id_override_old->lib == id_root->lib); - id_override_new->lib = id_root->lib; - /* Remap step below will tag directly linked ones properly as needed. */ - if (ID_IS_LINKED(id_override_new)) { - id_override_new->tag |= LIB_TAG_INDIRECT; - } + BLI_assert((id_override_new->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0); + + /* We need to 'move back' newly created override into its proper library (since it was + * duplicated from the reference ID with 'no main' option, it should currently be the same + * as the reference ID one). */ + BLI_assert(/*!ID_IS_LINKED(id_override_new) || */ id_override_new->lib == id->lib); + BLI_assert(id_override_old == nullptr || id_override_old->lib == id_root->lib); + id_override_new->lib = id_root->lib; + /* Remap step below will tag directly linked ones properly as needed. */ + if (ID_IS_LINKED(id_override_new)) { + id_override_new->tag |= LIB_TAG_INDIRECT; + } - if (id_override_old != nullptr) { - /* Swap the names between old override ID and new one. */ - char id_name_buf[MAX_ID_NAME]; - memcpy(id_name_buf, id_override_old->name, sizeof(id_name_buf)); - memcpy(id_override_old->name, id_override_new->name, sizeof(id_override_old->name)); - memcpy(id_override_new->name, id_name_buf, sizeof(id_override_new->name)); - - BLI_insertlinkreplace(lb, id_override_old, id_override_new); - id_override_old->tag |= LIB_TAG_NO_MAIN; - id_override_new->tag &= ~LIB_TAG_NO_MAIN; - - lib_override_object_posemode_transfer(id_override_new, id_override_old); - - if (ID_IS_OVERRIDE_LIBRARY_REAL(id_override_new)) { - BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_override_old)); - - id_override_new->override_library->flag = id_override_old->override_library->flag; - - /* Copy over overrides rules from old override ID to new one. */ - BLI_duplicatelist(&id_override_new->override_library->properties, - &id_override_old->override_library->properties); - IDOverrideLibraryProperty *op_new = static_cast<IDOverrideLibraryProperty *>( - id_override_new->override_library->properties.first); - IDOverrideLibraryProperty *op_old = static_cast<IDOverrideLibraryProperty *>( - id_override_old->override_library->properties.first); - for (; op_new; op_new = op_new->next, op_old = op_old->next) { - lib_override_library_property_copy(op_new, op_old); - } + if (id_override_old != nullptr) { + /* Swap the names between old override ID and new one. */ + char id_name_buf[MAX_ID_NAME]; + memcpy(id_name_buf, id_override_old->name, sizeof(id_name_buf)); + memcpy(id_override_old->name, id_override_new->name, sizeof(id_override_old->name)); + memcpy(id_override_new->name, id_name_buf, sizeof(id_override_new->name)); + + BLI_insertlinkreplace(lb, id_override_old, id_override_new); + id_override_old->tag |= LIB_TAG_NO_MAIN; + id_override_new->tag &= ~LIB_TAG_NO_MAIN; + + lib_override_object_posemode_transfer(id_override_new, id_override_old); + + if (ID_IS_OVERRIDE_LIBRARY_REAL(id_override_new)) { + BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_override_old)); + + id_override_new->override_library->flag = id_override_old->override_library->flag; + + /* Copy over overrides rules from old override ID to new one. */ + BLI_duplicatelist(&id_override_new->override_library->properties, + &id_override_old->override_library->properties); + IDOverrideLibraryProperty *op_new = static_cast<IDOverrideLibraryProperty *>( + id_override_new->override_library->properties.first); + IDOverrideLibraryProperty *op_old = static_cast<IDOverrideLibraryProperty *>( + id_override_old->override_library->properties.first); + for (; op_new; op_new = op_new->next, op_old = op_old->next) { + lib_override_library_property_copy(op_new, op_old); } - - BLI_addtail(no_main_ids_list, id_override_old); - } - else { - /* Add to proper main list, ensure unique name for local ID, sort, and clear relevant - * tags. */ - BKE_libblock_management_main_add(bmain, id_override_new); } + + BLI_addtail(no_main_ids_list, id_override_old); + } + else { + /* Add to proper main list, ensure unique name for local ID, sort, and clear relevant + * tags. */ + BKE_libblock_management_main_add(bmain, id_override_new); } } FOREACH_MAIN_LISTBASE_ID_END; @@ -1991,53 +1995,56 @@ static bool lib_override_library_resync(Main *bmain, * remapped, and all new local override IDs have gotten their proper original names, otherwise * override operations based on those ID names would fail. */ FOREACH_MAIN_ID_BEGIN (bmain, id) { - if (id->tag & LIB_TAG_DOIT && id->newid != nullptr && id->lib == id_root_reference->lib) { - ID *id_override_new = id->newid; - if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_override_new)) { - continue; - } - ID *id_override_old = static_cast<ID *>(BLI_ghash_lookup(linkedref_to_old_override, id)); + if ((id->tag & LIB_TAG_DOIT) == 0 || id->newid == nullptr || + id->lib != id_root_reference->lib) { + continue; + } - if (id_override_old == nullptr) { - continue; - } - if (ID_IS_OVERRIDE_LIBRARY_REAL(id_override_old)) { - /* Apply rules on new override ID using old one as 'source' data. */ - /* Note that since we already remapped ID pointers in old override IDs to new ones, we - * can also apply ID pointer override rules safely here. */ - PointerRNA rnaptr_src, rnaptr_dst; - RNA_id_pointer_create(id_override_old, &rnaptr_src); - RNA_id_pointer_create(id_override_new, &rnaptr_dst); - - /* We remove any operation tagged with `IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE`, - * that way the potentially new pointer will be properly kept, when old one is still valid - * too (typical case: assigning new ID to some usage, while old one remains used elsewhere - * in the override hierarchy). */ - LISTBASE_FOREACH_MUTABLE ( - IDOverrideLibraryProperty *, op, &id_override_new->override_library->properties) { - LISTBASE_FOREACH_MUTABLE (IDOverrideLibraryPropertyOperation *, opop, &op->operations) { - if (opop->flag & IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) { - lib_override_library_property_operation_clear(opop); - BLI_freelinkN(&op->operations, opop); - } - } - if (BLI_listbase_is_empty(&op->operations)) { - BKE_lib_override_library_property_delete(id_override_new->override_library, op); + ID *id_override_new = id->newid; + if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_override_new)) { + continue; + } + + ID *id_override_old = static_cast<ID *>(BLI_ghash_lookup(linkedref_to_old_override, id)); + if (id_override_old == nullptr) { + continue; + } + + if (ID_IS_OVERRIDE_LIBRARY_REAL(id_override_old)) { + /* Apply rules on new override ID using old one as 'source' data. */ + /* Note that since we already remapped ID pointers in old override IDs to new ones, we + * can also apply ID pointer override rules safely here. */ + PointerRNA rnaptr_src, rnaptr_dst; + RNA_id_pointer_create(id_override_old, &rnaptr_src); + RNA_id_pointer_create(id_override_new, &rnaptr_dst); + + /* We remove any operation tagged with `IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE`, + * that way the potentially new pointer will be properly kept, when old one is still valid + * too (typical case: assigning new ID to some usage, while old one remains used elsewhere + * in the override hierarchy). */ + LISTBASE_FOREACH_MUTABLE ( + IDOverrideLibraryProperty *, op, &id_override_new->override_library->properties) { + LISTBASE_FOREACH_MUTABLE (IDOverrideLibraryPropertyOperation *, opop, &op->operations) { + if (opop->flag & IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) { + lib_override_library_property_operation_clear(opop); + BLI_freelinkN(&op->operations, opop); } } - - RNA_struct_override_apply(bmain, - &rnaptr_dst, - &rnaptr_src, - nullptr, - id_override_new->override_library, - do_hierarchy_enforce ? - RNA_OVERRIDE_APPLY_FLAG_IGNORE_ID_POINTERS : - RNA_OVERRIDE_APPLY_FLAG_NOP); + if (BLI_listbase_is_empty(&op->operations)) { + BKE_lib_override_library_property_delete(id_override_new->override_library, op); + } } - BLI_linklist_prepend(&id_override_old_list, id_override_old); + RNA_struct_override_apply(bmain, + &rnaptr_dst, + &rnaptr_src, + nullptr, + id_override_new->override_library, + do_hierarchy_enforce ? RNA_OVERRIDE_APPLY_FLAG_IGNORE_ID_POINTERS : + RNA_OVERRIDE_APPLY_FLAG_NOP); } + + BLI_linklist_prepend(&id_override_old_list, id_override_old); } FOREACH_MAIN_ID_END; @@ -2081,9 +2088,13 @@ static bool lib_override_library_resync(Main *bmain, } /* Also deal with old overrides that went missing in new linked data - only for real local * overrides for now, not those who are linked. */ - else if (id->tag & LIB_TAG_MISSING && !ID_IS_LINKED(id)) { - BLI_assert(ID_IS_OVERRIDE_LIBRARY(id)); - if (!BKE_lib_override_library_is_user_edited(id)) { + else if (id->tag & LIB_TAG_MISSING && !ID_IS_LINKED(id) && ID_IS_OVERRIDE_LIBRARY(id)) { + if (ID_IS_OVERRIDE_LIBRARY_REAL(id) && + id->override_library->reference->lib->id.tag & LIB_TAG_MISSING) { + /* Do not delete overrides which reference is missing because the library itself is missing + * (ref. T100586). */ + } + else if (!BKE_lib_override_library_is_user_edited(id)) { /* If user never edited them, we can delete them. */ id->tag |= LIB_TAG_DOIT; id->tag &= ~LIB_TAG_MISSING; @@ -2390,11 +2401,21 @@ static void lib_override_library_main_resync_on_library_indirect_level( if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) { continue; } + + if (!lib_override_resync_id_lib_level_is_valid(id, library_indirect_level, true)) { + continue; + } + if (id->tag & (LIB_TAG_DOIT | LIB_TAG_MISSING)) { /* We already processed that ID as part of another ID's hierarchy. */ continue; } + /* Do not attempt to resync from missing data. */ + if (((id->tag | id->override_library->reference->tag) & LIB_TAG_MISSING) != 0) { + continue; + } + if (id->override_library->flag & IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY) { /* This ID is not part of an override hierarchy. */ continue; @@ -2423,6 +2444,11 @@ static void lib_override_library_main_resync_on_library_indirect_level( continue; } + /* Do not attempt to resync from missing data. */ + if (((id->tag | id->override_library->reference->tag) & LIB_TAG_MISSING) != 0) { + continue; + } + if (id->override_library->flag & IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY) { /* This ID is not part of an override hierarchy. */ BLI_assert((id->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0); @@ -2550,6 +2576,15 @@ static void lib_override_library_main_resync_on_library_indirect_level( /* Check there are no left-over IDs needing resync from the current (or higher) level of indirect * library level. */ FOREACH_MAIN_ID_BEGIN (bmain, id) { + if (!ID_IS_OVERRIDE_LIBRARY(id)) { + continue; + } + /* Do not attempt to resync to/from missing data. */ + if (((id->tag | (ID_IS_OVERRIDE_LIBRARY_REAL(id) ? id->override_library->reference->tag : 0)) & + LIB_TAG_MISSING) != 0) { + continue; + } + const bool is_valid_tagged_need_resync = ((id->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0 || lib_override_resync_id_lib_level_is_valid( id, library_indirect_level - 1, false)); diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 6acf15bbb2a..6f91ce2a4e9 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -101,6 +101,10 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int const Mesh *mesh_src = (const Mesh *)id_src; BKE_mesh_runtime_reset_on_copy(mesh_dst, flag); + /* Copy face dot tags, since meshes may be duplicated after a subsurf modifier + * or node, but we still need to be able to draw face center vertices. */ + mesh_dst->runtime.subsurf_face_dot_tags = static_cast<uint32_t *>( + MEM_dupallocN(mesh_src->runtime.subsurf_face_dot_tags)); if ((mesh_src->id.tag & LIB_TAG_NO_MAIN) == 0) { /* This is a direct copy of a main mesh, so for now it has the same topology. */ mesh_dst->runtime.deformed_only = true; diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc index 85aed01ce52..423f76407a0 100644 --- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc +++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc @@ -275,11 +275,15 @@ Mesh *BKE_mesh_remesh_voxel(const Mesh *mesh, #endif } -void BKE_mesh_remesh_reproject_paint_mask(Mesh *target, Mesh *source) +void BKE_mesh_remesh_reproject_paint_mask(Mesh *target, const Mesh *source) { BVHTreeFromMesh bvhtree = {nullptr}; BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_VERTS, 2); - MVert *target_verts = (MVert *)CustomData_get_layer(&target->vdata, CD_MVERT); + const MVert *target_verts = (const MVert *)CustomData_get_layer(&target->vdata, CD_MVERT); + const float *source_mask = (const float *)CustomData_get_layer(&source->vdata, CD_PAINT_MASK); + if (source_mask == nullptr) { + return; + } float *target_mask; if (CustomData_has_layer(&target->vdata, CD_PAINT_MASK)) { @@ -290,15 +294,6 @@ void BKE_mesh_remesh_reproject_paint_mask(Mesh *target, Mesh *source) &target->vdata, CD_PAINT_MASK, CD_CALLOC, nullptr, target->totvert); } - const float *source_mask; - if (CustomData_has_layer(&source->vdata, CD_PAINT_MASK)) { - source_mask = (float *)CustomData_get_layer(&source->vdata, CD_PAINT_MASK); - } - else { - source_mask = (float *)CustomData_add_layer( - &source->vdata, CD_PAINT_MASK, CD_CALLOC, nullptr, source->totvert); - } - for (int i = 0; i < target->totvert; i++) { float from_co[3]; BVHTreeNearest nearest; @@ -313,13 +308,16 @@ void BKE_mesh_remesh_reproject_paint_mask(Mesh *target, Mesh *source) free_bvhtree_from_mesh(&bvhtree); } -void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, Mesh *source) +void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source) { - BVHTreeFromMesh bvhtree = {nullptr}; - const MPoly *target_polys = (const MPoly *)CustomData_get_layer(&target->pdata, CD_MPOLY); const MVert *target_verts = (const MVert *)CustomData_get_layer(&target->vdata, CD_MVERT); const MLoop *target_loops = (const MLoop *)CustomData_get_layer(&target->ldata, CD_MLOOP); + const int *source_face_sets = (const int *)CustomData_get_layer(&source->pdata, + CD_SCULPT_FACE_SETS); + if (source_face_sets == nullptr) { + return; + } int *target_face_sets; if (CustomData_has_layer(&target->pdata, CD_SCULPT_FACE_SETS)) { @@ -330,16 +328,8 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, Mesh *source) &target->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, nullptr, target->totpoly); } - const int *source_face_sets; - if (CustomData_has_layer(&source->pdata, CD_SCULPT_FACE_SETS)) { - source_face_sets = (const int *)CustomData_get_layer(&source->pdata, CD_SCULPT_FACE_SETS); - } - else { - source_face_sets = (const int *)CustomData_add_layer( - &source->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, nullptr, source->totpoly); - } - const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(source); + BVHTreeFromMesh bvhtree = {nullptr}; BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_LOOPTRI, 2); for (int i = 0; i < target->totpoly; i++) { diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 9b28568aaf7..4ed2885dd90 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -3383,8 +3383,10 @@ struct bNodeSocket *ntreeAddSocketInterfaceFromSocket(bNodeTree *ntree, bNode *from_node, bNodeSocket *from_sock) { - bNodeSocket *iosock = ntreeAddSocketInterface( - ntree, static_cast<eNodeSocketInOut>(from_sock->in_out), from_sock->idname, DATA_(from_sock->name)); + bNodeSocket *iosock = ntreeAddSocketInterface(ntree, + static_cast<eNodeSocketInOut>(from_sock->in_out), + from_sock->idname, + DATA_(from_sock->name)); if (iosock) { if (iosock->typeinfo->interface_from_socket) { iosock->typeinfo->interface_from_socket(ntree, iosock, from_node, from_sock); diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh index 4784114c88a..19ee2334bd9 100644 --- a/source/blender/blenlib/BLI_virtual_array.hh +++ b/source/blender/blenlib/BLI_virtual_array.hh @@ -876,9 +876,12 @@ template<typename T> class VMutableArray; * construct the virtual array first and then move it into the vector. */ namespace varray_tag { -struct span {}; -struct single_ref {}; -struct single {}; +struct span { +}; +struct single_ref { +}; +struct single { +}; } // namespace varray_tag /** diff --git a/source/blender/draw/engines/eevee_next/eevee_engine.cc b/source/blender/draw/engines/eevee_next/eevee_engine.cc index 37b4bde324e..2e476b7d891 100644 --- a/source/blender/draw/engines/eevee_next/eevee_engine.cc +++ b/source/blender/draw/engines/eevee_next/eevee_engine.cc @@ -172,7 +172,51 @@ static void eevee_render_update_passes(RenderEngine *engine, Scene *scene, ViewL if (!GPU_shader_storage_buffer_objects_support()) { return; } - UNUSED_VARS(engine, scene, view_layer); + + RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA); + +#define CHECK_PASS_LEGACY(name, type, channels, chanid) \ + if (view_layer->passflag & (SCE_PASS_##name)) { \ + RE_engine_register_pass( \ + engine, scene, view_layer, RE_PASSNAME_##name, channels, chanid, type); \ + } \ + ((void)0) +#define CHECK_PASS_EEVEE(name, type, channels, chanid) \ + if (view_layer->eevee.render_passes & (EEVEE_RENDER_PASS_##name)) { \ + RE_engine_register_pass( \ + engine, scene, view_layer, RE_PASSNAME_##name, channels, chanid, type); \ + } \ + ((void)0) + + CHECK_PASS_LEGACY(Z, SOCK_FLOAT, 1, "Z"); + CHECK_PASS_LEGACY(MIST, SOCK_FLOAT, 1, "Z"); + CHECK_PASS_LEGACY(NORMAL, SOCK_VECTOR, 3, "XYZ"); + CHECK_PASS_LEGACY(DIFFUSE_DIRECT, SOCK_RGBA, 3, "RGB"); + CHECK_PASS_LEGACY(DIFFUSE_COLOR, SOCK_RGBA, 3, "RGB"); + CHECK_PASS_LEGACY(GLOSSY_DIRECT, SOCK_RGBA, 3, "RGB"); + CHECK_PASS_LEGACY(GLOSSY_COLOR, SOCK_RGBA, 3, "RGB"); + CHECK_PASS_EEVEE(VOLUME_LIGHT, SOCK_RGBA, 3, "RGB"); + CHECK_PASS_LEGACY(EMIT, SOCK_RGBA, 3, "RGB"); + CHECK_PASS_LEGACY(ENVIRONMENT, SOCK_RGBA, 3, "RGB"); + /* TODO: CHECK_PASS_LEGACY(SHADOW, SOCK_RGBA, 3, "RGB"); + * CHECK_PASS_LEGACY(AO, SOCK_RGBA, 3, "RGB"); + * When available they should be converted from Value textures to RGB. */ + + LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) { + if ((aov->flag & AOV_CONFLICT) != 0) { + continue; + } + switch (aov->type) { + case AOV_TYPE_COLOR: + RE_engine_register_pass(engine, scene, view_layer, aov->name, 4, "RGBA", SOCK_RGBA); + break; + case AOV_TYPE_VALUE: + RE_engine_register_pass(engine, scene, view_layer, aov->name, 1, "X", SOCK_FLOAT); + break; + default: + break; + } + } } static const DrawEngineDataSize eevee_data_size = DRW_VIEWPORT_DATA_SIZE(EEVEE_Data); diff --git a/source/blender/editors/asset/intern/asset_indexer.cc b/source/blender/editors/asset/intern/asset_indexer.cc index 3cc3638c299..cc06fa80429 100644 --- a/source/blender/editors/asset/intern/asset_indexer.cc +++ b/source/blender/editors/asset/intern/asset_indexer.cc @@ -351,7 +351,7 @@ static void init_indexer_entry_from_value(FileIndexerEntry &indexer_entry, { indexer_entry.idcode = entry.get_idcode(); - const std::string &name = entry.get_name(); + const std::string name = entry.get_name(); BLI_strncpy( indexer_entry.datablock_info.name, name.c_str(), sizeof(indexer_entry.datablock_info.name)); @@ -359,19 +359,19 @@ static void init_indexer_entry_from_value(FileIndexerEntry &indexer_entry, indexer_entry.datablock_info.asset_data = asset_data; if (entry.has_description()) { - const std::string &description = entry.get_description(); - char *description_c_str = static_cast<char *>(MEM_mallocN(description.length() + 1, __func__)); - BLI_strncpy(description_c_str, description.c_str(), description.length() + 1); + const StringRefNull description = entry.get_description(); + char *description_c_str = static_cast<char *>(MEM_mallocN(description.size() + 1, __func__)); + BLI_strncpy(description_c_str, description.c_str(), description.size() + 1); asset_data->description = description_c_str; } if (entry.has_author()) { - const std::string &author = entry.get_author(); - char *author_c_str = static_cast<char *>(MEM_mallocN(author.length() + 1, __func__)); - BLI_strncpy(author_c_str, author.c_str(), author.length() + 1); + const StringRefNull author = entry.get_author(); + char *author_c_str = static_cast<char *>(MEM_mallocN(author.size() + 1, __func__)); + BLI_strncpy(author_c_str, author.c_str(), author.size() + 1); asset_data->author = author_c_str; } - const std::string &catalog_name = entry.get_catalog_name(); + const StringRefNull catalog_name = entry.get_catalog_name(); BLI_strncpy(asset_data->catalog_simple_name, catalog_name.c_str(), sizeof(asset_data->catalog_simple_name)); diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index a6a9b2fcd26..aec22f0f3ae 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -275,7 +275,7 @@ static int geometry_attribute_convert_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); ID *ob_data = static_cast<ID *>(ob->data); - CustomDataLayer *layer = BKE_id_attributes_active_get(ob_data); + const CustomDataLayer *layer = BKE_id_attributes_active_get(ob_data); const std::string name = layer->name; const ConvertAttributeMode mode = static_cast<ConvertAttributeMode>( diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 537696a606e..9843bd22bb6 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -3987,9 +3987,11 @@ static int gpencil_stroke_outline_exec(bContext *C, wmOperator *op) bGPdata *gpd = (bGPdata *)ob->data; const int subdivisions = RNA_int_get(op->ptr, "subdivisions"); const float length = RNA_float_get(op->ptr, "length"); + const bool keep = RNA_boolean_get(op->ptr, "keep"); + const int thickness = RNA_int_get(op->ptr, "thickness"); const int view_mode = RNA_enum_get(op->ptr, "view_mode"); - const int mode = RNA_enum_get(op->ptr, "mode"); + const int material_mode = RNA_enum_get(op->ptr, "material_mode"); const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); /* sanity checks */ @@ -4050,7 +4052,7 @@ static int gpencil_stroke_outline_exec(bContext *C, wmOperator *op) } /* Create a new material. */ int mat_idx = 0; - if (mode == GP_STROKE_USE_NEW_MATERIAL) { + if (material_mode == GP_STROKE_USE_NEW_MATERIAL) { Material *ma = BKE_gpencil_object_material_new(bmain, ob, "Material", NULL); MaterialGPencilStyle *gp_style = ma->gp_style; @@ -4103,11 +4105,12 @@ static int gpencil_stroke_outline_exec(bContext *C, wmOperator *op) CLAMP_MIN(gps_duplicate->thickness, 1.0f); /* Stroke. */ + const float ovr_thickness = keep ? thickness : 0.0f; bGPDstroke *gps_perimeter = BKE_gpencil_stroke_perimeter_from_view( - rv3d, gpd, gpl, gps_duplicate, subdivisions, diff_mat); + rv3d, gpd, gpl, gps_duplicate, subdivisions, diff_mat, ovr_thickness); gps_perimeter->flag &= ~GP_STROKE_SELECT; /* Assign material. */ - switch (mode) { + switch (material_mode) { case GP_STROKE_USE_ACTIVE_MATERIAL: { if (ob->actcol - 1 < 0) { gps_perimeter->mat_nr = 0; @@ -4131,6 +4134,8 @@ static int gpencil_stroke_outline_exec(bContext *C, wmOperator *op) if (length > 0.0f) { BKE_gpencil_stroke_sample(gpd, gps_perimeter, length, false, 0); } + /* Set stroke thickness. */ + gps_perimeter->thickness = thickness; /* Set pressure constant. */ bGPDspoint *pt; @@ -4213,8 +4218,27 @@ void GPENCIL_OT_stroke_outline(wmOperatorType *ot) /* properties */ ot->prop = RNA_def_enum(ot->srna, "view_mode", view_mode, GP_PERIMETER_VIEW, "View", ""); - RNA_def_enum( - ot->srna, "mode", material_mode, GP_STROKE_USE_ACTIVE_MATERIAL, "Material Mode", ""); + RNA_def_enum(ot->srna, + "material_mode", + material_mode, + GP_STROKE_USE_ACTIVE_MATERIAL, + "Material Mode", + ""); + + RNA_def_int(ot->srna, + "thickness", + 1, + 1, + 1000, + "Thickness", + "Thickness of the stroke perimeter", + 1, + 1000); + RNA_def_boolean(ot->srna, + "keep", + true, + "Keep Shape", + "Try to keep global shape when the stroke thickness change"); RNA_def_int(ot->srna, "subdivisions", 3, 0, 10, "Subdivisions", "", 0, 10); diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 7f11ff7ebd5..b196fcae51c 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -944,7 +944,7 @@ static bGPDstroke *gpencil_stroke_to_outline(tGPsdata *p, bGPDstroke *gps) float diff_mat[4][4]; unit_m4(diff_mat); bGPDstroke *gps_perimeter = BKE_gpencil_stroke_perimeter_from_view( - rv3d, p->gpd, gpl, gps_duplicate, 3, diff_mat); + rv3d, p->gpd, gpl, gps_duplicate, 3, diff_mat, 0.0f); /* Assign material. */ if (gpencil_settings->material_alt == NULL) { gps_perimeter->mat_nr = gps->mat_nr; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 3618b933443..c069b3c6292 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -723,15 +723,16 @@ typedef struct sActionzoneData { static bool actionzone_area_poll(bContext *C) { wmWindow *win = CTX_wm_window(C); - bScreen *screen = WM_window_get_active_screen(win); - - if (screen && win && win->eventstate) { - const int *xy = &win->eventstate->xy[0]; + if (win && win->eventstate) { + bScreen *screen = WM_window_get_active_screen(win); + if (screen) { + const int *xy = &win->eventstate->xy[0]; - LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { - LISTBASE_FOREACH (AZone *, az, &area->actionzones) { - if (BLI_rcti_isect_pt_v(&az->rect, xy)) { - return true; + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (AZone *, az, &area->actionzones) { + if (BLI_rcti_isect_pt_v(&az->rect, xy)) { + return true; + } } } } diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc index ebdff8a6c4b..007bff0b170 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc @@ -149,6 +149,12 @@ struct SlideOperationExecutor { report_missing_uv_map_on_original_surface(stroke_extension.reports); return; } + if (curves_orig_->surface_uv_coords().is_empty()) { + BKE_report(stroke_extension.reports, + RPT_WARNING, + TIP_("Curves do not have surface attachment information")); + return; + } const StringRefNull uv_map_name = curves_id_orig_->surface_uv_map; curves_sculpt_ = ctx_.scene->toolsettings->curves_sculpt; diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 994ae4011b4..b78c60e7964 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -361,7 +361,6 @@ static int palette_color_add_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); Paint *paint = BKE_paint_get_active_from_context(C); - Brush *brush = paint->brush; ePaintMode mode = BKE_paintmode_get_active_from_context(C); Palette *palette = paint->palette; PaletteColor *color; @@ -369,17 +368,20 @@ static int palette_color_add_exec(bContext *C, wmOperator *UNUSED(op)) color = BKE_palette_color_add(palette); palette->active_color = BLI_listbase_count(&palette->colors) - 1; - if (ELEM(mode, - PAINT_MODE_TEXTURE_3D, - PAINT_MODE_TEXTURE_2D, - PAINT_MODE_VERTEX, - PAINT_MODE_SCULPT)) { - copy_v3_v3(color->rgb, BKE_brush_color_get(scene, brush)); - color->value = 0.0; - } - else if (mode == PAINT_MODE_WEIGHT) { - zero_v3(color->rgb); - color->value = brush->weight; + if (paint->brush) { + const Brush *brush = paint->brush; + if (ELEM(mode, + PAINT_MODE_TEXTURE_3D, + PAINT_MODE_TEXTURE_2D, + PAINT_MODE_VERTEX, + PAINT_MODE_SCULPT)) { + copy_v3_v3(color->rgb, BKE_brush_color_get(scene, brush)); + color->value = 0.0; + } + else if (mode == PAINT_MODE_WEIGHT) { + zero_v3(color->rgb); + color->value = brush->weight; + } } return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_outliner/outliner_collections.cc b/source/blender/editors/space_outliner/outliner_collections.cc index 440b77adefc..23ee8a2c3f2 100644 --- a/source/blender/editors/space_outliner/outliner_collections.cc +++ b/source/blender/editors/space_outliner/outliner_collections.cc @@ -88,7 +88,7 @@ Collection *outliner_collection_from_tree_element(const TreeElement *te) return nullptr; } -TreeTraversalAction outliner_find_selected_collections(TreeElement *te, void *customdata) +TreeTraversalAction outliner_collect_selected_collections(TreeElement *te, void *customdata) { struct IDsSelectedData *data = static_cast<IDsSelectedData *>(customdata); TreeStoreElem *tselem = TREESTORE(te); @@ -105,7 +105,7 @@ TreeTraversalAction outliner_find_selected_collections(TreeElement *te, void *cu return TRAVERSE_CONTINUE; } -TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata) +TreeTraversalAction outliner_collect_selected_objects(TreeElement *te, void *customdata) { struct IDsSelectedData *data = static_cast<IDsSelectedData *>(customdata); TreeStoreElem *tselem = TREESTORE(te); @@ -136,7 +136,7 @@ void ED_outliner_selected_objects_get(const bContext *C, ListBase *objects) &space_outliner->tree, 0, TSE_SELECTED, - outliner_find_selected_objects, + outliner_collect_selected_objects, &data); LISTBASE_FOREACH (LinkData *, link, &data.selected_array) { TreeElement *ten_selected = (TreeElement *)link->data; @@ -296,7 +296,7 @@ struct CollectionEditData { bool is_liboverride_hierarchy_root_allowed; }; -static TreeTraversalAction collection_find_data_to_edit(TreeElement *te, void *customdata) +static TreeTraversalAction collection_collect_data_to_edit(TreeElement *te, void *customdata) { CollectionEditData *data = static_cast<CollectionEditData *>(customdata); Collection *collection = outliner_collection_from_tree_element(te); @@ -346,7 +346,7 @@ void outliner_collection_delete( /* We first walk over and find the Collections we actually want to delete * (ignoring duplicates). */ outliner_tree_traverse( - space_outliner, &space_outliner->tree, 0, TSE_SELECTED, collection_find_data_to_edit, &data); + space_outliner, &space_outliner->tree, 0, TSE_SELECTED, collection_collect_data_to_edit, &data); /* Effectively delete the collections. */ GSetIterator collections_to_edit_iter; @@ -708,7 +708,7 @@ static int collection_link_exec(bContext *C, wmOperator *op) /* We first walk over and find the Collections we actually want to link (ignoring duplicates). */ outliner_tree_traverse( - space_outliner, &space_outliner->tree, 0, TSE_SELECTED, collection_find_data_to_edit, &data); + space_outliner, &space_outliner->tree, 0, TSE_SELECTED, collection_collect_data_to_edit, &data); /* Effectively link the collections. */ GSetIterator collections_to_edit_iter; @@ -767,7 +767,7 @@ static int collection_instance_exec(bContext *C, wmOperator *UNUSED(op)) /* We first walk over and find the Collections we actually want to instance * (ignoring duplicates). */ outliner_tree_traverse( - space_outliner, &space_outliner->tree, 0, TSE_SELECTED, collection_find_data_to_edit, &data); + space_outliner, &space_outliner->tree, 0, TSE_SELECTED, collection_collect_data_to_edit, &data); /* Find an active collection to add to, that doesn't give dependency cycles. */ LayerCollection *active_lc = BKE_layer_collection_get_active(view_layer); @@ -824,7 +824,7 @@ void OUTLINER_OT_collection_instance(wmOperatorType *ot) /** \name Exclude Collection * \{ */ -static TreeTraversalAction layer_collection_find_data_to_edit(TreeElement *te, void *customdata) +static TreeTraversalAction layer_collection_collect_data_to_edit(TreeElement *te, void *customdata) { CollectionEditData *data = static_cast<CollectionEditData *>(customdata); TreeStoreElem *tselem = TREESTORE(te); @@ -869,7 +869,7 @@ static bool collections_view_layer_poll(bContext *C, bool clear, int flag) &space_outliner->tree, 0, TSE_SELECTED, - layer_collection_find_data_to_edit, + layer_collection_collect_data_to_edit, &data); GSetIterator collections_to_edit_iter; @@ -941,7 +941,7 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op) &space_outliner->tree, 0, TSE_SELECTED, - layer_collection_find_data_to_edit, + layer_collection_collect_data_to_edit, &data); GSetIterator collections_to_edit_iter; @@ -1075,7 +1075,7 @@ static int collection_isolate_exec(bContext *C, wmOperator *op) &space_outliner->tree, 0, TSE_SELECTED, - layer_collection_find_data_to_edit, + layer_collection_collect_data_to_edit, &data); GSetIterator collections_to_edit_iter; @@ -1175,7 +1175,7 @@ static int collection_visibility_exec(bContext *C, wmOperator *op) &space_outliner->tree, 0, TSE_SELECTED, - layer_collection_find_data_to_edit, + layer_collection_collect_data_to_edit, &data); GSetIterator collections_to_edit_iter; @@ -1327,7 +1327,7 @@ static int collection_flag_exec(bContext *C, wmOperator *op) &space_outliner->tree, 0, TSE_SELECTED, - layer_collection_find_data_to_edit, + layer_collection_collect_data_to_edit, &data); GSetIterator collections_to_edit_iter; GSET_ITER (collections_to_edit_iter, data.collections_to_edit) { @@ -1356,7 +1356,7 @@ static int collection_flag_exec(bContext *C, wmOperator *op) &space_outliner->tree, 0, TSE_SELECTED, - collection_find_data_to_edit, + collection_collect_data_to_edit, &data); GSetIterator collections_to_edit_iter; GSET_ITER (collections_to_edit_iter, data.collections_to_edit) { @@ -1461,7 +1461,7 @@ struct OutlinerHideEditData { /** \name Visibility for Collection & Object Operators * \{ */ -static TreeTraversalAction outliner_hide_find_data_to_edit(TreeElement *te, void *customdata) +static TreeTraversalAction outliner_hide_collect_data_to_edit(TreeElement *te, void *customdata) { OutlinerHideEditData *data = static_cast<OutlinerHideEditData *>(customdata); TreeStoreElem *tselem = TREESTORE(te); @@ -1508,7 +1508,7 @@ static int outliner_hide_exec(bContext *C, wmOperator *UNUSED(op)) &space_outliner->tree, 0, TSE_SELECTED, - outliner_hide_find_data_to_edit, + outliner_hide_collect_data_to_edit, &data); GSetIterator collections_to_edit_iter; @@ -1604,7 +1604,7 @@ static int outliner_color_tag_set_exec(bContext *C, wmOperator *op) &space_outliner->tree, 0, TSE_SELECTED, - outliner_find_selected_collections, + outliner_collect_selected_collections, &selected); LISTBASE_FOREACH (LinkData *, link, &selected.selected_array) { diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.cc b/source/blender/editors/space_outliner/outliner_dragdrop.cc index 81224fb6a2b..4a0e00b8bf1 100644 --- a/source/blender/editors/space_outliner/outliner_dragdrop.cc +++ b/source/blender/editors/space_outliner/outliner_dragdrop.cc @@ -1476,7 +1476,7 @@ static int outliner_item_drag_drop_invoke(bContext *C, &space_outliner->tree, 0, TSE_SELECTED, - outliner_find_selected_objects, + outliner_collect_selected_objects, &selected); } else { @@ -1484,7 +1484,7 @@ static int outliner_item_drag_drop_invoke(bContext *C, &space_outliner->tree, 0, TSE_SELECTED, - outliner_find_selected_collections, + outliner_collect_selected_collections, &selected); } diff --git a/source/blender/editors/space_outliner/outliner_intern.hh b/source/blender/editors/space_outliner/outliner_intern.hh index 47b3dbe6152..3d91ee6b062 100644 --- a/source/blender/editors/space_outliner/outliner_intern.hh +++ b/source/blender/editors/space_outliner/outliner_intern.hh @@ -284,8 +284,8 @@ typedef struct IDsSelectedData { struct ListBase selected_array; } IDsSelectedData; -TreeTraversalAction outliner_find_selected_collections(TreeElement *te, void *customdata); -TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata); +TreeTraversalAction outliner_collect_selected_collections(TreeElement *te, void *customdata); +TreeTraversalAction outliner_collect_selected_objects(TreeElement *te, void *customdata); /* outliner_draw.c ---------------------------------------------- */ diff --git a/source/blender/editors/space_outliner/outliner_tools.cc b/source/blender/editors/space_outliner/outliner_tools.cc index ae6b2ee6d58..69c88f3b874 100644 --- a/source/blender/editors/space_outliner/outliner_tools.cc +++ b/source/blender/editors/space_outliner/outliner_tools.cc @@ -2335,7 +2335,7 @@ static void outliner_do_object_delete(bContext *C, } } -static TreeTraversalAction outliner_find_objects_to_delete(TreeElement *te, void *customdata) +static TreeTraversalAction outliner_collect_objects_to_delete(TreeElement *te, void *customdata) { ObjectEditData *data = static_cast<ObjectEditData *>(customdata); GSet *objects_to_delete = data->objects_set; @@ -2402,7 +2402,7 @@ static int outliner_delete_exec(bContext *C, wmOperator *op) &space_outliner->tree, 0, TSE_SELECTED, - outliner_find_objects_to_delete, + outliner_collect_objects_to_delete, &object_delete_data); if (delete_hierarchy) { diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc index fdcf9798b7f..68f172169f4 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc @@ -568,7 +568,7 @@ static void add_fields_as_extra_columns(SpaceSpreadsheet *sspreadsheet, GArray<> &evaluated_array = cache.arrays.lookup_or_add_cb({domain, field}, [&]() { GArray<> evaluated_array(field.cpp_type(), domain_num); - bke::GeometryComponentFieldContext field_context{component, domain}; + bke::GeometryFieldContext field_context{component, domain}; fn::FieldEvaluator field_evaluator{field_context, domain_num}; field_evaluator.add_with_destination(field, evaluated_array); field_evaluator.evaluate(); diff --git a/source/blender/editors/transform/transform_mode_rotate.c b/source/blender/editors/transform/transform_mode_rotate.c index 18c517fa5b4..f3186b21cb9 100644 --- a/source/blender/editors/transform/transform_mode_rotate.c +++ b/source/blender/editors/transform/transform_mode_rotate.c @@ -307,7 +307,7 @@ static bool uv_rotation_in_clip_bounds_test(const TransInfo *t, const float angl pr[0] = cos_angle * uv[0] + sin_angle * uv[1]; pr[1] = -sin_angle * uv[0] + cos_angle * uv[1]; add_v2_v2(pr, center); - /* TODO: udim support. */ + /* TODO: UDIM support. */ if (pr[0] < 0.0f || 1.0f < pr[0]) { return false; } diff --git a/source/blender/geometry/GEO_resample_curves.hh b/source/blender/geometry/GEO_resample_curves.hh index 97399ccb0a5..7ecfb5c26ec 100644 --- a/source/blender/geometry/GEO_resample_curves.hh +++ b/source/blender/geometry/GEO_resample_curves.hh @@ -4,12 +4,12 @@ #include "FN_field.hh" -#include "BKE_geometry_set.hh" - -struct Curves; +#include "BKE_curves.hh" namespace blender::geometry { +using bke::CurvesGeometry; + /** * Create new curves where the selected curves have been resampled with a number of uniform-length * samples defined by the count field. Interpolate attributes to the result, with an accuracy that @@ -17,23 +17,23 @@ namespace blender::geometry { * * \note The values provided by the #count_field are clamped to 1 or greater. */ -Curves *resample_to_count(const CurveComponent &src_component, - const fn::Field<bool> &selection_field, - const fn::Field<int> &count_field); +CurvesGeometry resample_to_count(const CurvesGeometry &src_curves, + const fn::Field<bool> &selection_field, + const fn::Field<int> &count_field); /** * Create new curves resampled to make each segment have the length specified by the * #segment_length field input, rounded to make the length of each segment the same. * The accuracy will depend on the curve's resolution parameter. */ -Curves *resample_to_length(const CurveComponent &src_component, - const fn::Field<bool> &selection_field, - const fn::Field<float> &segment_length_field); +CurvesGeometry resample_to_length(const CurvesGeometry &src_curves, + const fn::Field<bool> &selection_field, + const fn::Field<float> &segment_length_field); /** * Evaluate each selected curve to its implicit evaluated points. */ -Curves *resample_to_evaluated(const CurveComponent &src_component, - const fn::Field<bool> &selection_field); +CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, + const fn::Field<bool> &selection_field); } // namespace blender::geometry diff --git a/source/blender/geometry/intern/resample_curves.cc b/source/blender/geometry/intern/resample_curves.cc index e4cb99a9eac..d5560a95a18 100644 --- a/source/blender/geometry/intern/resample_curves.cc +++ b/source/blender/geometry/intern/resample_curves.cc @@ -88,20 +88,20 @@ static bool interpolate_attribute_to_poly_curve(const bke::AttributeIDRef &attri * Retrieve spans from source and result attributes. */ static void retrieve_attribute_spans(const Span<bke::AttributeIDRef> ids, - const CurveComponent &src_component, - CurveComponent &dst_component, + const CurvesGeometry &src_curves, + CurvesGeometry &dst_curves, Vector<GSpan> &src, Vector<GMutableSpan> &dst, Vector<bke::GSpanAttributeWriter> &dst_attributes) { for (const int i : ids.index_range()) { - GVArray src_attribute = src_component.attributes()->lookup(ids[i], ATTR_DOMAIN_POINT); + GVArray src_attribute = src_curves.attributes().lookup(ids[i], ATTR_DOMAIN_POINT); BLI_assert(src_attribute); src.append(src_attribute.get_internal_span()); const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(src_attribute.type()); bke::GSpanAttributeWriter dst_attribute = - dst_component.attributes_for_write()->lookup_or_add_for_write_only_span( + dst_curves.attributes_for_write().lookup_or_add_for_write_only_span( ids[i], ATTR_DOMAIN_POINT, data_type); dst.append(dst_attribute.span); dst_attributes.append(std::move(dst_attribute)); @@ -121,16 +121,13 @@ struct AttributesForInterpolation : NonCopyable, NonMovable { /** * Gather a set of all generic attribute IDs to copy to the result curves. */ -static void gather_point_attributes_to_interpolate(const CurveComponent &src_component, - CurveComponent &dst_component, +static void gather_point_attributes_to_interpolate(const CurvesGeometry &src_curves, + CurvesGeometry &dst_curves, AttributesForInterpolation &result) { - bke::CurvesGeometry &dst_curves = bke::CurvesGeometry::wrap( - dst_component.get_for_write()->geometry); - VectorSet<bke::AttributeIDRef> ids; VectorSet<bke::AttributeIDRef> ids_no_interpolation; - src_component.attributes()->for_all( + src_curves.attributes().for_all( [&](const bke::AttributeIDRef &id, const bke::AttributeMetaData meta_data) { if (meta_data.domain != ATTR_DOMAIN_POINT) { return true; @@ -152,29 +149,25 @@ static void gather_point_attributes_to_interpolate(const CurveComponent &src_com ids.remove_contained("position"); retrieve_attribute_spans( - ids, src_component, dst_component, result.src, result.dst, result.dst_attributes); + ids, src_curves, dst_curves, result.src, result.dst, result.dst_attributes); /* Attributes that aren't interpolated like Bezier handles still have to be copied * to the result when there are any unselected curves of the corresponding type. */ retrieve_attribute_spans(ids_no_interpolation, - src_component, - dst_component, + src_curves, + dst_curves, result.src_no_interpolation, result.dst_no_interpolation, result.dst_attributes); } -static Curves *resample_to_uniform(const CurveComponent &src_component, - const fn::Field<bool> &selection_field, - const fn::Field<int> &count_field) +static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, + const fn::Field<bool> &selection_field, + const fn::Field<int> &count_field) { - const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap( - src_component.get_for_read()->geometry); - /* Create the new curves without any points and evaluate the final count directly * into the offsets array, in order to be accumulated into offsets later. */ - Curves *dst_curves_id = bke::curves_new_nomain(0, src_curves.curves_num()); - bke::CurvesGeometry &dst_curves = bke::CurvesGeometry::wrap(dst_curves_id->geometry); + CurvesGeometry dst_curves = CurvesGeometry(0, src_curves.curves_num()); /* Directly copy curve attributes, since they stay the same (except for curve types). */ CustomData_copy(&src_curves.curve_data, @@ -184,7 +177,7 @@ static Curves *resample_to_uniform(const CurveComponent &src_component, src_curves.curves_num()); MutableSpan<int> dst_offsets = dst_curves.offsets_for_write(); - bke::GeometryComponentFieldContext field_context{src_component, ATTR_DOMAIN_CURVE}; + bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_CURVE}; fn::FieldEvaluator evaluator{field_context, src_curves.curves_num()}; evaluator.set_selection(selection_field); evaluator.add_with_destination(count_field, dst_offsets); @@ -207,9 +200,7 @@ static Curves *resample_to_uniform(const CurveComponent &src_component, MutableSpan<float3> dst_positions = dst_curves.positions_for_write(); AttributesForInterpolation attributes; - CurveComponent dst_component; - dst_component.replace(dst_curves_id, GeometryOwnershipType::Editable); - gather_point_attributes_to_interpolate(src_component, dst_component, attributes); + gather_point_attributes_to_interpolate(src_curves, dst_curves, attributes); src_curves.ensure_evaluated_lengths(); @@ -322,32 +313,30 @@ static Curves *resample_to_uniform(const CurveComponent &src_component, attribute.finish(); } - return dst_curves_id; + return dst_curves; } -Curves *resample_to_count(const CurveComponent &src_component, - const fn::Field<bool> &selection_field, - const fn::Field<int> &count_field) +CurvesGeometry resample_to_count(const CurvesGeometry &src_curves, + const fn::Field<bool> &selection_field, + const fn::Field<int> &count_field) { - return resample_to_uniform(src_component, selection_field, get_count_input_max_one(count_field)); + return resample_to_uniform(src_curves, selection_field, get_count_input_max_one(count_field)); } -Curves *resample_to_length(const CurveComponent &src_component, - const fn::Field<bool> &selection_field, - const fn::Field<float> &segment_length_field) +CurvesGeometry resample_to_length(const CurvesGeometry &src_curves, + const fn::Field<bool> &selection_field, + const fn::Field<float> &segment_length_field) { return resample_to_uniform( - src_component, selection_field, get_count_input_from_length(segment_length_field)); + src_curves, selection_field, get_count_input_from_length(segment_length_field)); } -Curves *resample_to_evaluated(const CurveComponent &src_component, - const fn::Field<bool> &selection_field) +CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, + const fn::Field<bool> &selection_field) { - const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap( - src_component.get_for_read()->geometry); src_curves.ensure_evaluated_offsets(); - bke::GeometryComponentFieldContext field_context{src_component, ATTR_DOMAIN_CURVE}; + bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_CURVE}; fn::FieldEvaluator evaluator{field_context, src_curves.curves_num()}; evaluator.set_selection(selection_field); evaluator.evaluate(); @@ -355,8 +344,7 @@ Curves *resample_to_evaluated(const CurveComponent &src_component, const Vector<IndexRange> unselected_ranges = selection.extract_ranges_invert( src_curves.curves_range(), nullptr); - Curves *dst_curves_id = bke::curves_new_nomain(0, src_curves.curves_num()); - bke::CurvesGeometry &dst_curves = bke::CurvesGeometry::wrap(dst_curves_id->geometry); + CurvesGeometry dst_curves(0, src_curves.curves_num()); /* Directly copy curve attributes, since they stay the same (except for curve types). */ CustomData_copy(&src_curves.curve_data, @@ -384,9 +372,7 @@ Curves *resample_to_evaluated(const CurveComponent &src_component, MutableSpan<float3> dst_positions = dst_curves.positions_for_write(); AttributesForInterpolation attributes; - CurveComponent dst_component; - dst_component.replace(dst_curves_id, GeometryOwnershipType::Editable); - gather_point_attributes_to_interpolate(src_component, dst_component, attributes); + gather_point_attributes_to_interpolate(src_curves, dst_curves, attributes); threading::parallel_for(selection.index_range(), 512, [&](IndexRange selection_range) { const IndexMask sliced_selection = selection.slice(selection_range); @@ -445,7 +431,7 @@ Curves *resample_to_evaluated(const CurveComponent &src_component, attribute.finish(); } - return dst_curves_id; + return dst_curves; } } // namespace blender::geometry diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 08d38baf39f..a87c7ea4809 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -331,20 +331,20 @@ void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id, for (int col_i = 0; col_i < totcol; col_i++) { GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, vbo_id->col[col_i], &col_step); - MPropCol *pcol = NULL; - MLoopCol *mcol = NULL; + const MPropCol *pcol = NULL; + const MLoopCol *mcol = NULL; GPUAttrRef *ref = vcol_refs + col_i; const CustomData *cdata = ref->domain == ATTR_DOMAIN_POINT ? &mesh->vdata : &mesh->ldata; - CustomDataLayer *layer = cdata->layers + ref->layer_idx; + const CustomDataLayer *layer = cdata->layers + ref->layer_idx; bool color_loops = ref->domain == ATTR_DOMAIN_CORNER; if (layer->type == CD_PROP_COLOR) { - pcol = (MPropCol *)layer->data; + pcol = (const MPropCol *)layer->data; } else { - mcol = (MLoopCol *)layer->data; + mcol = (const MLoopCol *)layer->data; } for (uint i = 0; i < buffers->face_indices_len; i++) { @@ -366,7 +366,7 @@ void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id, ushort scol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX}; if (pcol) { - MPropCol *pcol2 = pcol + (color_loops ? loop_index : vtri[j]); + const MPropCol *pcol2 = pcol + (color_loops ? loop_index : vtri[j]); scol[0] = unit_float_to_ushort_clamp(pcol2->color[0]); scol[1] = unit_float_to_ushort_clamp(pcol2->color[1]); @@ -1233,7 +1233,7 @@ static int gpu_pbvh_make_attr_offs(eAttrDomainMask domain_mask, continue; } - CustomDataLayer *cl = cdata->layers; + const CustomDataLayer *cl = cdata->layers; for (int i = 0; count < MAX_GPU_ATTR && i < cdata->totlayer; i++, cl++) { if ((CD_TYPE_AS_MASK(cl->type) & type_mask) && !(cl->flag & CD_FLAG_TEMPORARY)) { @@ -1320,8 +1320,8 @@ bool GPU_pbvh_attribute_names_update(PBVHType pbvh_type, BKE_id_attribute_copy_domains_temp(ID_ME, vdata, NULL, ldata, NULL, NULL, &me_query.id); - CustomDataLayer *active_color_layer = BKE_id_attributes_active_color_get(&me_query.id); - CustomDataLayer *render_color_layer = BKE_id_attributes_render_color_get(&me_query.id); + const CustomDataLayer *active_color_layer = BKE_id_attributes_active_color_get(&me_query.id); + const CustomDataLayer *render_color_layer = BKE_id_attributes_render_color_get(&me_query.id); eAttrDomain active_color_domain = active_color_layer ? BKE_id_attribute_domain(&me_query.id, active_color_layer) : @@ -1375,7 +1375,7 @@ bool GPU_pbvh_attribute_names_update(PBVHType pbvh_type, vbo_id->totuv = 0; if (pbvh_type == PBVH_FACES && ldata && CustomData_has_layer(ldata, CD_MLOOPUV)) { GPUAttrRef uv_layers[MAX_GPU_ATTR]; - CustomDataLayer *active = NULL, *render = NULL; + const CustomDataLayer *active = NULL, *render = NULL; active = get_active_layer(ldata, CD_MLOOPUV); render = get_render_layer(ldata, CD_MLOOPUV); @@ -1401,7 +1401,7 @@ bool GPU_pbvh_attribute_names_update(PBVHType pbvh_type, vbo_id->uv[i] = GPU_vertformat_attr_add( &vbo_id->format, "uvs", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - CustomDataLayer *cl = ldata->layers + ref->layer_idx; + const CustomDataLayer *cl = ldata->layers + ref->layer_idx; bool is_active = ref->layer_idx == CustomData_get_active_layer_index(ldata, CD_MLOOPUV); DRW_cdlayer_attr_aliases_add(&vbo_id->format, "u", ldata, cl, cl == render, is_active); diff --git a/source/blender/gpu/metal/mtl_query.mm b/source/blender/gpu/metal/mtl_query.mm index 73e5f72dc5b..8983ea7ec44 100644 --- a/source/blender/gpu/metal/mtl_query.mm +++ b/source/blender/gpu/metal/mtl_query.mm @@ -30,8 +30,8 @@ void MTLQueryPool::allocate_buffer() { /* Allocate Metal buffer for visibility results. */ size_t buffer_size_in_bytes = VISIBILITY_COUNT_PER_BUFFER * VISIBILITY_RESULT_SIZE_IN_BYTES; - gpu::MTLBuffer *buffer = MTLContext::get_global_memory_manager().allocate( - buffer_size_in_bytes, true); + gpu::MTLBuffer *buffer = MTLContext::get_global_memory_manager().allocate(buffer_size_in_bytes, + true); BLI_assert(buffer); buffer_.append(buffer); } diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc index cc4d604bd7b..83f970d3965 100644 --- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc +++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc @@ -367,7 +367,7 @@ bool ABCGenericMeshWriter::get_velocities(struct Mesh *mesh, std::vector<Imath:: { /* Export velocity attribute output by fluid sim, sequence cache modifier * and geometry nodes. */ - CustomDataLayer *velocity_layer = BKE_id_attribute_find( + const CustomDataLayer *velocity_layer = BKE_id_attribute_find( &mesh->id, "velocity", CD_PROP_FLOAT3, ATTR_DOMAIN_POINT); if (velocity_layer == nullptr) { diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.cc b/source/blender/io/gpencil/intern/gpencil_io_base.cc index 6db3eccedbe..e7d8faaacfa 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_base.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_base.cc @@ -257,7 +257,7 @@ float GpencilIO::stroke_point_radius_get(bGPDlayer *gpl, bGPDstroke *gps) /* Radius. */ bGPDstroke *gps_perimeter = BKE_gpencil_stroke_perimeter_from_view( - rv3d_, gpd_, gpl, gps, 3, diff_mat_.values); + rv3d_, gpd_, gpl, gps, 3, diff_mat_.values, 0.0f); pt = &gps_perimeter->points[0]; const float2 screen_ex = gpencil_3D_point_to_2D(&pt->x); diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc index 700d91791a8..95e83769979 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc @@ -192,7 +192,7 @@ void GpencilExporterPDF::export_gpencil_layers() } else { bGPDstroke *gps_perimeter = BKE_gpencil_stroke_perimeter_from_view( - rv3d_, gpd_, gpl, gps_duplicate, 3, diff_mat_.values); + rv3d_, gpd_, gpl, gps_duplicate, 3, diff_mat_.values, 0.0f); /* Sample stroke. */ if (params_.stroke_sample > 0.0f) { diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc index 2601ad05ea7..e0eded35ce9 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc @@ -217,7 +217,7 @@ void GpencilExporterSVG::export_gpencil_layers() } else { bGPDstroke *gps_perimeter = BKE_gpencil_stroke_perimeter_from_view( - rv3d_, gpd_, gpl, gps_duplicate, 3, diff_mat_.values); + rv3d_, gpd_, gpl, gps_duplicate, 3, diff_mat_.values, 0.0f); /* Sample stroke. */ if (params_.stroke_sample > 0.0f) { diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc index 076f6b724a0..4c3d52131b7 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc @@ -255,7 +255,7 @@ void OBJWriter::write_vertex_coords(FormatHandler<eFileType::OBJ> &fh, const int tot_count = obj_mesh_data.tot_vertices(); Mesh *mesh = obj_mesh_data.get_mesh(); - CustomDataLayer *colors_layer = nullptr; + const CustomDataLayer *colors_layer = nullptr; if (write_colors) { colors_layer = BKE_id_attributes_active_color_get(&mesh->id); } diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 9c95561904a..d3b43176700 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1002,7 +1002,7 @@ static Vector<OutputAttributeToStore> compute_attributes_to_store( continue; } const int domain_size = attributes.domain_size(domain); - blender::bke::GeometryComponentFieldContext field_context{component, domain}; + blender::bke::GeometryFieldContext field_context{component, domain}; blender::fn::FieldEvaluator field_evaluator{field_context, domain_size}; for (const OutputAttributeInfo &output_info : outputs_info) { const CPPType &type = output_info.field.cpp_type(); diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh index c5bc42b059d..a7f5fbf1926 100644 --- a/source/blender/nodes/NOD_geometry_exec.hh +++ b/source/blender/nodes/NOD_geometry_exec.hh @@ -28,8 +28,6 @@ using bke::AttributeReader; using bke::AttributeWriter; using bke::GAttributeReader; using bke::GAttributeWriter; -using bke::GeometryComponentFieldContext; -using bke::GeometryFieldInput; using bke::GSpanAttributeWriter; using bke::MutableAttributeAccessor; using bke::SpanAttributeWriter; diff --git a/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc b/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc index 58fbfb5a000..13a9cdc8600 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc @@ -192,7 +192,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) } } -template<typename T> class AccumulateFieldInput final : public GeometryFieldInput { +template<typename T> class AccumulateFieldInput final : public bke::GeometryFieldInput { private: Field<T> input_; Field<int> group_index_; @@ -204,7 +204,7 @@ template<typename T> class AccumulateFieldInput final : public GeometryFieldInpu Field<T> input, Field<int> group_index, AccumulationMode accumulation_mode) - : GeometryFieldInput(CPPType::get<T>(), "Accumulation"), + : bke::GeometryFieldInput(CPPType::get<T>(), "Accumulation"), input_(input), group_index_(group_index), source_domain_(source_domain), @@ -212,18 +212,18 @@ template<typename T> class AccumulateFieldInput final : public GeometryFieldInpu { } - GVArray get_varray_for_context(const GeometryComponent &component, - const eAttrDomain domain, - IndexMask UNUSED(mask)) const final + GVArray get_varray_for_context(const bke::GeometryFieldContext &context, + const IndexMask /*mask*/) const final { - const GeometryComponentFieldContext field_context{component, source_domain_}; - const int domain_size = component.attribute_domain_size(field_context.domain()); + const AttributeAccessor attributes = *context.attributes(); + const int domain_size = attributes.domain_size(source_domain_); if (domain_size == 0) { return {}; } - const AttributeAccessor attributes = *component.attributes(); - fn::FieldEvaluator evaluator{field_context, domain_size}; + const bke::GeometryFieldContext source_context{ + context.geometry(), context.type(), source_domain_}; + fn::FieldEvaluator evaluator{source_context, domain_size}; evaluator.add(input_); evaluator.add(group_index_); evaluator.evaluate(); @@ -266,7 +266,7 @@ template<typename T> class AccumulateFieldInput final : public GeometryFieldInpu } return attributes.adapt_domain<T>( - VArray<T>::ForContainer(std::move(accumulations_out)), source_domain_, domain); + VArray<T>::ForContainer(std::move(accumulations_out)), source_domain_, context.domain()); } uint64_t hash() const override @@ -287,7 +287,7 @@ template<typename T> class AccumulateFieldInput final : public GeometryFieldInpu } }; -template<typename T> class TotalFieldInput final : public GeometryFieldInput { +template<typename T> class TotalFieldInput final : public bke::GeometryFieldInput { private: Field<T> input_; Field<int> group_index_; @@ -295,25 +295,25 @@ template<typename T> class TotalFieldInput final : public GeometryFieldInput { public: TotalFieldInput(const eAttrDomain source_domain, Field<T> input, Field<int> group_index) - : GeometryFieldInput(CPPType::get<T>(), "Total Value"), + : bke::GeometryFieldInput(CPPType::get<T>(), "Total Value"), input_(input), group_index_(group_index), source_domain_(source_domain) { } - GVArray get_varray_for_context(const GeometryComponent &component, - const eAttrDomain domain, - IndexMask UNUSED(mask)) const final + GVArray get_varray_for_context(const bke::GeometryFieldContext &context, + IndexMask /*mask*/) const final { - const GeometryComponentFieldContext field_context{component, source_domain_}; - const int domain_size = component.attribute_domain_size(field_context.domain()); + const AttributeAccessor attributes = *context.attributes(); + const int domain_size = attributes.domain_size(source_domain_); if (domain_size == 0) { return {}; } - const AttributeAccessor attributes = *component.attributes(); - fn::FieldEvaluator evaluator{field_context, domain_size}; + const bke::GeometryFieldContext source_context{ + context.geometry(), context.type(), source_domain_}; + fn::FieldEvaluator evaluator{source_context, domain_size}; evaluator.add(input_); evaluator.add(group_index_); evaluator.evaluate(); @@ -339,7 +339,7 @@ template<typename T> class TotalFieldInput final : public GeometryFieldInput { } return attributes.adapt_domain<T>( - VArray<T>::ForContainer(std::move(accumulations_out)), source_domain_, domain); + VArray<T>::ForContainer(std::move(accumulations_out)), source_domain_, context.domain()); } uint64_t hash() const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc index 9f317075bb5..8c11288efdd 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc @@ -115,7 +115,7 @@ static void try_capture_field_on_geometry(GeometryComponent &component, if (domain_size == 0) { return; } - GeometryComponentFieldContext field_context{component, domain}; + bke::GeometryFieldContext field_context{component, domain}; MutableAttributeAccessor attributes = *component.attributes_for_write(); const IndexMask mask{IndexMask(domain_size)}; diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc index 34e28e50c81..af0007c2fa4 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc @@ -200,7 +200,7 @@ static void node_geo_exec(GeoNodeExecParams params) continue; } if (attributes->domain_supported(domain)) { - GeometryComponentFieldContext field_context{*component, domain}; + bke::GeometryFieldContext field_context{*component, domain}; const int domain_num = attributes->domain_size(domain); fn::FieldEvaluator data_evaluator{field_context, domain_num}; @@ -282,7 +282,7 @@ static void node_geo_exec(GeoNodeExecParams params) continue; } if (attributes->domain_supported(domain)) { - GeometryComponentFieldContext field_context{*component, domain}; + bke::GeometryFieldContext field_context{*component, domain}; const int domain_num = attributes->domain_size(domain); fn::FieldEvaluator data_evaluator{field_context, domain_num}; diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc index db3f108aad5..8c3e97edac0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc @@ -27,39 +27,31 @@ static void node_declare(NodeDeclarationBuilder &b) N_("The selection from the start and end of the splines based on the input sizes")); } -class EndpointFieldInput final : public GeometryFieldInput { +class EndpointFieldInput final : public bke::CurvesFieldInput { Field<int> start_size_; Field<int> end_size_; public: EndpointFieldInput(Field<int> start_size, Field<int> end_size) - : GeometryFieldInput(CPPType::get<bool>(), "Endpoint Selection node"), + : bke::CurvesFieldInput(CPPType::get<bool>(), "Endpoint Selection node"), start_size_(start_size), end_size_(end_size) { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const bke::CurvesGeometry &curves, const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - if (component.type() != GEO_COMPONENT_TYPE_CURVE || domain != ATTR_DOMAIN_POINT) { - return nullptr; + if (domain != ATTR_DOMAIN_POINT) { + return {}; } - - const CurveComponent &curve_component = static_cast<const CurveComponent &>(component); - if (!curve_component.has_curves()) { - return nullptr; - } - - const Curves &curves_id = *curve_component.get_for_read(); - const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); if (curves.points_num() == 0) { - return nullptr; + return {}; } - GeometryComponentFieldContext size_context{curve_component, ATTR_DOMAIN_CURVE}; + bke::CurvesFieldContext size_context{curves, ATTR_DOMAIN_CURVE}; fn::FieldEvaluator evaluator{size_context, curves.curves_num()}; evaluator.add(start_size_); evaluator.add(end_size_); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc index ab1f8269c39..4586bb24464 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc @@ -72,10 +72,9 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - const CurveComponent &component = *geometry_set.get_component_for_read<CurveComponent>(); - const Curves &curves_id = *component.get_for_read(); + const Curves &curves_id = *geometry_set.get_curves_for_read(); const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); - GeometryComponentFieldContext context{component, ATTR_DOMAIN_POINT}; + bke::CurvesFieldContext context{curves, ATTR_DOMAIN_POINT}; fn::FieldEvaluator evaluator{context, curves.points_num()}; evaluator.add(radius_field); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc index 5ef20f03f28..b34b22e995d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc @@ -70,35 +70,28 @@ static void select_by_handle_type(const bke::CurvesGeometry &curves, } } -class HandleTypeFieldInput final : public GeometryFieldInput { +class HandleTypeFieldInput final : public bke::CurvesFieldInput { HandleType type_; GeometryNodeCurveHandleMode mode_; public: HandleTypeFieldInput(HandleType type, GeometryNodeCurveHandleMode mode) - : GeometryFieldInput(CPPType::get<bool>(), "Handle Type Selection node"), + : bke::CurvesFieldInput(CPPType::get<bool>(), "Handle Type Selection node"), type_(type), mode_(mode) { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const bke::CurvesGeometry &curves, const eAttrDomain domain, IndexMask mask) const final { - if (component.type() != GEO_COMPONENT_TYPE_CURVE || domain != ATTR_DOMAIN_POINT) { + if (domain != ATTR_DOMAIN_POINT) { return {}; } - - const CurveComponent &curve_component = static_cast<const CurveComponent &>(component); - const Curves *curves_id = curve_component.get_for_read(); - if (curves_id == nullptr) { - return {}; - } - Array<bool> selection(mask.min_array_size()); - select_by_handle_type(bke::CurvesGeometry::wrap(curves_id->geometry), type_, mode_, selection); + select_by_handle_type(curves, type_, mode_, selection); return VArray<bool>::ForContainer(std::move(selection)); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc index 37fc6823b9a..41eafe2a741 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc @@ -66,12 +66,14 @@ static void node_geo_exec(GeoNodeExecParams params) case GEO_NODE_CURVE_RESAMPLE_COUNT: { Field<int> count = params.extract_input<Field<int>>("Count"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry) { - if (const CurveComponent *component = geometry.get_component_for_read<CurveComponent>()) { - if (const Curves *src_curves = component->get_for_read()) { - Curves *dst_curves = geometry::resample_to_count(*component, selection, count); - bke::curves_copy_parameters(*src_curves, *dst_curves); - geometry.replace_curves(dst_curves); - } + if (const Curves *src_curves_id = geometry.get_curves_for_read()) { + const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap( + src_curves_id->geometry); + bke::CurvesGeometry dst_curves = geometry::resample_to_count( + src_curves, selection, count); + Curves *dst_curves_id = bke::curves_new_nomain(std::move(dst_curves)); + bke::curves_copy_parameters(*src_curves_id, *dst_curves_id); + geometry.replace_curves(dst_curves_id); } }); break; @@ -79,24 +81,27 @@ static void node_geo_exec(GeoNodeExecParams params) case GEO_NODE_CURVE_RESAMPLE_LENGTH: { Field<float> length = params.extract_input<Field<float>>("Length"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry) { - if (const CurveComponent *component = geometry.get_component_for_read<CurveComponent>()) { - if (const Curves *src_curves = component->get_for_read()) { - Curves *dst_curves = geometry::resample_to_length(*component, selection, length); - bke::curves_copy_parameters(*src_curves, *dst_curves); - geometry.replace_curves(dst_curves); - } + if (const Curves *src_curves_id = geometry.get_curves_for_read()) { + const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap( + src_curves_id->geometry); + bke::CurvesGeometry dst_curves = geometry::resample_to_length( + src_curves, selection, length); + Curves *dst_curves_id = bke::curves_new_nomain(std::move(dst_curves)); + bke::curves_copy_parameters(*src_curves_id, *dst_curves_id); + geometry.replace_curves(dst_curves_id); } }); break; } case GEO_NODE_CURVE_RESAMPLE_EVALUATED: geometry_set.modify_geometry_sets([&](GeometrySet &geometry) { - if (const CurveComponent *component = geometry.get_component_for_read<CurveComponent>()) { - if (const Curves *src_curves = component->get_for_read()) { - Curves *dst_curves = geometry::resample_to_evaluated(*component, selection); - bke::curves_copy_parameters(*src_curves, *dst_curves); - geometry.replace_curves(dst_curves); - } + if (const Curves *src_curves_id = geometry.get_curves_for_read()) { + const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap( + src_curves_id->geometry); + bke::CurvesGeometry dst_curves = geometry::resample_to_evaluated(src_curves, selection); + Curves *dst_curves_id = bke::curves_new_nomain(std::move(dst_curves)); + bke::curves_copy_parameters(*src_curves_id, *dst_curves_id); + geometry.replace_curves(dst_curves_id); } }); break; diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc index de29735bd2d..0169ead5bd2 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc @@ -23,14 +23,12 @@ static void node_geo_exec(GeoNodeExecParams params) if (!geometry_set.has_curves()) { return; } + const Curves &src_curves_id = *geometry_set.get_curves_for_read(); + const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap(src_curves_id.geometry); - Field<bool> selection_field = params.get_input<Field<bool>>("Selection"); - const CurveComponent &component = *geometry_set.get_component_for_read<CurveComponent>(); - GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_CURVE}; - const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_CURVE); - - fn::FieldEvaluator selection_evaluator{field_context, domain_size}; - selection_evaluator.add(selection_field); + bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_CURVE}; + fn::FieldEvaluator selection_evaluator{field_context, src_curves.curves_num()}; + selection_evaluator.add(params.get_input<Field<bool>>("Selection")); selection_evaluator.evaluate(); const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0); if (selection.is_empty()) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc index f7ba724c377..8bb24821064 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc @@ -51,15 +51,12 @@ static HandleType handle_type_from_input_type(GeometryNodeCurveHandleType type) return BEZIER_HANDLE_AUTO; } -static void set_type_in_component(CurveComponent &component, - const GeometryNodeCurveHandleMode mode, - const HandleType new_handle_type, - const Field<bool> &selection_field) +static void set_handle_type(bke::CurvesGeometry &curves, + const GeometryNodeCurveHandleMode mode, + const HandleType new_handle_type, + const Field<bool> &selection_field) { - Curves &curves_id = *component.get_for_write(); - bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); - - GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT}; + bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_POINT}; fn::FieldEvaluator evaluator{field_context, curves.points_num()}; evaluator.set_selection(selection_field); evaluator.evaluate(); @@ -93,21 +90,17 @@ static void node_geo_exec(GeoNodeExecParams params) std::atomic<bool> has_bezier = false; geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - if (!geometry_set.has_curves()) { - return; - } - has_curves = true; - const CurveComponent &component = *geometry_set.get_component_for_read<CurveComponent>(); - const AttributeAccessor attributes = *component.attributes(); - if (!attributes.contains("handle_type_left") || !attributes.contains("handle_type_right")) { - return; + if (Curves *curves_id = geometry_set.get_curves_for_write()) { + bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry); + has_curves = true; + const AttributeAccessor attributes = curves.attributes(); + if (!attributes.contains("handle_type_left") || !attributes.contains("handle_type_right")) { + return; + } + has_bezier = true; + + set_handle_type(curves, mode, new_handle_type, selection_field); } - has_bezier = true; - - set_type_in_component(geometry_set.get_component_for_write<CurveComponent>(), - mode, - new_handle_type, - selection_field); }); if (has_curves && !has_bezier) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc index 5901d310df4..b5d8d1f020a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc @@ -203,26 +203,18 @@ static VArray<int> construct_index_on_spline_varray(const bke::CurvesGeometry &c return {}; } -class CurveParameterFieldInput final : public GeometryFieldInput { +class CurveParameterFieldInput final : public bke::CurvesFieldInput { public: - CurveParameterFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Curve Parameter node") + CurveParameterFieldInput() : bke::CurvesFieldInput(CPPType::get<float>(), "Curve Parameter node") { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const bke::CurvesGeometry &curves, const eAttrDomain domain, IndexMask mask) const final { - if (component.type() == GEO_COMPONENT_TYPE_CURVE) { - const CurveComponent &curve_component = static_cast<const CurveComponent &>(component); - if (curve_component.has_curves()) { - const Curves &curves_id = *curve_component.get_for_read(); - const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); - return construct_curve_parameter_varray(curves, mask, domain); - } - } - return {}; + return construct_curve_parameter_varray(curves, mask, domain); } uint64_t hash() const override @@ -237,26 +229,19 @@ class CurveParameterFieldInput final : public GeometryFieldInput { } }; -class CurveLengthParameterFieldInput final : public GeometryFieldInput { +class CurveLengthParameterFieldInput final : public bke::CurvesFieldInput { public: - CurveLengthParameterFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Curve Length node") + CurveLengthParameterFieldInput() + : bke::CurvesFieldInput(CPPType::get<float>(), "Curve Length node") { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const bke::CurvesGeometry &curves, const eAttrDomain domain, IndexMask mask) const final { - if (component.type() == GEO_COMPONENT_TYPE_CURVE) { - const CurveComponent &curve_component = static_cast<const CurveComponent &>(component); - if (curve_component.has_curves()) { - const Curves &curves_id = *curve_component.get_for_read(); - const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); - return construct_curve_length_parameter_varray(curves, mask, domain); - } - } - return {}; + return construct_curve_length_parameter_varray(curves, mask, domain); } uint64_t hash() const override @@ -271,26 +256,18 @@ class CurveLengthParameterFieldInput final : public GeometryFieldInput { } }; -class IndexOnSplineFieldInput final : public GeometryFieldInput { +class IndexOnSplineFieldInput final : public bke::CurvesFieldInput { public: - IndexOnSplineFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Spline Index") + IndexOnSplineFieldInput() : bke::CurvesFieldInput(CPPType::get<int>(), "Spline Index") { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const bke::CurvesGeometry &curves, const eAttrDomain domain, IndexMask mask) const final { - if (component.type() == GEO_COMPONENT_TYPE_CURVE) { - const CurveComponent &curve_component = static_cast<const CurveComponent &>(component); - if (curve_component.has_curves()) { - const Curves &curves_id = *curve_component.get_for_read(); - const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); - return construct_index_on_spline_varray(curves, mask, domain); - } - } - return {}; + return construct_index_on_spline_varray(curves, mask, domain); } uint64_t hash() const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc index a92479bc5f1..4d7e5f13969 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc @@ -45,14 +45,13 @@ static void node_geo_exec(GeoNodeExecParams params) if (!geometry_set.has_curves()) { return; } - const CurveComponent &src_component = *geometry_set.get_component_for_read<CurveComponent>(); - const Curves &src_curves_id = *src_component.get_for_read(); + const Curves &src_curves_id = *geometry_set.get_curves_for_read(); const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap(src_curves_id.geometry); if (src_curves.is_single_type(dst_type)) { return; } - GeometryComponentFieldContext field_context{src_component, ATTR_DOMAIN_CURVE}; + bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_CURVE}; fn::FieldEvaluator evaluator{field_context, src_curves.curves_num()}; evaluator.set_selection(selection_field); evaluator.evaluate(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc index bd44adb35a2..919d0056bca 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc @@ -34,11 +34,10 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - const CurveComponent &component = *geometry_set.get_component_for_read<CurveComponent>(); - const Curves &src_curves_id = *component.get_for_read(); + const Curves &src_curves_id = *geometry_set.get_curves_for_read(); const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap(src_curves_id.geometry); - GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT}; + bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_POINT}; fn::FieldEvaluator evaluator{field_context, src_curves.points_num()}; evaluator.add(cuts_field); evaluator.evaluate(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc index 0932de237a9..443f67be421 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc @@ -504,19 +504,17 @@ static void geometry_set_curve_trim(GeometrySet &geometry_set, if (!geometry_set.has_curves()) { return; } + const Curves &src_curves_id = *geometry_set.get_curves_for_read(); + const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(src_curves_id.geometry); - CurveComponent &component = geometry_set.get_component_for_write<CurveComponent>(); - GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_CURVE}; - const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_CURVE); - - fn::FieldEvaluator evaluator{field_context, domain_size}; + bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_CURVE}; + fn::FieldEvaluator evaluator{field_context, curves.curves_num()}; evaluator.add(start_field); evaluator.add(end_field); evaluator.evaluate(); const VArray<float> starts = evaluator.get_evaluated<float>(0); const VArray<float> ends = evaluator.get_evaluated<float>(1); - const Curves &src_curves_id = *geometry_set.get_curves_for_read(); std::unique_ptr<CurveEval> curve = curves_to_curve_eval(src_curves_id); MutableSpan<SplinePtr> splines = curve->splines(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc index b74b4e45199..58ba2fefff9 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc @@ -7,6 +7,7 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_pointcloud_types.h" #include "BKE_attribute_math.hh" #include "BKE_curves.hh" @@ -316,18 +317,19 @@ static void delete_curves_selection(GeometrySet &geometry_set, const Field<bool> &selection_field, const eAttrDomain selection_domain) { - const CurveComponent &src_component = *geometry_set.get_component_for_read<CurveComponent>(); - GeometryComponentFieldContext field_context{src_component, selection_domain}; + const Curves &src_curves_id = *geometry_set.get_curves_for_read(); + const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap(src_curves_id.geometry); - const int domain_num = src_component.attribute_domain_size(selection_domain); - fn::FieldEvaluator evaluator{field_context, domain_num}; + const int domain_size = src_curves.attributes().domain_size(selection_domain); + bke::CurvesFieldContext field_context{src_curves, selection_domain}; + fn::FieldEvaluator evaluator{field_context, domain_size}; evaluator.set_selection(selection_field); evaluator.evaluate(); const IndexMask selection = evaluator.get_evaluated_selection_as_mask(); if (selection.is_empty()) { return; } - if (selection.size() == domain_num) { + if (selection.size() == domain_size) { geometry_set.remove<CurveComponent>(); return; } @@ -347,11 +349,10 @@ static void delete_curves_selection(GeometrySet &geometry_set, static void separate_point_cloud_selection(GeometrySet &geometry_set, const Field<bool> &selection_field) { - const PointCloudComponent &src_points = - *geometry_set.get_component_for_read<PointCloudComponent>(); - GeometryComponentFieldContext field_context{src_points, ATTR_DOMAIN_POINT}; + const PointCloud &src_pointcloud = *geometry_set.get_pointcloud_for_read(); - fn::FieldEvaluator evaluator{field_context, src_points.attribute_domain_size(ATTR_DOMAIN_POINT)}; + bke::PointCloudFieldContext field_context{src_pointcloud}; + fn::FieldEvaluator evaluator{field_context, src_pointcloud.totpoint}; evaluator.set_selection(selection_field); evaluator.evaluate(); const IndexMask selection = evaluator.get_evaluated_selection_as_mask(); @@ -367,7 +368,7 @@ static void separate_point_cloud_selection(GeometrySet &geometry_set, {GEO_COMPONENT_TYPE_POINT_CLOUD}, GEO_COMPONENT_TYPE_POINT_CLOUD, false, attributes); copy_attributes_based_on_mask(attributes, - bke::pointcloud_attributes(*src_points.get_for_read()), + bke::pointcloud_attributes(src_pointcloud), bke::pointcloud_attributes_for_write(*pointcloud), ATTR_DOMAIN_POINT, selection); @@ -378,7 +379,7 @@ static void delete_selected_instances(GeometrySet &geometry_set, const Field<bool> &selection_field) { InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>(); - GeometryComponentFieldContext field_context{instances, ATTR_DOMAIN_INSTANCE}; + bke::GeometryFieldContext field_context{instances, ATTR_DOMAIN_INSTANCE}; fn::FieldEvaluator evaluator{field_context, instances.instances_num()}; evaluator.set_selection(selection_field); @@ -1063,11 +1064,10 @@ static void separate_mesh_selection(GeometrySet &geometry_set, const eAttrDomain selection_domain, const GeometryNodeDeleteGeometryMode mode) { - const MeshComponent &src_component = *geometry_set.get_component_for_read<MeshComponent>(); - GeometryComponentFieldContext field_context{src_component, selection_domain}; - + const Mesh &src_mesh = *geometry_set.get_mesh_for_read(); + bke::MeshFieldContext field_context{src_mesh, selection_domain}; fn::FieldEvaluator evaluator{field_context, - src_component.attribute_domain_size(selection_domain)}; + bke::mesh_attributes(src_mesh).domain_size(selection_domain)}; evaluator.add(selection_field); evaluator.evaluate(); const VArray<bool> selection = evaluator.get_evaluated<bool>(0); @@ -1078,8 +1078,7 @@ static void separate_mesh_selection(GeometrySet &geometry_set, const VArraySpan<bool> selection_span{selection}; - do_mesh_separation( - geometry_set, *src_component.get_for_read(), selection_span, selection_domain, mode); + do_mesh_separation(geometry_set, src_mesh, selection_span, selection_domain, mode); } } // namespace blender::nodes::node_geo_delete_geometry_cc diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc index a6c67cac916..d9115d39705 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc @@ -283,15 +283,14 @@ BLI_NOINLINE static void interpolate_attribute(const Mesh &mesh, } BLI_NOINLINE static void propagate_existing_attributes( - const MeshComponent &mesh_component, + const Mesh &mesh, const Map<AttributeIDRef, AttributeKind> &attributes, - GeometryComponent &point_component, + PointCloud &points, const Span<float3> bary_coords, const Span<int> looptri_indices) { - const Mesh &mesh = *mesh_component.get_for_read(); - const AttributeAccessor mesh_attributes = *mesh_component.attributes(); - MutableAttributeAccessor point_attributes = *point_component.attributes_for_write(); + const AttributeAccessor mesh_attributes = bke::mesh_attributes(mesh); + MutableAttributeAccessor point_attributes = bke::pointcloud_attributes_for_write(points); for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; @@ -326,30 +325,29 @@ struct AttributeOutputs { }; } // namespace -BLI_NOINLINE static void compute_attribute_outputs(const MeshComponent &mesh_component, - PointCloudComponent &point_component, +BLI_NOINLINE static void compute_attribute_outputs(const Mesh &mesh, + PointCloud &points, const Span<float3> bary_coords, const Span<int> looptri_indices, const AttributeOutputs &attribute_outputs) { - MutableAttributeAccessor pointcloud_attributes = *point_component.attributes_for_write(); + MutableAttributeAccessor point_attributes = bke::pointcloud_attributes_for_write(points); - SpanAttributeWriter<int> ids = pointcloud_attributes.lookup_or_add_for_write_only_span<int>( + SpanAttributeWriter<int> ids = point_attributes.lookup_or_add_for_write_only_span<int>( "id", ATTR_DOMAIN_POINT); SpanAttributeWriter<float3> normals; SpanAttributeWriter<float3> rotations; if (attribute_outputs.normal_id) { - normals = pointcloud_attributes.lookup_or_add_for_write_only_span<float3>( + normals = point_attributes.lookup_or_add_for_write_only_span<float3>( attribute_outputs.normal_id.get(), ATTR_DOMAIN_POINT); } if (attribute_outputs.rotation_id) { - rotations = pointcloud_attributes.lookup_or_add_for_write_only_span<float3>( + rotations = point_attributes.lookup_or_add_for_write_only_span<float3>( attribute_outputs.rotation_id.get(), ATTR_DOMAIN_POINT); } - const Mesh &mesh = *mesh_component.get_for_read(); const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh), BKE_mesh_runtime_looptri_len(&mesh)}; @@ -389,16 +387,15 @@ BLI_NOINLINE static void compute_attribute_outputs(const MeshComponent &mesh_com } } -static Array<float> calc_full_density_factors_with_selection(const MeshComponent &component, +static Array<float> calc_full_density_factors_with_selection(const Mesh &mesh, const Field<float> &density_field, const Field<bool> &selection_field) { - const eAttrDomain attribute_domain = ATTR_DOMAIN_CORNER; - GeometryComponentFieldContext field_context{component, attribute_domain}; - const int domain_size = component.attribute_domain_size(attribute_domain); - + const eAttrDomain domain = ATTR_DOMAIN_CORNER; + const int domain_size = bke::mesh_attributes(mesh).domain_size(domain); Array<float> densities(domain_size, 0.0f); + bke::MeshFieldContext field_context{mesh, domain}; fn::FieldEvaluator evaluator{field_context, domain_size}; evaluator.set_selection(selection_field); evaluator.add_with_destination(density_field, densities.as_mutable_span()); @@ -406,7 +403,7 @@ static Array<float> calc_full_density_factors_with_selection(const MeshComponent return densities; } -static void distribute_points_random(const MeshComponent &component, +static void distribute_points_random(const Mesh &mesh, const Field<float> &density_field, const Field<bool> &selection_field, const int seed, @@ -415,12 +412,11 @@ static void distribute_points_random(const MeshComponent &component, Vector<int> &looptri_indices) { const Array<float> densities = calc_full_density_factors_with_selection( - component, density_field, selection_field); - const Mesh &mesh = *component.get_for_read(); + mesh, density_field, selection_field); sample_mesh_surface(mesh, 1.0f, densities, seed, positions, bary_coords, looptri_indices); } -static void distribute_points_poisson_disk(const MeshComponent &mesh_component, +static void distribute_points_poisson_disk(const Mesh &mesh, const float minimum_distance, const float max_density, const Field<float> &density_factor_field, @@ -430,14 +426,13 @@ static void distribute_points_poisson_disk(const MeshComponent &mesh_component, Vector<float3> &bary_coords, Vector<int> &looptri_indices) { - const Mesh &mesh = *mesh_component.get_for_read(); sample_mesh_surface(mesh, max_density, {}, seed, positions, bary_coords, looptri_indices); Array<bool> elimination_mask(positions.size(), false); update_elimination_mask_for_close_points(positions, minimum_distance, elimination_mask); const Array<float> density_factors = calc_full_density_factors_with_selection( - mesh_component, density_factor_field, selection_field); + mesh, density_factor_field, selection_field); update_elimination_mask_based_on_density_factors( mesh, density_factors, bary_coords, looptri_indices, elimination_mask.as_mutable_span()); @@ -457,7 +452,7 @@ static void point_distribution_calculate(GeometrySet &geometry_set, return; } - const MeshComponent &mesh_component = *geometry_set.get_component_for_read<MeshComponent>(); + const Mesh &mesh = *geometry_set.get_mesh_for_read(); Vector<float3> positions; Vector<float3> bary_coords; @@ -466,20 +461,15 @@ static void point_distribution_calculate(GeometrySet &geometry_set, switch (method) { case GEO_NODE_POINT_DISTRIBUTE_POINTS_ON_FACES_RANDOM: { const Field<float> density_field = params.get_input<Field<float>>("Density"); - distribute_points_random(mesh_component, - density_field, - selection_field, - seed, - positions, - bary_coords, - looptri_indices); + distribute_points_random( + mesh, density_field, selection_field, seed, positions, bary_coords, looptri_indices); break; } case GEO_NODE_POINT_DISTRIBUTE_POINTS_ON_FACES_POISSON: { const float minimum_distance = params.get_input<float>("Distance Min"); const float density_max = params.get_input<float>("Density Max"); const Field<float> density_factors_field = params.get_input<Field<float>>("Density Factor"); - distribute_points_poisson_disk(mesh_component, + distribute_points_poisson_disk(mesh, minimum_distance, density_max, density_factors_field, @@ -510,9 +500,6 @@ static void point_distribution_calculate(GeometrySet &geometry_set, geometry_set.replace_pointcloud(pointcloud); - PointCloudComponent &point_component = - geometry_set.get_component_for_write<PointCloudComponent>(); - Map<AttributeIDRef, AttributeKind> attributes; geometry_set.gather_attributes_for_propagation( {GEO_COMPONENT_TYPE_MESH}, GEO_COMPONENT_TYPE_POINT_CLOUD, false, attributes); @@ -520,11 +507,9 @@ static void point_distribution_calculate(GeometrySet &geometry_set, /* Position is set separately. */ attributes.remove("position"); - propagate_existing_attributes( - mesh_component, attributes, point_component, bary_coords, looptri_indices); + propagate_existing_attributes(mesh, attributes, *pointcloud, bary_coords, looptri_indices); - compute_attribute_outputs( - mesh_component, point_component, bary_coords, looptri_indices, attribute_outputs); + compute_attribute_outputs(mesh, *pointcloud, bary_coords, looptri_indices, attribute_outputs); } static void node_geo_exec(GeoNodeExecParams params) diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc index c6b0fb4c068..2eb3706bac9 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc @@ -334,11 +334,10 @@ static void duplicate_curves(GeometrySet &geometry_set, geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_CURVE}); GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set); - const CurveComponent &src_component = *geometry_set.get_component_for_read<CurveComponent>(); - const Curves &curves_id = *src_component.get_for_read(); + const Curves &curves_id = *geometry_set.get_curves_for_read(); const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); - GeometryComponentFieldContext field_context{src_component, ATTR_DOMAIN_CURVE}; + bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_CURVE}; FieldEvaluator evaluator{field_context, curves.curves_num()}; evaluator.add(count_field); evaluator.set_selection(selection_field); @@ -522,14 +521,13 @@ static void duplicate_faces(GeometrySet &geometry_set, } geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_MESH}); - const MeshComponent &src_component = *geometry_set.get_component_for_read<MeshComponent>(); - const Mesh &mesh = *src_component.get_for_read(); + const Mesh &mesh = *geometry_set.get_mesh_for_read(); Span<MVert> verts(mesh.mvert, mesh.totvert); Span<MEdge> edges(mesh.medge, mesh.totedge); Span<MPoly> polys(mesh.mpoly, mesh.totpoly); Span<MLoop> loops(mesh.mloop, mesh.totloop); - GeometryComponentFieldContext field_context{src_component, ATTR_DOMAIN_FACE}; + bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_FACE}; FieldEvaluator evaluator(field_context, polys.size()); evaluator.add(count_field); evaluator.set_selection(selection_field); @@ -724,12 +722,11 @@ static void duplicate_edges(GeometrySet &geometry_set, geometry_set.remove_geometry_during_modify(); return; }; - const MeshComponent &src_component = *geometry_set.get_component_for_read<MeshComponent>(); - const Mesh &mesh = *src_component.get_for_read(); + const Mesh &mesh = *geometry_set.get_mesh_for_read(); Span<MVert> verts(mesh.mvert, mesh.totvert); Span<MEdge> edges(mesh.medge, mesh.totedge); - GeometryComponentFieldContext field_context{src_component, ATTR_DOMAIN_EDGE}; + bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_EDGE}; FieldEvaluator evaluator{field_context, edges.size()}; evaluator.add(count_field); evaluator.set_selection(selection_field); @@ -805,14 +802,13 @@ static void duplicate_points_curve(GeometrySet &geometry_set, const Field<bool> &selection_field, const IndexAttributes &attribute_outputs) { - const CurveComponent &src_component = *geometry_set.get_component_for_read<CurveComponent>(); - const Curves &src_curves_id = *src_component.get_for_read(); + const Curves &src_curves_id = *geometry_set.get_curves_for_read(); const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap(src_curves_id.geometry); if (src_curves.points_num() == 0) { return; } - GeometryComponentFieldContext field_context{src_component, ATTR_DOMAIN_POINT}; + bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_POINT}; FieldEvaluator evaluator{field_context, src_curves.points_num()}; evaluator.add(count_field); evaluator.set_selection(selection_field); @@ -845,7 +841,7 @@ static void duplicate_points_curve(GeometrySet &geometry_set, for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; - GAttributeReader src_attribute = src_component.attributes()->lookup(attribute_id); + GAttributeReader src_attribute = src_curves.attributes().lookup(attribute_id); if (!src_attribute) { continue; } @@ -909,11 +905,10 @@ static void duplicate_points_mesh(GeometrySet &geometry_set, const Field<bool> &selection_field, const IndexAttributes &attribute_outputs) { - const MeshComponent &src_component = *geometry_set.get_component_for_read<MeshComponent>(); const Mesh &mesh = *geometry_set.get_mesh_for_read(); Span<MVert> src_verts(mesh.mvert, mesh.totvert); - GeometryComponentFieldContext field_context{src_component, ATTR_DOMAIN_POINT}; + bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_POINT}; FieldEvaluator evaluator{field_context, src_verts.size()}; evaluator.add(count_field); evaluator.set_selection(selection_field); @@ -961,12 +956,10 @@ static void duplicate_points_pointcloud(GeometrySet &geometry_set, const Field<bool> &selection_field, const IndexAttributes &attribute_outputs) { - const PointCloudComponent &src_points = - *geometry_set.get_component_for_read<PointCloudComponent>(); - const int point_num = src_points.attribute_domain_size(ATTR_DOMAIN_POINT); + const PointCloud &src_points = *geometry_set.get_pointcloud_for_read(); - GeometryComponentFieldContext field_context{src_points, ATTR_DOMAIN_POINT}; - FieldEvaluator evaluator{field_context, point_num}; + bke::PointCloudFieldContext field_context{src_points}; + FieldEvaluator evaluator{field_context, src_points.totpoint}; evaluator.add(count_field); evaluator.set_selection(selection_field); evaluator.evaluate(); @@ -982,11 +975,12 @@ static void duplicate_points_pointcloud(GeometrySet &geometry_set, ATTR_DOMAIN_POINT, offsets, selection, - *src_points.attributes(), + bke::pointcloud_attributes(src_points), bke::pointcloud_attributes_for_write(*pointcloud)); - copy_stable_id_point( - offsets, *src_points.attributes(), bke::pointcloud_attributes_for_write(*pointcloud)); + copy_stable_id_point(offsets, + bke::pointcloud_attributes(src_points), + bke::pointcloud_attributes_for_write(*pointcloud)); if (attribute_outputs.duplicate_index) { create_duplicate_index_attribute(bke::pointcloud_attributes_for_write(*pointcloud), @@ -1055,7 +1049,7 @@ static void duplicate_instances(GeometrySet &geometry_set, const InstancesComponent &src_instances = *geometry_set.get_component_for_read<InstancesComponent>(); - GeometryComponentFieldContext field_context{src_instances, ATTR_DOMAIN_INSTANCE}; + bke::GeometryFieldContext field_context{src_instances, ATTR_DOMAIN_INSTANCE}; FieldEvaluator evaluator{field_context, src_instances.instances_num()}; evaluator.add(count_field); evaluator.set_selection(selection_field); diff --git a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_curves.cc index 89abfa0aa88..30b5b7fbd22 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_curves.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_curves.cc @@ -70,14 +70,14 @@ static void node_geo_exec(GeoNodeExecParams params) GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - if (!geometry_set.has_mesh()) { + const Mesh *mesh = geometry_set.get_mesh_for_read(); + if (mesh == nullptr) { geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES}); return; } - const MeshComponent &component = *geometry_set.get_component_for_read<MeshComponent>(); - GeometryComponentFieldContext context{component, ATTR_DOMAIN_POINT}; - fn::FieldEvaluator evaluator{context, component.attribute_domain_size(ATTR_DOMAIN_POINT)}; + bke::MeshFieldContext context{*mesh, ATTR_DOMAIN_POINT}; + fn::FieldEvaluator evaluator{context, mesh->totvert}; evaluator.add(params.get_input<Field<int>>("Next Vertex Index")); evaluator.add(params.get_input<Field<bool>>("Start Vertices")); evaluator.evaluate(); @@ -89,8 +89,7 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - const Mesh &mesh = *component.get_for_read(); - geometry_set.replace_curves(edge_paths_to_curves_convert(mesh, start_verts, next_vert)); + geometry_set.replace_curves(edge_paths_to_curves_convert(*mesh, start_verts, next_vert)); geometry_set.keep_only({GEO_COMPONENT_TYPE_CURVE, GEO_COMPONENT_TYPE_INSTANCES}); }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc index 53cbd691fdb..5e9826837a0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc @@ -54,36 +54,26 @@ static void edge_paths_to_selection(const Mesh &src_mesh, } } -class PathToEdgeSelectionFieldInput final : public GeometryFieldInput { +class PathToEdgeSelectionFieldInput final : public bke::MeshFieldInput { private: Field<bool> start_vertices_; Field<int> next_vertex_; public: PathToEdgeSelectionFieldInput(Field<bool> start_vertices, Field<int> next_vertex) - : GeometryFieldInput(CPPType::get<bool>(), "Edge Selection"), + : bke::MeshFieldInput(CPPType::get<bool>(), "Edge Selection"), start_vertices_(start_vertices), next_vertex_(next_vertex) { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, - [[maybe_unused]] IndexMask mask) const final + const IndexMask /*mask*/) const final { - if (component.type() != GEO_COMPONENT_TYPE_MESH) { - return {}; - } - - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - const Mesh *mesh = mesh_component.get_for_read(); - if (mesh == nullptr) { - return {}; - } - - GeometryComponentFieldContext context{mesh_component, ATTR_DOMAIN_POINT}; - fn::FieldEvaluator evaluator{context, mesh_component.attribute_domain_size(ATTR_DOMAIN_POINT)}; + bke::MeshFieldContext context{mesh, ATTR_DOMAIN_POINT}; + fn::FieldEvaluator evaluator{context, mesh.totvert}; evaluator.add(next_vertex_); evaluator.add(start_vertices_); evaluator.evaluate(); @@ -94,12 +84,12 @@ class PathToEdgeSelectionFieldInput final : public GeometryFieldInput { return {}; } - Array<bool> selection(mesh->totedge, false); + Array<bool> selection(mesh.totedge, false); MutableSpan<bool> selection_span = selection.as_mutable_span(); - edge_paths_to_selection(*mesh, start_verts, next_vert, selection_span); + edge_paths_to_selection(mesh, start_verts, next_vert, selection_span); - return mesh_component.attributes()->adapt_domain<bool>( + return bke::mesh_attributes(mesh).adapt_domain<bool>( VArray<bool>::ForContainer(std::move(selection)), ATTR_DOMAIN_EDGE, domain); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc index 84acab47661..0b4d5bd53f3 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "DNA_mesh_types.h" + #include "BKE_mesh.h" #include "BKE_mesh_runtime.h" @@ -51,19 +53,18 @@ static void node_geo_exec(GeoNodeExecParams params) const Field<bool> selection_field = params.extract_input<Field<bool>>("Selection"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - if (!geometry_set.has_mesh()) { - return; - } + if (const Mesh *mesh = geometry_set.get_mesh_for_write()) { - const MeshComponent &mesh_component = *geometry_set.get_component_for_read<MeshComponent>(); - GeometryComponentFieldContext field_context{mesh_component, ATTR_DOMAIN_EDGE}; - const int domain_size = mesh_component.attribute_domain_size(ATTR_DOMAIN_EDGE); - fn::FieldEvaluator selection_evaluator{field_context, domain_size}; - selection_evaluator.add(selection_field); - selection_evaluator.evaluate(); - const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0); + bke::MeshFieldContext field_context{*mesh, ATTR_DOMAIN_EDGE}; + fn::FieldEvaluator selection_evaluator{field_context, mesh->totedge}; + selection_evaluator.add(selection_field); + selection_evaluator.evaluate(); + const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0); - geometry_set.replace_mesh(mesh_edge_split(*mesh_component.get_for_read(), selection)); + Mesh *result = mesh_edge_split(*mesh, selection); + + geometry_set.replace_mesh(result); + } }); params.set_output("Mesh", std::move(geometry_set)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc index 024dbd1c852..237e8ffaa7c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc @@ -61,15 +61,15 @@ struct AttributeOutputs { StrongAnonymousAttributeID side_id; }; -static void save_selection_as_attribute(MeshComponent &component, +static void save_selection_as_attribute(Mesh &mesh, const AnonymousAttributeID *id, const eAttrDomain domain, const IndexMask selection) { - BLI_assert(!component.attributes()->contains(id)); + MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(mesh); + BLI_assert(!attributes.contains(id)); - SpanAttributeWriter<bool> attribute = - component.attributes_for_write()->lookup_or_add_for_write_span<bool>(id, domain); + SpanAttributeWriter<bool> attribute = attributes.lookup_or_add_for_write_span<bool>(id, domain); /* Rely on the new attribute being zeroed by default. */ BLI_assert(!attribute.span.as_span().contains(true)); @@ -247,16 +247,15 @@ static Array<Vector<int>> create_vert_to_edge_map(const int vert_size, return vert_to_edge_map; } -static void extrude_mesh_vertices(MeshComponent &component, +static void extrude_mesh_vertices(Mesh &mesh, const Field<bool> &selection_field, const Field<float3> &offset_field, const AttributeOutputs &attribute_outputs) { - Mesh &mesh = *component.get_for_write(); const int orig_vert_size = mesh.totvert; const int orig_edge_size = mesh.totedge; - GeometryComponentFieldContext context{component, ATTR_DOMAIN_POINT}; + bke::MeshFieldContext context{mesh, ATTR_DOMAIN_POINT}; FieldEvaluator evaluator{context, mesh.totvert}; evaluator.add(offset_field); evaluator.set_selection(selection_field); @@ -279,7 +278,7 @@ static void extrude_mesh_vertices(MeshComponent &component, new_edges[i_selection] = new_loose_edge(selection[i_selection], new_vert_range[i_selection]); } - MutableAttributeAccessor attributes = *component.attributes_for_write(); + MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(mesh); attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) { if (!ELEM(meta_data.domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE)) { @@ -326,11 +325,11 @@ static void extrude_mesh_vertices(MeshComponent &component, if (attribute_outputs.top_id) { save_selection_as_attribute( - component, attribute_outputs.top_id.get(), ATTR_DOMAIN_POINT, new_vert_range); + mesh, attribute_outputs.top_id.get(), ATTR_DOMAIN_POINT, new_vert_range); } if (attribute_outputs.side_id) { save_selection_as_attribute( - component, attribute_outputs.side_id.get(), ATTR_DOMAIN_EDGE, new_edge_range); + mesh, attribute_outputs.side_id.get(), ATTR_DOMAIN_EDGE, new_edge_range); } BKE_mesh_runtime_clear_cache(&mesh); @@ -408,18 +407,17 @@ static VectorSet<int> vert_indices_from_edges(const Mesh &mesh, const Span<T> ed return vert_indices; } -static void extrude_mesh_edges(MeshComponent &component, +static void extrude_mesh_edges(Mesh &mesh, const Field<bool> &selection_field, const Field<float3> &offset_field, const AttributeOutputs &attribute_outputs) { - Mesh &mesh = *component.get_for_write(); const int orig_vert_size = mesh.totvert; Span<MEdge> orig_edges = mesh_edges(mesh); Span<MPoly> orig_polys = mesh_polys(mesh); const int orig_loop_size = mesh.totloop; - GeometryComponentFieldContext edge_context{component, ATTR_DOMAIN_EDGE}; + bke::MeshFieldContext edge_context{mesh, ATTR_DOMAIN_EDGE}; FieldEvaluator edge_evaluator{edge_context, mesh.totedge}; edge_evaluator.set_selection(selection_field); edge_evaluator.add(offset_field); @@ -525,7 +523,7 @@ static void extrude_mesh_edges(MeshComponent &component, const Array<Vector<int>> new_vert_to_duplicate_edge_map = create_vert_to_edge_map( new_vert_range.size(), duplicate_edges, orig_vert_size); - MutableAttributeAccessor attributes = *component.attributes_for_write(); + MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(mesh); attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) { GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span( @@ -658,11 +656,11 @@ static void extrude_mesh_edges(MeshComponent &component, if (attribute_outputs.top_id) { save_selection_as_attribute( - component, attribute_outputs.top_id.get(), ATTR_DOMAIN_EDGE, duplicate_edge_range); + mesh, attribute_outputs.top_id.get(), ATTR_DOMAIN_EDGE, duplicate_edge_range); } if (attribute_outputs.side_id) { save_selection_as_attribute( - component, attribute_outputs.side_id.get(), ATTR_DOMAIN_FACE, new_poly_range); + mesh, attribute_outputs.side_id.get(), ATTR_DOMAIN_FACE, new_poly_range); } BKE_mesh_runtime_clear_cache(&mesh); @@ -672,18 +670,17 @@ static void extrude_mesh_edges(MeshComponent &component, * Edges connected to one selected face are on the boundary of a region and will be duplicated into * a "side face". Edges inside a region will be duplicated to leave any original faces unchanged. */ -static void extrude_mesh_face_regions(MeshComponent &component, +static void extrude_mesh_face_regions(Mesh &mesh, const Field<bool> &selection_field, const Field<float3> &offset_field, const AttributeOutputs &attribute_outputs) { - Mesh &mesh = *component.get_for_write(); const int orig_vert_size = mesh.totvert; Span<MEdge> orig_edges = mesh_edges(mesh); Span<MPoly> orig_polys = mesh_polys(mesh); Span<MLoop> orig_loops = mesh_loops(mesh); - GeometryComponentFieldContext poly_context{component, ATTR_DOMAIN_FACE}; + bke::MeshFieldContext poly_context{mesh, ATTR_DOMAIN_FACE}; FieldEvaluator poly_evaluator{poly_context, mesh.totpoly}; poly_evaluator.set_selection(selection_field); poly_evaluator.add(offset_field); @@ -905,7 +902,7 @@ static void extrude_mesh_face_regions(MeshComponent &component, const Array<Vector<int>> new_vert_to_duplicate_edge_map = create_vert_to_edge_map( new_vert_range.size(), boundary_edges, orig_vert_size); - MutableAttributeAccessor attributes = *component.attributes_for_write(); + MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(mesh); attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) { GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span( @@ -1039,11 +1036,11 @@ static void extrude_mesh_face_regions(MeshComponent &component, if (attribute_outputs.top_id) { save_selection_as_attribute( - component, attribute_outputs.top_id.get(), ATTR_DOMAIN_FACE, poly_selection); + mesh, attribute_outputs.top_id.get(), ATTR_DOMAIN_FACE, poly_selection); } if (attribute_outputs.side_id) { save_selection_as_attribute( - component, attribute_outputs.side_id.get(), ATTR_DOMAIN_FACE, side_poly_range); + mesh, attribute_outputs.side_id.get(), ATTR_DOMAIN_FACE, side_poly_range); } BKE_mesh_runtime_clear_cache(&mesh); @@ -1057,12 +1054,11 @@ static IndexRange selected_corner_range(Span<int> offsets, const int index) return IndexRange(offset, next_offset - offset); } -static void extrude_individual_mesh_faces(MeshComponent &component, +static void extrude_individual_mesh_faces(Mesh &mesh, const Field<bool> &selection_field, const Field<float3> &offset_field, const AttributeOutputs &attribute_outputs) { - Mesh &mesh = *component.get_for_write(); const int orig_vert_size = mesh.totvert; const int orig_edge_size = mesh.totedge; Span<MPoly> orig_polys = mesh_polys(mesh); @@ -1071,7 +1067,7 @@ static void extrude_individual_mesh_faces(MeshComponent &component, /* Use a mesh for the result of the evaluation because the mesh is reallocated before * the vertices are moved, and the evaluated result might reference an attribute. */ Array<float3> poly_offset(orig_polys.size()); - GeometryComponentFieldContext poly_context{component, ATTR_DOMAIN_FACE}; + bke::MeshFieldContext poly_context{mesh, ATTR_DOMAIN_FACE}; FieldEvaluator poly_evaluator{poly_context, mesh.totpoly}; poly_evaluator.set_selection(selection_field); poly_evaluator.add_with_destination(offset_field, poly_offset.as_mutable_span()); @@ -1159,7 +1155,7 @@ static void extrude_individual_mesh_faces(MeshComponent &component, } }); - MutableAttributeAccessor attributes = *component.attributes_for_write(); + MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(mesh); attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) { GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span( @@ -1318,11 +1314,11 @@ static void extrude_individual_mesh_faces(MeshComponent &component, if (attribute_outputs.top_id) { save_selection_as_attribute( - component, attribute_outputs.top_id.get(), ATTR_DOMAIN_FACE, poly_selection); + mesh, attribute_outputs.top_id.get(), ATTR_DOMAIN_FACE, poly_selection); } if (attribute_outputs.side_id) { save_selection_as_attribute( - component, attribute_outputs.side_id.get(), ATTR_DOMAIN_FACE, side_poly_range); + mesh, attribute_outputs.side_id.get(), ATTR_DOMAIN_FACE, side_poly_range); } BKE_mesh_runtime_clear_cache(&mesh); @@ -1359,27 +1355,26 @@ static void node_geo_exec(GeoNodeExecParams params) params.extract_input<bool>("Individual"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - if (geometry_set.has_mesh()) { - MeshComponent &component = geometry_set.get_component_for_write<MeshComponent>(); + if (Mesh *mesh = geometry_set.get_mesh_for_write()) { switch (mode) { case GEO_NODE_EXTRUDE_MESH_VERTICES: - extrude_mesh_vertices(component, selection, final_offset, attribute_outputs); + extrude_mesh_vertices(*mesh, selection, final_offset, attribute_outputs); break; case GEO_NODE_EXTRUDE_MESH_EDGES: - extrude_mesh_edges(component, selection, final_offset, attribute_outputs); + extrude_mesh_edges(*mesh, selection, final_offset, attribute_outputs); break; case GEO_NODE_EXTRUDE_MESH_FACES: { if (extrude_individual) { - extrude_individual_mesh_faces(component, selection, final_offset, attribute_outputs); + extrude_individual_mesh_faces(*mesh, selection, final_offset, attribute_outputs); } else { - extrude_mesh_face_regions(component, selection, final_offset, attribute_outputs); + extrude_mesh_face_regions(*mesh, selection, final_offset, attribute_outputs); } break; } } - BLI_assert(BKE_mesh_is_valid(component.get_for_write())); + BLI_assert(BKE_mesh_is_valid(mesh)); } }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc b/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc index bde4af12d84..c8df5785fed 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc @@ -89,7 +89,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) } } -class FieldAtIndex final : public GeometryFieldInput { +class FieldAtIndex final : public bke::GeometryFieldInput { private: Field<int> index_field_; GField value_field_; @@ -97,26 +97,25 @@ class FieldAtIndex final : public GeometryFieldInput { public: FieldAtIndex(Field<int> index_field, GField value_field, eAttrDomain value_field_domain) - : GeometryFieldInput(value_field.cpp_type(), "Field at Index"), + : bke::GeometryFieldInput(value_field.cpp_type(), "Field at Index"), index_field_(std::move(index_field)), value_field_(std::move(value_field)), value_field_domain_(value_field_domain) { } - GVArray get_varray_for_context(const GeometryComponent &component, - const eAttrDomain domain, - IndexMask mask) const final + GVArray get_varray_for_context(const bke::GeometryFieldContext &context, + const IndexMask mask) const final { - const GeometryComponentFieldContext value_field_context{component, value_field_domain_}; + const bke::GeometryFieldContext value_field_context{ + context.geometry(), context.type(), value_field_domain_}; FieldEvaluator value_evaluator{value_field_context, - component.attribute_domain_size(value_field_domain_)}; + context.attributes()->domain_size(value_field_domain_)}; value_evaluator.add(value_field_); value_evaluator.evaluate(); const GVArray &values = value_evaluator.get_evaluated(0); - const GeometryComponentFieldContext index_field_context{component, domain}; - FieldEvaluator index_evaluator{index_field_context, &mask}; + FieldEvaluator index_evaluator{context, &mask}; index_evaluator.add(index_field_); index_evaluator.evaluate(); const VArray<int> indices = index_evaluator.get_evaluated<int>(0); diff --git a/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc index 15b2822805a..a752abc2522 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc @@ -19,24 +19,20 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output<decl::Geometry>(N_("Mesh")); } -static void mesh_flip_faces(MeshComponent &component, const Field<bool> &selection_field) +static void mesh_flip_faces(Mesh &mesh, const Field<bool> &selection_field) { - GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_FACE}; - const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_FACE); - if (domain_size == 0) { + if (mesh.totpoly == 0) { return; } - fn::FieldEvaluator evaluator{field_context, domain_size}; + bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_FACE}; + fn::FieldEvaluator evaluator{field_context, mesh.totpoly}; evaluator.add(selection_field); evaluator.evaluate(); const IndexMask selection = evaluator.get_evaluated_as_mask(0); - Mesh *mesh = component.get_for_write(); - - mesh->mloop = (MLoop *)CustomData_duplicate_referenced_layer( - &mesh->ldata, CD_MLOOP, mesh->totloop); - Span<MPoly> polys{mesh->mpoly, mesh->totpoly}; - MutableSpan<MLoop> loops{mesh->mloop, mesh->totloop}; + mesh.mloop = (MLoop *)CustomData_duplicate_referenced_layer(&mesh.ldata, CD_MLOOP, mesh.totloop); + const Span<MPoly> polys{mesh.mpoly, mesh.totpoly}; + MutableSpan<MLoop> loops{mesh.mloop, mesh.totloop}; for (const int i : selection.index_range()) { const MPoly &poly = polys[selection[i]]; @@ -49,7 +45,7 @@ static void mesh_flip_faces(MeshComponent &component, const Field<bool> &selecti } } - MutableAttributeAccessor attributes = *component.attributes_for_write(); + MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(mesh); attributes.for_all( [&](const bke::AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) { if (meta_data.domain == ATTR_DOMAIN_CORNER) { @@ -76,11 +72,9 @@ static void node_geo_exec(GeoNodeExecParams params) const Field<bool> selection_field = params.extract_input<Field<bool>>("Selection"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - if (!geometry_set.has_mesh()) { - return; + if (Mesh *mesh = geometry_set.get_mesh_for_write()) { + mesh_flip_faces(*mesh, selection_field); } - MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>(); - mesh_flip_faces(mesh_component, selection_field); }); params.set_output("Mesh", std::move(geometry_set)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc index bc1b9e940a1..bff2e7831c6 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "BKE_curves.hh" + #include "node_geometry_util.hh" namespace blender::nodes::node_geo_input_curve_handles_cc { @@ -15,31 +17,27 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output<decl::Vector>(N_("Right")).field_source(); } -class HandlePositionFieldInput final : public GeometryFieldInput { +class HandlePositionFieldInput final : public bke::CurvesFieldInput { Field<bool> relative_; bool left_; public: HandlePositionFieldInput(Field<bool> relative, bool left) - : GeometryFieldInput(CPPType::get<float3>(), "Handle"), relative_(relative), left_(left) + : bke::CurvesFieldInput(CPPType::get<float3>(), "Handle"), relative_(relative), left_(left) { } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const bke::CurvesGeometry &curves, const eAttrDomain domain, - IndexMask mask) const final + const IndexMask mask) const final { - if (component.type() != GEO_COMPONENT_TYPE_CURVE) { - return {}; - } - - GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT}; + bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_POINT}; fn::FieldEvaluator evaluator(field_context, &mask); evaluator.add(relative_); evaluator.evaluate(); const VArray<bool> relative = evaluator.get_evaluated<bool>(0); - const AttributeAccessor attributes = *component.attributes(); + const AttributeAccessor attributes = curves.attributes(); VArray<float3> positions = attributes.lookup_or_default<float3>( "position", ATTR_DOMAIN_POINT, {0, 0, 0}); @@ -69,7 +67,7 @@ class HandlePositionFieldInput final : public GeometryFieldInput { output[i] = handles[i]; } } - return component.attributes()->adapt_domain<float3>( + return attributes.adapt_domain<float3>( VArray<float3>::ForContainer(std::move(output)), ATTR_DOMAIN_POINT, domain); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_instance_rotation.cc b/source/blender/nodes/geometry/nodes/node_geo_input_instance_rotation.cc index 4c7a148a797..8c5a92904ab 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_instance_rotation.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_instance_rotation.cc @@ -9,28 +9,20 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output<decl::Vector>(N_("Rotation")).field_source(); } -class VectorFieldInput final : public GeometryFieldInput { +class InstanceRotationFieldInput final : public bke::InstancesFieldInput { public: - VectorFieldInput() : GeometryFieldInput(CPPType::get<float3>(), "Rotation") + InstanceRotationFieldInput() : bke::InstancesFieldInput(CPPType::get<float3>(), "Rotation") { } - GVArray get_varray_for_context(const GeometryComponent &component, - const eAttrDomain UNUSED(domain), + GVArray get_varray_for_context(const InstancesComponent &instances, IndexMask UNUSED(mask)) const final { - if (component.type() != GEO_COMPONENT_TYPE_INSTANCES) { - return {}; - } - - const InstancesComponent &instance_component = static_cast<const InstancesComponent &>( - component); - auto rotation_fn = [&](const int i) -> float3 { - return instance_component.instance_transforms()[i].to_euler(); + return instances.instance_transforms()[i].to_euler(); }; - return VArray<float3>::ForFunc(instance_component.instances_num(), rotation_fn); + return VArray<float3>::ForFunc(instances.instances_num(), rotation_fn); } uint64_t hash() const override @@ -40,13 +32,13 @@ class VectorFieldInput final : public GeometryFieldInput { bool is_equal_to(const fn::FieldNode &other) const override { - return dynamic_cast<const VectorFieldInput *>(&other) != nullptr; + return dynamic_cast<const InstanceRotationFieldInput *>(&other) != nullptr; } }; static void node_geo_exec(GeoNodeExecParams params) { - Field<float3> rotation{std::make_shared<VectorFieldInput>()}; + Field<float3> rotation{std::make_shared<InstanceRotationFieldInput>()}; params.set_output("Rotation", std::move(rotation)); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_instance_scale.cc b/source/blender/nodes/geometry/nodes/node_geo_input_instance_scale.cc index b3a362fbf3e..b79e73915b7 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_instance_scale.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_instance_scale.cc @@ -9,28 +9,20 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output<decl::Vector>(N_("Scale")).field_source(); } -class VectorFieldInput final : public GeometryFieldInput { +class InstanceScaleFieldInput final : public bke::InstancesFieldInput { public: - VectorFieldInput() : GeometryFieldInput(CPPType::get<float3>(), "Scale") + InstanceScaleFieldInput() : bke::InstancesFieldInput(CPPType::get<float3>(), "Scale") { } - GVArray get_varray_for_context(const GeometryComponent &component, - const eAttrDomain UNUSED(domain), + GVArray get_varray_for_context(const InstancesComponent &instances, IndexMask UNUSED(mask)) const final { - if (component.type() != GEO_COMPONENT_TYPE_INSTANCES) { - return {}; - } - - const InstancesComponent &instance_component = static_cast<const InstancesComponent &>( - component); - auto scale_fn = [&](const int i) -> float3 { - return instance_component.instance_transforms()[i].scale(); + return instances.instance_transforms()[i].scale(); }; - return VArray<float3>::ForFunc(instance_component.instances_num(), scale_fn); + return VArray<float3>::ForFunc(instances.instances_num(), scale_fn); } uint64_t hash() const override @@ -40,13 +32,13 @@ class VectorFieldInput final : public GeometryFieldInput { bool is_equal_to(const fn::FieldNode &other) const override { - return dynamic_cast<const VectorFieldInput *>(&other) != nullptr; + return dynamic_cast<const InstanceScaleFieldInput *>(&other) != nullptr; } }; static void node_geo_exec(GeoNodeExecParams params) { - Field<float3> scale{std::make_shared<VectorFieldInput>()}; + Field<float3> scale{std::make_shared<InstanceScaleFieldInput>()}; params.set_output("Scale", std::move(scale)); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc index b009aaa5291..3e9fcb10c8e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc @@ -53,45 +53,37 @@ static Array<EdgeMapEntry> create_edge_map(const Span<MPoly> polys, return edge_map; } -class AngleFieldInput final : public GeometryFieldInput { +class AngleFieldInput final : public bke::MeshFieldInput { public: - AngleFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Unsigned Angle Field") + AngleFieldInput() : bke::MeshFieldInput(CPPType::get<float>(), "Unsigned Angle Field") { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - if (component.type() != GEO_COMPONENT_TYPE_MESH) { - return {}; - } - - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - const Mesh *mesh = mesh_component.get_for_read(); - if (mesh == nullptr) { - return {}; - } + Span<MVert> vertices{mesh.mvert, mesh.totvert}; + Span<MPoly> polys{mesh.mpoly, mesh.totpoly}; + Span<MLoop> loops{mesh.mloop, mesh.totloop}; + Array<EdgeMapEntry> edge_map = create_edge_map(polys, loops, mesh.totedge); - Span<MPoly> polys{mesh->mpoly, mesh->totpoly}; - Span<MLoop> loops{mesh->mloop, mesh->totloop}; - Array<EdgeMapEntry> edge_map = create_edge_map(polys, loops, mesh->totedge); - - auto angle_fn = [edge_map, polys, loops, mesh](const int i) -> float { + auto angle_fn = + [edge_map = std::move(edge_map), vertices, polys, loops](const int i) -> float { if (edge_map[i].face_count != 2) { return 0.0f; } const MPoly &mpoly_1 = polys[edge_map[i].face_index_1]; const MPoly &mpoly_2 = polys[edge_map[i].face_index_2]; float3 normal_1, normal_2; - BKE_mesh_calc_poly_normal(&mpoly_1, &loops[mpoly_1.loopstart], mesh->mvert, normal_1); - BKE_mesh_calc_poly_normal(&mpoly_2, &loops[mpoly_2.loopstart], mesh->mvert, normal_2); + BKE_mesh_calc_poly_normal(&mpoly_1, &loops[mpoly_1.loopstart], vertices.data(), normal_1); + BKE_mesh_calc_poly_normal(&mpoly_2, &loops[mpoly_2.loopstart], vertices.data(), normal_2); return angle_normalized_v3v3(normal_1, normal_2); }; - VArray<float> angles = VArray<float>::ForFunc(mesh->totedge, angle_fn); - return component.attributes()->adapt_domain<float>( + VArray<float> angles = VArray<float>::ForFunc(mesh.totedge, angle_fn); + return bke::mesh_attributes(mesh).adapt_domain<float>( std::move(angles), ATTR_DOMAIN_EDGE, domain); } @@ -107,32 +99,25 @@ class AngleFieldInput final : public GeometryFieldInput { } }; -class SignedAngleFieldInput final : public GeometryFieldInput { +class SignedAngleFieldInput final : public bke::MeshFieldInput { public: - SignedAngleFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Signed Angle Field") + SignedAngleFieldInput() : bke::MeshFieldInput(CPPType::get<float>(), "Signed Angle Field") { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - if (component.type() != GEO_COMPONENT_TYPE_MESH) { - return {}; - } - - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - const Mesh *mesh = mesh_component.get_for_read(); - if (mesh == nullptr) { - return {}; - } - - Span<MPoly> polys{mesh->mpoly, mesh->totpoly}; - Span<MLoop> loops{mesh->mloop, mesh->totloop}; - Array<EdgeMapEntry> edge_map = create_edge_map(polys, loops, mesh->totedge); - - auto angle_fn = [edge_map, polys, loops, mesh](const int i) -> float { + const Span<MVert> vertices(mesh.mvert, mesh.totvert); + const Span<MEdge> edges(mesh.medge, mesh.totedge); + const Span<MPoly> polys(mesh.mpoly, mesh.totpoly); + const Span<MLoop> loops(mesh.mloop, mesh.totloop); + Array<EdgeMapEntry> edge_map = create_edge_map(polys, loops, mesh.totedge); + + auto angle_fn = + [edge_map = std::move(edge_map), vertices, edges, polys, loops](const int i) -> float { if (edge_map[i].face_count != 2) { return 0.0f; } @@ -141,18 +126,21 @@ class SignedAngleFieldInput final : public GeometryFieldInput { /* Find the normals of the 2 polys. */ float3 poly_1_normal, poly_2_normal; - BKE_mesh_calc_poly_normal(&mpoly_1, &loops[mpoly_1.loopstart], mesh->mvert, poly_1_normal); - BKE_mesh_calc_poly_normal(&mpoly_2, &loops[mpoly_2.loopstart], mesh->mvert, poly_2_normal); + BKE_mesh_calc_poly_normal( + &mpoly_1, &loops[mpoly_1.loopstart], vertices.data(), poly_1_normal); + BKE_mesh_calc_poly_normal( + &mpoly_2, &loops[mpoly_2.loopstart], vertices.data(), poly_2_normal); /* Find the centerpoint of the axis edge */ - const float3 edge_centerpoint = (float3(mesh->mvert[mesh->medge[i].v1].co) + - float3(mesh->mvert[mesh->medge[i].v2].co)) * + const float3 edge_centerpoint = (float3(vertices[edges[i].v1].co) + + float3(vertices[edges[i].v2].co)) * 0.5f; /* Get the centerpoint of poly 2 and subtract the edge centerpoint to get a tangent * normal for poly 2. */ float3 poly_center_2; - BKE_mesh_calc_poly_center(&mpoly_2, &loops[mpoly_2.loopstart], mesh->mvert, poly_center_2); + BKE_mesh_calc_poly_center( + &mpoly_2, &loops[mpoly_2.loopstart], vertices.data(), poly_center_2); const float3 poly_2_tangent = math::normalize(poly_center_2 - edge_centerpoint); const float concavity = math::dot(poly_1_normal, poly_2_tangent); @@ -165,8 +153,8 @@ class SignedAngleFieldInput final : public GeometryFieldInput { return -angle; }; - VArray<float> angles = VArray<float>::ForFunc(mesh->totedge, angle_fn); - return component.attributes()->adapt_domain<float>( + VArray<float> angles = VArray<float>::ForFunc(mesh.totedge, angle_fn); + return bke::mesh_attributes(mesh).adapt_domain<float>( std::move(angles), ATTR_DOMAIN_EDGE, domain); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc index 50d6998bb27..b532b55697b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc @@ -16,34 +16,25 @@ static void node_declare(NodeDeclarationBuilder &b) .description(N_("The number of faces that use each edge as one of their sides")); } -class EdgeNeighborCountFieldInput final : public GeometryFieldInput { +class EdgeNeighborCountFieldInput final : public bke::MeshFieldInput { public: EdgeNeighborCountFieldInput() - : GeometryFieldInput(CPPType::get<int>(), "Edge Neighbor Count Field") + : bke::MeshFieldInput(CPPType::get<int>(), "Edge Neighbor Count Field") { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - if (component.type() == GEO_COMPONENT_TYPE_MESH) { - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - const Mesh *mesh = mesh_component.get_for_read(); - if (mesh == nullptr) { - return {}; - } - - Array<int> face_count(mesh->totedge, 0); - for (const int i : IndexRange(mesh->totloop)) { - face_count[mesh->mloop[i].e]++; - } - - return mesh_component.attributes()->adapt_domain<int>( - VArray<int>::ForContainer(std::move(face_count)), ATTR_DOMAIN_EDGE, domain); + Array<int> face_count(mesh.totedge, 0); + for (const int i : IndexRange(mesh.totloop)) { + face_count[mesh.mloop[i].e]++; } - return {}; + + return bke::mesh_attributes(mesh).adapt_domain<int>( + VArray<int>::ForContainer(std::move(face_count)), ATTR_DOMAIN_EDGE, domain); } uint64_t hash() const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc index 83e511f45c2..426e7636d53 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc @@ -27,45 +27,37 @@ static void node_declare(NodeDeclarationBuilder &b) enum VertexNumber { VERTEX_ONE, VERTEX_TWO }; -static VArray<int> construct_edge_vertices_gvarray(const MeshComponent &component, +static VArray<int> construct_edge_vertices_gvarray(const Mesh &mesh, const VertexNumber vertex, const eAttrDomain domain) { - const Mesh *mesh = component.get_for_read(); - if (mesh == nullptr) { - return {}; - } + const Span<MEdge> edges(mesh.medge, mesh.totedge); if (domain == ATTR_DOMAIN_EDGE) { if (vertex == VERTEX_ONE) { - return VArray<int>::ForFunc(mesh->totedge, - [mesh](const int i) -> int { return mesh->medge[i].v1; }); + return VArray<int>::ForFunc(edges.size(), + [edges](const int i) -> int { return edges[i].v1; }); } - return VArray<int>::ForFunc(mesh->totedge, - [mesh](const int i) -> int { return mesh->medge[i].v2; }); + return VArray<int>::ForFunc(edges.size(), [edges](const int i) -> int { return edges[i].v2; }); } return {}; } -class EdgeVerticesFieldInput final : public GeometryFieldInput { +class EdgeVerticesFieldInput final : public bke::MeshFieldInput { private: VertexNumber vertex_; public: EdgeVerticesFieldInput(VertexNumber vertex) - : GeometryFieldInput(CPPType::get<int>(), "Edge Vertices Field"), vertex_(vertex) + : bke::MeshFieldInput(CPPType::get<int>(), "Edge Vertices Field"), vertex_(vertex) { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - if (component.type() == GEO_COMPONENT_TYPE_MESH) { - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - return construct_edge_vertices_gvarray(mesh_component, vertex_, domain); - } - return {}; + return construct_edge_vertices_gvarray(mesh, vertex_, domain); } uint64_t hash() const override @@ -83,51 +75,43 @@ class EdgeVerticesFieldInput final : public GeometryFieldInput { } }; -static VArray<float3> construct_edge_positions_gvarray(const MeshComponent &component, +static VArray<float3> construct_edge_positions_gvarray(const Mesh &mesh, const VertexNumber vertex, const eAttrDomain domain) { - const Mesh *mesh = component.get_for_read(); - if (mesh == nullptr) { - return {}; - } + const Span<MVert> vertices(mesh.mvert, mesh.totvert); + const Span<MEdge> edges(mesh.medge, mesh.totedge); if (vertex == VERTEX_ONE) { - return component.attributes()->adapt_domain<float3>( + return bke::mesh_attributes(mesh).adapt_domain<float3>( VArray<float3>::ForFunc( - mesh->totedge, - [mesh](const int i) { return float3(mesh->mvert[mesh->medge[i].v1].co); }), + edges.size(), [vertices, edges](const int i) { return vertices[edges[i].v1].co; }), ATTR_DOMAIN_EDGE, domain); } - return component.attributes()->adapt_domain<float3>( - VArray<float3>::ForFunc( - mesh->totedge, - [mesh](const int i) { return float3(mesh->mvert[mesh->medge[i].v2].co); }), + return bke::mesh_attributes(mesh).adapt_domain<float3>( + VArray<float3>::ForFunc(edges.size(), + [vertices, edges](const int i) { return vertices[edges[i].v2].co; }), ATTR_DOMAIN_EDGE, domain); } -class EdgePositionFieldInput final : public GeometryFieldInput { +class EdgePositionFieldInput final : public bke::MeshFieldInput { private: VertexNumber vertex_; public: EdgePositionFieldInput(VertexNumber vertex) - : GeometryFieldInput(CPPType::get<float3>(), "Edge Position Field"), vertex_(vertex) + : bke::MeshFieldInput(CPPType::get<float3>(), "Edge Position Field"), vertex_(vertex) { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - if (component.type() == GEO_COMPONENT_TYPE_MESH) { - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - return construct_edge_positions_gvarray(mesh_component, vertex_, domain); - } - return {}; + return construct_edge_positions_gvarray(mesh, vertex_, domain); } uint64_t hash() const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc index 4d21bf9443a..67b4be0d95d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc @@ -16,39 +16,33 @@ static void node_declare(NodeDeclarationBuilder &b) .description(N_("The surface area of each of the mesh's faces")); } -static VArray<float> construct_face_area_gvarray(const MeshComponent &component, - const eAttrDomain domain) +static VArray<float> construct_face_area_varray(const Mesh &mesh, const eAttrDomain domain) { - const Mesh *mesh = component.get_for_read(); - if (mesh == nullptr) { - return {}; - } + const Span<MVert> vertices(mesh.mvert, mesh.totvert); + const Span<MPoly> polygons(mesh.mpoly, mesh.totpoly); + const Span<MLoop> loops(mesh.mloop, mesh.totloop); - auto area_fn = [mesh](const int i) -> float { - const MPoly *mp = &mesh->mpoly[i]; - return BKE_mesh_calc_poly_area(mp, &mesh->mloop[mp->loopstart], mesh->mvert); + auto area_fn = [vertices, polygons, loops](const int i) -> float { + const MPoly &poly = polygons[i]; + return BKE_mesh_calc_poly_area(&poly, &loops[poly.loopstart], vertices.data()); }; - return component.attributes()->adapt_domain<float>( - VArray<float>::ForFunc(mesh->totpoly, area_fn), ATTR_DOMAIN_FACE, domain); + return bke::mesh_attributes(mesh).adapt_domain<float>( + VArray<float>::ForFunc(polygons.size(), area_fn), ATTR_DOMAIN_FACE, domain); } -class FaceAreaFieldInput final : public GeometryFieldInput { +class FaceAreaFieldInput final : public bke::MeshFieldInput { public: - FaceAreaFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Face Area Field") + FaceAreaFieldInput() : bke::MeshFieldInput(CPPType::get<float>(), "Face Area Field") { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - if (component.type() == GEO_COMPONENT_TYPE_MESH) { - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - return construct_face_area_gvarray(mesh_component, domain); - } - return {}; + return construct_face_area_varray(mesh, domain); } uint64_t hash() const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc index 6b04ff08d9e..57ab1223d44 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc @@ -22,53 +22,46 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output<decl::Bool>("Planar").field_source(); } -class PlanarFieldInput final : public GeometryFieldInput { +class PlanarFieldInput final : public bke::MeshFieldInput { private: Field<float> threshold_; public: PlanarFieldInput(Field<float> threshold) - : GeometryFieldInput(CPPType::get<bool>(), "Planar"), threshold_(threshold) + : bke::MeshFieldInput(CPPType::get<bool>(), "Planar"), threshold_(threshold) { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, - [[maybe_unused]] IndexMask mask) const final + IndexMask /*mask*/) const final { - if (component.type() != GEO_COMPONENT_TYPE_MESH) { - return {}; - } - - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - const Mesh *mesh = mesh_component.get_for_read(); - if (mesh == nullptr) { - return {}; - } - - GeometryComponentFieldContext context{mesh_component, ATTR_DOMAIN_FACE}; - fn::FieldEvaluator evaluator{context, mesh->totpoly}; + const Span<MVert> vertices(mesh.mvert, mesh.totvert); + const Span<MPoly> polygons(mesh.mpoly, mesh.totpoly); + const Span<MLoop> loops(mesh.mloop, mesh.totloop); + + bke::MeshFieldContext context{mesh, ATTR_DOMAIN_FACE}; + fn::FieldEvaluator evaluator{context, polygons.size()}; evaluator.add(threshold_); evaluator.evaluate(); const VArray<float> thresholds = evaluator.get_evaluated<float>(0); - Span<float3> poly_normals{(float3 *)BKE_mesh_poly_normals_ensure(mesh), mesh->totpoly}; + Span<float3> poly_normals{(float3 *)BKE_mesh_poly_normals_ensure(&mesh), polygons.size()}; - auto planar_fn = [mesh, thresholds, poly_normals](const int i_poly) -> bool { - if (mesh->mpoly[i_poly].totloop <= 3) { + auto planar_fn = [vertices, polygons, loops, thresholds, poly_normals](const int i) -> bool { + const MPoly &poly = polygons[i]; + if (poly.totloop <= 3) { return true; } - const int loopstart = mesh->mpoly[i_poly].loopstart; - const int loops = mesh->mpoly[i_poly].totloop; - Span<MLoop> poly_loops(&mesh->mloop[loopstart], loops); - float3 reference_normal = poly_normals[i_poly]; + const Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); + float3 reference_normal = poly_normals[i]; float min = FLT_MAX; float max = -FLT_MAX; for (const int i_loop : poly_loops.index_range()) { - const float3 vert = mesh->mvert[poly_loops[i_loop].v].co; + const float3 vert = vertices[poly_loops[i_loop].v].co; float dot = math::dot(reference_normal, vert); if (dot > max) { max = dot; @@ -77,11 +70,11 @@ class PlanarFieldInput final : public GeometryFieldInput { min = dot; } } - return max - min < thresholds[i_poly] / 2.0f; + return max - min < thresholds[i] / 2.0f; }; - return component.attributes()->adapt_domain<bool>( - VArray<bool>::ForFunc(mesh->totpoly, planar_fn), ATTR_DOMAIN_FACE, domain); + return bke::mesh_attributes(mesh).adapt_domain<bool>( + VArray<bool>::ForFunc(polygons.size(), planar_fn), ATTR_DOMAIN_FACE, domain); } uint64_t hash() const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc index a225ce61b14..c4cb81c5fe5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc @@ -19,48 +19,42 @@ static void node_declare(NodeDeclarationBuilder &b) .description(N_("Number of faces which share an edge with the face")); } -static VArray<int> construct_neighbor_count_gvarray(const MeshComponent &component, - const eAttrDomain domain) +static VArray<int> construct_neighbor_count_varray(const Mesh &mesh, const eAttrDomain domain) { - const Mesh *mesh = component.get_for_read(); - if (mesh == nullptr) { - return {}; - } + const Span<MEdge> edges(mesh.medge, mesh.totedge); + const Span<MPoly> polygons(mesh.mpoly, mesh.totpoly); + const Span<MLoop> loops(mesh.mloop, mesh.totloop); - Array<int> edge_count(mesh->totedge, 0); - for (const int i : IndexRange(mesh->totloop)) { - edge_count[mesh->mloop[i].e]++; + Array<int> edge_count(edges.size(), 0); + for (const int i : loops.index_range()) { + edge_count[loops[i].e]++; } - Array<int> poly_count(mesh->totpoly, 0); - for (const int poly_num : IndexRange(mesh->totpoly)) { - MPoly &poly = mesh->mpoly[poly_num]; - for (const int loop_num : IndexRange(poly.loopstart, poly.totloop)) { - poly_count[poly_num] += edge_count[mesh->mloop[loop_num].e] - 1; + Array<int> poly_count(polygons.size(), 0); + for (const int poly_i : polygons.index_range()) { + const MPoly &poly = polygons[poly_i]; + for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { + poly_count[poly_i] += edge_count[loop.e] - 1; } } - return component.attributes()->adapt_domain<int>( + return bke::mesh_attributes(mesh).adapt_domain<int>( VArray<int>::ForContainer(std::move(poly_count)), ATTR_DOMAIN_FACE, domain); } -class FaceNeighborCountFieldInput final : public GeometryFieldInput { +class FaceNeighborCountFieldInput final : public bke::MeshFieldInput { public: FaceNeighborCountFieldInput() - : GeometryFieldInput(CPPType::get<int>(), "Face Neighbor Count Field") + : bke::MeshFieldInput(CPPType::get<int>(), "Face Neighbor Count Field") { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - if (component.type() == GEO_COMPONENT_TYPE_MESH) { - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - return construct_neighbor_count_gvarray(mesh_component, domain); - } - return {}; + return construct_neighbor_count_varray(mesh, domain); } uint64_t hash() const override @@ -75,37 +69,28 @@ class FaceNeighborCountFieldInput final : public GeometryFieldInput { } }; -static VArray<int> construct_vertex_count_gvarray(const MeshComponent &component, - const eAttrDomain domain) +static VArray<int> construct_vertex_count_varray(const Mesh &mesh, const eAttrDomain domain) { - const Mesh *mesh = component.get_for_read(); - if (mesh == nullptr) { - return {}; - } - - return component.attributes()->adapt_domain<int>( - VArray<int>::ForFunc(mesh->totpoly, - [mesh](const int i) -> float { return mesh->mpoly[i].totloop; }), + const Span<MPoly> polygons(mesh.mpoly, mesh.totpoly); + return bke::mesh_attributes(mesh).adapt_domain<int>( + VArray<int>::ForFunc(polygons.size(), + [polygons](const int i) -> float { return polygons[i].totloop; }), ATTR_DOMAIN_FACE, domain); } -class FaceVertexCountFieldInput final : public GeometryFieldInput { +class FaceVertexCountFieldInput final : public bke::MeshFieldInput { public: - FaceVertexCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Vertex Count Field") + FaceVertexCountFieldInput() : bke::MeshFieldInput(CPPType::get<int>(), "Vertex Count Field") { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - if (component.type() == GEO_COMPONENT_TYPE_MESH) { - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - return construct_vertex_count_gvarray(mesh_component, domain); - } - return {}; + return construct_vertex_count_varray(mesh, domain); } uint64_t hash() const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc index 2c7eef5665f..5752535d149 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc @@ -22,39 +22,32 @@ static void node_declare(NodeDeclarationBuilder &b) .description(N_("The total number of mesh islands")); } -class IslandFieldInput final : public GeometryFieldInput { +class IslandFieldInput final : public bke::MeshFieldInput { public: - IslandFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Island Index") + IslandFieldInput() : bke::MeshFieldInput(CPPType::get<int>(), "Island Index") { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - if (component.type() != GEO_COMPONENT_TYPE_MESH) { - return {}; - } - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - const Mesh *mesh = mesh_component.get_for_read(); - if (mesh == nullptr) { - return {}; - } + const Span<MEdge> edges(mesh.medge, mesh.totedge); - DisjointSet islands(mesh->totvert); - for (const int i : IndexRange(mesh->totedge)) { - islands.join(mesh->medge[i].v1, mesh->medge[i].v2); + DisjointSet islands(mesh.totvert); + for (const int i : edges.index_range()) { + islands.join(edges[i].v1, edges[i].v2); } - Array<int> output(mesh->totvert); + Array<int> output(mesh.totvert); VectorSet<int> ordered_roots; - for (const int i : IndexRange(mesh->totvert)) { + for (const int i : IndexRange(mesh.totvert)) { const int64_t root = islands.find_root(i); output[i] = ordered_roots.index_of_or_add(root); } - return mesh_component.attributes()->adapt_domain<int>( + return bke::mesh_attributes(mesh).adapt_domain<int>( VArray<int>::ForContainer(std::move(output)), ATTR_DOMAIN_POINT, domain); } @@ -70,39 +63,32 @@ class IslandFieldInput final : public GeometryFieldInput { } }; -class IslandCountFieldInput final : public GeometryFieldInput { +class IslandCountFieldInput final : public bke::MeshFieldInput { public: - IslandCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Island Count") + IslandCountFieldInput() : bke::MeshFieldInput(CPPType::get<int>(), "Island Count") { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - if (component.type() != GEO_COMPONENT_TYPE_MESH) { - return {}; - } - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - const Mesh *mesh = mesh_component.get_for_read(); - if (mesh == nullptr) { - return {}; - } + const Span<MEdge> edges(mesh.medge, mesh.totedge); - DisjointSet islands(mesh->totvert); - for (const int i : IndexRange(mesh->totedge)) { - islands.join(mesh->medge[i].v1, mesh->medge[i].v2); + DisjointSet islands(mesh.totvert); + for (const int i : edges.index_range()) { + islands.join(edges[i].v1, edges[i].v2); } Set<int> island_list; - for (const int i_vert : IndexRange(mesh->totvert)) { + for (const int i_vert : IndexRange(mesh.totvert)) { const int64_t root = islands.find_root(i_vert); island_list.add(root); } return VArray<int>::ForSingle(island_list.size(), - mesh_component.attribute_domain_size(domain)); + bke::mesh_attributes(mesh).domain_size(domain)); } uint64_t hash() const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc index 62b3f9d0e92..244d454b8d1 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc @@ -20,41 +20,33 @@ static void node_declare(NodeDeclarationBuilder &b) .description(N_("Number of faces that contain the vertex")); } -static VArray<int> construct_vertex_count_gvarray(const MeshComponent &component, - const eAttrDomain domain) +static VArray<int> construct_vertex_count_gvarray(const Mesh &mesh, const eAttrDomain domain) { - const Mesh *mesh = component.get_for_read(); - if (mesh == nullptr) { - return {}; - } + const Span<MEdge> edges(mesh.medge, mesh.totedge); if (domain == ATTR_DOMAIN_POINT) { - Array<int> vertices(mesh->totvert, 0); - for (const int i : IndexRange(mesh->totedge)) { - vertices[mesh->medge[i].v1]++; - vertices[mesh->medge[i].v2]++; + Array<int> counts(mesh.totvert, 0); + for (const int i : edges.index_range()) { + counts[edges[i].v1]++; + counts[edges[i].v2]++; } - return VArray<int>::ForContainer(std::move(vertices)); + return VArray<int>::ForContainer(std::move(counts)); } return {}; } -class VertexCountFieldInput final : public GeometryFieldInput { +class VertexCountFieldInput final : public bke::MeshFieldInput { public: - VertexCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Vertex Count Field") + VertexCountFieldInput() : bke::MeshFieldInput(CPPType::get<int>(), "Vertex Count Field") { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - if (component.type() == GEO_COMPONENT_TYPE_MESH) { - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - return construct_vertex_count_gvarray(mesh_component, domain); - } - return {}; + return construct_vertex_count_gvarray(mesh, domain); } uint64_t hash() const override @@ -69,18 +61,14 @@ class VertexCountFieldInput final : public GeometryFieldInput { } }; -static VArray<int> construct_face_count_gvarray(const MeshComponent &component, - const eAttrDomain domain) +static VArray<int> construct_face_count_gvarray(const Mesh &mesh, const eAttrDomain domain) { - const Mesh *mesh = component.get_for_read(); - if (mesh == nullptr) { - return {}; - } + const Span<MLoop> loops(mesh.mloop, mesh.totloop); if (domain == ATTR_DOMAIN_POINT) { - Array<int> vertices(mesh->totvert, 0); - for (const int i : IndexRange(mesh->totloop)) { - int vertex = mesh->mloop[i].v; + Array<int> vertices(mesh.totvert, 0); + for (const int i : loops.index_range()) { + int vertex = loops[i].v; vertices[vertex]++; } return VArray<int>::ForContainer(std::move(vertices)); @@ -88,22 +76,18 @@ static VArray<int> construct_face_count_gvarray(const MeshComponent &component, return {}; } -class VertexFaceCountFieldInput final : public GeometryFieldInput { +class VertexFaceCountFieldInput final : public bke::MeshFieldInput { public: - VertexFaceCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Vertex Face Count Field") + VertexFaceCountFieldInput() : bke::MeshFieldInput(CPPType::get<int>(), "Vertex Face Count Field") { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - if (component.type() == GEO_COMPONENT_TYPE_MESH) { - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - return construct_face_count_gvarray(mesh_component, domain); - } - return {}; + return construct_face_count_gvarray(mesh, domain); } uint64_t hash() const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc b/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc index ca6406d2810..8549bdfa87d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc @@ -28,10 +28,10 @@ typedef std::pair<float, int> VertPriority; struct EdgeVertMap { Array<Vector<int>> edges_by_vertex_map; - EdgeVertMap(const Mesh *mesh) + EdgeVertMap(const Mesh &mesh) { - const Span<MEdge> edges{mesh->medge, mesh->totedge}; - edges_by_vertex_map.reinitialize(mesh->totvert); + const Span<MEdge> edges{mesh.medge, mesh.totedge}; + edges_by_vertex_map.reinitialize(mesh.totvert); for (const int edge_i : edges.index_range()) { const MEdge &edge = edges[edge_i]; edges_by_vertex_map[edge.v1].append(edge_i); @@ -40,16 +40,16 @@ struct EdgeVertMap { } }; -static void shortest_paths(const Mesh *mesh, +static void shortest_paths(const Mesh &mesh, EdgeVertMap &maps, const IndexMask end_selection, const VArray<float> &input_cost, MutableSpan<int> r_next_index, MutableSpan<float> r_cost) { - const Span<MVert> verts{mesh->mvert, mesh->totvert}; - const Span<MEdge> edges{mesh->medge, mesh->totedge}; - Array<bool> visited(mesh->totvert, false); + const Span<MVert> verts{mesh.mvert, mesh.totvert}; + const Span<MEdge> edges{mesh.medge, mesh.totedge}; + Array<bool> visited(mesh.totvert, false); std::priority_queue<VertPriority, std::vector<VertPriority>, std::greater<VertPriority>> queue; @@ -84,46 +84,38 @@ static void shortest_paths(const Mesh *mesh, } } -class ShortestEdgePathsNextVertFieldInput final : public GeometryFieldInput { +class ShortestEdgePathsNextVertFieldInput final : public bke::MeshFieldInput { private: Field<bool> end_selection_; Field<float> cost_; public: ShortestEdgePathsNextVertFieldInput(Field<bool> end_selection, Field<float> cost) - : GeometryFieldInput(CPPType::get<int>(), "Shortest Edge Paths Next Vertex Field"), + : bke::MeshFieldInput(CPPType::get<int>(), "Shortest Edge Paths Next Vertex Field"), end_selection_(end_selection), cost_(cost) { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, - [[maybe_unused]] IndexMask mask) const final + const IndexMask /*mask*/) const final { - if (component.type() != GEO_COMPONENT_TYPE_MESH) { - return {}; - } - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - const Mesh *mesh = mesh_component.get_for_read(); - if (mesh == nullptr) { - return {}; - } - GeometryComponentFieldContext edge_context{component, ATTR_DOMAIN_EDGE}; - fn::FieldEvaluator edge_evaluator{edge_context, mesh->totedge}; + bke::MeshFieldContext edge_context{mesh, ATTR_DOMAIN_EDGE}; + fn::FieldEvaluator edge_evaluator{edge_context, mesh.totedge}; edge_evaluator.add(cost_); edge_evaluator.evaluate(); const VArray<float> input_cost = edge_evaluator.get_evaluated<float>(0); - GeometryComponentFieldContext point_context{component, ATTR_DOMAIN_POINT}; - fn::FieldEvaluator point_evaluator{point_context, mesh->totvert}; + bke::MeshFieldContext point_context{mesh, ATTR_DOMAIN_POINT}; + fn::FieldEvaluator point_evaluator{point_context, mesh.totvert}; point_evaluator.add(end_selection_); point_evaluator.evaluate(); const IndexMask end_selection = point_evaluator.get_evaluated_as_mask(0); - Array<int> next_index(mesh->totvert, -1); - Array<float> cost(mesh->totvert, FLT_MAX); + Array<int> next_index(mesh.totvert, -1); + Array<float> cost(mesh.totvert, FLT_MAX); if (!end_selection.is_empty()) { EdgeVertMap maps(mesh); @@ -136,7 +128,7 @@ class ShortestEdgePathsNextVertFieldInput final : public GeometryFieldInput { } } }); - return component.attributes()->adapt_domain<int>( + return bke::mesh_attributes(mesh).adapt_domain<int>( VArray<int>::ForContainer(std::move(next_index)), ATTR_DOMAIN_POINT, domain); } @@ -156,46 +148,38 @@ class ShortestEdgePathsNextVertFieldInput final : public GeometryFieldInput { } }; -class ShortestEdgePathsCostFieldInput final : public GeometryFieldInput { +class ShortestEdgePathsCostFieldInput final : public bke::MeshFieldInput { private: Field<bool> end_selection_; Field<float> cost_; public: ShortestEdgePathsCostFieldInput(Field<bool> end_selection, Field<float> cost) - : GeometryFieldInput(CPPType::get<float>(), "Shortest Edge Paths Cost Field"), + : bke::MeshFieldInput(CPPType::get<float>(), "Shortest Edge Paths Cost Field"), end_selection_(end_selection), cost_(cost) { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, - [[maybe_unused]] IndexMask mask) const final + const IndexMask /*mask*/) const final { - if (component.type() != GEO_COMPONENT_TYPE_MESH) { - return {}; - } - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - const Mesh *mesh = mesh_component.get_for_read(); - if (mesh == nullptr) { - return {}; - } - GeometryComponentFieldContext edge_context{component, ATTR_DOMAIN_EDGE}; - fn::FieldEvaluator edge_evaluator{edge_context, mesh->totedge}; + bke::MeshFieldContext edge_context{mesh, ATTR_DOMAIN_EDGE}; + fn::FieldEvaluator edge_evaluator{edge_context, mesh.totedge}; edge_evaluator.add(cost_); edge_evaluator.evaluate(); const VArray<float> input_cost = edge_evaluator.get_evaluated<float>(0); - GeometryComponentFieldContext point_context{component, ATTR_DOMAIN_POINT}; - fn::FieldEvaluator point_evaluator{point_context, mesh->totvert}; + bke::MeshFieldContext point_context{mesh, ATTR_DOMAIN_POINT}; + fn::FieldEvaluator point_evaluator{point_context, mesh.totvert}; point_evaluator.add(end_selection_); point_evaluator.evaluate(); const IndexMask end_selection = point_evaluator.get_evaluated_as_mask(0); - Array<int> next_index(mesh->totvert, -1); - Array<float> cost(mesh->totvert, FLT_MAX); + Array<int> next_index(mesh.totvert, -1); + Array<float> cost(mesh.totvert, FLT_MAX); if (!end_selection.is_empty()) { EdgeVertMap maps(mesh); @@ -208,7 +192,7 @@ class ShortestEdgePathsCostFieldInput final : public GeometryFieldInput { } } }); - return component.attributes()->adapt_domain<float>( + return bke::mesh_attributes(mesh).adapt_domain<float>( VArray<float>::ForContainer(std::move(cost)), ATTR_DOMAIN_POINT, domain); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc index 267ba44cc00..07dc158ff48 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc @@ -16,15 +16,9 @@ static void node_declare(NodeDeclarationBuilder &b) * Spline Count */ -static VArray<int> construct_curve_point_count_gvarray(const CurveComponent &component, +static VArray<int> construct_curve_point_count_gvarray(const bke::CurvesGeometry &curves, const eAttrDomain domain) { - if (!component.has_curves()) { - return {}; - } - const Curves &curves_id = *component.get_for_read(); - const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); - auto count_fn = [curves](int64_t i) { return curves.points_for_curve(i).size(); }; if (domain == ATTR_DOMAIN_CURVE) { @@ -32,29 +26,24 @@ static VArray<int> construct_curve_point_count_gvarray(const CurveComponent &com } if (domain == ATTR_DOMAIN_POINT) { VArray<int> count = VArray<int>::ForFunc(curves.curves_num(), count_fn); - return component.attributes()->adapt_domain<int>( - std::move(count), ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT); + return curves.adapt_domain<int>(std::move(count), ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT); } return {}; } -class SplineCountFieldInput final : public GeometryFieldInput { +class SplineCountFieldInput final : public bke::CurvesFieldInput { public: - SplineCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Spline Point Count") + SplineCountFieldInput() : bke::CurvesFieldInput(CPPType::get<int>(), "Spline Point Count") { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const bke::CurvesGeometry &curves, const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - if (component.type() == GEO_COMPONENT_TYPE_CURVE) { - const CurveComponent &curve_component = static_cast<const CurveComponent &>(component); - return construct_curve_point_count_gvarray(curve_component, domain); - } - return {}; + return construct_curve_point_count_gvarray(curves, domain); } uint64_t hash() const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc index a2aab5464aa..ea3d060f03c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc @@ -63,19 +63,12 @@ static Array<float3> curve_tangent_point_domain(const bke::CurvesGeometry &curve return results; } -static VArray<float3> construct_curve_tangent_gvarray(const CurveComponent &component, +static VArray<float3> construct_curve_tangent_gvarray(const bke::CurvesGeometry &curves, const eAttrDomain domain) { - if (!component.has_curves()) { - return {}; - } - - const Curves &curves_id = *component.get_for_read(); - const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); - const VArray<int8_t> types = curves.curve_types(); if (curves.is_single_type(CURVE_TYPE_POLY)) { - return component.attributes()->adapt_domain<float3>( + return curves.adapt_domain<float3>( VArray<float3>::ForSpan(curves.evaluated_tangents()), ATTR_DOMAIN_POINT, domain); } @@ -86,29 +79,25 @@ static VArray<float3> construct_curve_tangent_gvarray(const CurveComponent &comp } if (domain == ATTR_DOMAIN_CURVE) { - return component.attributes()->adapt_domain<float3>( + return curves.adapt_domain<float3>( VArray<float3>::ForContainer(std::move(tangents)), ATTR_DOMAIN_POINT, ATTR_DOMAIN_CURVE); } return nullptr; } -class TangentFieldInput final : public GeometryFieldInput { +class TangentFieldInput final : public bke::CurvesFieldInput { public: - TangentFieldInput() : GeometryFieldInput(CPPType::get<float3>(), "Tangent node") + TangentFieldInput() : bke::CurvesFieldInput(CPPType::get<float3>(), "Tangent node") { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const bke::CurvesGeometry &curves, const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - if (component.type() == GEO_COMPONENT_TYPE_CURVE) { - const CurveComponent &curve_component = static_cast<const CurveComponent &>(component); - return construct_curve_tangent_gvarray(curve_component, domain); - } - return {}; + return construct_curve_tangent_gvarray(curves, domain); } uint64_t hash() const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc index 37f9917f39d..d54d082311f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc @@ -57,7 +57,7 @@ static void add_instances_from_component( VArray<float3> rotations; VArray<float3> scales; - GeometryComponentFieldContext field_context{src_component, domain}; + bke::GeometryFieldContext field_context{src_component, domain}; const Field<bool> selection_field = params.get_input<Field<bool>>("Selection"); fn::FieldEvaluator evaluator{field_context, domain_num}; evaluator.set_selection(selection_field); diff --git a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc index 5e0789e557b..2a80d7d855a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc @@ -29,10 +29,8 @@ static void convert_instances_to_points(GeometrySet &geometry_set, { const InstancesComponent &instances = *geometry_set.get_component_for_read<InstancesComponent>(); - GeometryComponentFieldContext field_context{instances, ATTR_DOMAIN_INSTANCE}; - const int domain_size = instances.instances_num(); - - fn::FieldEvaluator evaluator{field_context, domain_size}; + const bke::InstancesFieldContext context{instances}; + fn::FieldEvaluator evaluator{context, instances.instances_num()}; evaluator.set_selection(std::move(selection_field)); evaluator.add(std::move(position_field)); evaluator.add(std::move(radius_field)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc b/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc index 93203988552..8e38ef14aba 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc @@ -83,31 +83,33 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) } } -class InterpolateDomain final : public GeometryFieldInput { +class InterpolateDomain final : public bke::GeometryFieldInput { private: GField src_field_; eAttrDomain src_domain_; public: InterpolateDomain(GField field, eAttrDomain domain) - : GeometryFieldInput(field.cpp_type(), "Interpolate Domain"), + : bke::GeometryFieldInput(field.cpp_type(), "Interpolate Domain"), src_field_(std::move(field)), src_domain_(domain) { } - GVArray get_varray_for_context(const GeometryComponent &component, - const eAttrDomain domain, - IndexMask /* mask */) const final + GVArray get_varray_for_context(const bke::GeometryFieldContext &context, + IndexMask /*mask*/) const final { - const GeometryComponentFieldContext context{component, src_domain_}; - const int64_t src_domain_size = component.attribute_domain_size(src_domain_); + const bke::AttributeAccessor attributes = *context.attributes(); + + const bke::GeometryFieldContext other_domain_context{ + context.geometry(), context.type(), src_domain_}; + const int64_t src_domain_size = attributes.domain_size(src_domain_); GArray values(src_field_.cpp_type(), src_domain_size); - FieldEvaluator value_evaluator{context, src_domain_size}; + FieldEvaluator value_evaluator{other_domain_context, src_domain_size}; value_evaluator.add_with_destination(src_field_, values.as_mutable_span()); value_evaluator.evaluate(); - return component.attributes()->adapt_domain( - GVArray::ForGArray(std::move(values)), src_domain_, domain); + return attributes.adapt_domain( + GVArray::ForGArray(std::move(values)), src_domain_, context.domain()); } }; diff --git a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc index 0fb435eaa48..9822e0ea0d6 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc @@ -51,29 +51,28 @@ static void select_mesh_by_material(const Mesh &mesh, }); } -class MaterialSelectionFieldInput final : public GeometryFieldInput { +class MaterialSelectionFieldInput final : public bke::GeometryFieldInput { Material *material_; public: MaterialSelectionFieldInput(Material *material) - : GeometryFieldInput(CPPType::get<bool>(), "Material Selection node"), material_(material) + : bke::GeometryFieldInput(CPPType::get<bool>(), "Material Selection node"), + material_(material) { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, - const eAttrDomain domain, - IndexMask mask) const final + GVArray get_varray_for_context(const bke::GeometryFieldContext &context, + const IndexMask mask) const final { - if (component.type() != GEO_COMPONENT_TYPE_MESH) { + if (context.type() != GEO_COMPONENT_TYPE_MESH) { return {}; } - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - const Mesh *mesh = mesh_component.get_for_read(); + const Mesh *mesh = context.mesh(); if (mesh == nullptr) { return {}; } - + const eAttrDomain domain = context.domain(); if (domain == ATTR_DOMAIN_FACE) { Array<bool> selection(mask.min_array_size()); select_mesh_by_material(*mesh, material_, mask, selection); @@ -82,7 +81,7 @@ class MaterialSelectionFieldInput final : public GeometryFieldInput { Array<bool> selection(mesh->totpoly); select_mesh_by_material(*mesh, material_, IndexMask(mesh->totpoly), selection); - return mesh_component.attributes()->adapt_domain<bool>( + return bke::mesh_attributes(*mesh).adapt_domain<bool>( VArray<bool>::ForContainer(std::move(selection)), ATTR_DOMAIN_FACE, domain); return nullptr; diff --git a/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc b/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc index a4fb79bef7a..f64f997810e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc @@ -1,5 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "DNA_mesh_types.h" +#include "DNA_pointcloud_types.h" + #include "GEO_mesh_merge_by_distance.hh" #include "GEO_point_merge_by_distance.hh" @@ -35,13 +38,12 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node) node->storage = data; } -static PointCloud *pointcloud_merge_by_distance(const PointCloudComponent &src_points, +static PointCloud *pointcloud_merge_by_distance(const PointCloud &src_points, const float merge_distance, const Field<bool> &selection_field) { - const int src_num = src_points.attribute_domain_size(ATTR_DOMAIN_POINT); - GeometryComponentFieldContext context{src_points, ATTR_DOMAIN_POINT}; - FieldEvaluator evaluator{context, src_num}; + bke::PointCloudFieldContext context{src_points}; + FieldEvaluator evaluator{context, src_points.totpoint}; evaluator.add(selection_field); evaluator.evaluate(); @@ -50,31 +52,28 @@ static PointCloud *pointcloud_merge_by_distance(const PointCloudComponent &src_p return nullptr; } - return geometry::point_merge_by_distance(*src_points.get_for_read(), merge_distance, selection); + return geometry::point_merge_by_distance(src_points, merge_distance, selection); } -static std::optional<Mesh *> mesh_merge_by_distance_connected(const MeshComponent &mesh_component, +static std::optional<Mesh *> mesh_merge_by_distance_connected(const Mesh &mesh, const float merge_distance, const Field<bool> &selection_field) { - const int src_num = mesh_component.attribute_domain_size(ATTR_DOMAIN_POINT); - Array<bool> selection(src_num); - GeometryComponentFieldContext context{mesh_component, ATTR_DOMAIN_POINT}; - FieldEvaluator evaluator{context, src_num}; + Array<bool> selection(mesh.totvert); + bke::MeshFieldContext context{mesh, ATTR_DOMAIN_POINT}; + FieldEvaluator evaluator{context, mesh.totvert}; evaluator.add_with_destination(selection_field, selection.as_mutable_span()); evaluator.evaluate(); - const Mesh &mesh = *mesh_component.get_for_read(); return geometry::mesh_merge_by_distance_connected(mesh, selection, merge_distance, false); } -static std::optional<Mesh *> mesh_merge_by_distance_all(const MeshComponent &mesh_component, +static std::optional<Mesh *> mesh_merge_by_distance_all(const Mesh &mesh, const float merge_distance, const Field<bool> &selection_field) { - const int src_num = mesh_component.attribute_domain_size(ATTR_DOMAIN_POINT); - GeometryComponentFieldContext context{mesh_component, ATTR_DOMAIN_POINT}; - FieldEvaluator evaluator{context, src_num}; + bke::MeshFieldContext context{mesh, ATTR_DOMAIN_POINT}; + FieldEvaluator evaluator{context, mesh.totvert}; evaluator.add(selection_field); evaluator.evaluate(); @@ -83,7 +82,6 @@ static std::optional<Mesh *> mesh_merge_by_distance_all(const MeshComponent &mes return std::nullopt; } - const Mesh &mesh = *mesh_component.get_for_read(); return geometry::mesh_merge_by_distance_all(mesh, selection, merge_distance); } @@ -98,22 +96,20 @@ static void node_geo_exec(GeoNodeExecParams params) const float merge_distance = params.extract_input<float>("Distance"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - if (geometry_set.has_pointcloud()) { - PointCloud *result = pointcloud_merge_by_distance( - *geometry_set.get_component_for_read<PointCloudComponent>(), merge_distance, selection); + if (const PointCloud *pointcloud = geometry_set.get_pointcloud_for_read()) { + PointCloud *result = pointcloud_merge_by_distance(*pointcloud, merge_distance, selection); if (result) { geometry_set.replace_pointcloud(result); } } - if (geometry_set.has_mesh()) { - const MeshComponent &component = *geometry_set.get_component_for_read<MeshComponent>(); + if (const Mesh *mesh = geometry_set.get_mesh_for_read()) { std::optional<Mesh *> result; switch (mode) { case GEO_NODE_MERGE_BY_DISTANCE_MODE_ALL: - result = mesh_merge_by_distance_all(component, merge_distance, selection); + result = mesh_merge_by_distance_all(*mesh, merge_distance, selection); break; case GEO_NODE_MERGE_BY_DISTANCE_MODE_CONNECTED: - result = mesh_merge_by_distance_connected(component, merge_distance, selection); + result = mesh_merge_by_distance_connected(*mesh, merge_distance, selection); break; default: BLI_assert_unreachable(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc index 40169def51e..4d08fa40a29 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "DNA_mesh_types.h" + #include "GEO_mesh_to_curve.hh" #include "node_geometry_util.hh" @@ -24,9 +26,8 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - const MeshComponent &component = *geometry_set.get_component_for_read<MeshComponent>(); - GeometryComponentFieldContext context{component, ATTR_DOMAIN_EDGE}; - fn::FieldEvaluator evaluator{context, component.attribute_domain_size(ATTR_DOMAIN_EDGE)}; + bke::MeshFieldContext context{*mesh, ATTR_DOMAIN_EDGE}; + fn::FieldEvaluator evaluator{context, mesh->totedge}; evaluator.add(params.get_input<Field<bool>>("Selection")); evaluator.evaluate(); const IndexMask selection = evaluator.get_evaluated_as_mask(0); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc index d3d1312be6d..d5c7fec4ce7 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc @@ -60,18 +60,18 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set, Field<bool> &selection_field, const eAttrDomain domain) { - const MeshComponent *mesh_component = geometry_set.get_component_for_read<MeshComponent>(); - if (mesh_component == nullptr) { + const Mesh *mesh = geometry_set.get_mesh_for_read(); + if (mesh == nullptr) { geometry_set.remove_geometry_during_modify(); return; } - GeometryComponentFieldContext field_context{*mesh_component, domain}; - const int domain_num = mesh_component->attribute_domain_size(domain); - if (domain_num == 0) { + const int domain_size = bke::mesh_attributes(*mesh).domain_size(domain); + if (domain_size == 0) { geometry_set.remove_geometry_during_modify(); return; } - fn::FieldEvaluator evaluator{field_context, domain_num}; + bke::MeshFieldContext field_context{*mesh, domain}; + fn::FieldEvaluator evaluator{field_context, domain_size}; evaluator.set_selection(selection_field); /* Evaluating directly into the point cloud doesn't work because we are not using the full * "min_array_size" array but compressing the selected elements into the final array with no @@ -83,16 +83,15 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set, PointCloud *pointcloud = BKE_pointcloud_new_nomain(selection.size()); geometry_set.replace_pointcloud(pointcloud); - MutableAttributeAccessor pointcloud_attributes = bke::pointcloud_attributes_for_write( - *pointcloud); + MutableAttributeAccessor dst_attributes = bke::pointcloud_attributes_for_write(*pointcloud); - GSpanAttributeWriter position = pointcloud_attributes.lookup_or_add_for_write_only_span( + GSpanAttributeWriter position = dst_attributes.lookup_or_add_for_write_only_span( "position", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3); materialize_compressed_to_uninitialized_threaded( evaluator.get_evaluated(0), selection, position.span); position.finish(); - GSpanAttributeWriter radius = pointcloud_attributes.lookup_or_add_for_write_only_span( + GSpanAttributeWriter radius = dst_attributes.lookup_or_add_for_write_only_span( "radius", ATTR_DOMAIN_POINT, CD_PROP_FLOAT); materialize_compressed_to_uninitialized_threaded( evaluator.get_evaluated(1), selection, radius.span); @@ -103,11 +102,13 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set, {GEO_COMPONENT_TYPE_MESH}, GEO_COMPONENT_TYPE_POINT_CLOUD, false, attributes); attributes.remove("position"); + const AttributeAccessor src_attributes = bke::mesh_attributes(*mesh); + for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; const eCustomDataType data_type = entry.value.data_type; - GVArray src = mesh_component->attributes()->lookup_or_default(attribute_id, domain, data_type); - GSpanAttributeWriter dst = pointcloud_attributes.lookup_or_add_for_write_only_span( + GVArray src = src_attributes.lookup_or_default(attribute_id, domain, data_type); + GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span( attribute_id, ATTR_DOMAIN_POINT, data_type); if (dst && src) { materialize_compressed_to_uninitialized_threaded(src, selection, dst.span); diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc index ed7ef9b7c71..1f6ffca0303 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc @@ -2,6 +2,8 @@ #include "BLI_task.hh" +#include "DNA_pointcloud_types.h" + #include "BKE_attribute_math.hh" #include "BKE_mesh.h" @@ -22,21 +24,18 @@ static void node_declare(NodeDeclarationBuilder &b) static void geometry_set_points_to_vertices(GeometrySet &geometry_set, Field<bool> &selection_field) { - const PointCloudComponent *point_component = - geometry_set.get_component_for_read<PointCloudComponent>(); - if (point_component == nullptr) { + const PointCloud *points = geometry_set.get_pointcloud_for_read(); + if (points == nullptr) { geometry_set.remove_geometry_during_modify(); return; } - - GeometryComponentFieldContext field_context{*point_component, ATTR_DOMAIN_POINT}; - const int domain_num = point_component->attribute_domain_size(ATTR_DOMAIN_POINT); - if (domain_num == 0) { + if (points->totpoint == 0) { geometry_set.remove_geometry_during_modify(); return; } - fn::FieldEvaluator selection_evaluator{field_context, domain_num}; + bke::PointCloudFieldContext field_context{*points}; + fn::FieldEvaluator selection_evaluator{field_context, points->totpoint}; selection_evaluator.add(selection_field); selection_evaluator.evaluate(); const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0); @@ -47,16 +46,16 @@ static void geometry_set_points_to_vertices(GeometrySet &geometry_set, Mesh *mesh = BKE_mesh_new_nomain(selection.size(), 0, 0, 0, 0); geometry_set.replace_mesh(mesh); - MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>(); + + const AttributeAccessor src_attributes = bke::pointcloud_attributes(*points); + MutableAttributeAccessor dst_attributes = bke::mesh_attributes_for_write(*mesh); for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; const eCustomDataType data_type = entry.value.data_type; - GVArray src = point_component->attributes()->lookup_or_default( + GVArray src = src_attributes.lookup_or_default(attribute_id, ATTR_DOMAIN_POINT, data_type); + GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span( attribute_id, ATTR_DOMAIN_POINT, data_type); - GSpanAttributeWriter dst = - mesh_component.attributes_for_write()->lookup_or_add_for_write_only_span( - attribute_id, ATTR_DOMAIN_POINT, data_type); if (dst && src) { src.materialize_compressed_to_uninitialized(selection, dst.span.data()); dst.finish(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc index 4a3048e5f4a..ba6bd40a6b6 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc @@ -170,7 +170,7 @@ static void gather_point_data_from_component(GeoNodeExecParams ¶ms, "position", ATTR_DOMAIN_POINT, {0, 0, 0}); Field<float> radius_field = params.get_input<Field<float>>("Radius"); - GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT}; + bke::GeometryFieldContext field_context{component, ATTR_DOMAIN_POINT}; const int domain_num = component.attribute_domain_size(ATTR_DOMAIN_POINT); r_positions.resize(r_positions.size() + domain_num); diff --git a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc index f81748da587..5c2ec74b59e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc @@ -208,7 +208,7 @@ class RaycastFunction : public fn::MultiFunction { GeometryNodeRaycastMapMode mapping_; /** The field for data evaluated on the target geometry. */ - std::optional<GeometryComponentFieldContext> target_context_; + std::optional<bke::MeshFieldContext> target_context_; std::unique_ptr<FieldEvaluator> target_evaluator_; const GVArray *target_data_ = nullptr; @@ -310,9 +310,9 @@ class RaycastFunction : public fn::MultiFunction { if (!src_field) { return; } - const MeshComponent &mesh_component = *target_.get_component_for_read<MeshComponent>(); - target_context_.emplace(GeometryComponentFieldContext{mesh_component, domain_}); - const int domain_size = mesh_component.attribute_domain_size(domain_); + const Mesh &mesh = *target_.get_mesh_for_read(); + target_context_.emplace(bke::MeshFieldContext{mesh, domain_}); + const int domain_size = bke::mesh_attributes(mesh).domain_size(domain_); target_evaluator_ = std::make_unique<FieldEvaluator>(*target_context_, domain_size); target_evaluator_->add(std::move(src_field)); target_evaluator_->evaluate(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc index d414bb1fa1d..4ed94e67e74 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc @@ -18,10 +18,8 @@ static void node_declare(NodeDeclarationBuilder &b) static void rotate_instances(GeoNodeExecParams ¶ms, InstancesComponent &instances_component) { - GeometryComponentFieldContext field_context{instances_component, ATTR_DOMAIN_INSTANCE}; - const int domain_num = instances_component.instances_num(); - - fn::FieldEvaluator evaluator{field_context, domain_num}; + const bke::InstancesFieldContext context{instances_component}; + fn::FieldEvaluator evaluator{context, instances_component.instances_num()}; evaluator.set_selection(params.extract_input<Field<bool>>("Selection")); evaluator.add(params.extract_input<Field<float3>>("Rotation")); evaluator.add(params.extract_input<Field<float3>>("Pivot Point")); diff --git a/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc index d674f611c9f..dbcc5d15fd3 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc @@ -288,13 +288,12 @@ static AxisScaleParams evaluate_axis_scale_fields(FieldEvaluator &evaluator, return out; } -static void scale_faces_on_axis(MeshComponent &mesh_component, const AxisScaleFields &fields) +static void scale_faces_on_axis(Mesh &mesh, const AxisScaleFields &fields) { - Mesh &mesh = *mesh_component.get_for_write(); mesh.mvert = static_cast<MVert *>( CustomData_duplicate_referenced_layer(&mesh.vdata, CD_MVERT, mesh.totvert)); - GeometryComponentFieldContext field_context{mesh_component, ATTR_DOMAIN_FACE}; + bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_FACE}; FieldEvaluator evaluator{field_context, mesh.totpoly}; AxisScaleParams params = evaluate_axis_scale_fields(evaluator, fields); @@ -314,13 +313,12 @@ static UniformScaleParams evaluate_uniform_scale_fields(FieldEvaluator &evaluato return out; } -static void scale_faces_uniformly(MeshComponent &mesh_component, const UniformScaleFields &fields) +static void scale_faces_uniformly(Mesh &mesh, const UniformScaleFields &fields) { - Mesh &mesh = *mesh_component.get_for_write(); mesh.mvert = static_cast<MVert *>( CustomData_duplicate_referenced_layer(&mesh.vdata, CD_MVERT, mesh.totvert)); - GeometryComponentFieldContext field_context{mesh_component, ATTR_DOMAIN_FACE}; + bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_FACE}; FieldEvaluator evaluator{field_context, mesh.totpoly}; UniformScaleParams params = evaluate_uniform_scale_fields(evaluator, fields); @@ -364,13 +362,12 @@ static void get_edge_vertices(const Mesh &mesh, int edge_index, VectorSet<int> & r_vertex_indices.add(edge.v2); } -static void scale_edges_uniformly(MeshComponent &mesh_component, const UniformScaleFields &fields) +static void scale_edges_uniformly(Mesh &mesh, const UniformScaleFields &fields) { - Mesh &mesh = *mesh_component.get_for_write(); mesh.mvert = static_cast<MVert *>( CustomData_duplicate_referenced_layer(&mesh.vdata, CD_MVERT, mesh.totvert)); - GeometryComponentFieldContext field_context{mesh_component, ATTR_DOMAIN_EDGE}; + bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_EDGE}; FieldEvaluator evaluator{field_context, mesh.totedge}; UniformScaleParams params = evaluate_uniform_scale_fields(evaluator, fields); @@ -378,13 +375,12 @@ static void scale_edges_uniformly(MeshComponent &mesh_component, const UniformSc scale_vertex_islands_uniformly(mesh, island, params, get_edge_vertices); } -static void scale_edges_on_axis(MeshComponent &mesh_component, const AxisScaleFields &fields) +static void scale_edges_on_axis(Mesh &mesh, const AxisScaleFields &fields) { - Mesh &mesh = *mesh_component.get_for_write(); mesh.mvert = static_cast<MVert *>( CustomData_duplicate_referenced_layer(&mesh.vdata, CD_MVERT, mesh.totvert)); - GeometryComponentFieldContext field_context{mesh_component, ATTR_DOMAIN_EDGE}; + bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_EDGE}; FieldEvaluator evaluator{field_context, mesh.totedge}; AxisScaleParams params = evaluate_axis_scale_fields(evaluator, fields); @@ -410,42 +406,38 @@ static void node_geo_exec(GeoNodeExecParams params) } geometry.modify_geometry_sets([&](GeometrySet &geometry) { - if (!geometry.has_mesh()) { - return; - } - MeshComponent &mesh_component = geometry.get_component_for_write<MeshComponent>(); - switch (domain) { - case ATTR_DOMAIN_FACE: { - switch (scale_mode) { - case GEO_NODE_SCALE_ELEMENTS_UNIFORM: { - scale_faces_uniformly(mesh_component, {selection_field, scale_field, center_field}); - break; - } - case GEO_NODE_SCALE_ELEMENTS_SINGLE_AXIS: { - scale_faces_on_axis(mesh_component, - {selection_field, scale_field, center_field, axis_field}); - break; + if (Mesh *mesh = geometry.get_mesh_for_write()) { + switch (domain) { + case ATTR_DOMAIN_FACE: { + switch (scale_mode) { + case GEO_NODE_SCALE_ELEMENTS_UNIFORM: { + scale_faces_uniformly(*mesh, {selection_field, scale_field, center_field}); + break; + } + case GEO_NODE_SCALE_ELEMENTS_SINGLE_AXIS: { + scale_faces_on_axis(*mesh, {selection_field, scale_field, center_field, axis_field}); + break; + } } + break; } - break; - } - case ATTR_DOMAIN_EDGE: { - switch (scale_mode) { - case GEO_NODE_SCALE_ELEMENTS_UNIFORM: { - scale_edges_uniformly(mesh_component, {selection_field, scale_field, center_field}); - break; - } - case GEO_NODE_SCALE_ELEMENTS_SINGLE_AXIS: { - scale_edges_on_axis(mesh_component, - {selection_field, scale_field, center_field, axis_field}); - break; + case ATTR_DOMAIN_EDGE: { + switch (scale_mode) { + case GEO_NODE_SCALE_ELEMENTS_UNIFORM: { + scale_edges_uniformly(*mesh, {selection_field, scale_field, center_field}); + break; + } + case GEO_NODE_SCALE_ELEMENTS_SINGLE_AXIS: { + scale_edges_on_axis(*mesh, {selection_field, scale_field, center_field, axis_field}); + break; + } } + break; } - break; + default: + BLI_assert_unreachable(); + break; } - default: - BLI_assert_unreachable(); - break; } }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc index 7156feb37d7..21fe724e194 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc @@ -21,9 +21,8 @@ static void node_declare(NodeDeclarationBuilder &b) static void scale_instances(GeoNodeExecParams ¶ms, InstancesComponent &instances_component) { - GeometryComponentFieldContext field_context{instances_component, ATTR_DOMAIN_INSTANCE}; - - fn::FieldEvaluator evaluator{field_context, instances_component.instances_num()}; + const bke::InstancesFieldContext context{instances_component}; + fn::FieldEvaluator evaluator{context, instances_component.instances_num()}; evaluator.set_selection(params.extract_input<Field<bool>>("Selection")); evaluator.add(params.extract_input<Field<float3>>("Scale")); evaluator.add(params.extract_input<Field<float3>>("Center")); diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc index fc3cb7006bb..e529ddddabe 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc @@ -68,19 +68,18 @@ static void update_handle_types_for_movement(int8_t &type, int8_t &other) } } -static void set_position_in_component(CurveComponent &component, +static void set_position_in_component(bke::CurvesGeometry &curves, const GeometryNodeCurveHandleMode mode, const Field<bool> &selection_field, const Field<float3> &position_field, const Field<float3> &offset_field) { - GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT}; - const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT); - if (domain_size == 0) { + if (curves.points_num() == 0) { return; } - fn::FieldEvaluator evaluator{field_context, domain_size}; + bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_POINT}; + fn::FieldEvaluator evaluator{field_context, curves.points_num()}; evaluator.set_selection(selection_field); evaluator.add(position_field); evaluator.add(offset_field); @@ -89,9 +88,6 @@ static void set_position_in_component(CurveComponent &component, const VArray<float3> new_positions = evaluator.get_evaluated<float3>(0); const VArray<float3> new_offsets = evaluator.get_evaluated<float3>(1); - Curves &curves_id = *component.get_for_write(); - bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); - Span<float3> positions = curves.positions(); const bool use_left = mode == GEO_NODE_CURVE_HANDLE_LEFT; @@ -141,22 +137,17 @@ static void node_geo_exec(GeoNodeExecParams params) std::atomic<bool> has_bezier = false; geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - if (!geometry_set.has_curves()) { - return; - } - has_curves = true; - const CurveComponent &component = *geometry_set.get_component_for_read<CurveComponent>(); - const AttributeAccessor attributes = *component.attributes(); - if (!attributes.contains("handle_left") || !attributes.contains("handle_right")) { - return; - } - has_bezier = true; + if (Curves *curves_id = geometry_set.get_curves_for_write()) { + bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry); + has_curves = true; + const AttributeAccessor attributes = curves.attributes(); + if (!attributes.contains("handle_left") || !attributes.contains("handle_right")) { + return; + } + has_bezier = true; - set_position_in_component(geometry_set.get_component_for_write<CurveComponent>(), - mode, - selection_field, - position_field, - offset_field); + set_position_in_component(curves, mode, selection_field, position_field, offset_field); + } }); if (has_curves && !has_bezier) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc index e4fae95b5a5..0d361090068 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "BKE_curves.hh" + #include "node_geometry_util.hh" namespace blender::nodes::node_geo_set_curve_radius_cc { @@ -16,21 +18,19 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output<decl::Geometry>(N_("Curve")); } -static void set_radius_in_component(GeometryComponent &component, - const Field<bool> &selection_field, - const Field<float> &radius_field) +static void set_radius(bke::CurvesGeometry &curves, + const Field<bool> &selection_field, + const Field<float> &radius_field) { - const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT); - if (domain_size == 0) { + if (curves.points_num() == 0) { return; } - MutableAttributeAccessor attributes = *component.attributes_for_write(); - GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT}; - + MutableAttributeAccessor attributes = curves.attributes_for_write(); AttributeWriter<float> radii = attributes.lookup_or_add_for_write<float>("radius", ATTR_DOMAIN_POINT); - fn::FieldEvaluator evaluator{field_context, domain_size}; + bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_POINT}; + fn::FieldEvaluator evaluator{field_context, curves.points_num()}; evaluator.set_selection(selection_field); evaluator.add_with_destination(radius_field, radii.varray); evaluator.evaluate(); @@ -45,9 +45,8 @@ static void node_geo_exec(GeoNodeExecParams params) Field<float> radii_field = params.extract_input<Field<float>>("Radius"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - if (geometry_set.has_curves()) { - set_radius_in_component( - geometry_set.get_component_for_write<CurveComponent>(), selection_field, radii_field); + if (Curves *curves_id = geometry_set.get_curves_for_write()) { + set_radius(bke::CurvesGeometry::wrap(curves_id->geometry), selection_field, radii_field); } }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc index 2211ac62727..8c1fb883f46 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "BKE_curves.hh" + #include "node_geometry_util.hh" namespace blender::nodes::node_geo_set_curve_tilt_cc { @@ -12,22 +14,19 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output<decl::Geometry>(N_("Curve")); } -static void set_tilt_in_component(GeometryComponent &component, - const Field<bool> &selection_field, - const Field<float> &tilt_field) +static void set_tilt(bke::CurvesGeometry &curves, + const Field<bool> &selection_field, + const Field<float> &tilt_field) { - const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT); - if (domain_size == 0) { + if (curves.points_num() == 0) { return; } - MutableAttributeAccessor attributes = *component.attributes_for_write(); - - GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT}; - + MutableAttributeAccessor attributes = curves.attributes_for_write(); AttributeWriter<float> tilts = attributes.lookup_or_add_for_write<float>("tilt", ATTR_DOMAIN_POINT); - fn::FieldEvaluator evaluator{field_context, domain_size}; + bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_POINT}; + fn::FieldEvaluator evaluator{field_context, curves.points_num()}; evaluator.set_selection(selection_field); evaluator.add_with_destination(tilt_field, tilts.varray); evaluator.evaluate(); @@ -42,9 +41,8 @@ static void node_geo_exec(GeoNodeExecParams params) Field<float> tilt_field = params.extract_input<Field<float>>("Tilt"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - if (geometry_set.has_curves()) { - set_tilt_in_component( - geometry_set.get_component_for_write<CurveComponent>(), selection_field, tilt_field); + if (Curves *curves_id = geometry_set.get_curves_for_write()) { + set_tilt(bke::CurvesGeometry::wrap(curves_id->geometry), selection_field, tilt_field); } }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_id.cc b/source/blender/nodes/geometry/nodes/node_geo_set_id.cc index fbb2ecbb799..5864401223b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_id.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_id.cc @@ -24,7 +24,7 @@ static void set_id_in_component(GeometryComponent &component, return; } MutableAttributeAccessor attributes = *component.attributes_for_write(); - GeometryComponentFieldContext field_context{component, domain}; + bke::GeometryFieldContext field_context{component, domain}; fn::FieldEvaluator evaluator{field_context, domain_size}; evaluator.set_selection(selection_field); diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_material.cc b/source/blender/nodes/geometry/nodes/node_geo_set_material.cc index a10a690ad45..c6a2f89220a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_material.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_material.cc @@ -72,8 +72,8 @@ static void node_geo_exec(GeoNodeExecParams params) if (geometry_set.has_mesh()) { MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>(); Mesh &mesh = *mesh_component.get_for_write(); - GeometryComponentFieldContext field_context{mesh_component, ATTR_DOMAIN_FACE}; + bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_FACE}; fn::FieldEvaluator selection_evaluator{field_context, mesh.totpoly}; selection_evaluator.add(selection_field); selection_evaluator.evaluate(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc b/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc index 0dc89bb7ef4..f6dded56315 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc @@ -14,17 +14,17 @@ static void node_declare(NodeDeclarationBuilder &b) static void set_material_index_in_component(GeometryComponent &component, const Field<bool> &selection_field, - const Field<int> &index_field) + const Field<int> &index_field, + const eAttrDomain domain) { - const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_FACE); + const int domain_size = component.attribute_domain_size(domain); if (domain_size == 0) { return; } MutableAttributeAccessor attributes = *component.attributes_for_write(); - GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_FACE}; + bke::GeometryFieldContext field_context{component, domain}; - AttributeWriter<int> indices = attributes.lookup_or_add_for_write<int>("material_index", - ATTR_DOMAIN_FACE); + AttributeWriter<int> indices = attributes.lookup_or_add_for_write<int>("material_index", domain); fn::FieldEvaluator evaluator{field_context, domain_size}; evaluator.set_selection(selection_field); @@ -41,8 +41,10 @@ static void node_geo_exec(GeoNodeExecParams params) geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { if (geometry_set.has_mesh()) { - set_material_index_in_component( - geometry_set.get_component_for_write<MeshComponent>(), selection_field, index_field); + set_material_index_in_component(geometry_set.get_component_for_write<MeshComponent>(), + selection_field, + index_field, + ATTR_DOMAIN_FACE); } }); params.set_output("Geometry", std::move(geometry_set)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc b/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc index da7977a4fb4..f1ac6e7f14c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "DNA_pointcloud_types.h" + #include "node_geometry_util.hh" namespace blender::nodes::node_geo_set_point_radius_cc { @@ -16,21 +18,19 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output<decl::Geometry>(N_("Points")); } -static void set_radius_in_component(GeometryComponent &component, +static void set_radius_in_component(PointCloud &pointcloud, const Field<bool> &selection_field, const Field<float> &radius_field) { - const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT); - if (domain_size == 0) { + if (pointcloud.totpoint == 0) { return; } - MutableAttributeAccessor attributes = *component.attributes_for_write(); - GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT}; - + MutableAttributeAccessor attributes = bke::pointcloud_attributes_for_write(pointcloud); AttributeWriter<float> radii = attributes.lookup_or_add_for_write<float>("radius", ATTR_DOMAIN_POINT); - fn::FieldEvaluator evaluator{field_context, domain_size}; + bke::PointCloudFieldContext field_context{pointcloud}; + fn::FieldEvaluator evaluator{field_context, pointcloud.totpoint}; evaluator.set_selection(selection_field); evaluator.add_with_destination(radius_field, radii.varray); evaluator.evaluate(); @@ -45,10 +45,8 @@ static void node_geo_exec(GeoNodeExecParams params) Field<float> radii_field = params.extract_input<Field<float>>("Radius"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - if (geometry_set.has_pointcloud()) { - set_radius_in_component(geometry_set.get_component_for_write<PointCloudComponent>(), - selection_field, - radii_field); + if (PointCloud *pointcloud = geometry_set.get_pointcloud_for_write()) { + set_radius_in_component(*pointcloud, selection_field, radii_field); } }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc index 880252de4fa..d9c7c9422eb 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc @@ -136,7 +136,7 @@ static void set_position_in_component(GeometryComponent &component, { eAttrDomain domain = component.type() == GEO_COMPONENT_TYPE_INSTANCES ? ATTR_DOMAIN_INSTANCE : ATTR_DOMAIN_POINT; - GeometryComponentFieldContext field_context{component, domain}; + bke::GeometryFieldContext field_context{component, domain}; const int domain_size = component.attribute_domain_size(domain); if (domain_size == 0) { return; diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc b/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc index e0cf0f98d58..fa4d3eb6ac9 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "DNA_mesh_types.h" + #include "node_geometry_util.hh" namespace blender::nodes::node_geo_set_shade_smooth_cc { @@ -12,27 +14,25 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output<decl::Geometry>(N_("Geometry")); } -static void set_smooth_in_component(GeometryComponent &component, - const Field<bool> &selection_field, - const Field<bool> &shade_field) +static void set_smooth(Mesh &mesh, + const Field<bool> &selection_field, + const Field<bool> &shade_field) { - const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_FACE); - if (domain_size == 0) { + if (mesh.totpoly == 0) { return; } - MutableAttributeAccessor attributes = *component.attributes_for_write(); - - GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_FACE}; - AttributeWriter<bool> shades = attributes.lookup_or_add_for_write<bool>("shade_smooth", + MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(mesh); + AttributeWriter<bool> smooth = attributes.lookup_or_add_for_write<bool>("shade_smooth", ATTR_DOMAIN_FACE); - fn::FieldEvaluator evaluator{field_context, domain_size}; + bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_FACE}; + fn::FieldEvaluator evaluator{field_context, mesh.totpoly}; evaluator.set_selection(selection_field); - evaluator.add_with_destination(shade_field, shades.varray); + evaluator.add_with_destination(shade_field, smooth.varray); evaluator.evaluate(); - shades.finish(); + smooth.finish(); } static void node_geo_exec(GeoNodeExecParams params) @@ -42,9 +42,8 @@ static void node_geo_exec(GeoNodeExecParams params) Field<bool> shade_field = params.extract_input<Field<bool>>("Shade Smooth"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - if (geometry_set.has_mesh()) { - set_smooth_in_component( - geometry_set.get_component_for_write<MeshComponent>(), selection_field, shade_field); + if (Mesh *mesh = geometry_set.get_mesh_for_write()) { + set_smooth(*mesh, selection_field, shade_field); } }); params.set_output("Geometry", std::move(geometry_set)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc b/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc index a35d8d66558..d8faa154477 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "BKE_curves.hh" + #include "node_geometry_util.hh" namespace blender::nodes::node_geo_set_spline_cyclic_cc { @@ -12,22 +14,19 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output<decl::Geometry>(N_("Geometry")); } -static void set_cyclic_in_component(GeometryComponent &component, - const Field<bool> &selection_field, - const Field<bool> &cyclic_field) +static void set_cyclic(bke::CurvesGeometry &curves, + const Field<bool> &selection_field, + const Field<bool> &cyclic_field) { - const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_CURVE); - if (domain_size == 0) { + if (curves.curves_num() == 0) { return; } - MutableAttributeAccessor attributes = *component.attributes_for_write(); - - GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_CURVE}; - + MutableAttributeAccessor attributes = curves.attributes_for_write(); AttributeWriter<bool> cyclics = attributes.lookup_or_add_for_write<bool>("cyclic", ATTR_DOMAIN_CURVE); - fn::FieldEvaluator evaluator{field_context, domain_size}; + bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_CURVE}; + fn::FieldEvaluator evaluator{field_context, curves.curves_num()}; evaluator.set_selection(selection_field); evaluator.add_with_destination(cyclic_field, cyclics.varray); evaluator.evaluate(); @@ -42,9 +41,8 @@ static void node_geo_exec(GeoNodeExecParams params) Field<bool> cyclic_field = params.extract_input<Field<bool>>("Cyclic"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - if (geometry_set.has_curves()) { - set_cyclic_in_component( - geometry_set.get_component_for_write<CurveComponent>(), selection_field, cyclic_field); + if (Curves *curves_id = geometry_set.get_curves_for_write()) { + set_cyclic(bke::CurvesGeometry::wrap(curves_id->geometry), selection_field, cyclic_field); } }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc b/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc index fcebc1116d7..d46ceac92ba 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "BKE_curves.hh" + #include "node_geometry_util.hh" namespace blender::nodes::node_geo_set_spline_resolution_cc { @@ -12,22 +14,19 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output<decl::Geometry>(N_("Geometry")); } -static void set_resolution_in_component(GeometryComponent &component, - const Field<bool> &selection_field, - const Field<int> &resolution_field) +static void set_resolution(bke::CurvesGeometry &curves, + const Field<bool> &selection_field, + const Field<int> &resolution_field) { - const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_CURVE); - if (domain_size == 0) { + if (curves.curves_num() == 0) { return; } - MutableAttributeAccessor attributes = *component.attributes_for_write(); - - GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_CURVE}; - + MutableAttributeAccessor attributes = curves.attributes_for_write(); AttributeWriter<int> resolutions = attributes.lookup_or_add_for_write<int>("resolution", ATTR_DOMAIN_CURVE); - fn::FieldEvaluator evaluator{field_context, domain_size}; + bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_CURVE}; + fn::FieldEvaluator evaluator{field_context, curves.curves_num()}; evaluator.set_selection(selection_field); evaluator.add_with_destination(resolution_field, resolutions.varray); evaluator.evaluate(); @@ -38,12 +37,13 @@ static void set_resolution_in_component(GeometryComponent &component, static void node_geo_exec(GeoNodeExecParams params) { GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry"); - Field<bool> selection_field = params.extract_input<Field<bool>>("Selection"); - Field<int> resolution_field = params.extract_input<Field<int>>("Resolution"); + Field<bool> selection = params.extract_input<Field<bool>>("Selection"); + Field<int> resolution = params.extract_input<Field<int>>("Resolution"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - set_resolution_in_component( - geometry_set.get_component_for_write<CurveComponent>(), selection_field, resolution_field); + if (Curves *curves_id = geometry_set.get_curves_for_write()) { + set_resolution(bke::CurvesGeometry::wrap(curves_id->geometry), selection, resolution); + } }); params.set_output("Geometry", std::move(geometry_set)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc index 70c33ad6a96..9719833097e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc @@ -98,7 +98,7 @@ static void try_capture_field_on_geometry(GeometryComponent &component, return; } - GeometryComponentFieldContext field_context{component, domain}; + bke::GeometryFieldContext field_context{component, domain}; const IndexMask mask{IndexMask(domain_size)}; const CPPType &type = field.cpp_type(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc index eda6a51d412..f1fb9ce5563 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc @@ -119,21 +119,19 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - const MeshComponent &mesh_component = *geometry_set.get_component_for_read<MeshComponent>(); - const int verts_num = mesh_component.attribute_domain_size(ATTR_DOMAIN_POINT); - const int edges_num = mesh_component.attribute_domain_size(ATTR_DOMAIN_EDGE); - if (verts_num == 0 || edges_num == 0) { + const Mesh &mesh = *geometry_set.get_mesh_for_read(); + if (mesh.totvert == 0 || mesh.totedge == 0) { return; } - GeometryComponentFieldContext point_context{mesh_component, ATTR_DOMAIN_POINT}; - FieldEvaluator point_evaluator(point_context, verts_num); + bke::MeshFieldContext point_context{mesh, ATTR_DOMAIN_POINT}; + FieldEvaluator point_evaluator(point_context, mesh.totvert); point_evaluator.add(vertex_crease_field); point_evaluator.evaluate(); const VArray<float> vertex_creases = point_evaluator.get_evaluated<float>(0); - GeometryComponentFieldContext edge_context{mesh_component, ATTR_DOMAIN_EDGE}; - FieldEvaluator edge_evaluator(edge_context, edges_num); + bke::MeshFieldContext edge_context{mesh, ATTR_DOMAIN_EDGE}; + FieldEvaluator edge_evaluator(edge_context, mesh.totedge); edge_evaluator.add(edge_crease_field); edge_evaluator.evaluate(); const VArray<float> edge_creases = edge_evaluator.get_evaluated<float>(0); @@ -162,17 +160,15 @@ static void node_geo_exec(GeoNodeExecParams params) subdiv_settings.fvar_linear_interpolation = BKE_subdiv_fvar_interpolation_from_uv_smooth( uv_smooth); - const Mesh &mesh_in = *geometry_set.get_mesh_for_read(); - /* Apply subdivision to mesh. */ - Subdiv *subdiv = BKE_subdiv_update_from_mesh(nullptr, &subdiv_settings, &mesh_in); + Subdiv *subdiv = BKE_subdiv_update_from_mesh(nullptr, &subdiv_settings, &mesh); /* In case of bad topology, skip to input mesh. */ if (subdiv == nullptr) { return; } - Mesh *mesh_out = BKE_subdiv_to_mesh(subdiv, &mesh_settings, &mesh_in); + Mesh *mesh_out = BKE_subdiv_to_mesh(subdiv, &mesh_settings, &mesh); geometry_set.replace_mesh(mesh_out); diff --git a/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc index cd75822f665..539a1488f53 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc @@ -387,7 +387,7 @@ class NearestInterpolatedTransferFunction : public fn::MultiFunction { fn::MFSignature signature_; - std::optional<GeometryComponentFieldContext> source_context_; + std::optional<bke::MeshFieldContext> source_context_; std::unique_ptr<FieldEvaluator> source_evaluator_; const GVArray *source_data_; @@ -431,10 +431,10 @@ class NearestInterpolatedTransferFunction : public fn::MultiFunction { private: void evaluate_source_field() { - const MeshComponent &mesh_component = *source_.get_component_for_read<MeshComponent>(); - source_context_.emplace(GeometryComponentFieldContext{mesh_component, domain_}); - const int domain_num = mesh_component.attribute_domain_size(domain_); - source_evaluator_ = std::make_unique<FieldEvaluator>(*source_context_, domain_num); + const Mesh &mesh = *source_.get_mesh_for_read(); + source_context_.emplace(bke::MeshFieldContext{mesh, domain_}); + const int domain_size = bke::mesh_attributes(mesh).domain_size(domain_); + source_evaluator_ = std::make_unique<FieldEvaluator>(*source_context_, domain_size); source_evaluator_->add(src_field_); source_evaluator_->evaluate(); source_data_ = &source_evaluator_->get_evaluated(0); @@ -457,11 +457,11 @@ class NearestTransferFunction : public fn::MultiFunction { bool use_points_; /* Store data from the source as a virtual array, since we may only access a few indices. */ - std::optional<GeometryComponentFieldContext> mesh_context_; + std::optional<bke::MeshFieldContext> mesh_context_; std::unique_ptr<FieldEvaluator> mesh_evaluator_; const GVArray *mesh_data_; - std::optional<GeometryComponentFieldContext> point_context_; + std::optional<bke::PointCloudFieldContext> point_context_; std::unique_ptr<FieldEvaluator> point_evaluator_; const GVArray *point_data_; @@ -577,20 +577,19 @@ class NearestTransferFunction : public fn::MultiFunction { void evaluate_source_field() { if (use_mesh_) { - const MeshComponent &mesh = *source_.get_component_for_read<MeshComponent>(); - const int domain_num = mesh.attribute_domain_size(domain_); - mesh_context_.emplace(GeometryComponentFieldContext(mesh, domain_)); - mesh_evaluator_ = std::make_unique<FieldEvaluator>(*mesh_context_, domain_num); + const Mesh &mesh = *source_.get_mesh_for_read(); + const int domain_size = bke::mesh_attributes(mesh).domain_size(domain_); + mesh_context_.emplace(bke::MeshFieldContext(mesh, domain_)); + mesh_evaluator_ = std::make_unique<FieldEvaluator>(*mesh_context_, domain_size); mesh_evaluator_->add(src_field_); mesh_evaluator_->evaluate(); mesh_data_ = &mesh_evaluator_->get_evaluated(0); } if (use_points_) { - const PointCloudComponent &points = *source_.get_component_for_read<PointCloudComponent>(); - const int domain_num = points.attribute_domain_size(domain_); - point_context_.emplace(GeometryComponentFieldContext(points, domain_)); - point_evaluator_ = std::make_unique<FieldEvaluator>(*point_context_, domain_num); + const PointCloud &points = *source_.get_pointcloud_for_read(); + point_context_.emplace(bke::PointCloudFieldContext(points)); + point_evaluator_ = std::make_unique<FieldEvaluator>(*point_context_, points.totpoint); point_evaluator_->add(src_field_); point_evaluator_->evaluate(); point_data_ = &point_evaluator_->get_evaluated(0); @@ -628,7 +627,7 @@ class IndexTransferFunction : public fn::MultiFunction { fn::MFSignature signature_; - std::optional<GeometryComponentFieldContext> geometry_context_; + std::optional<bke::GeometryFieldContext> geometry_context_; std::unique_ptr<FieldEvaluator> evaluator_; const GVArray *src_data_ = nullptr; @@ -659,7 +658,7 @@ class IndexTransferFunction : public fn::MultiFunction { return; } const int domain_num = component->attribute_domain_size(domain_); - geometry_context_.emplace(GeometryComponentFieldContext(*component, domain_)); + geometry_context_.emplace(bke::GeometryFieldContext(*component, domain_)); evaluator_ = std::make_unique<FieldEvaluator>(*geometry_context_, domain_num); evaluator_->add(src_field_); evaluator_->evaluate(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc index ae538072e65..3e9fe99adb0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc @@ -17,9 +17,8 @@ static void node_declare(NodeDeclarationBuilder &b) static void translate_instances(GeoNodeExecParams ¶ms, InstancesComponent &instances_component) { - GeometryComponentFieldContext field_context{instances_component, ATTR_DOMAIN_INSTANCE}; - - fn::FieldEvaluator evaluator{field_context, instances_component.instances_num()}; + const bke::InstancesFieldContext context{instances_component}; + fn::FieldEvaluator evaluator{context, instances_component.instances_num()}; evaluator.set_selection(params.extract_input<Field<bool>>("Selection")); evaluator.add(params.extract_input<Field<float3>>("Translation")); evaluator.add(params.extract_input<Field<bool>>("Local Space")); diff --git a/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc b/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc index 5cc4d6e6dbc..57487059437 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc @@ -77,12 +77,10 @@ static void node_geo_exec(GeoNodeExecParams params) if (!geometry_set.has_mesh()) { return; } - GeometryComponent &component = geometry_set.get_component_for_write<MeshComponent>(); const Mesh &mesh_in = *geometry_set.get_mesh_for_read(); - const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_FACE); - GeometryComponentFieldContext context{component, ATTR_DOMAIN_FACE}; - FieldEvaluator evaluator{context, domain_size}; + bke::MeshFieldContext context{mesh_in, ATTR_DOMAIN_FACE}; + FieldEvaluator evaluator{context, mesh_in.totpoly}; evaluator.add(selection_field); evaluator.evaluate(); const IndexMask selection = evaluator.get_evaluated_as_mask(0); diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc index 17413e64f7d..a59704291cd 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc @@ -28,21 +28,15 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output<decl::Vector>(N_("UV")).field_source(); } -static VArray<float3> construct_uv_gvarray(const MeshComponent &component, +static VArray<float3> construct_uv_gvarray(const Mesh &mesh, const Field<bool> selection_field, const Field<float3> uv_field, const bool rotate, const float margin, const eAttrDomain domain) { - const Mesh *mesh = component.get_for_read(); - if (mesh == nullptr) { - return {}; - } - - const int face_num = component.attribute_domain_size(ATTR_DOMAIN_FACE); - GeometryComponentFieldContext face_context{component, ATTR_DOMAIN_FACE}; - FieldEvaluator face_evaluator{face_context, face_num}; + bke::MeshFieldContext face_context{mesh, ATTR_DOMAIN_FACE}; + FieldEvaluator face_evaluator{face_context, mesh.totpoly}; face_evaluator.add(selection_field); face_evaluator.evaluate(); const IndexMask selection = face_evaluator.get_evaluated_as_mask(0); @@ -50,25 +44,29 @@ static VArray<float3> construct_uv_gvarray(const MeshComponent &component, return {}; } - const int corner_num = component.attribute_domain_size(ATTR_DOMAIN_CORNER); - GeometryComponentFieldContext corner_context{component, ATTR_DOMAIN_CORNER}; - FieldEvaluator evaluator{corner_context, corner_num}; - Array<float3> uv(corner_num); + bke::MeshFieldContext corner_context{mesh, ATTR_DOMAIN_CORNER}; + FieldEvaluator evaluator{corner_context, mesh.totloop}; + Array<float3> uv(mesh.totloop); evaluator.add_with_destination(uv_field, uv.as_mutable_span()); evaluator.evaluate(); + const Span<MVert> vertices(mesh.mvert, mesh.totvert); + const Span<MEdge> edges(mesh.medge, mesh.totedge); + const Span<MPoly> polygons(mesh.mpoly, mesh.totpoly); + const Span<MLoop> loops(mesh.mloop, mesh.totloop); + ParamHandle *handle = GEO_uv_parametrizer_construct_begin(); for (const int mp_index : selection) { - const MPoly &mp = mesh->mpoly[mp_index]; + const MPoly &mp = polygons[mp_index]; Array<ParamKey, 16> mp_vkeys(mp.totloop); Array<bool, 16> mp_pin(mp.totloop); Array<bool, 16> mp_select(mp.totloop); Array<const float *, 16> mp_co(mp.totloop); Array<float *, 16> mp_uv(mp.totloop); for (const int i : IndexRange(mp.totloop)) { - const MLoop &ml = mesh->mloop[mp.loopstart + i]; + const MLoop &ml = loops[mp.loopstart + i]; mp_vkeys[i] = ml.v; - mp_co[i] = mesh->mvert[ml.v].co; + mp_co[i] = vertices[ml.v].co; mp_uv[i] = uv[mp.loopstart + i]; mp_pin[i] = false; mp_select[i] = false; @@ -88,11 +86,11 @@ static VArray<float3> construct_uv_gvarray(const MeshComponent &component, GEO_uv_parametrizer_flush(handle); GEO_uv_parametrizer_delete(handle); - return component.attributes()->adapt_domain<float3>( + return bke::mesh_attributes(mesh).adapt_domain<float3>( VArray<float3>::ForContainer(std::move(uv)), ATTR_DOMAIN_CORNER, domain); } -class PackIslandsFieldInput final : public GeometryFieldInput { +class PackIslandsFieldInput final : public bke::MeshFieldInput { private: const Field<bool> selection_field; const Field<float3> uv_field; @@ -104,7 +102,7 @@ class PackIslandsFieldInput final : public GeometryFieldInput { const Field<float3> uv_field, const bool rotate, const float margin) - : GeometryFieldInput(CPPType::get<float3>(), "Pack UV Islands Field"), + : bke::MeshFieldInput(CPPType::get<float3>(), "Pack UV Islands Field"), selection_field(selection_field), uv_field(uv_field), rotate(rotate), @@ -113,16 +111,11 @@ class PackIslandsFieldInput final : public GeometryFieldInput { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - if (component.type() == GEO_COMPONENT_TYPE_MESH) { - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - return construct_uv_gvarray( - mesh_component, selection_field, uv_field, rotate, margin, domain); - } - return {}; + return construct_uv_gvarray(mesh, selection_field, uv_field, rotate, margin, domain); } }; diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc index 03657f3e016..786438ad62a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc @@ -52,7 +52,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node) node->storage = data; } -static VArray<float3> construct_uv_gvarray(const MeshComponent &component, +static VArray<float3> construct_uv_gvarray(const Mesh &mesh, const Field<bool> selection_field, const Field<bool> seam_field, const bool fill_holes, @@ -60,14 +60,8 @@ static VArray<float3> construct_uv_gvarray(const MeshComponent &component, const GeometryNodeUVUnwrapMethod method, const eAttrDomain domain) { - const Mesh *mesh = component.get_for_read(); - if (mesh == nullptr) { - return {}; - } - - const int face_num = component.attribute_domain_size(ATTR_DOMAIN_FACE); - GeometryComponentFieldContext face_context{component, ATTR_DOMAIN_FACE}; - FieldEvaluator face_evaluator{face_context, face_num}; + bke::MeshFieldContext face_context{mesh, ATTR_DOMAIN_FACE}; + FieldEvaluator face_evaluator{face_context, mesh.totpoly}; face_evaluator.add(selection_field); face_evaluator.evaluate(); const IndexMask selection = face_evaluator.get_evaluated_as_mask(0); @@ -75,27 +69,31 @@ static VArray<float3> construct_uv_gvarray(const MeshComponent &component, return {}; } - const int edge_num = component.attribute_domain_size(ATTR_DOMAIN_EDGE); - GeometryComponentFieldContext edge_context{component, ATTR_DOMAIN_EDGE}; - FieldEvaluator edge_evaluator{edge_context, edge_num}; + bke::MeshFieldContext edge_context{mesh, ATTR_DOMAIN_EDGE}; + FieldEvaluator edge_evaluator{edge_context, mesh.totedge}; edge_evaluator.add(seam_field); edge_evaluator.evaluate(); const IndexMask seam = edge_evaluator.get_evaluated_as_mask(0); - Array<float3> uv(mesh->totloop, float3(0)); + const Span<MVert> vertices(mesh.mvert, mesh.totvert); + const Span<MEdge> edges(mesh.medge, mesh.totedge); + const Span<MPoly> polygons(mesh.mpoly, mesh.totpoly); + const Span<MLoop> loops(mesh.mloop, mesh.totloop); + + Array<float3> uv(loops.size(), float3(0)); ParamHandle *handle = GEO_uv_parametrizer_construct_begin(); for (const int mp_index : selection) { - const MPoly &mp = mesh->mpoly[mp_index]; + const MPoly &mp = polygons[mp_index]; Array<ParamKey, 16> mp_vkeys(mp.totloop); Array<bool, 16> mp_pin(mp.totloop); Array<bool, 16> mp_select(mp.totloop); Array<const float *, 16> mp_co(mp.totloop); Array<float *, 16> mp_uv(mp.totloop); for (const int i : IndexRange(mp.totloop)) { - const MLoop &ml = mesh->mloop[mp.loopstart + i]; + const MLoop &ml = loops[mp.loopstart + i]; mp_vkeys[i] = ml.v; - mp_co[i] = mesh->mvert[ml.v].co; + mp_co[i] = vertices[ml.v].co; mp_uv[i] = uv[mp.loopstart + i]; mp_pin[i] = false; mp_select[i] = false; @@ -110,7 +108,7 @@ static VArray<float3> construct_uv_gvarray(const MeshComponent &component, mp_select.data()); } for (const int i : seam) { - const MEdge &edge = mesh->medge[i]; + const MEdge &edge = edges[i]; ParamKey vkeys[2]{edge.v1, edge.v2}; GEO_uv_parametrizer_edge_set_seam(handle, vkeys); } @@ -126,11 +124,11 @@ static VArray<float3> construct_uv_gvarray(const MeshComponent &component, GEO_uv_parametrizer_flush(handle); GEO_uv_parametrizer_delete(handle); - return component.attributes()->adapt_domain<float3>( + return bke::mesh_attributes(mesh).adapt_domain<float3>( VArray<float3>::ForContainer(std::move(uv)), ATTR_DOMAIN_CORNER, domain); } -class UnwrapFieldInput final : public GeometryFieldInput { +class UnwrapFieldInput final : public bke::MeshFieldInput { private: const Field<bool> selection; const Field<bool> seam; @@ -144,7 +142,7 @@ class UnwrapFieldInput final : public GeometryFieldInput { const bool fill_holes, const float margin, const GeometryNodeUVUnwrapMethod method) - : GeometryFieldInput(CPPType::get<float3>(), "UV Unwrap Field"), + : bke::MeshFieldInput(CPPType::get<float3>(), "UV Unwrap Field"), selection(selection), seam(seam), fill_holes(fill_holes), @@ -154,16 +152,11 @@ class UnwrapFieldInput final : public GeometryFieldInput { category_ = Category::Generated; } - GVArray get_varray_for_context(const GeometryComponent &component, + GVArray get_varray_for_context(const Mesh &mesh, const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - if (component.type() == GEO_COMPONENT_TYPE_MESH) { - const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); - return construct_uv_gvarray( - mesh_component, selection, seam, fill_holes, margin, method, domain); - } - return {}; + return construct_uv_gvarray(mesh, selection, seam, fill_holes, margin, method, domain); } }; diff --git a/source/blender/render/intern/pipeline.cc b/source/blender/render/intern/pipeline.cc index 71b83a63d12..8cc1293eae3 100644 --- a/source/blender/render/intern/pipeline.cc +++ b/source/blender/render/intern/pipeline.cc @@ -436,7 +436,7 @@ void RE_AcquireResultImage(Render *re, RenderResult *rr, const int view_id) rr->rectx = re->result->rectx; rr->recty = re->result->recty; - /* actview view */ + /* `scene.rd.actview` view. */ rv = RE_RenderViewGetById(re->result, view_id); rr->have_combined = (rv->rectf != nullptr); diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 9b3a0d39dfa..a0200373ac6 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -616,7 +616,10 @@ void wm_close_and_free_all(bContext *C, ListBase *wmlist) while ((wm = wmlist->first)) { wm_close_and_free(C, wm); BLI_remlink(wmlist, wm); - BKE_libblock_free_data(&wm->id, true); + /* Don't handle user counts as this is only ever called once #G_MAIN has already been freed via + * #BKE_main_free so any ID's referenced by the window-manager (from ID properties) will crash. + * See: T100703. */ + BKE_libblock_free_data(&wm->id, false); BKE_libblock_free_data_py(&wm->id); MEM_freeN(wm); } |