diff options
Diffstat (limited to 'source/blender/nodes/geometry')
72 files changed, 784 insertions, 1065 deletions
diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt index ddd8c8949b1..31c00cc6b82 100644 --- a/source/blender/nodes/geometry/CMakeLists.txt +++ b/source/blender/nodes/geometry/CMakeLists.txt @@ -76,8 +76,8 @@ set(SRC nodes/node_geo_input_index.cc nodes/node_geo_input_instance_rotation.cc nodes/node_geo_input_instance_scale.cc - nodes/node_geo_input_material_index.cc nodes/node_geo_input_material.cc + nodes/node_geo_input_material_index.cc nodes/node_geo_input_mesh_edge_angle.cc nodes/node_geo_input_mesh_edge_neighbors.cc nodes/node_geo_input_mesh_edge_vertices.cc @@ -118,9 +118,9 @@ set(SRC nodes/node_geo_mesh_to_points.cc nodes/node_geo_mesh_to_volume.cc nodes/node_geo_object_info.cc + nodes/node_geo_points.cc nodes/node_geo_points_to_vertices.cc nodes/node_geo_points_to_volume.cc - nodes/node_geo_points.cc nodes/node_geo_proximity.cc nodes/node_geo_raycast.cc nodes/node_geo_realize_instances.cc @@ -134,8 +134,8 @@ set(SRC nodes/node_geo_set_curve_radius.cc nodes/node_geo_set_curve_tilt.cc nodes/node_geo_set_id.cc - nodes/node_geo_set_material_index.cc nodes/node_geo_set_material.cc + nodes/node_geo_set_material_index.cc nodes/node_geo_set_point_radius.cc nodes/node_geo_set_position.cc nodes/node_geo_set_shade_smooth.cc diff --git a/source/blender/nodes/geometry/node_geometry_tree.cc b/source/blender/nodes/geometry/node_geometry_tree.cc index 38e914b9a9f..c6914bbcb0c 100644 --- a/source/blender/nodes/geometry/node_geometry_tree.cc +++ b/source/blender/nodes/geometry/node_geometry_tree.cc @@ -7,6 +7,7 @@ #include "NOD_geometry.h" #include "BKE_context.h" +#include "BKE_layer.h" #include "BKE_node.h" #include "BKE_object.h" @@ -32,7 +33,7 @@ static void geometry_node_tree_get_from_context(const bContext *C, ID **r_from) { ViewLayer *view_layer = CTX_data_view_layer(C); - Object *ob = OBACT(view_layer); + Object *ob = BKE_view_layer_active_object_get(view_layer); if (ob == nullptr) { return; @@ -109,6 +110,7 @@ void register_node_tree_type_geo() MEM_callocN(sizeof(bNodeTreeType), "geometry node tree type")); tt->type = NTREE_GEOMETRY; strcpy(tt->idname, "GeometryNodeTree"); + strcpy(tt->group_idname, "GeometryNodeGroup"); strcpy(tt->ui_name, N_("Geometry Node Editor")); tt->ui_icon = ICON_GEOMETRY_NODES; strcpy(tt->ui_description, N_("Geometry nodes")); diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh index a4af608a40e..4db4d8bb097 100644 --- a/source/blender/nodes/geometry/node_geometry_util.hh +++ b/source/blender/nodes/geometry/node_geometry_util.hh @@ -20,6 +20,8 @@ #include "NOD_socket_declarations.hh" #include "NOD_socket_declarations_geometry.hh" +#include "RNA_access.h" + #include "node_util.h" void geo_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass); 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..28d979facac 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_); @@ -72,12 +64,12 @@ class EndpointFieldInput final : public GeometryFieldInput { devirtualize_varray2(start_size, end_size, [&](const auto &start_size, const auto &end_size) { threading::parallel_for(curves.curves_range(), 1024, [&](IndexRange curves_range) { for (const int i : curves_range) { - const IndexRange range = curves.points_for_curve(i); + const IndexRange points = curves.points_for_curve(i); const int start = std::max(start_size[i], 0); const int end = std::max(end_size[i], 0); - selection_span.slice(range.take_front(start)).fill(true); - selection_span.slice(range.take_back(end)).fill(true); + selection_span.slice(points.take_front(start)).fill(true); + selection_span.slice(points.take_back(end)).fill(true); } }); }); 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_deform_curves_on_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc index 5a40ededa96..2481170835b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc @@ -249,7 +249,7 @@ static void node_geo_exec(GeoNodeExecParams params) Mesh &surface_object_data = *static_cast<Mesh *>(surface_ob_orig->data); if (BMEditMesh *em = surface_object_data.edit_mesh) { - surface_mesh_orig = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL, &surface_object_data); + surface_mesh_orig = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, nullptr, &surface_object_data); free_suface_mesh_orig = true; } else { 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 cfb9cbf7e24..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 @@ -220,11 +220,11 @@ BLI_NOINLINE static void update_elimination_mask_based_on_density_factors( const float v1_density_factor = std::max(0.0f, density_factors[v1_loop]); const float v2_density_factor = std::max(0.0f, density_factors[v2_loop]); - const float probablity = v0_density_factor * bary_coord.x + v1_density_factor * bary_coord.y + - v2_density_factor * bary_coord.z; + const float probability = v0_density_factor * bary_coord.x + v1_density_factor * bary_coord.y + + v2_density_factor * bary_coord.z; const float hash = noise::hash_float_to_float(bary_coord); - if (hash > probablity) { + if (hash > probability) { elimination_mask[i] = true; } } @@ -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 acf85e74353..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)); @@ -225,7 +225,7 @@ template<typename T, typename GetMixIndicesFn> void copy_with_mixing(MutableSpan<T> dst, Span<T> src, GetMixIndicesFn get_mix_indices_fn) { threading::parallel_for(dst.index_range(), 512, [&](const IndexRange range) { - attribute_math::DefaultPropatationMixer<T> mixer{dst.slice(range)}; + attribute_math::DefaultPropagationMixer<T> mixer{dst.slice(range)}; for (const int i_dst : IndexRange(range.size())) { for (const int i_src : get_mix_indices_fn(range[i_dst])) { mixer.mix_in(i_dst, src[i_src]); @@ -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); @@ -437,7 +435,7 @@ static void extrude_mesh_edges(MeshComponent &component, Array<float3> vert_offsets; if (!edge_offsets.is_single()) { vert_offsets.reinitialize(orig_vert_size); - attribute_math::DefaultPropatationMixer<float3> mixer(vert_offsets); + attribute_math::DefaultPropagationMixer<float3> mixer(vert_offsets); for (const int i_edge : edge_selection) { const MEdge &edge = orig_edges[i_edge]; const float3 offset = edge_offsets[i_edge]; @@ -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( @@ -583,7 +581,7 @@ static void extrude_mesh_edges(MeshComponent &component, /* Both corners on each vertical edge of the side polygon get the same value, * so there are only two unique values to mix. */ Array<T> side_poly_corner_data(2); - attribute_math::DefaultPropatationMixer<T> mixer{side_poly_corner_data}; + attribute_math::DefaultPropagationMixer<T> mixer{side_poly_corner_data}; const MEdge &duplicate_edge = duplicate_edges[i_edge_selection]; const int new_vert_1 = duplicate_edge.v1; @@ -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); @@ -705,7 +702,7 @@ static void extrude_mesh_face_regions(MeshComponent &component, Array<float3> vert_offsets; if (!poly_offsets.is_single()) { vert_offsets.reinitialize(orig_vert_size); - attribute_math::DefaultPropatationMixer<float3> mixer(vert_offsets); + attribute_math::DefaultPropagationMixer<float3> mixer(vert_offsets); for (const int i_poly : poly_selection) { const MPoly &poly = orig_polys[i_poly]; const float3 offset = poly_offsets[i_poly]; @@ -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 ca613ae009b..9822e0ea0d6 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc @@ -23,46 +23,56 @@ static void node_declare(NodeDeclarationBuilder &b) static void select_mesh_by_material(const Mesh &mesh, const Material *material, const IndexMask mask, - const MutableSpan<bool> r_selection) + MutableSpan<bool> r_selection) { BLI_assert(mesh.totpoly >= r_selection.size()); - Vector<int> material_indices; + Vector<int> slots; for (const int i : IndexRange(mesh.totcol)) { if (mesh.mat[i] == material) { - material_indices.append(i); + slots.append(i); } } + const AttributeAccessor attributes = bke::mesh_attributes(mesh); + const VArray<int> material_indices = attributes.lookup_or_default<int>( + "material_index", ATTR_DOMAIN_FACE, 0); + if (material != nullptr && material_indices.is_single() && + material_indices.get_internal_single() == 0) { + r_selection.fill_indices(mask, false); + return; + } + + const VArraySpan<int> material_indices_span(material_indices); + threading::parallel_for(mask.index_range(), 1024, [&](IndexRange range) { for (const int i : range) { const int face_index = mask[i]; - r_selection[i] = material_indices.contains(mesh.mpoly[face_index].mat_nr); + r_selection[i] = slots.contains(material_indices_span[face_index]); } }); } -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); @@ -71,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.cc b/source/blender/nodes/geometry/nodes/node_geo_points.cc index dd32e6714f4..e0ba1f1c810 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_points.cc @@ -69,10 +69,8 @@ static void node_geo_exec(GeoNodeExecParams params) Field<float3> position_field = params.extract_input<Field<float3>>("Position"); Field<float> radius_field = params.extract_input<Field<float>>("Radius"); - PointCloud *new_point_cloud = BKE_pointcloud_new_nomain(count); - GeometrySet geometry_set = GeometrySet::create_with_pointcloud(new_point_cloud); - PointCloudComponent &points = geometry_set.get_component_for_write<PointCloudComponent>(); - MutableAttributeAccessor attributes = *points.attributes_for_write(); + PointCloud *points = BKE_pointcloud_new_nomain(count); + MutableAttributeAccessor attributes = bke::pointcloud_attributes_for_write(*points); AttributeWriter<float3> output_position = attributes.lookup_or_add_for_write<float3>( "position", ATTR_DOMAIN_POINT); AttributeWriter<float> output_radii = attributes.lookup_or_add_for_write<float>( @@ -86,7 +84,7 @@ static void node_geo_exec(GeoNodeExecParams params) output_position.finish(); output_radii.finish(); - params.set_output("Geometry", std::move(geometry_set)); + params.set_output("Geometry", GeometrySet::create_with_pointcloud(points)); } } // namespace blender::nodes::node_geo_points_cc 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 507c6e81b1f..c6a2f89220a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_material.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_material.cc @@ -49,11 +49,11 @@ static void assign_material_to_faces(Mesh &mesh, const IndexMask selection, Mate BKE_id_material_eval_assign(&mesh.id, new_material_index + 1, material); } - mesh.mpoly = (MPoly *)CustomData_duplicate_referenced_layer(&mesh.pdata, CD_MPOLY, mesh.totpoly); - for (const int i : selection) { - MPoly &poly = mesh.mpoly[i]; - poly.mat_nr = new_material_index; - } + MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(mesh); + SpanAttributeWriter<int> material_indices = attributes.lookup_or_add_for_write_span<int>( + "material_index", ATTR_DOMAIN_FACE); + material_indices.span.fill_indices(selection, new_material_index); + material_indices.finish(); } static void node_geo_exec(GeoNodeExecParams params) @@ -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..c2d6f57ce8a 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(); @@ -123,7 +123,7 @@ static void try_capture_field_on_geometry(GeometryComponent &component, } } attributes.remove(name); - if (attributes.add(name, domain, data_type, bke::AttributeInitMove{buffer})) { + if (attributes.add(name, domain, data_type, bke::AttributeInitMoveArray{buffer})) { return; } 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..60c8a89a6bf 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc @@ -73,7 +73,7 @@ static void write_vertex_creases(Mesh &mesh, const VArray<float> &crease_varray) } else { crease = static_cast<float *>( - CustomData_add_layer(&mesh.vdata, CD_CREASE, CD_DEFAULT, nullptr, mesh.totvert)); + CustomData_add_layer(&mesh.vdata, CD_CREASE, CD_CONSTRUCT, nullptr, mesh.totvert)); } materialize_and_clamp_creases(crease_varray, {crease, mesh.totvert}); } @@ -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); } }; |