Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/nodes')
-rw-r--r--source/blender/nodes/NOD_composite.h2
-rw-r--r--source/blender/nodes/NOD_function.h2
-rw-r--r--source/blender/nodes/NOD_geometry_exec.hh24
-rw-r--r--source/blender/nodes/NOD_geometry_nodes_eval_log.hh20
-rw-r--r--source/blender/nodes/NOD_node_tree_ref.hh3
-rw-r--r--source/blender/nodes/NOD_shader.h2
-rw-r--r--source/blender/nodes/NOD_static_types.h44
-rw-r--r--source/blender/nodes/NOD_texture.h2
-rw-r--r--source/blender/nodes/composite/CMakeLists.txt1
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_sepcomb_color.cc139
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_sepcomb_hsva.cc4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_sepcomb_rgba.cc4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_sepcomb_ycca.cc4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_sepcomb_yuva.cc4
-rw-r--r--source/blender/nodes/function/CMakeLists.txt2
-rw-r--r--source/blender/nodes/function/nodes/node_fn_combine_color.cc108
-rw-r--r--source/blender/nodes/function/nodes/node_fn_random_value.cc8
-rw-r--r--source/blender/nodes/function/nodes/node_fn_separate_color.cc205
-rw-r--r--source/blender/nodes/geometry/node_geometry_tree.cc2
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.cc4
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.hh18
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc36
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc72
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc17
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc18
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc86
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc600
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc28
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc75
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc40
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc37
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc62
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc36
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc12
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc60
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_edge_split.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc16
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc8
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc8
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc7
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc8
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc13
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc75
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_material_selection.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc419
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc50
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc8
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc12
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_raycast.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc7
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_id.cc12
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_position.cc13
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc29
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc98
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc42
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_triangulate.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_viewer.cc6
-rw-r--r--source/blender/nodes/intern/geometry_nodes_eval_log.cc14
-rw-r--r--source/blender/nodes/intern/node_geometry_exec.cc36
-rw-r--r--source/blender/nodes/intern/node_socket.cc5
-rw-r--r--source/blender/nodes/intern/node_socket_declarations.cc7
-rw-r--r--source/blender/nodes/intern/node_util.c33
-rw-r--r--source/blender/nodes/intern/node_util.h1
-rw-r--r--source/blender/nodes/shader/CMakeLists.txt1
-rw-r--r--source/blender/nodes/shader/node_shader_tree.cc2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_curves.cc211
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_map_range.cc10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcomb_color.cc162
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcomb_hsv.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.cc2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_uvmap.cc2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vertex_color.cc2
-rw-r--r--source/blender/nodes/texture/CMakeLists.txt2
-rw-r--r--source/blender/nodes/texture/node_texture_util.c4
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_combine_color.c76
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_compose.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_decompose.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_separate_color.c102
112 files changed, 1689 insertions, 1797 deletions
diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h
index 3d3450d9252..5d782674f16 100644
--- a/source/blender/nodes/NOD_composite.h
+++ b/source/blender/nodes/NOD_composite.h
@@ -126,6 +126,8 @@ void register_node_type_cmp_planetrackdeform(void);
void register_node_type_cmp_cornerpin(void);
void register_node_type_cmp_separate_xyz(void);
void register_node_type_cmp_combine_xyz(void);
+void register_node_type_cmp_separate_color(void);
+void register_node_type_cmp_combine_color(void);
void node_cmp_rlayers_outputs(struct bNodeTree *ntree, struct bNode *node);
void node_cmp_rlayers_register_pass(struct bNodeTree *ntree,
diff --git a/source/blender/nodes/NOD_function.h b/source/blender/nodes/NOD_function.h
index cde4b67e120..ad96fba1929 100644
--- a/source/blender/nodes/NOD_function.h
+++ b/source/blender/nodes/NOD_function.h
@@ -8,6 +8,7 @@ extern "C" {
void register_node_type_fn_align_euler_to_vector(void);
void register_node_type_fn_boolean_math(void);
+void register_node_type_fn_combine_color(void);
void register_node_type_fn_compare(void);
void register_node_type_fn_float_to_int(void);
void register_node_type_fn_input_bool(void);
@@ -19,6 +20,7 @@ void register_node_type_fn_input_vector(void);
void register_node_type_fn_random_value(void);
void register_node_type_fn_replace_string(void);
void register_node_type_fn_rotate_euler(void);
+void register_node_type_fn_separate_color(void);
void register_node_type_fn_slice_string(void);
void register_node_type_fn_string_length(void);
void register_node_type_fn_value_to_string(void);
diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh
index bac4d0165e9..8ffa9d978a8 100644
--- a/source/blender/nodes/NOD_geometry_exec.hh
+++ b/source/blender/nodes/NOD_geometry_exec.hh
@@ -40,7 +40,7 @@ using fn::FieldInput;
using fn::FieldOperation;
using fn::GField;
using fn::ValueOrField;
-using geometry_nodes_eval_log::NamedAttributeUsage;
+using geometry_nodes_eval_log::eNamedAttrUsage;
using geometry_nodes_eval_log::NodeWarningType;
/**
@@ -307,17 +307,17 @@ class GeoNodeExecParams {
*/
GVArray get_input_attribute(const StringRef name,
const GeometryComponent &component,
- AttributeDomain domain,
- const CustomDataType type,
+ eAttrDomain domain,
+ eCustomDataType type,
const void *default_value) const;
template<typename T>
VArray<T> get_input_attribute(const StringRef name,
const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
const T &default_value) const
{
- const CustomDataType type = bke::cpp_type_to_custom_data_type(CPPType::get<T>());
+ const eCustomDataType type = bke::cpp_type_to_custom_data_type(CPPType::get<T>());
GVArray varray = this->get_input_attribute(name, component, domain, type, &default_value);
return varray.typed<T>();
}
@@ -326,24 +326,24 @@ class GeoNodeExecParams {
* Get the type of an input property or the associated constant socket types with the
* same names. Fall back to the default value if no attribute exists with the name.
*/
- CustomDataType get_input_attribute_data_type(const StringRef name,
- const GeometryComponent &component,
- const CustomDataType default_type) const;
+ eCustomDataType get_input_attribute_data_type(const StringRef name,
+ const GeometryComponent &component,
+ eCustomDataType default_type) const;
/**
* If any of the corresponding input sockets are attributes instead of single values,
* use the highest priority attribute domain from among them.
* Otherwise return the default domain.
*/
- AttributeDomain get_highest_priority_input_domain(Span<std::string> names,
- const GeometryComponent &component,
- AttributeDomain default_domain) const;
+ eAttrDomain get_highest_priority_input_domain(Span<std::string> names,
+ const GeometryComponent &component,
+ eAttrDomain default_domain) const;
std::string attribute_producer_name() const;
void set_default_remaining_outputs();
- void used_named_attribute(std::string attribute_name, NamedAttributeUsage usage);
+ void used_named_attribute(std::string attribute_name, eNamedAttrUsage usage);
private:
/* Utilities for detecting common errors at when using this class. */
diff --git a/source/blender/nodes/NOD_geometry_nodes_eval_log.hh b/source/blender/nodes/NOD_geometry_nodes_eval_log.hh
index 43792a2d90a..05c97c3903d 100644
--- a/source/blender/nodes/NOD_geometry_nodes_eval_log.hh
+++ b/source/blender/nodes/NOD_geometry_nodes_eval_log.hh
@@ -90,8 +90,8 @@ class GFieldValueLog : public ValueLog {
struct GeometryAttributeInfo {
std::string name;
/** Can be empty when #name does not actually exist on a geometry yet. */
- std::optional<AttributeDomain> domain;
- std::optional<CustomDataType> data_type;
+ std::optional<eAttrDomain> domain;
+ std::optional<eCustomDataType> data_type;
};
/** Contains information about a geometry set. In most cases this does not store the entire
@@ -104,16 +104,16 @@ class GeometryValueLog : public ValueLog {
public:
struct MeshInfo {
- int tot_verts, tot_edges, tot_faces;
+ int verts_num, edges_num, faces_num;
};
struct CurveInfo {
- int tot_splines;
+ int splines_num;
};
struct PointCloudInfo {
- int tot_points;
+ int points_num;
};
struct InstancesInfo {
- int tot_instances;
+ int instances_num;
};
std::optional<MeshInfo> mesh_info;
@@ -171,17 +171,17 @@ struct ValueOfSockets {
destruct_ptr<ValueLog> value;
};
-enum class NamedAttributeUsage {
+enum class eNamedAttrUsage {
None = 0,
Read = 1 << 0,
Write = 1 << 1,
Remove = 1 << 2,
};
-ENUM_OPERATORS(NamedAttributeUsage, NamedAttributeUsage::Remove);
+ENUM_OPERATORS(eNamedAttrUsage, eNamedAttrUsage::Remove);
struct UsedNamedAttribute {
std::string name;
- NamedAttributeUsage usage;
+ eNamedAttrUsage usage;
};
struct NodeWithUsedNamedAttribute {
@@ -219,7 +219,7 @@ class LocalGeoLogger {
void log_multi_value_socket(DSocket socket, Span<GPointer> values);
void log_node_warning(DNode node, NodeWarningType type, std::string message);
void log_execution_time(DNode node, std::chrono::microseconds exec_time);
- void log_used_named_attribute(DNode node, std::string attribute_name, NamedAttributeUsage usage);
+ void log_used_named_attribute(DNode node, std::string attribute_name, eNamedAttrUsage usage);
/**
* Log a message that will be displayed in the node editor next to the node.
* This should only be used for debugging purposes and not to display information to users.
diff --git a/source/blender/nodes/NOD_node_tree_ref.hh b/source/blender/nodes/NOD_node_tree_ref.hh
index 61d1d11d859..257aa5f4110 100644
--- a/source/blender/nodes/NOD_node_tree_ref.hh
+++ b/source/blender/nodes/NOD_node_tree_ref.hh
@@ -41,6 +41,7 @@
#include "BLI_vector.hh"
#include "BKE_node.h"
+#include "BKE_node_runtime.hh"
#include "DNA_node_types.h"
@@ -597,7 +598,7 @@ inline bNodeType *NodeRef::typeinfo() const
inline const NodeDeclaration *NodeRef::declaration() const
{
nodeDeclarationEnsure(this->tree().btree(), bnode_);
- return bnode_->declaration;
+ return bnode_->runtime->declaration;
}
inline int NodeRef::id() const
diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h
index 4996f12e27d..1d1310360b8 100644
--- a/source/blender/nodes/NOD_shader.h
+++ b/source/blender/nodes/NOD_shader.h
@@ -43,6 +43,8 @@ void register_node_type_sh_vect_math(void);
void register_node_type_sh_squeeze(void);
void register_node_type_sh_dynamic(void);
void register_node_type_sh_invert(void);
+void register_node_type_sh_sepcolor(void);
+void register_node_type_sh_combcolor(void);
void register_node_type_sh_seprgb(void);
void register_node_type_sh_combrgb(void);
void register_node_type_sh_sephsv(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 5818fa631e7..e0a4d241b3b 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -42,9 +42,9 @@ DefNode(ShaderNode, SH_NODE_MATH, def_math, "MATH",
DefNode(ShaderNode, SH_NODE_VECTOR_MATH, def_vector_math, "VECT_MATH", VectorMath, "Vector Math", "" )
DefNode(ShaderNode, SH_NODE_SQUEEZE, 0, "SQUEEZE", Squeeze, "Squeeze Value", "" )
DefNode(ShaderNode, SH_NODE_INVERT, 0, "INVERT", Invert, "Invert", "" )
-DefNode(ShaderNode, SH_NODE_SEPRGB, 0, "SEPRGB", SeparateRGB, "Separate RGB", "" )
-DefNode(ShaderNode, SH_NODE_COMBRGB, 0, "COMBRGB", CombineRGB, "Combine RGB", "" )
-DefNode(ShaderNode, SH_NODE_HUE_SAT, 0, "HUE_SAT", HueSaturation, "Hue/Saturation", "" )
+DefNode(ShaderNode, SH_NODE_SEPRGB_LEGACY, 0, "SEPRGB", SeparateRGB, "Separate RGB", "" )
+DefNode(ShaderNode, SH_NODE_COMBRGB_LEGACY, 0, "COMBRGB", CombineRGB, "Combine RGB", "" )
+DefNode(ShaderNode, SH_NODE_HUE_SAT, 0, "HUE_SAT", HueSaturation, "Hue Saturation Value", "" )
DefNode(ShaderNode, SH_NODE_OUTPUT_MATERIAL, def_sh_output, "OUTPUT_MATERIAL", OutputMaterial, "Material Output", "" )
DefNode(ShaderNode, SH_NODE_EEVEE_SPECULAR, 0, "EEVEE_SPECULAR", EeveeSpecular, "Specular BSDF", "" )
@@ -106,8 +106,8 @@ DefNode(ShaderNode, SH_NODE_TEX_POINTDENSITY, def_sh_tex_pointdensity,"TEX
DefNode(ShaderNode, SH_NODE_TEX_COORD, def_sh_tex_coord, "TEX_COORD", TexCoord, "Texture Coordinate","" )
DefNode(ShaderNode, SH_NODE_VECTOR_ROTATE, def_sh_vector_rotate, "VECTOR_ROTATE", VectorRotate, "Vector Rotate", "" )
DefNode(ShaderNode, SH_NODE_VECT_TRANSFORM, def_sh_vect_transform, "VECT_TRANSFORM", VectorTransform, "Vector Transform", "" )
-DefNode(ShaderNode, SH_NODE_SEPHSV, 0, "SEPHSV", SeparateHSV, "Separate HSV", "" )
-DefNode(ShaderNode, SH_NODE_COMBHSV, 0, "COMBHSV", CombineHSV, "Combine HSV", "" )
+DefNode(ShaderNode, SH_NODE_SEPHSV_LEGACY, 0, "SEPHSV", SeparateHSV, "Separate HSV", "" )
+DefNode(ShaderNode, SH_NODE_COMBHSV_LEGACY, 0, "COMBHSV", CombineHSV, "Combine HSV", "" )
DefNode(ShaderNode, SH_NODE_UVMAP, def_sh_uvmap, "UVMAP", UVMap, "UV Map", "" )
DefNode(ShaderNode, SH_NODE_VERTEX_COLOR, def_sh_vertex_color, "VERTEX_COLOR", VertexColor, "Color Attribute", "" )
DefNode(ShaderNode, SH_NODE_UVALONGSTROKE, def_sh_uvalongstroke, "UVALONGSTROKE", UVAlongStroke, "UV Along Stroke", "" )
@@ -120,6 +120,8 @@ DefNode(ShaderNode, SH_NODE_TEX_IES, def_sh_tex_ies, "TEX
DefNode(ShaderNode, SH_NODE_TEX_WHITE_NOISE, def_sh_tex_white_noise, "TEX_WHITE_NOISE", TexWhiteNoise, "White Noise", "" )
DefNode(ShaderNode, SH_NODE_OUTPUT_AOV, def_sh_output_aov, "OUTPUT_AOV", OutputAOV, "AOV Output", "" )
DefNode(ShaderNode, SH_NODE_CURVE_FLOAT, def_float_curve, "CURVE_FLOAT", FloatCurve, "Float Curve", "" )
+DefNode(ShaderNode, SH_NODE_COMBINE_COLOR, def_sh_combsep_color, "COMBINE_COLOR", CombineColor, "Combine Color", "" )
+DefNode(ShaderNode, SH_NODE_SEPARATE_COLOR, def_sh_combsep_color, "SEPARATE_COLOR", SeparateColor, "Separate Color", "" )
DefNode(CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" )
DefNode(CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" )
@@ -137,8 +139,8 @@ DefNode(CompositorNode, CMP_NODE_MAP_VALUE, def_cmp_map_value, "MAP_VA
DefNode(CompositorNode, CMP_NODE_MAP_RANGE, def_cmp_map_range, "MAP_RANGE", MapRange, "Map Range", "" )
DefNode(CompositorNode, CMP_NODE_TIME, def_time, "TIME", Time, "Time Curve", "" )
DefNode(CompositorNode, CMP_NODE_VECBLUR, def_cmp_vector_blur, "VECBLUR", VecBlur, "Vector Blur", "" )
-DefNode(CompositorNode, CMP_NODE_SEPRGBA, 0, "SEPRGBA", SepRGBA, "Separate RGBA", "" )
-DefNode(CompositorNode, CMP_NODE_SEPHSVA, 0, "SEPHSVA", SepHSVA, "Separate HSVA", "" )
+DefNode(CompositorNode, CMP_NODE_SEPRGBA_LEGACY, 0, "SEPRGBA", SepRGBA, "Separate RGBA", "" )
+DefNode(CompositorNode, CMP_NODE_SEPHSVA_LEGACY, 0, "SEPHSVA", SepHSVA, "Separate HSVA", "" )
DefNode(CompositorNode, CMP_NODE_SETALPHA, def_cmp_set_alpha, "SETALPHA", SetAlpha, "Set Alpha", "" )
DefNode(CompositorNode, CMP_NODE_HUE_SAT, 0, "HUE_SAT", HueSat, "Hue Saturation Value","" )
DefNode(CompositorNode, CMP_NODE_IMAGE, def_cmp_image, "IMAGE", Image, "Image", "" )
@@ -149,16 +151,16 @@ DefNode(CompositorNode, CMP_NODE_OUTPUT_FILE, 0, "OUTPUT
DefNode(CompositorNode, CMP_NODE_TEXTURE, def_texture, "TEXTURE", Texture, "Texture", "" )
DefNode(CompositorNode, CMP_NODE_TRANSLATE, def_cmp_translate, "TRANSLATE", Translate, "Translate", "" )
DefNode(CompositorNode, CMP_NODE_ZCOMBINE, def_cmp_zcombine, "ZCOMBINE", Zcombine, "Z Combine", "" )
-DefNode(CompositorNode, CMP_NODE_COMBRGBA, 0, "COMBRGBA", CombRGBA, "Combine RGBA", "" )
+DefNode(CompositorNode, CMP_NODE_COMBRGBA_LEGACY,0, "COMBRGBA", CombRGBA, "Combine RGBA", "" )
DefNode(CompositorNode, CMP_NODE_DILATEERODE, def_cmp_dilate_erode, "DILATEERODE", DilateErode, "Dilate/Erode", "" )
DefNode(CompositorNode, CMP_NODE_INPAINT, def_cmp_inpaint, "INPAINT", Inpaint, "Inpaint", "" )
DefNode(CompositorNode, CMP_NODE_DESPECKLE, def_cmp_despeckle, "DESPECKLE", Despeckle, "Despeckle", "" )
DefNode(CompositorNode, CMP_NODE_ROTATE, def_cmp_rotate, "ROTATE", Rotate, "Rotate", "" )
DefNode(CompositorNode, CMP_NODE_SCALE, def_cmp_scale, "SCALE", Scale, "Scale", "" )
-DefNode(CompositorNode, CMP_NODE_SEPYCCA, def_cmp_ycc, "SEPYCCA", SepYCCA, "Separate YCbCrA", "" )
-DefNode(CompositorNode, CMP_NODE_COMBYCCA, def_cmp_ycc, "COMBYCCA", CombYCCA, "Combine YCbCrA", "" )
-DefNode(CompositorNode, CMP_NODE_SEPYUVA, 0, "SEPYUVA", SepYUVA, "Separate YUVA", "" )
-DefNode(CompositorNode, CMP_NODE_COMBYUVA, 0, "COMBYUVA", CombYUVA, "Combine YUVA", "" )
+DefNode(CompositorNode, CMP_NODE_SEPYCCA_LEGACY, def_cmp_ycc, "SEPYCCA", SepYCCA, "Separate YCbCrA", "" )
+DefNode(CompositorNode, CMP_NODE_COMBYCCA_LEGACY,def_cmp_ycc, "COMBYCCA", CombYCCA, "Combine YCbCrA", "" )
+DefNode(CompositorNode, CMP_NODE_SEPYUVA_LEGACY, 0, "SEPYUVA", SepYUVA, "Separate YUVA", "" )
+DefNode(CompositorNode, CMP_NODE_COMBYUVA_LEGACY,0, "COMBYUVA", CombYUVA, "Combine YUVA", "" )
DefNode(CompositorNode, CMP_NODE_DIFF_MATTE, def_cmp_diff_matte, "DIFF_MATTE", DiffMatte, "Difference Key", "" )
DefNode(CompositorNode, CMP_NODE_COLOR_SPILL, def_cmp_color_spill, "COLOR_SPILL", ColorSpill, "Color Spill", "" )
DefNode(CompositorNode, CMP_NODE_CHROMA_MATTE, def_cmp_chroma_matte, "CHROMA_MATTE", ChromaMatte, "Chroma Key", "" )
@@ -170,7 +172,7 @@ DefNode(CompositorNode, CMP_NODE_ID_MASK, def_cmp_id_mask, "ID_MAS
DefNode(CompositorNode, CMP_NODE_DOUBLEEDGEMASK, def_cmp_double_edge_mask,"DOUBLEEDGEMASK", DoubleEdgeMask, "Double Edge Mask", "" )
DefNode(CompositorNode, CMP_NODE_DEFOCUS, def_cmp_defocus, "DEFOCUS", Defocus, "Defocus", "" )
DefNode(CompositorNode, CMP_NODE_DISPLACE, 0, "DISPLACE", Displace, "Displace", "" )
-DefNode(CompositorNode, CMP_NODE_COMBHSVA, 0, "COMBHSVA", CombHSVA, "Combine HSVA", "" )
+DefNode(CompositorNode, CMP_NODE_COMBHSVA_LEGACY,0, "COMBHSVA", CombHSVA, "Combine HSVA", "" )
DefNode(CompositorNode, CMP_NODE_MATH, def_math, "MATH", Math, "Math", "" )
DefNode(CompositorNode, CMP_NODE_LUMA_MATTE, def_cmp_luma_matte, "LUMA_MATTE", LumaMatte, "Luminance Key", "" )
DefNode(CompositorNode, CMP_NODE_BRIGHTCONTRAST, def_cmp_brightcontrast, "BRIGHTCONTRAST", BrightContrast, "Bright/Contrast", "" )
@@ -214,10 +216,12 @@ DefNode(CompositorNode, CMP_NODE_DENOISE, def_cmp_denoise, "DENOIS
DefNode(CompositorNode, CMP_NODE_EXPOSURE, 0, "EXPOSURE", Exposure, "Exposure", "" )
DefNode(CompositorNode, CMP_NODE_ANTIALIASING, def_cmp_antialiasing, "ANTIALIASING", AntiAliasing, "Anti-Aliasing", "" )
DefNode(CompositorNode, CMP_NODE_POSTERIZE, 0, "POSTERIZE", Posterize, "Posterize", "" )
-DefNode(CompositorNode, CMP_NODE_CONVERT_COLOR_SPACE,def_cmp_convert_color_space, "CONVERT_COLORSPACE", ConvertColorSpace, "Color Space","" )
-DefNode(CompositorNode, CMP_NODE_SCENE_TIME, 0, "SCENE_TIME", SceneTime, "Scene Time", "" )
+DefNode(CompositorNode, CMP_NODE_CONVERT_COLOR_SPACE,def_cmp_convert_color_space, "CONVERT_COLORSPACE", ConvertColorSpace, "Color Space", "" )
+DefNode(CompositorNode, CMP_NODE_SCENE_TIME, 0, "SCENE_TIME", SceneTime, "Scene Time", "" )
DefNode(CompositorNode, CMP_NODE_COMBINE_XYZ, 0, "COMBINE_XYZ", CombineXYZ, "Combine XYZ", "" )
DefNode(CompositorNode, CMP_NODE_SEPARATE_XYZ, 0, "SEPARATE_XYZ", SeparateXYZ, "Separate XYZ", "" )
+DefNode(CompositorNode, CMP_NODE_SEPARATE_COLOR, def_cmp_combsep_color, "SEPARATE_COLOR", SeparateColor, "Separate Color", "" )
+DefNode(CompositorNode, CMP_NODE_COMBINE_COLOR, def_cmp_combsep_color, "COMBINE_COLOR", CombineColor, "Combine Color", "" )
DefNode(TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" )
DefNode(TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" )
@@ -230,18 +234,20 @@ DefNode(TextureNode, TEX_NODE_VALTORGB, def_colorramp, "VALTOR
DefNode(TextureNode, TEX_NODE_IMAGE, def_tex_image, "IMAGE", Image, "Image", "" )
DefNode(TextureNode, TEX_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", CurveRGB, "RGB Curves", "" )
DefNode(TextureNode, TEX_NODE_INVERT, 0, "INVERT", Invert, "Invert", "" )
-DefNode(TextureNode, TEX_NODE_HUE_SAT, 0, "HUE_SAT", HueSaturation, "Hue/Saturation", "" )
+DefNode(TextureNode, TEX_NODE_HUE_SAT, 0, "HUE_SAT", HueSaturation, "Hue Saturation Value", "" )
DefNode(TextureNode, TEX_NODE_CURVE_TIME, def_time, "CURVE_TIME", CurveTime, "Curve Time", "" )
DefNode(TextureNode, TEX_NODE_ROTATE, 0, "ROTATE", Rotate, "Rotate", "" )
DefNode(TextureNode, TEX_NODE_VIEWER, 0, "VIEWER", Viewer, "Viewer", "" )
DefNode(TextureNode, TEX_NODE_TRANSLATE, 0, "TRANSLATE", Translate, "Translate", "" )
DefNode(TextureNode, TEX_NODE_COORD, 0, "COORD", Coordinates, "Coordinates", "" )
DefNode(TextureNode, TEX_NODE_DISTANCE, 0, "DISTANCE", Distance, "Distance", "" )
-DefNode(TextureNode, TEX_NODE_COMPOSE, 0, "COMPOSE", Compose, "Combine RGBA", "" )
-DefNode(TextureNode, TEX_NODE_DECOMPOSE, 0, "DECOMPOSE", Decompose, "Separate RGBA", "" )
+DefNode(TextureNode, TEX_NODE_COMPOSE_LEGACY, 0, "COMPOSE", Compose, "Combine RGBA", "" )
+DefNode(TextureNode, TEX_NODE_DECOMPOSE_LEGACY,0, "DECOMPOSE", Decompose, "Separate RGBA", "" )
DefNode(TextureNode, TEX_NODE_VALTONOR, 0, "VALTONOR", ValToNor, "Value to Normal", "" )
DefNode(TextureNode, TEX_NODE_SCALE, 0, "SCALE", Scale, "Scale", "" )
DefNode(TextureNode, TEX_NODE_AT, 0, "AT", At, "At", "" )
+DefNode(TextureNode, TEX_NODE_COMBINE_COLOR, def_tex_combsep_color, "COMBINE_COLOR", CombineColor, "Combine Color", "" )
+DefNode(TextureNode, TEX_NODE_SEPARATE_COLOR, def_tex_combsep_color, "SEPARATE_COLOR", SeparateColor, "Separate Color", "" )
/* procedural textures */
DefNode(TextureNode, TEX_NODE_PROC+TEX_VORONOI, 0, "TEX_VORONOI", TexVoronoi, "Voronoi", "" )
DefNode(TextureNode, TEX_NODE_PROC+TEX_BLEND, 0, "TEX_BLEND", TexBlend, "Blend", "" )
@@ -256,6 +262,7 @@ DefNode(TextureNode, TEX_NODE_PROC+TEX_DISTNOISE, 0, "TEX_DI
DefNode(FunctionNode, FN_NODE_ALIGN_EULER_TO_VECTOR, def_fn_align_euler_to_vector, "ALIGN_EULER_TO_VECTOR", AlignEulerToVector, "Align Euler To Vector", "")
DefNode(FunctionNode, FN_NODE_BOOLEAN_MATH, def_boolean_math, "BOOLEAN_MATH", BooleanMath, "Boolean Math", "")
+DefNode(FunctionNode, FN_NODE_COMBINE_COLOR, def_fn_combsep_color, "COMBINE_COLOR", CombineColor, "Combine Color", "")
DefNode(FunctionNode, FN_NODE_COMPARE, def_compare, "COMPARE", Compare, "Compare", "")
DefNode(FunctionNode, FN_NODE_FLOAT_TO_INT, def_float_to_int, "FLOAT_TO_INT", FloatToInt, "Float to Integer", "")
DefNode(FunctionNode, FN_NODE_INPUT_BOOL, def_fn_input_bool, "INPUT_BOOL", InputBool, "Boolean", "")
@@ -267,6 +274,7 @@ DefNode(FunctionNode, FN_NODE_INPUT_VECTOR, def_fn_input_vector, "INPUT_VECTOR",
DefNode(FunctionNode, FN_NODE_RANDOM_VALUE, def_fn_random_value, "RANDOM_VALUE", RandomValue, "Random Value", "")
DefNode(FunctionNode, FN_NODE_REPLACE_STRING, 0, "REPLACE_STRING", ReplaceString, "Replace String", "")
DefNode(FunctionNode, FN_NODE_ROTATE_EULER, def_fn_rotate_euler, "ROTATE_EULER", RotateEuler, "Rotate Euler", "")
+DefNode(FunctionNode, FN_NODE_SEPARATE_COLOR, def_fn_combsep_color, "SEPARATE_COLOR", SeparateColor, "Separate Color", "")
DefNode(FunctionNode, FN_NODE_SLICE_STRING, 0, "SLICE_STRING", SliceString, "Slice String", "")
DefNode(FunctionNode, FN_NODE_STRING_LENGTH, 0, "STRING_LENGTH", StringLength, "String Length", "")
DefNode(FunctionNode, FN_NODE_VALUE_TO_STRING, 0, "VALUE_TO_STRING", ValueToString, "Value to String", "")
diff --git a/source/blender/nodes/NOD_texture.h b/source/blender/nodes/NOD_texture.h
index 0f07b17f165..9a2dc705c0d 100644
--- a/source/blender/nodes/NOD_texture.h
+++ b/source/blender/nodes/NOD_texture.h
@@ -46,6 +46,8 @@ void register_node_type_tex_at(void);
void register_node_type_tex_compose(void);
void register_node_type_tex_decompose(void);
+void register_node_type_tex_combine_color(void);
+void register_node_type_tex_separate_color(void);
void register_node_type_tex_proc_voronoi(void);
void register_node_type_tex_proc_blend(void);
diff --git a/source/blender/nodes/composite/CMakeLists.txt b/source/blender/nodes/composite/CMakeLists.txt
index 57f76f20ac6..c0100d77889 100644
--- a/source/blender/nodes/composite/CMakeLists.txt
+++ b/source/blender/nodes/composite/CMakeLists.txt
@@ -91,6 +91,7 @@ set(SRC
nodes/node_composite_rotate.cc
nodes/node_composite_scale.cc
nodes/node_composite_scene_time.cc
+ nodes/node_composite_sepcomb_color.cc
nodes/node_composite_sepcomb_hsva.cc
nodes/node_composite_sepcomb_rgba.cc
nodes/node_composite_sepcomb_xyz.cc
diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcomb_color.cc b/source/blender/nodes/composite/nodes/node_composite_sepcomb_color.cc
new file mode 100644
index 00000000000..b253656a628
--- /dev/null
+++ b/source/blender/nodes/composite/nodes/node_composite_sepcomb_color.cc
@@ -0,0 +1,139 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "node_composite_util.hh"
+
+static void node_cmp_combsep_color_init(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeCMPCombSepColor *data = MEM_cnew<NodeCMPCombSepColor>(__func__);
+ data->mode = CMP_NODE_COMBSEP_COLOR_RGB;
+ data->ycc_mode = BLI_YCC_ITU_BT709;
+ node->storage = data;
+}
+
+static void node_cmp_combsep_color_label(const ListBase *sockets, CMPNodeCombSepColorMode mode)
+{
+ bNodeSocket *sock1 = (bNodeSocket *)sockets->first;
+ bNodeSocket *sock2 = sock1->next;
+ bNodeSocket *sock3 = sock2->next;
+
+ node_sock_label_clear(sock1);
+ node_sock_label_clear(sock2);
+ node_sock_label_clear(sock3);
+
+ switch (mode) {
+ case CMP_NODE_COMBSEP_COLOR_RGB:
+ node_sock_label(sock1, "Red");
+ node_sock_label(sock2, "Green");
+ node_sock_label(sock3, "Blue");
+ break;
+ case CMP_NODE_COMBSEP_COLOR_HSV:
+ node_sock_label(sock1, "Hue");
+ node_sock_label(sock2, "Saturation");
+ node_sock_label(sock3, "Value");
+ break;
+ case CMP_NODE_COMBSEP_COLOR_HSL:
+ node_sock_label(sock1, "Hue");
+ node_sock_label(sock2, "Saturation");
+ node_sock_label(sock3, "Lightness");
+ break;
+ case CMP_NODE_COMBSEP_COLOR_YCC:
+ node_sock_label(sock1, "Y");
+ node_sock_label(sock2, "Cb");
+ node_sock_label(sock3, "Cr");
+ break;
+ case CMP_NODE_COMBSEP_COLOR_YUV:
+ node_sock_label(sock1, "Y");
+ node_sock_label(sock2, "U");
+ node_sock_label(sock3, "V");
+ break;
+ default:
+ BLI_assert_unreachable();
+ break;
+ }
+}
+
+/* **************** SEPARATE COLOR ******************** */
+
+namespace blender::nodes::node_composite_separate_color_cc {
+
+static void cmp_node_separate_color_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Image")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
+ b.add_output<decl::Float>(N_("Red"));
+ b.add_output<decl::Float>(N_("Green"));
+ b.add_output<decl::Float>(N_("Blue"));
+ b.add_output<decl::Float>(N_("Alpha"));
+}
+
+static void cmp_node_separate_color_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ const NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)node->storage;
+ node_cmp_combsep_color_label(&node->outputs, (CMPNodeCombSepColorMode)storage->mode);
+}
+
+} // namespace blender::nodes::node_composite_separate_color_cc
+
+void register_node_type_cmp_separate_color()
+{
+ namespace file_ns = blender::nodes::node_composite_separate_color_cc;
+
+ static bNodeType ntype;
+
+ cmp_node_type_base(&ntype, CMP_NODE_SEPARATE_COLOR, "Separate Color", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::cmp_node_separate_color_declare;
+ node_type_init(&ntype, node_cmp_combsep_color_init);
+ node_type_storage(
+ &ntype, "NodeCMPCombSepColor", node_free_standard_storage, node_copy_standard_storage);
+ node_type_update(&ntype, file_ns::cmp_node_separate_color_update);
+
+ nodeRegisterType(&ntype);
+}
+
+/* **************** COMBINE COLOR ******************** */
+
+namespace blender::nodes::node_composite_combine_color_cc {
+
+static void cmp_node_combine_color_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("Red")).default_value(0.0f).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Green"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Blue"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Alpha"))
+ .default_value(1.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_output<decl::Color>(N_("Image"));
+}
+
+static void cmp_node_combine_color_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ const NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)node->storage;
+ node_cmp_combsep_color_label(&node->inputs, (CMPNodeCombSepColorMode)storage->mode);
+}
+
+} // namespace blender::nodes::node_composite_combine_color_cc
+
+void register_node_type_cmp_combine_color()
+{
+ namespace file_ns = blender::nodes::node_composite_combine_color_cc;
+
+ static bNodeType ntype;
+
+ cmp_node_type_base(&ntype, CMP_NODE_COMBINE_COLOR, "Combine Color", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::cmp_node_combine_color_declare;
+ node_type_init(&ntype, node_cmp_combsep_color_init);
+ node_type_storage(
+ &ntype, "NodeCMPCombSepColor", node_free_standard_storage, node_copy_standard_storage);
+ node_type_update(&ntype, file_ns::cmp_node_combine_color_update);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcomb_hsva.cc b/source/blender/nodes/composite/nodes/node_composite_sepcomb_hsva.cc
index 349c27d876d..a0d2485ea5a 100644
--- a/source/blender/nodes/composite/nodes/node_composite_sepcomb_hsva.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_sepcomb_hsva.cc
@@ -28,7 +28,7 @@ void register_node_type_cmp_sephsva()
static bNodeType ntype;
- cmp_node_type_base(&ntype, CMP_NODE_SEPHSVA, "Separate HSVA", NODE_CLASS_CONVERTER);
+ cmp_node_type_base(&ntype, CMP_NODE_SEPHSVA_LEGACY, "Separate HSVA", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_sephsva_declare;
nodeRegisterType(&ntype);
}
@@ -54,7 +54,7 @@ void register_node_type_cmp_combhsva()
static bNodeType ntype;
- cmp_node_type_base(&ntype, CMP_NODE_COMBHSVA, "Combine HSVA", NODE_CLASS_CONVERTER);
+ cmp_node_type_base(&ntype, CMP_NODE_COMBHSVA_LEGACY, "Combine HSVA", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_combhsva_declare;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcomb_rgba.cc b/source/blender/nodes/composite/nodes/node_composite_sepcomb_rgba.cc
index c46603be847..ae46681b0f4 100644
--- a/source/blender/nodes/composite/nodes/node_composite_sepcomb_rgba.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_sepcomb_rgba.cc
@@ -27,7 +27,7 @@ void register_node_type_cmp_seprgba()
static bNodeType ntype;
- cmp_node_type_base(&ntype, CMP_NODE_SEPRGBA, "Separate RGBA", NODE_CLASS_CONVERTER);
+ cmp_node_type_base(&ntype, CMP_NODE_SEPRGBA_LEGACY, "Separate RGBA", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_seprgba_declare;
nodeRegisterType(&ntype);
@@ -54,7 +54,7 @@ void register_node_type_cmp_combrgba()
static bNodeType ntype;
- cmp_node_type_base(&ntype, CMP_NODE_COMBRGBA, "Combine RGBA", NODE_CLASS_CONVERTER);
+ cmp_node_type_base(&ntype, CMP_NODE_COMBRGBA_LEGACY, "Combine RGBA", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_combrgba_declare;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcomb_ycca.cc b/source/blender/nodes/composite/nodes/node_composite_sepcomb_ycca.cc
index 9b5c153fddf..a3c40b61e64 100644
--- a/source/blender/nodes/composite/nodes/node_composite_sepcomb_ycca.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_sepcomb_ycca.cc
@@ -33,7 +33,7 @@ void register_node_type_cmp_sepycca()
static bNodeType ntype;
- cmp_node_type_base(&ntype, CMP_NODE_SEPYCCA, "Separate YCbCrA", NODE_CLASS_CONVERTER);
+ cmp_node_type_base(&ntype, CMP_NODE_SEPYCCA_LEGACY, "Separate YCbCrA", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_sepycca_declare;
node_type_init(&ntype, file_ns::node_composit_init_mode_sepycca);
@@ -66,7 +66,7 @@ void register_node_type_cmp_combycca()
static bNodeType ntype;
- cmp_node_type_base(&ntype, CMP_NODE_COMBYCCA, "Combine YCbCrA", NODE_CLASS_CONVERTER);
+ cmp_node_type_base(&ntype, CMP_NODE_COMBYCCA_LEGACY, "Combine YCbCrA", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_combycca_declare;
node_type_init(&ntype, file_ns::node_composit_init_mode_combycca);
diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcomb_yuva.cc b/source/blender/nodes/composite/nodes/node_composite_sepcomb_yuva.cc
index e458c9cfb7e..7fdece5904d 100644
--- a/source/blender/nodes/composite/nodes/node_composite_sepcomb_yuva.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_sepcomb_yuva.cc
@@ -28,7 +28,7 @@ void register_node_type_cmp_sepyuva()
static bNodeType ntype;
- cmp_node_type_base(&ntype, CMP_NODE_SEPYUVA, "Separate YUVA", NODE_CLASS_CONVERTER);
+ cmp_node_type_base(&ntype, CMP_NODE_SEPYUVA_LEGACY, "Separate YUVA", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_sepyuva_declare;
nodeRegisterType(&ntype);
@@ -55,7 +55,7 @@ void register_node_type_cmp_combyuva()
static bNodeType ntype;
- cmp_node_type_base(&ntype, CMP_NODE_COMBYUVA, "Combine YUVA", NODE_CLASS_CONVERTER);
+ cmp_node_type_base(&ntype, CMP_NODE_COMBYUVA_LEGACY, "Combine YUVA", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_combyuva_declare;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/function/CMakeLists.txt b/source/blender/nodes/function/CMakeLists.txt
index 6ccc4c7bf5c..d03f1cb63ff 100644
--- a/source/blender/nodes/function/CMakeLists.txt
+++ b/source/blender/nodes/function/CMakeLists.txt
@@ -20,6 +20,7 @@ set(INC
set(SRC
nodes/node_fn_align_euler_to_vector.cc
nodes/node_fn_boolean_math.cc
+ nodes/node_fn_combine_color.cc
nodes/node_fn_compare.cc
nodes/node_fn_float_to_int.cc
nodes/node_fn_input_bool.cc
@@ -31,6 +32,7 @@ set(SRC
nodes/node_fn_random_value.cc
nodes/node_fn_replace_string.cc
nodes/node_fn_rotate_euler.cc
+ nodes/node_fn_separate_color.cc
nodes/node_fn_slice_string.cc
nodes/node_fn_string_length.cc
nodes/node_fn_value_to_string.cc
diff --git a/source/blender/nodes/function/nodes/node_fn_combine_color.cc b/source/blender/nodes/function/nodes/node_fn_combine_color.cc
new file mode 100644
index 00000000000..c5fd3ce38a1
--- /dev/null
+++ b/source/blender/nodes/function/nodes/node_fn_combine_color.cc
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "node_function_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes {
+
+NODE_STORAGE_FUNCS(NodeCombSepColor)
+
+static void fn_node_combine_color_declare(NodeDeclarationBuilder &b)
+{
+ b.is_function_node();
+ b.add_input<decl::Float>(N_("Red")).default_value(0.0f).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Green"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Blue"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Alpha"))
+ .default_value(1.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_output<decl::Color>(N_("Color"));
+};
+
+static void fn_node_combine_color_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
+}
+
+static void fn_node_combine_color_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ const NodeCombSepColor &storage = node_storage(*node);
+ node_combsep_color_label(&node->inputs, (NodeCombSepColorMode)storage.mode);
+}
+
+static void fn_node_combine_color_init(bNodeTree *UNUSED(tree), bNode *node)
+{
+ NodeCombSepColor *data = MEM_cnew<NodeCombSepColor>(__func__);
+ data->mode = NODE_COMBSEP_COLOR_RGB;
+ node->storage = data;
+}
+
+static const fn::MultiFunction *get_multi_function(bNode &bnode)
+{
+ const NodeCombSepColor &storage = node_storage(bnode);
+
+ static fn::CustomMF_SI_SI_SI_SI_SO<float, float, float, float, ColorGeometry4f> rgba_fn{
+ "RGB", [](float r, float g, float b, float a) { return ColorGeometry4f(r, g, b, a); }};
+ static fn::CustomMF_SI_SI_SI_SI_SO<float, float, float, float, ColorGeometry4f> hsva_fn{
+ "HSV", [](float h, float s, float v, float a) {
+ ColorGeometry4f r_color;
+ hsv_to_rgb(h, s, v, &r_color.r, &r_color.g, &r_color.b);
+ r_color.a = a;
+ return r_color;
+ }};
+ static fn::CustomMF_SI_SI_SI_SI_SO<float, float, float, float, ColorGeometry4f> hsla_fn{
+ "HSL", [](float h, float s, float l, float a) {
+ ColorGeometry4f color;
+ hsl_to_rgb(h, s, l, &color.r, &color.g, &color.b);
+ color.a = a;
+ return color;
+ }};
+
+ switch (storage.mode) {
+ case NODE_COMBSEP_COLOR_RGB:
+ return &rgba_fn;
+ case NODE_COMBSEP_COLOR_HSV:
+ return &hsva_fn;
+ case NODE_COMBSEP_COLOR_HSL:
+ return &hsla_fn;
+ }
+
+ BLI_assert_unreachable();
+ return nullptr;
+}
+
+static void fn_node_combine_color_build_multi_function(NodeMultiFunctionBuilder &builder)
+{
+ const fn::MultiFunction *fn = get_multi_function(builder.node());
+ builder.set_matching_fn(fn);
+}
+
+} // namespace blender::nodes
+
+void register_node_type_fn_combine_color(void)
+{
+ static bNodeType ntype;
+
+ fn_node_type_base(&ntype, FN_NODE_COMBINE_COLOR, "Combine Color", NODE_CLASS_CONVERTER);
+ ntype.declare = blender::nodes::fn_node_combine_color_declare;
+ node_type_update(&ntype, blender::nodes::fn_node_combine_color_update);
+ node_type_init(&ntype, blender::nodes::fn_node_combine_color_init);
+ node_type_storage(
+ &ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
+ ntype.build_multi_function = blender::nodes::fn_node_combine_color_build_multi_function;
+ ntype.draw_buttons = blender::nodes::fn_node_combine_color_layout;
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/function/nodes/node_fn_random_value.cc b/source/blender/nodes/function/nodes/node_fn_random_value.cc
index a0942ced1be..360695299cb 100644
--- a/source/blender/nodes/function/nodes/node_fn_random_value.cc
+++ b/source/blender/nodes/function/nodes/node_fn_random_value.cc
@@ -57,7 +57,7 @@ static void fn_node_random_value_init(bNodeTree *UNUSED(tree), bNode *node)
static void fn_node_random_value_update(bNodeTree *ntree, bNode *node)
{
const NodeRandomValue &storage = node_storage(*node);
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
bNodeSocket *sock_min_vector = (bNodeSocket *)node->inputs.first;
bNodeSocket *sock_max_vector = sock_min_vector->next;
@@ -86,7 +86,7 @@ static void fn_node_random_value_update(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, sock_out_bool, data_type == CD_PROP_BOOL);
}
-static std::optional<CustomDataType> node_type_from_other_socket(const bNodeSocket &socket)
+static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSocket &socket)
{
switch (socket.type) {
case SOCK_FLOAT:
@@ -106,7 +106,7 @@ static std::optional<CustomDataType> node_type_from_other_socket(const bNodeSock
static void fn_node_random_value_gather_link_search(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
- const std::optional<CustomDataType> type = node_type_from_other_socket(params.other_socket());
+ const std::optional<eCustomDataType> type = node_type_from_other_socket(params.other_socket());
if (!type) {
return;
}
@@ -137,7 +137,7 @@ static void fn_node_random_value_gather_link_search(GatherLinkSearchOpParams &pa
static void fn_node_random_value_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const NodeRandomValue &storage = node_storage(builder.node());
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
switch (data_type) {
case CD_PROP_FLOAT3: {
diff --git a/source/blender/nodes/function/nodes/node_fn_separate_color.cc b/source/blender/nodes/function/nodes/node_fn_separate_color.cc
new file mode 100644
index 00000000000..1701dfdc6fa
--- /dev/null
+++ b/source/blender/nodes/function/nodes/node_fn_separate_color.cc
@@ -0,0 +1,205 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "node_function_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes {
+
+NODE_STORAGE_FUNCS(NodeCombSepColor)
+
+static void fn_node_separate_color_declare(NodeDeclarationBuilder &b)
+{
+ b.is_function_node();
+ b.add_input<decl::Color>(N_("Color")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
+ b.add_output<decl::Float>(N_("Red"));
+ b.add_output<decl::Float>(N_("Green"));
+ b.add_output<decl::Float>(N_("Blue"));
+ b.add_output<decl::Float>(N_("Alpha"));
+};
+
+static void fn_node_separate_color_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
+}
+
+static void fn_node_separate_color_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ const NodeCombSepColor &storage = node_storage(*node);
+ node_combsep_color_label(&node->outputs, (NodeCombSepColorMode)storage.mode);
+}
+
+static void fn_node_separate_color_init(bNodeTree *UNUSED(tree), bNode *node)
+{
+ NodeCombSepColor *data = MEM_cnew<NodeCombSepColor>(__func__);
+ data->mode = NODE_COMBSEP_COLOR_RGB;
+ node->storage = data;
+}
+
+class SeparateRGBAFunction : public fn::MultiFunction {
+ public:
+ SeparateRGBAFunction()
+ {
+ static fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static fn::MFSignature create_signature()
+ {
+ fn::MFSignatureBuilder signature{"Separate Color"};
+ signature.single_input<ColorGeometry4f>("Color");
+ signature.single_output<float>("Red");
+ signature.single_output<float>("Green");
+ signature.single_output<float>("Blue");
+ signature.single_output<float>("Alpha");
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ {
+ const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
+ "Color");
+ MutableSpan<float> red = params.uninitialized_single_output<float>(1, "Red");
+ MutableSpan<float> green = params.uninitialized_single_output<float>(2, "Green");
+ MutableSpan<float> blue = params.uninitialized_single_output<float>(3, "Blue");
+ MutableSpan<float> alpha = params.uninitialized_single_output_if_required<float>(4, "Alpha");
+
+ for (int64_t i : mask) {
+ red[i] = colors[i].r;
+ green[i] = colors[i].g;
+ blue[i] = colors[i].b;
+ }
+
+ if (!alpha.is_empty()) {
+ for (int64_t i : mask) {
+ alpha[i] = colors[i].a;
+ }
+ }
+ }
+};
+
+class SeparateHSVAFunction : public fn::MultiFunction {
+ public:
+ SeparateHSVAFunction()
+ {
+ static fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static fn::MFSignature create_signature()
+ {
+ fn::MFSignatureBuilder signature{"Separate Color"};
+ signature.single_input<ColorGeometry4f>("Color");
+ signature.single_output<float>("Hue");
+ signature.single_output<float>("Saturation");
+ signature.single_output<float>("Value");
+ signature.single_output<float>("Alpha");
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ {
+ const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
+ "Color");
+ MutableSpan<float> hue = params.uninitialized_single_output<float>(1, "Hue");
+ MutableSpan<float> saturation = params.uninitialized_single_output<float>(2, "Saturation");
+ MutableSpan<float> value = params.uninitialized_single_output<float>(3, "Value");
+ MutableSpan<float> alpha = params.uninitialized_single_output_if_required<float>(4, "Alpha");
+
+ for (int64_t i : mask) {
+ rgb_to_hsv(colors[i].r, colors[i].g, colors[i].b, &hue[i], &saturation[i], &value[i]);
+ }
+
+ if (!alpha.is_empty()) {
+ for (int64_t i : mask) {
+ alpha[i] = colors[i].a;
+ }
+ }
+ }
+};
+
+class SeparateHSLAFunction : public fn::MultiFunction {
+ public:
+ SeparateHSLAFunction()
+ {
+ static fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static fn::MFSignature create_signature()
+ {
+ fn::MFSignatureBuilder signature{"Separate Color"};
+ signature.single_input<ColorGeometry4f>("Color");
+ signature.single_output<float>("Hue");
+ signature.single_output<float>("Saturation");
+ signature.single_output<float>("Lightness");
+ signature.single_output<float>("Alpha");
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ {
+ const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
+ "Color");
+ MutableSpan<float> hue = params.uninitialized_single_output<float>(1, "Hue");
+ MutableSpan<float> saturation = params.uninitialized_single_output<float>(2, "Saturation");
+ MutableSpan<float> lightness = params.uninitialized_single_output<float>(3, "Lightness");
+ MutableSpan<float> alpha = params.uninitialized_single_output_if_required<float>(4, "Alpha");
+
+ for (int64_t i : mask) {
+ rgb_to_hsl(colors[i].r, colors[i].g, colors[i].b, &hue[i], &saturation[i], &lightness[i]);
+ }
+
+ if (!alpha.is_empty()) {
+ for (int64_t i : mask) {
+ alpha[i] = colors[i].a;
+ }
+ }
+ }
+};
+
+static void fn_node_separate_color_build_multi_function(NodeMultiFunctionBuilder &builder)
+{
+ const NodeCombSepColor &storage = node_storage(builder.node());
+
+ switch (storage.mode) {
+ case NODE_COMBSEP_COLOR_RGB: {
+ static SeparateRGBAFunction fn;
+ builder.set_matching_fn(fn);
+ break;
+ }
+ case NODE_COMBSEP_COLOR_HSV: {
+ static SeparateHSVAFunction fn;
+ builder.set_matching_fn(fn);
+ break;
+ }
+ case NODE_COMBSEP_COLOR_HSL: {
+ static SeparateHSLAFunction fn;
+ builder.set_matching_fn(fn);
+ break;
+ }
+ default: {
+ BLI_assert_unreachable();
+ break;
+ }
+ }
+}
+
+} // namespace blender::nodes
+
+void register_node_type_fn_separate_color(void)
+{
+ static bNodeType ntype;
+
+ fn_node_type_base(&ntype, FN_NODE_SEPARATE_COLOR, "Separate Color", NODE_CLASS_CONVERTER);
+ ntype.declare = blender::nodes::fn_node_separate_color_declare;
+ node_type_update(&ntype, blender::nodes::fn_node_separate_color_update);
+ node_type_init(&ntype, blender::nodes::fn_node_separate_color_init);
+ node_type_storage(
+ &ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
+ ntype.build_multi_function = blender::nodes::fn_node_separate_color_build_multi_function;
+ ntype.draw_buttons = blender::nodes::fn_node_separate_color_layout;
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/node_geometry_tree.cc b/source/blender/nodes/geometry/node_geometry_tree.cc
index e081e007c81..38e914b9a9f 100644
--- a/source/blender/nodes/geometry/node_geometry_tree.cc
+++ b/source/blender/nodes/geometry/node_geometry_tree.cc
@@ -110,7 +110,7 @@ void register_node_tree_type_geo()
tt->type = NTREE_GEOMETRY;
strcpy(tt->idname, "GeometryNodeTree");
strcpy(tt->ui_name, N_("Geometry Node Editor"));
- tt->ui_icon = ICON_NODETREE;
+ tt->ui_icon = ICON_GEOMETRY_NODES;
strcpy(tt->ui_description, N_("Geometry nodes"));
tt->rna_ext.srna = &RNA_GeometryNodeTree;
tt->update = geometry_node_tree_update;
diff --git a/source/blender/nodes/geometry/node_geometry_util.cc b/source/blender/nodes/geometry/node_geometry_util.cc
index 7f9ec329efd..8f673d2264e 100644
--- a/source/blender/nodes/geometry/node_geometry_util.cc
+++ b/source/blender/nodes/geometry/node_geometry_util.cc
@@ -14,7 +14,7 @@
namespace blender::nodes {
-std::optional<CustomDataType> node_data_type_to_custom_data_type(const eNodeSocketDatatype type)
+std::optional<eCustomDataType> node_data_type_to_custom_data_type(const eNodeSocketDatatype type)
{
switch (type) {
case SOCK_FLOAT:
@@ -34,7 +34,7 @@ std::optional<CustomDataType> node_data_type_to_custom_data_type(const eNodeSock
}
}
-std::optional<CustomDataType> node_socket_to_custom_data_type(const bNodeSocket &socket)
+std::optional<eCustomDataType> node_socket_to_custom_data_type(const bNodeSocket &socket)
{
return node_data_type_to_custom_data_type(static_cast<eNodeSocketDatatype>(socket.type));
}
diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh
index 7af3159bbf8..d261928d1b8 100644
--- a/source/blender/nodes/geometry/node_geometry_util.hh
+++ b/source/blender/nodes/geometry/node_geometry_util.hh
@@ -57,8 +57,6 @@ Mesh *create_cylinder_or_cone_mesh(float radius_top,
GeometryNodeMeshCircleFillType fill_type,
ConeAttributeOutputs &attribute_outputs);
-Mesh *create_cuboid_mesh(float3 size, int verts_x, int verts_y, int verts_z);
-
/**
* Copies the point domain attributes from `in_component` that are in the mask to `out_component`.
*/
@@ -72,23 +70,13 @@ void copy_point_attributes_based_on_mask(const GeometryComponent &in_component,
* component. If no component can work with the domain, then `error_message` is set to true.
*/
void separate_geometry(GeometrySet &geometry_set,
- AttributeDomain domain,
+ eAttrDomain domain,
GeometryNodeDeleteGeometryMode mode,
const Field<bool> &selection_field,
bool invert,
bool &r_is_error);
-std::optional<CustomDataType> node_data_type_to_custom_data_type(eNodeSocketDatatype type);
-std::optional<CustomDataType> node_socket_to_custom_data_type(const bNodeSocket &socket);
-
-class SplineLengthFieldInput final : public GeometryFieldInput {
- public:
- SplineLengthFieldInput();
- GVArray get_varray_for_context(const GeometryComponent &component,
- AttributeDomain domain,
- IndexMask mask) const final;
- uint64_t hash() const override;
- bool is_equal_to(const fn::FieldNode &other) const override;
-};
+std::optional<eCustomDataType> node_data_type_to_custom_data_type(eNodeSocketDatatype type);
+std::optional<eCustomDataType> node_socket_to_custom_data_type(const bNodeSocket &socket);
} // namespace blender::nodes
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 ea26eec0c15..a7404af8564 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc
@@ -87,7 +87,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeAccumulateField &storage = node_storage(*node);
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
bNodeSocket *sock_in_vector = (bNodeSocket *)node->inputs.first;
bNodeSocket *sock_in_float = sock_in_vector->next;
@@ -123,7 +123,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
enum class AccumulationMode { Leading = 0, Trailing = 1 };
-static std::optional<CustomDataType> node_type_from_other_socket(const bNodeSocket &socket)
+static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSocket &socket)
{
switch (socket.type) {
case SOCK_FLOAT:
@@ -141,7 +141,7 @@ static std::optional<CustomDataType> node_type_from_other_socket(const bNodeSock
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
- const std::optional<CustomDataType> type = node_type_from_other_socket(params.other_socket());
+ const std::optional<eCustomDataType> type = node_type_from_other_socket(params.other_socket());
if (!type) {
return;
}
@@ -196,11 +196,11 @@ template<typename T> class AccumulateFieldInput final : public GeometryFieldInpu
private:
Field<T> input_;
Field<int> group_index_;
- AttributeDomain source_domain_;
+ eAttrDomain source_domain_;
AccumulationMode accumulation_mode_;
public:
- AccumulateFieldInput(const AttributeDomain source_domain,
+ AccumulateFieldInput(const eAttrDomain source_domain,
Field<T> input,
Field<int> group_index,
AccumulationMode accumulation_mode)
@@ -213,20 +213,20 @@ template<typename T> class AccumulateFieldInput final : public GeometryFieldInpu
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask UNUSED(mask)) const final
{
const GeometryComponentFieldContext field_context{component, source_domain_};
- const int domain_size = component.attribute_domain_size(field_context.domain());
+ const int domain_num = component.attribute_domain_num(field_context.domain());
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.add(input_);
evaluator.add(group_index_);
evaluator.evaluate();
const VArray<T> &values = evaluator.get_evaluated<T>(0);
const VArray<int> &group_indices = evaluator.get_evaluated<int>(1);
- Array<T> accumulations_out(domain_size);
+ Array<T> accumulations_out(domain_num);
if (group_indices.is_single()) {
T accumulation = T();
@@ -287,10 +287,10 @@ template<typename T> class TotalFieldInput final : public GeometryFieldInput {
private:
Field<T> input_;
Field<int> group_index_;
- AttributeDomain source_domain_;
+ eAttrDomain source_domain_;
public:
- TotalFieldInput(const AttributeDomain source_domain, Field<T> input, Field<int> group_index)
+ TotalFieldInput(const eAttrDomain source_domain, Field<T> input, Field<int> group_index)
: GeometryFieldInput(CPPType::get<T>(), "Total Value"),
input_(input),
group_index_(group_index),
@@ -299,13 +299,13 @@ template<typename T> class TotalFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask UNUSED(mask)) const final
{
const GeometryComponentFieldContext field_context{component, source_domain_};
- const int domain_size = component.attribute_domain_size(field_context.domain());
+ const int domain_num = component.attribute_domain_num(field_context.domain());
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.add(input_);
evaluator.add(group_index_);
evaluator.evaluate();
@@ -317,10 +317,10 @@ template<typename T> class TotalFieldInput final : public GeometryFieldInput {
for (const int i : values.index_range()) {
accumulation = values[i] + accumulation;
}
- return VArray<T>::ForSingle(accumulation, domain_size);
+ return VArray<T>::ForSingle(accumulation, domain_num);
}
- Array<T> accumulations_out(domain_size);
+ Array<T> accumulations_out(domain_num);
Map<int, T> accumulations;
for (const int i : values.index_range()) {
T &value = accumulations.lookup_or_add_default(group_indices[i]);
@@ -365,8 +365,8 @@ template<typename T> std::string identifier_suffix()
static void node_geo_exec(GeoNodeExecParams params)
{
const NodeAccumulateField &storage = node_storage(params.node());
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
- const AttributeDomain source_domain = static_cast<AttributeDomain>(storage.domain);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
+ const eAttrDomain source_domain = static_cast<eAttrDomain>(storage.domain);
Field<int> group_index_field = params.extract_input<Field<int>>("Group Index");
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
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 45a6aabeb03..496fb081d6b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc
@@ -50,7 +50,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryAttributeCapture &storage = node_storage(*node);
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
bNodeSocket *socket_value_geometry = (bNodeSocket *)node->inputs.first;
bNodeSocket *socket_value_vector = socket_value_geometry->next;
@@ -86,7 +86,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
search_link_ops_for_declarations(params, declaration.outputs().take_front(1));
const bNodeType &node_type = params.node_type();
- const std::optional<CustomDataType> type = node_data_type_to_custom_data_type(
+ const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type(
(eNodeSocketDatatype)params.other_socket().type);
if (type && *type != CD_PROP_STRING) {
if (params.in_out() == SOCK_OUT) {
@@ -108,14 +108,14 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
static void try_capture_field_on_geometry(GeometryComponent &component,
const AttributeIDRef &attribute_id,
- const AttributeDomain domain,
+ const eAttrDomain domain,
const GField &field)
{
GeometryComponentFieldContext field_context{component, domain};
- const int domain_size = component.attribute_domain_size(domain);
- const IndexMask mask{IndexMask(domain_size)};
+ const int domain_num = component.attribute_domain_num(domain);
+ const IndexMask mask{IndexMask(domain_num)};
- const CustomDataType data_type = bke::cpp_type_to_custom_data_type(field.cpp_type());
+ const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(field.cpp_type());
OutputAttribute output_attribute = component.attribute_try_get_for_output_only(
attribute_id, domain, data_type);
@@ -126,30 +126,66 @@ static void try_capture_field_on_geometry(GeometryComponent &component,
output_attribute.save();
}
+static StringRefNull identifier_suffix(eCustomDataType data_type)
+{
+ switch (data_type) {
+ case CD_PROP_FLOAT:
+ return "_001";
+ case CD_PROP_INT32:
+ return "_004";
+ case CD_PROP_COLOR:
+ return "_002";
+ case CD_PROP_BOOL:
+ return "_003";
+ case CD_PROP_FLOAT3:
+ return "";
+ default:
+ BLI_assert_unreachable();
+ return "";
+ }
+}
+
static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+ if (!params.output_is_required("Geometry")) {
+ params.error_message_add(
+ NodeWarningType::Info,
+ TIP_("The attribute output can not be used without the geometry output"));
+ params.set_default_remaining_outputs();
+ return;
+ }
+
const NodeGeometryAttributeCapture &storage = node_storage(params.node());
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
- const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
+ const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain);
+ const std::string output_identifier = "Attribute" + identifier_suffix(data_type);
+
+ if (!params.output_is_required(output_identifier)) {
+ params.set_output("Geometry", geometry_set);
+ return;
+ }
+
+ const std::string input_identifier = "Value" + identifier_suffix(data_type);
GField field;
+
switch (data_type) {
case CD_PROP_FLOAT:
- field = params.get_input<Field<float>>("Value_001");
+ field = params.get_input<Field<float>>(input_identifier);
break;
case CD_PROP_FLOAT3:
- field = params.get_input<Field<float3>>("Value");
+ field = params.get_input<Field<float3>>(input_identifier);
break;
case CD_PROP_COLOR:
- field = params.get_input<Field<ColorGeometry4f>>("Value_002");
+ field = params.get_input<Field<ColorGeometry4f>>(input_identifier);
break;
case CD_PROP_BOOL:
- field = params.get_input<Field<bool>>("Value_003");
+ field = params.get_input<Field<bool>>(input_identifier);
break;
case CD_PROP_INT32:
- field = params.get_input<Field<int>>("Value_004");
+ field = params.get_input<Field<int>>(input_identifier);
break;
default:
break;
@@ -185,23 +221,23 @@ static void node_geo_exec(GeoNodeExecParams params)
switch (data_type) {
case CD_PROP_FLOAT: {
- params.set_output("Attribute_001", Field<float>(output_field));
+ params.set_output(output_identifier, Field<float>(output_field));
break;
}
case CD_PROP_FLOAT3: {
- params.set_output("Attribute", Field<float3>(output_field));
+ params.set_output(output_identifier, Field<float3>(output_field));
break;
}
case CD_PROP_COLOR: {
- params.set_output("Attribute_002", Field<ColorGeometry4f>(output_field));
+ params.set_output(output_identifier, Field<ColorGeometry4f>(output_field));
break;
}
case CD_PROP_BOOL: {
- params.set_output("Attribute_003", Field<bool>(output_field));
+ params.set_output(output_identifier, Field<bool>(output_field));
break;
}
case CD_PROP_INT32: {
- params.set_output("Attribute_004", Field<int>(output_field));
+ params.set_output(output_identifier, Field<int>(output_field));
break;
}
default:
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc
index b3fe9d160b3..8ab0eb678e7 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc
@@ -72,11 +72,11 @@ static void node_geo_exec(GeoNodeExecParams params)
case GEO_COMPONENT_TYPE_MESH: {
if (geometry_set.has_mesh()) {
const MeshComponent *component = geometry_set.get_component_for_read<MeshComponent>();
- params.set_output("Point Count", component->attribute_domain_size(ATTR_DOMAIN_POINT));
- params.set_output("Edge Count", component->attribute_domain_size(ATTR_DOMAIN_EDGE));
- params.set_output("Face Count", component->attribute_domain_size(ATTR_DOMAIN_FACE));
+ params.set_output("Point Count", component->attribute_domain_num(ATTR_DOMAIN_POINT));
+ params.set_output("Edge Count", component->attribute_domain_num(ATTR_DOMAIN_EDGE));
+ params.set_output("Face Count", component->attribute_domain_num(ATTR_DOMAIN_FACE));
params.set_output("Face Corner Count",
- component->attribute_domain_size(ATTR_DOMAIN_CORNER));
+ component->attribute_domain_num(ATTR_DOMAIN_CORNER));
}
else {
params.set_default_remaining_outputs();
@@ -86,8 +86,8 @@ static void node_geo_exec(GeoNodeExecParams params)
case GEO_COMPONENT_TYPE_CURVE: {
if (geometry_set.has_curves()) {
const CurveComponent *component = geometry_set.get_component_for_read<CurveComponent>();
- params.set_output("Point Count", component->attribute_domain_size(ATTR_DOMAIN_POINT));
- params.set_output("Spline Count", component->attribute_domain_size(ATTR_DOMAIN_CURVE));
+ params.set_output("Point Count", component->attribute_domain_num(ATTR_DOMAIN_POINT));
+ params.set_output("Spline Count", component->attribute_domain_num(ATTR_DOMAIN_CURVE));
}
else {
params.set_default_remaining_outputs();
@@ -98,7 +98,7 @@ static void node_geo_exec(GeoNodeExecParams params)
if (geometry_set.has_pointcloud()) {
const PointCloudComponent *component =
geometry_set.get_component_for_read<PointCloudComponent>();
- params.set_output("Point Count", component->attribute_domain_size(ATTR_DOMAIN_POINT));
+ params.set_output("Point Count", component->attribute_domain_num(ATTR_DOMAIN_POINT));
}
else {
params.set_default_remaining_outputs();
@@ -109,8 +109,7 @@ static void node_geo_exec(GeoNodeExecParams params)
if (geometry_set.has_instances()) {
const InstancesComponent *component =
geometry_set.get_component_for_read<InstancesComponent>();
- params.set_output("Instance Count",
- component->attribute_domain_size(ATTR_DOMAIN_INSTANCE));
+ params.set_output("Instance Count", component->attribute_domain_num(ATTR_DOMAIN_INSTANCE));
}
else {
params.set_default_remaining_outputs();
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 1153f18ffd4..35404725998 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc
@@ -77,7 +77,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
bNodeSocket *socket_vector_std = socket_vector_range->next;
bNodeSocket *socket_vector_variance = socket_vector_std->next;
- const CustomDataType data_type = static_cast<CustomDataType>(node->custom1);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(node->custom1);
nodeSetSocketAvailability(ntree, socket_float_attr, data_type == CD_PROP_FLOAT);
nodeSetSocketAvailability(ntree, socket_float_mean, data_type == CD_PROP_FLOAT);
@@ -100,7 +100,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, socket_vector_variance, data_type == CD_PROP_FLOAT3);
}
-static std::optional<CustomDataType> node_type_from_other_socket(const bNodeSocket &socket)
+static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSocket &socket)
{
switch (socket.type) {
case SOCK_FLOAT:
@@ -121,7 +121,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
search_link_ops_for_declarations(params, declaration.inputs().take_front(2));
- const std::optional<CustomDataType> type = node_type_from_other_socket(params.other_socket());
+ const std::optional<eCustomDataType> type = node_type_from_other_socket(params.other_socket());
if (!type) {
return;
}
@@ -184,8 +184,8 @@ static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.get_input<GeometrySet>("Geometry");
const bNode &node = params.node();
- const CustomDataType data_type = static_cast<CustomDataType>(node.custom1);
- const AttributeDomain domain = static_cast<AttributeDomain>(node.custom2);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(node.custom1);
+ const eAttrDomain domain = static_cast<eAttrDomain>(node.custom2);
Vector<const GeometryComponent *> components = geometry_set.get_components_for_read();
const Field<bool> selection_field = params.get_input<Field<bool>>("Selection");
@@ -197,9 +197,9 @@ static void node_geo_exec(GeoNodeExecParams params)
for (const GeometryComponent *component : components) {
if (component->attribute_domain_supported(domain)) {
GeometryComponentFieldContext field_context{*component, domain};
- const int domain_size = component->attribute_domain_size(domain);
+ const int domain_num = component->attribute_domain_num(domain);
- fn::FieldEvaluator data_evaluator{field_context, domain_size};
+ fn::FieldEvaluator data_evaluator{field_context, domain_num};
data_evaluator.add(input_field);
data_evaluator.set_selection(selection_field);
data_evaluator.evaluate();
@@ -275,9 +275,9 @@ static void node_geo_exec(GeoNodeExecParams params)
for (const GeometryComponent *component : components) {
if (component->attribute_domain_supported(domain)) {
GeometryComponentFieldContext field_context{*component, domain};
- const int domain_size = component->attribute_domain_size(domain);
+ const int domain_num = component->attribute_domain_num(domain);
- fn::FieldEvaluator data_evaluator{field_context, domain_size};
+ fn::FieldEvaluator data_evaluator{field_context, domain_num};
data_evaluator.add(input_field);
data_evaluator.set_selection(selection_field);
data_evaluator.evaluate();
diff --git a/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc b/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc
index 558129fb384..00b10cc8a2f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc
@@ -1,5 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "GEO_mesh_primitive_cuboid.hh"
+
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_bounding_box_cc {
@@ -53,7 +55,7 @@ static void node_geo_exec(GeoNodeExecParams params)
else {
const float3 scale = sub_max - sub_min;
const float3 center = sub_min + scale / 2.0f;
- Mesh *mesh = create_cuboid_mesh(scale, 2, 2, 2);
+ Mesh *mesh = geometry::create_cuboid_mesh(scale, 2, 2, 2, "uv_map");
transform_mesh(*mesh, center, float3(0), float3(1));
sub_geometry.replace_mesh(mesh);
sub_geometry.keep_only({GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_INSTANCES});
diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
index 09d0f13c50d..31f706c497c 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
@@ -138,14 +138,14 @@ static Mesh *compute_hull(const GeometrySet &geometry_set)
{
int span_count = 0;
int count = 0;
- int total_size = 0;
+ int total_num = 0;
Span<float3> positions_span;
if (geometry_set.has_mesh()) {
count++;
const MeshComponent *component = geometry_set.get_component_for_read<MeshComponent>();
- total_size += component->attribute_domain_size(ATTR_DOMAIN_POINT);
+ total_num += component->attribute_domain_num(ATTR_DOMAIN_POINT);
}
if (geometry_set.has_pointcloud()) {
@@ -155,7 +155,7 @@ static Mesh *compute_hull(const GeometrySet &geometry_set)
geometry_set.get_component_for_read<PointCloudComponent>();
VArray<float3> varray = component->attribute_get_for_read<float3>(
"position", ATTR_DOMAIN_POINT, {0, 0, 0});
- total_size += varray.size();
+ total_num += varray.size();
positions_span = varray.get_internal_span();
}
@@ -165,7 +165,7 @@ static Mesh *compute_hull(const GeometrySet &geometry_set)
const Curves &curves_id = *geometry_set.get_curves_for_read();
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
positions_span = curves.evaluated_positions();
- total_size += positions_span.size();
+ total_num += positions_span.size();
}
if (count == 0) {
@@ -178,7 +178,7 @@ static Mesh *compute_hull(const GeometrySet &geometry_set)
return hull_from_bullet(nullptr, positions_span);
}
- Array<float3> positions(total_size);
+ Array<float3> positions(total_num);
int offset = 0;
if (geometry_set.has_mesh()) {
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 bbc8758952d..b52bf2571b5 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
@@ -41,7 +41,7 @@ class EndpointFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask UNUSED(mask)) const final
{
if (component.type() != GEO_COMPONENT_TYPE_CURVE || domain != ATTR_DOMAIN_POINT) {
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 95ea978541c..fb8a488ddae 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
@@ -106,13 +106,13 @@ static float3 get_center(const float3 vec_pos2prev, const FilletData &fd, const
/* Calculate the direction vectors from each vertex to their previous vertex. */
static Array<float3> calculate_directions(const Span<float3> positions)
{
- const int size = positions.size();
- Array<float3> directions(size);
+ const int num = positions.size();
+ Array<float3> directions(num);
- for (const int i : IndexRange(size - 1)) {
+ for (const int i : IndexRange(num - 1)) {
directions[i] = math::normalize(positions[i + 1] - positions[i]);
}
- directions[size - 1] = math::normalize(positions[0] - positions[size - 1]);
+ directions[num - 1] = math::normalize(positions[0] - positions[num - 1]);
return directions;
}
@@ -120,11 +120,11 @@ static Array<float3> calculate_directions(const Span<float3> positions)
/* Calculate the axes around which the fillet is built. */
static Array<float3> calculate_axes(const Span<float3> directions)
{
- const int size = directions.size();
- Array<float3> axes(size);
+ const int num = directions.size();
+ Array<float3> axes(num);
- axes[0] = math::normalize(math::cross(-directions[size - 1], directions[0]));
- for (const int i : IndexRange(1, size - 1)) {
+ axes[0] = math::normalize(math::cross(-directions[num - 1], directions[0]));
+ for (const int i : IndexRange(1, num - 1)) {
axes[i] = math::normalize(math::cross(-directions[i - 1], directions[i]));
}
@@ -134,11 +134,11 @@ static Array<float3> calculate_axes(const Span<float3> directions)
/* Calculate the angle of the arc formed by the fillet. */
static Array<float> calculate_angles(const Span<float3> directions)
{
- const int size = directions.size();
- Array<float> angles(size);
+ const int num = directions.size();
+ Array<float> angles(num);
- angles[0] = M_PI - angle_v3v3(-directions[size - 1], directions[0]);
- for (const int i : IndexRange(1, size - 1)) {
+ angles[0] = M_PI - angle_v3v3(-directions[num - 1], directions[0]);
+ for (const int i : IndexRange(1, num - 1)) {
angles[i] = M_PI - angle_v3v3(-directions[i - 1], directions[i]);
}
@@ -147,18 +147,18 @@ static Array<float> calculate_angles(const Span<float3> directions)
/* Calculate the segment count in each filleted arc. */
static Array<int> calculate_counts(const FilletParam &fillet_param,
- const int size,
+ const int num,
const int spline_offset,
const bool cyclic)
{
- Array<int> counts(size, 1);
+ Array<int> counts(num, 1);
if (fillet_param.mode == GEO_NODE_CURVE_FILLET_POLY) {
- for (const int i : IndexRange(size)) {
+ for (const int i : IndexRange(num)) {
counts[i] = fillet_param.counts[spline_offset + i];
}
}
if (!cyclic) {
- counts[0] = counts[size - 1] = 0;
+ counts[0] = counts[num - 1] = 0;
}
return counts;
@@ -166,17 +166,17 @@ static Array<int> calculate_counts(const FilletParam &fillet_param,
/* Calculate the radii for the vertices to be filleted. */
static Array<float> calculate_radii(const FilletParam &fillet_param,
- const int size,
+ const int num,
const int spline_offset)
{
- Array<float> radii(size, 0.0f);
+ Array<float> radii(num, 0.0f);
if (fillet_param.limit_radius) {
- for (const int i : IndexRange(size)) {
+ for (const int i : IndexRange(num)) {
radii[i] = std::max(fillet_param.radii[spline_offset + i], 0.0f);
}
}
else {
- for (const int i : IndexRange(size)) {
+ for (const int i : IndexRange(num)) {
radii[i] = fillet_param.radii[spline_offset + i];
}
}
@@ -207,15 +207,15 @@ static FilletData calculate_fillet_data(const Spline &spline,
MutableSpan<int> point_counts,
const int spline_offset)
{
- const int size = spline.size();
+ const int num = spline.size();
FilletData fd;
fd.directions = calculate_directions(spline.positions());
fd.positions = spline.positions();
fd.axes = calculate_axes(fd.directions);
fd.angles = calculate_angles(fd.directions);
- fd.counts = calculate_counts(fillet_param, size, spline_offset, spline.is_cyclic());
- fd.radii = calculate_radii(fillet_param, size, spline_offset);
+ fd.counts = calculate_counts(fillet_param, num, spline_offset, spline.is_cyclic());
+ fd.radii = calculate_radii(fillet_param, num, spline_offset);
added_count = calculate_point_counts(point_counts, fd.radii, fd.counts);
@@ -229,19 +229,19 @@ static void limit_radii(FilletData &fd, const bool cyclic)
Span<float> angles(fd.angles);
Span<float3> positions(fd.positions);
- const int size = radii.size();
- const int fillet_count = cyclic ? size : size - 2;
+ const int num = radii.size();
+ const int fillet_count = cyclic ? num : num - 2;
const int start = cyclic ? 0 : 1;
- Array<float> max_radii(size, FLT_MAX);
+ Array<float> max_radii(num, FLT_MAX);
if (cyclic) {
/* Calculate lengths between adjacent control points. */
- const float len_prev = math::distance(positions[0], positions[size - 1]);
+ const float len_prev = math::distance(positions[0], positions[num - 1]);
const float len_next = math::distance(positions[0], positions[1]);
/* Calculate tangent lengths of fillets in control points. */
const float tan_len = radii[0] * tan(angles[0] / 2.0f);
- const float tan_len_prev = radii[size - 1] * tan(angles[size - 1] / 2.0f);
+ const float tan_len_prev = radii[num - 1] * tan(angles[num - 1] / 2.0f);
const float tan_len_next = radii[1] * tan(angles[1] / 2.0f);
float factor_prev = 1.0f, factor_next = 1.0f;
@@ -255,12 +255,12 @@ static void limit_radii(FilletData &fd, const bool cyclic)
/* Scale max radii by calculated factors. */
max_radii[0] = radii[0] * std::min(factor_next, factor_prev);
max_radii[1] = radii[1] * factor_next;
- max_radii[size - 1] = radii[size - 1] * factor_prev;
+ max_radii[num - 1] = radii[num - 1] * factor_prev;
}
/* Initialize max_radii to largest possible radii. */
float prev_dist = math::distance(positions[1], positions[0]);
- for (const int i : IndexRange(1, size - 2)) {
+ for (const int i : IndexRange(1, num - 2)) {
const float temp_dist = math::distance(positions[i], positions[i + 1]);
max_radii[i] = std::min(prev_dist, temp_dist) / tan(angles[i] / 2.0f);
prev_dist = temp_dist;
@@ -282,7 +282,7 @@ static void limit_radii(FilletData &fd, const bool cyclic)
}
/* Assign the max_radii to the fillet data's radii. */
- for (const int i : IndexRange(size)) {
+ for (const int i : IndexRange(num)) {
radii[i] = std::min(radii[i], max_radii[i]);
}
}
@@ -358,10 +358,10 @@ static void update_bezier_positions(const FilletData &fd,
Span<float3> positions(fd.positions);
Span<float3> directions(fd.directions);
- const int size = radii.size();
+ const int num = radii.size();
int i_dst = 0;
- for (const int i_src : IndexRange(size)) {
+ for (const int i_src : IndexRange(num)) {
const int count = point_counts[i_src];
/* Skip if the point count for the vertex is 1. */
@@ -385,7 +385,7 @@ static void update_bezier_positions(const FilletData &fd,
/* Position the end points of the arc and their handles. */
const int end_i = i_dst + count - 1;
- const float3 prev_dir = i_src == 0 ? -directions[size - 1] : -directions[i_src - 1];
+ const float3 prev_dir = i_src == 0 ? -directions[num - 1] : -directions[i_src - 1];
const float3 next_dir = directions[i_src];
dst_spline.positions()[i_dst] = positions[i_src] + displacement * prev_dir;
dst_spline.positions()[end_i] = positions[i_src] + displacement * next_dir;
@@ -442,10 +442,10 @@ static void update_poly_positions(const FilletData &fd,
Span<float3> positions(fd.positions);
Span<float3> directions(fd.directions);
- const int size = radii.size();
+ const int num = radii.size();
int i_dst = 0;
- for (const int i_src : IndexRange(size)) {
+ for (const int i_src : IndexRange(num)) {
const int count = point_counts[i_src];
/* Skip if the point count for the vertex is 1. */
@@ -460,7 +460,7 @@ static void update_poly_positions(const FilletData &fd,
/* Position the end points of the arc. */
const int end_i = i_dst + count - 1;
- const float3 prev_dir = i_src == 0 ? -directions[size - 1] : -directions[i_src - 1];
+ const float3 prev_dir = i_src == 0 ? -directions[num - 1] : -directions[i_src - 1];
const float3 next_dir = directions[i_src];
dst_spline.positions()[i_dst] = positions[i_src] + displacement * prev_dir;
dst_spline.positions()[end_i] = positions[i_src] + displacement * next_dir;
@@ -487,15 +487,15 @@ static SplinePtr fillet_spline(const Spline &spline,
const FilletParam &fillet_param,
const int spline_offset)
{
- const int size = spline.size();
+ const int num = spline.size();
const bool cyclic = spline.is_cyclic();
- if (size < 3) {
+ if (num < 3) {
return spline.copy();
}
/* Initialize the point_counts with 1s (at least one vertex on dst for each vertex on src). */
- Array<int> point_counts(size, 1);
+ Array<int> point_counts(num, 1);
int added_count = 0;
/* Update point_counts array and added_count. */
@@ -505,7 +505,7 @@ static SplinePtr fillet_spline(const Spline &spline,
limit_radii(fd, cyclic);
}
- const int total_points = added_count + size;
+ const int total_points = added_count + num;
const Array<int> dst_to_src = create_dst_to_src_map(point_counts, total_points);
SplinePtr dst_spline_ptr = spline.copy_only_settings();
(*dst_spline_ptr).resize(total_points);
@@ -581,8 +581,8 @@ static void calculate_curve_fillet(GeometrySet &geometry_set,
CurveComponent &component = geometry_set.get_component_for_write<CurveComponent>();
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
- const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
- fn::FieldEvaluator field_evaluator{field_context, domain_size};
+ const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_POINT);
+ fn::FieldEvaluator field_evaluator{field_context, domain_num};
field_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 dc2b9d40894..5ef20f03f28 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
@@ -84,7 +84,7 @@ class HandleTypeFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask mask) const final
{
if (component.type() != GEO_COMPONENT_TYPE_CURVE || domain != ATTR_DOMAIN_POINT) {
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 e0348f27e51..78a132064ed 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
@@ -1,12 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#include "BLI_array.hh"
-#include "BLI_index_mask_ops.hh"
-#include "BLI_length_parameterize.hh"
-#include "BLI_task.hh"
-#include "BLI_timeit.hh"
+#include "GEO_resample_curves.hh"
-#include "BKE_attribute_math.hh"
#include "BKE_curves.hh"
#include "UI_interface.h"
@@ -56,556 +51,6 @@ static void node_update(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, length_socket, mode == GEO_NODE_CURVE_RESAMPLE_LENGTH);
}
-/** Returns the number of evaluated points in each curve. Used to deselect curves with none. */
-class EvaluatedCountFieldInput final : public GeometryFieldInput {
- public:
- EvaluatedCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Evaluated Point Count")
- {
- category_ = Category::Generated;
- }
-
- GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
- IndexMask UNUSED(mask)) const final
- {
- if (component.type() == GEO_COMPONENT_TYPE_CURVE && domain == ATTR_DOMAIN_CURVE &&
- !component.is_empty()) {
- const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
- const Curves &curves_id = *curve_component.get_for_read();
- const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
- curves.ensure_evaluated_offsets();
- return VArray<int>::ForFunc(curves.curves_num(), [&](const int64_t index) -> int {
- return curves.evaluated_points_for_curve(index).size();
- });
- }
- return {};
- }
-
- uint64_t hash() const override
- {
- /* Some random constant hash. */
- return 234905872379865;
- }
-
- bool is_equal_to(const fn::FieldNode &other) const override
- {
- return dynamic_cast<const EvaluatedCountFieldInput *>(&other) != nullptr;
- }
-};
-
-/**
- * Return true if the attribute should be copied/interpolated to the result curves.
- * Don't output attributes that correspond to curve types that have no curves in the result.
- */
-static bool interpolate_attribute_to_curves(const AttributeIDRef &attribute_id,
- const std::array<int, CURVE_TYPES_NUM> &type_counts)
-{
- if (!attribute_id.is_named()) {
- return true;
- }
- if (ELEM(attribute_id.name(),
- "handle_type_left",
- "handle_type_right",
- "handle_left",
- "handle_right")) {
- return type_counts[CURVE_TYPE_BEZIER] != 0;
- }
- if (ELEM(attribute_id.name(), "nurbs_weight")) {
- return type_counts[CURVE_TYPE_NURBS] != 0;
- }
- return true;
-}
-
-/**
- * Return true if the attribute should be copied to poly curves.
- */
-static bool interpolate_attribute_to_poly_curve(const AttributeIDRef &attribute_id)
-{
- static const Set<StringRef> no_interpolation{{
- "handle_type_left",
- "handle_type_right",
- "handle_position_right",
- "handle_position_left",
- "nurbs_weight",
- }};
- return !(attribute_id.is_named() && no_interpolation.contains(attribute_id.name()));
-}
-
-/**
- * Retrieve spans from source and result attributes.
- */
-static void retrieve_attribute_spans(const Span<AttributeIDRef> ids,
- const CurveComponent &src_component,
- CurveComponent &dst_component,
- Vector<GSpan> &src,
- Vector<GMutableSpan> &dst,
- Vector<OutputAttribute> &dst_attributes)
-{
- for (const int i : ids.index_range()) {
- GVArray src_attribute = src_component.attribute_try_get_for_read(ids[i], ATTR_DOMAIN_POINT);
- BLI_assert(src_attribute);
- src.append(src_attribute.get_internal_span());
-
- const CustomDataType data_type = bke::cpp_type_to_custom_data_type(src_attribute.type());
- OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
- ids[i], ATTR_DOMAIN_POINT, data_type);
- dst.append(dst_attribute.as_span());
- dst_attributes.append(std::move(dst_attribute));
- }
-}
-
-struct AttributesForInterpolation : NonCopyable, NonMovable {
- Vector<GSpan> src;
- Vector<GMutableSpan> dst;
-
- Vector<OutputAttribute> dst_attributes;
-
- Vector<GSpan> src_no_interpolation;
- Vector<GMutableSpan> dst_no_interpolation;
-};
-
-/**
- * Gather a set of all generic attribute IDs to copy to the result curves.
- */
-static void gather_point_attributes_to_interpolate(const CurveComponent &src_component,
- CurveComponent &dst_component,
- AttributesForInterpolation &result)
-{
- const Curves &dst_curves_id = *dst_component.get_for_read();
- const bke::CurvesGeometry &dst_curves = bke::CurvesGeometry::wrap(dst_curves_id.geometry);
-
- VectorSet<AttributeIDRef> ids;
- VectorSet<AttributeIDRef> ids_no_interpolation;
- src_component.attribute_foreach(
- [&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
- if (meta_data.domain != ATTR_DOMAIN_POINT) {
- return true;
- }
- if (!interpolate_attribute_to_curves(id, dst_curves.curve_type_counts())) {
- return true;
- }
- if (interpolate_attribute_to_poly_curve(id)) {
- ids.add_new(id);
- }
- else {
- ids_no_interpolation.add_new(id);
- }
- return true;
- });
-
- /* Position is handled differently since it has non-generic interpolation for Bezier
- * curves and because the evaluated positions are cached for each evaluated point. */
- ids.remove_contained("position");
-
- retrieve_attribute_spans(
- ids, src_component, dst_component, result.src, result.dst, result.dst_attributes);
-
- /* Attributes that aren't interpolated like Bezier handles still have to be be copied
- * to the result when there are any unselected curves of the corresponding type. */
- retrieve_attribute_spans(ids_no_interpolation,
- src_component,
- dst_component,
- result.src_no_interpolation,
- result.dst_no_interpolation,
- result.dst_attributes);
-}
-
-/**
- * Copy the provided point attribute values between all curves in the #curve_ranges index
- * ranges, assuming that all curves are the same size in #src_curves and #dst_curves.
- */
-template<typename T>
-static void copy_between_curves(const bke::CurvesGeometry &src_curves,
- const bke::CurvesGeometry &dst_curves,
- const Span<IndexRange> curve_ranges,
- const Span<T> src,
- const MutableSpan<T> dst)
-{
- threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange range) {
- for (const IndexRange range : curve_ranges.slice(range)) {
- const IndexRange src_points = src_curves.points_for_curves(range);
- const IndexRange dst_points = dst_curves.points_for_curves(range);
- /* The arrays might be large, so a threaded copy might make sense here too. */
- dst.slice(dst_points).copy_from(src.slice(src_points));
- }
- });
-}
-static void copy_between_curves(const bke::CurvesGeometry &src_curves,
- const bke::CurvesGeometry &dst_curves,
- const Span<IndexRange> unselected_ranges,
- const GSpan src,
- const GMutableSpan dst)
-{
- attribute_math::convert_to_static_type(src.type(), [&](auto dummy) {
- using T = decltype(dummy);
- copy_between_curves(src_curves, dst_curves, unselected_ranges, src.typed<T>(), dst.typed<T>());
- });
-}
-
-/**
- * Copy the size of every curve in #curve_ranges to the corresponding index in #counts.
- */
-static void fill_curve_counts(const bke::CurvesGeometry &src_curves,
- const Span<IndexRange> curve_ranges,
- MutableSpan<int> counts)
-{
- threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange ranges_range) {
- for (const IndexRange curves_range : curve_ranges.slice(ranges_range)) {
- for (const int i : curves_range) {
- counts[i] = src_curves.points_for_curve(i).size();
- }
- }
- });
-}
-
-/**
- * Turn an array of sizes into the offset at each index including all previous sizes.
- */
-static void accumulate_counts_to_offsets(MutableSpan<int> counts_to_offsets)
-{
- int total = 0;
- for (const int i : counts_to_offsets.index_range().drop_back(1)) {
- const int count = counts_to_offsets[i];
- BLI_assert(count > 0);
- counts_to_offsets[i] = total;
- total += count;
- }
- counts_to_offsets.last() = total;
-}
-
-/**
- * Create new curves where the selected curves have been resampled with a number of uniform-length
- * samples defined by the count field. Interpolate attributes to the result, with an accuracy that
- * depends on the curve's resolution parameter.
- *
- * \warning The values provided by the #count_field must be 1 or greater.
- * \warning Curves with no evaluated points must not be selected.
- */
-static Curves *resample_to_uniform_count(const CurveComponent &src_component,
- const Field<bool> &selection_field,
- const Field<int> &count_field)
-{
- const Curves &src_curves_id = *src_component.get_for_read();
- const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap(src_curves_id.geometry);
-
- /* Create the new curves without any points and evaluate the final count directly
- * into the offsets array, in order to be accumulated into offsets later. */
- Curves *dst_curves_id = bke::curves_new_nomain(0, src_curves.curves_num());
- bke::CurvesGeometry &dst_curves = bke::CurvesGeometry::wrap(dst_curves_id->geometry);
- CurveComponent dst_component;
- dst_component.replace(dst_curves_id, GeometryOwnershipType::Editable);
- /* Directly copy curve attributes, since they stay the same (except for curve types). */
- CustomData_copy(&src_curves.curve_data,
- &dst_curves.curve_data,
- CD_MASK_ALL,
- CD_DUPLICATE,
- src_curves.curves_num());
- MutableSpan<int> dst_offsets = dst_curves.offsets_for_write();
-
- GeometryComponentFieldContext field_context{src_component, ATTR_DOMAIN_CURVE};
- fn::FieldEvaluator evaluator{field_context, src_curves.curves_num()};
- evaluator.set_selection(selection_field);
- evaluator.add_with_destination(count_field, dst_offsets);
- evaluator.evaluate();
- const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
- const Vector<IndexRange> unselected_ranges = selection.extract_ranges_invert(
- src_curves.curves_range(), nullptr);
-
- /* Fill the counts for the curves that aren't selected and accumulate the counts into offsets. */
- fill_curve_counts(src_curves, unselected_ranges, dst_offsets);
- accumulate_counts_to_offsets(dst_offsets);
- dst_curves.resize(dst_offsets.last(), dst_curves.curves_num());
-
- /* All resampled curves are poly curves. */
- dst_curves.fill_curve_types(selection, CURVE_TYPE_POLY);
-
- VArray<bool> curves_cyclic = src_curves.cyclic();
- VArray<int8_t> curve_types = src_curves.curve_types();
- Span<float3> evaluated_positions = src_curves.evaluated_positions();
- MutableSpan<float3> dst_positions = dst_curves.positions_for_write();
-
- AttributesForInterpolation attributes;
- gather_point_attributes_to_interpolate(src_component, dst_component, attributes);
-
- src_curves.ensure_evaluated_lengths();
-
- /* Sampling arbitrary attributes works by first interpolating them to the curve's standard
- * "evaluated points" and then interpolating that result with the uniform samples. This is
- * potentially wasteful when down-sampling a curve to many fewer points. There are two possible
- * solutions: only sample the necessary points for interpolation, or first sample curve
- * parameter/segment indices and evaluate the curve directly. */
- Array<int> sample_indices(dst_curves.points_num());
- Array<float> sample_factors(dst_curves.points_num());
-
- /* Use a "for each group of curves: for each attribute: for each curve" pattern to work on
- * smaller sections of data that ideally fit into CPU cache better than simply one attribute at a
- * time or one curve at a time. */
- threading::parallel_for(selection.index_range(), 512, [&](IndexRange selection_range) {
- const IndexMask sliced_selection = selection.slice(selection_range);
-
- Vector<std::byte> evaluated_buffer;
-
- /* Gather uniform samples based on the accumulated lengths of the original curve. */
- for (const int i_curve : sliced_selection) {
- const bool cyclic = curves_cyclic[i_curve];
- const IndexRange dst_points = dst_curves.points_for_curve(i_curve);
- length_parameterize::create_uniform_samples(
- src_curves.evaluated_lengths_for_curve(i_curve, cyclic),
- curves_cyclic[i_curve],
- sample_indices.as_mutable_span().slice(dst_points),
- sample_factors.as_mutable_span().slice(dst_points));
- }
-
- /* For every attribute, evaluate attributes from every curve in the range in the original
- * curve's "evaluated points", then use linear interpolation to sample to the result. */
- for (const int i_attribute : attributes.dst.index_range()) {
- attribute_math::convert_to_static_type(attributes.src[i_attribute].type(), [&](auto dummy) {
- using T = decltype(dummy);
- Span<T> src = attributes.src[i_attribute].typed<T>();
- MutableSpan<T> dst = attributes.dst[i_attribute].typed<T>();
-
- for (const int i_curve : sliced_selection) {
- const IndexRange src_points = src_curves.points_for_curve(i_curve);
- const IndexRange dst_points = dst_curves.points_for_curve(i_curve);
-
- if (curve_types[i_curve] == CURVE_TYPE_POLY) {
- length_parameterize::linear_interpolation(src.slice(src_points),
- sample_indices.as_span().slice(dst_points),
- sample_factors.as_span().slice(dst_points),
- dst.slice(dst_points));
- }
- else {
- const int evaluated_size = src_curves.evaluated_points_for_curve(i_curve).size();
- evaluated_buffer.clear();
- evaluated_buffer.resize(sizeof(T) * evaluated_size);
- MutableSpan<T> evaluated = evaluated_buffer.as_mutable_span().cast<T>();
- src_curves.interpolate_to_evaluated(i_curve, src.slice(src_points), evaluated);
-
- length_parameterize::linear_interpolation(evaluated.as_span(),
- sample_indices.as_span().slice(dst_points),
- sample_factors.as_span().slice(dst_points),
- dst.slice(dst_points));
- }
- }
- });
- }
-
- /* Interpolate the evaluated positions to the resampled curves. */
- for (const int i_curve : sliced_selection) {
- const IndexRange src_points = src_curves.evaluated_points_for_curve(i_curve);
- const IndexRange dst_points = dst_curves.points_for_curve(i_curve);
- length_parameterize::linear_interpolation(evaluated_positions.slice(src_points),
- sample_indices.as_span().slice(dst_points),
- sample_factors.as_span().slice(dst_points),
- dst_positions.slice(dst_points));
- }
-
- /* Fill the default value for non-interpolating attributes that still must be copied. */
- for (GMutableSpan dst : attributes.dst_no_interpolation) {
- for (const int i_curve : sliced_selection) {
- const IndexRange dst_points = dst_curves.points_for_curve(i_curve);
- dst.type().value_initialize_n(dst.slice(dst_points).data(), dst_points.size());
- }
- }
- });
-
- /* Any attribute data from unselected curve points can be directly copied. */
- for (const int i : attributes.src.index_range()) {
- copy_between_curves(
- src_curves, dst_curves, unselected_ranges, attributes.src[i], attributes.dst[i]);
- }
- for (const int i : attributes.src_no_interpolation.index_range()) {
- copy_between_curves(src_curves,
- dst_curves,
- unselected_ranges,
- attributes.src_no_interpolation[i],
- attributes.dst_no_interpolation[i]);
- }
-
- /* Copy positions for unselected curves. */
- Span<float3> src_positions = src_curves.positions();
- copy_between_curves(src_curves, dst_curves, unselected_ranges, src_positions, dst_positions);
-
- for (OutputAttribute &attribute : attributes.dst_attributes) {
- attribute.save();
- }
-
- return dst_curves_id;
-}
-
-/**
- * Evaluate each selected curve to its implicit evaluated points.
- *
- * \warning Curves with no evaluated points must not be selected.
- */
-static Curves *resample_to_evaluated(const CurveComponent &src_component,
- const Field<bool> &selection_field)
-{
- const Curves &src_curves_id = *src_component.get_for_read();
- const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap(src_curves_id.geometry);
-
- GeometryComponentFieldContext field_context{src_component, ATTR_DOMAIN_CURVE};
- fn::FieldEvaluator evaluator{field_context, src_curves.curves_num()};
- evaluator.set_selection(selection_field);
- evaluator.evaluate();
- const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
- const Vector<IndexRange> unselected_ranges = selection.extract_ranges_invert(
- src_curves.curves_range(), nullptr);
-
- Curves *dst_curves_id = bke::curves_new_nomain(0, src_curves.curves_num());
- bke::CurvesGeometry &dst_curves = bke::CurvesGeometry::wrap(dst_curves_id->geometry);
- CurveComponent dst_component;
- dst_component.replace(dst_curves_id, GeometryOwnershipType::Editable);
- /* Directly copy curve attributes, since they stay the same (except for curve types). */
- CustomData_copy(&src_curves.curve_data,
- &dst_curves.curve_data,
- CD_MASK_ALL,
- CD_DUPLICATE,
- src_curves.curves_num());
- /* All resampled curves are poly curves. */
- dst_curves.fill_curve_types(selection, CURVE_TYPE_POLY);
- MutableSpan<int> dst_offsets = dst_curves.offsets_for_write();
-
- src_curves.ensure_evaluated_offsets();
- threading::parallel_for(selection.index_range(), 4096, [&](IndexRange range) {
- for (const int i : selection.slice(range)) {
- dst_offsets[i] = src_curves.evaluated_points_for_curve(i).size();
- }
- });
- fill_curve_counts(src_curves, unselected_ranges, dst_offsets);
- accumulate_counts_to_offsets(dst_offsets);
-
- dst_curves.resize(dst_offsets.last(), dst_curves.curves_num());
-
- /* Create the correct number of uniform-length samples for every selected curve. */
- Span<float3> evaluated_positions = src_curves.evaluated_positions();
- MutableSpan<float3> dst_positions = dst_curves.positions_for_write();
-
- AttributesForInterpolation attributes;
- gather_point_attributes_to_interpolate(src_component, dst_component, attributes);
-
- threading::parallel_for(selection.index_range(), 512, [&](IndexRange selection_range) {
- const IndexMask sliced_selection = selection.slice(selection_range);
-
- /* Evaluate generic point attributes directly to the result attributes. */
- for (const int i_attribute : attributes.dst.index_range()) {
- attribute_math::convert_to_static_type(attributes.src[i_attribute].type(), [&](auto dummy) {
- using T = decltype(dummy);
- Span<T> src = attributes.src[i_attribute].typed<T>();
- MutableSpan<T> dst = attributes.dst[i_attribute].typed<T>();
-
- for (const int i_curve : sliced_selection) {
- const IndexRange src_points = src_curves.points_for_curve(i_curve);
- const IndexRange dst_points = dst_curves.points_for_curve(i_curve);
- src_curves.interpolate_to_evaluated(
- i_curve, src.slice(src_points), dst.slice(dst_points));
- }
- });
- }
-
- /* Copy the evaluated positions to the selected curves. */
- for (const int i_curve : sliced_selection) {
- const IndexRange src_points = src_curves.evaluated_points_for_curve(i_curve);
- const IndexRange dst_points = dst_curves.points_for_curve(i_curve);
- dst_positions.slice(dst_points).copy_from(evaluated_positions.slice(src_points));
- }
-
- /* Fill the default value for non-interpolating attributes that still must be copied. */
- for (GMutableSpan dst : attributes.dst_no_interpolation) {
- for (const int i_curve : sliced_selection) {
- const IndexRange dst_points = dst_curves.points_for_curve(i_curve);
- dst.type().value_initialize_n(dst.slice(dst_points).data(), dst_points.size());
- }
- }
- });
-
- /* Any attribute data from unselected curve points can be directly copied. */
- for (const int i : attributes.src.index_range()) {
- copy_between_curves(
- src_curves, dst_curves, unselected_ranges, attributes.src[i], attributes.dst[i]);
- }
- for (const int i : attributes.src_no_interpolation.index_range()) {
- copy_between_curves(src_curves,
- dst_curves,
- unselected_ranges,
- attributes.src_no_interpolation[i],
- attributes.dst_no_interpolation[i]);
- }
-
- /* Copy positions for unselected curves. */
- Span<float3> src_positions = src_curves.positions();
- copy_between_curves(src_curves, dst_curves, unselected_ranges, src_positions, dst_positions);
-
- for (OutputAttribute &attribute : attributes.dst_attributes) {
- attribute.save();
- }
-
- return dst_curves_id;
-}
-
-/**
- * Create a resampled curve point count field for both "uniform" options.
- * The complexity is handled here in order to make the actual resampling functions simpler.
- */
-static Field<int> get_curve_count_field(GeoNodeExecParams params,
- const GeometryNodeCurveResampleMode mode)
-{
- if (mode == GEO_NODE_CURVE_RESAMPLE_COUNT) {
- static fn::CustomMF_SI_SO<int, int> max_one_fn(
- "Clamp Above One",
- [](int value) { return std::max(1, value); },
- fn::CustomMF_presets::AllSpanOrSingle());
- auto clamp_op = std::make_shared<FieldOperation>(
- FieldOperation(max_one_fn, {Field<int>(params.extract_input<Field<int>>("Count"))}));
-
- return Field<int>(std::move(clamp_op));
- }
-
- if (mode == GEO_NODE_CURVE_RESAMPLE_LENGTH) {
- static fn::CustomMF_SI_SI_SO<float, float, int> get_count_fn(
- "Length Input to Count",
- [](const float curve_length, const float sample_length) {
- /* Find the number of sampled segments by dividing the total length by
- * the sample length. Then there is one more sampled point than segment. */
- const int count = int(curve_length / sample_length) + 1;
- return std::max(1, count);
- },
- fn::CustomMF_presets::AllSpanOrSingle());
-
- auto get_count_op = std::make_shared<FieldOperation>(
- FieldOperation(get_count_fn,
- {Field<float>(std::make_shared<SplineLengthFieldInput>()),
- params.extract_input<Field<float>>("Length")}));
-
- return Field<int>(std::move(get_count_op));
- }
-
- BLI_assert_unreachable();
- return {};
-}
-
-/**
- * Create a selection field that removes curves without any evaluated points (invalid NURBS curves)
- * from the original selection provided to the node. This is here to simplify the sampling actual
- * resampling code.
- */
-static Field<bool> get_selection_field(GeoNodeExecParams params)
-{
- static fn::CustomMF_SI_SI_SO<bool, int, bool> get_selection_fn(
- "Create Curve Selection",
- [](const bool orig_selection, const int evaluated_points_num) {
- return orig_selection && evaluated_points_num > 1;
- },
- fn::CustomMF_presets::AllSpanOrSingle());
-
- auto selection_op = std::make_shared<FieldOperation>(
- FieldOperation(get_selection_fn,
- {params.extract_input<Field<bool>>("Selection"),
- Field<int>(std::make_shared<EvaluatedCountFieldInput>())}));
-
- return Field<bool>(std::move(selection_op));
-}
-
static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
@@ -613,35 +58,38 @@ static void node_geo_exec(GeoNodeExecParams params)
const NodeGeometryCurveResample &storage = node_storage(params.node());
const GeometryNodeCurveResampleMode mode = (GeometryNodeCurveResampleMode)storage.mode;
- const Field<bool> selection = get_selection_field(params);
+ const Field<bool> selection = params.extract_input<Field<bool>>("Selection");
switch (mode) {
- case GEO_NODE_CURVE_RESAMPLE_COUNT:
+ 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 (!component->is_empty()) {
+ geometry.replace_curves(geometry::resample_to_count(*component, selection, count));
+ }
+ }
+ });
+ break;
+ }
case GEO_NODE_CURVE_RESAMPLE_LENGTH: {
- Field<int> count = get_curve_count_field(params, mode);
-
- geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
- if (!geometry_set.has_curves()) {
- return;
+ 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 (!component->is_empty()) {
+ geometry.replace_curves(geometry::resample_to_length(*component, selection, length));
+ }
}
-
- Curves *result = resample_to_uniform_count(
- *geometry_set.get_component_for_read<CurveComponent>(), selection, count);
-
- geometry_set.replace_curves(result);
});
break;
}
case GEO_NODE_CURVE_RESAMPLE_EVALUATED:
- geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
- if (!geometry_set.has_curves()) {
- return;
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry) {
+ if (const CurveComponent *component = geometry.get_component_for_read<CurveComponent>()) {
+ if (!component->is_empty()) {
+ geometry.replace_curves(geometry::resample_to_evaluated(*component, selection));
+ }
}
-
- Curves *result = resample_to_evaluated(
- *geometry_set.get_component_for_read<CurveComponent>(), selection);
-
- geometry_set.replace_curves(result);
});
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..64a174df599 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
@@ -27,9 +27,9 @@ static void node_geo_exec(GeoNodeExecParams params)
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);
+ const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_CURVE);
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
+ fn::FieldEvaluator selection_evaluator{field_context, domain_num};
selection_evaluator.add(selection_field);
selection_evaluator.evaluate();
const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
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 5d97720a4f8..8401c94be4b 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
@@ -75,7 +75,7 @@ static Array<float> curve_length_point_domain(const bke::CurvesGeometry &curves)
case CURVE_TYPE_CATMULL_ROM: {
const int resolution = resolutions[i_curve];
for (const int i : IndexRange(points.size()).drop_back(1)) {
- lengths[i + 1] = evaluated_lengths[resolution * i - 1];
+ lengths[i + 1] = evaluated_lengths[resolution * i];
}
break;
}
@@ -107,7 +107,7 @@ static Array<float> curve_length_point_domain(const bke::CurvesGeometry &curves)
static VArray<float> construct_curve_parameter_varray(const bke::CurvesGeometry &curves,
const IndexMask UNUSED(mask),
- const AttributeDomain domain)
+ const eAttrDomain domain)
{
VArray<bool> cyclic = curves.cyclic();
@@ -144,9 +144,9 @@ static VArray<float> construct_curve_parameter_varray(const bke::CurvesGeometry
return {};
}
-static VArray<float> construct_curve_length_varray(const bke::CurvesGeometry &curves,
- const IndexMask UNUSED(mask),
- const AttributeDomain domain)
+static VArray<float> construct_curve_length_parameter_varray(const bke::CurvesGeometry &curves,
+ const IndexMask UNUSED(mask),
+ const eAttrDomain domain)
{
curves.ensure_evaluated_lengths();
@@ -165,7 +165,7 @@ static VArray<float> construct_curve_length_varray(const bke::CurvesGeometry &cu
static VArray<int> construct_index_on_spline_varray(const bke::CurvesGeometry &curves,
const IndexMask UNUSED(mask),
- const AttributeDomain domain)
+ const eAttrDomain domain)
{
if (domain == ATTR_DOMAIN_POINT) {
Array<int> result(curves.points_num());
@@ -191,7 +191,7 @@ class CurveParameterFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask mask) const final
{
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
@@ -217,15 +217,15 @@ class CurveParameterFieldInput final : public GeometryFieldInput {
}
};
-class CurveLengthFieldInput final : public GeometryFieldInput {
+class CurveLengthParameterFieldInput final : public GeometryFieldInput {
public:
- CurveLengthFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Curve Length node")
+ CurveLengthParameterFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Curve Length node")
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask mask) const final
{
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
@@ -233,7 +233,7 @@ class CurveLengthFieldInput final : public GeometryFieldInput {
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_varray(curves, mask, domain);
+ return construct_curve_length_parameter_varray(curves, mask, domain);
}
}
return {};
@@ -247,7 +247,7 @@ class CurveLengthFieldInput final : public GeometryFieldInput {
bool is_equal_to(const fn::FieldNode &other) const override
{
- return dynamic_cast<const CurveLengthFieldInput *>(&other) != nullptr;
+ return dynamic_cast<const CurveLengthParameterFieldInput *>(&other) != nullptr;
}
};
@@ -259,7 +259,7 @@ class IndexOnSplineFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask mask) const final
{
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
@@ -288,7 +288,7 @@ class IndexOnSplineFieldInput final : public GeometryFieldInput {
static void node_geo_exec(GeoNodeExecParams params)
{
Field<float> parameter_field{std::make_shared<CurveParameterFieldInput>()};
- Field<float> length_field{std::make_shared<CurveLengthFieldInput>()};
+ Field<float> length_field{std::make_shared<CurveLengthParameterFieldInput>()};
Field<int> index_on_spline_field{std::make_shared<IndexOnSplineFieldInput>()};
params.set_output("Factor", std::move(parameter_field));
params.set_output("Length", std::move(length_field));
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 4118448b237..500804e41f0 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
@@ -33,52 +33,49 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
node->storage = data;
}
-template<class T>
-static void scale_input_assign(const Span<T> input,
+template<typename T>
+static void scale_input_assign(const Span<T> src,
const int scale,
const int offset,
- const MutableSpan<T> r_output)
+ MutableSpan<T> dst)
{
- for (const int i : IndexRange(r_output.size())) {
- r_output[i] = input[i * scale + offset];
+ for (const int i : dst.index_range()) {
+ dst[i] = src[i * scale + offset];
}
}
-template<class T>
-static void scale_output_assign(const Span<T> input,
+template<typename T>
+static void scale_output_assign(const Span<T> src,
const int scale,
const int offset,
- const MutableSpan<T> &r_output)
+ MutableSpan<T> dst)
{
- for (const int i : IndexRange(input.size())) {
- r_output[i * scale + offset] = input[i];
+ for (const int i : src.index_range()) {
+ dst[i * scale + offset] = src[i];
}
}
-template<class T>
-static void nurbs_to_bezier_assign(const Span<T> input,
- const MutableSpan<T> r_output,
- const KnotsMode knotsMode)
+template<typename T>
+static void nurbs_to_bezier_assign(const Span<T> src,
+ const MutableSpan<T> dst,
+ const KnotsMode knots_mode)
{
- const int input_size = input.size();
- const int output_size = r_output.size();
-
- switch (knotsMode) {
+ switch (knots_mode) {
case NURBS_KNOT_MODE_BEZIER:
- scale_input_assign<T>(input, 3, 1, r_output);
+ scale_input_assign<T>(src, 3, 1, dst);
break;
case NURBS_KNOT_MODE_NORMAL:
- for (const int i : IndexRange(output_size)) {
- r_output[i] = input[(i + 1) % input_size];
+ for (const int i : dst.index_range()) {
+ dst[i] = src[(i + 1) % src.size()];
}
break;
case NURBS_KNOT_MODE_ENDPOINT_BEZIER:
case NURBS_KNOT_MODE_ENDPOINT:
- for (const int i : IndexRange(1, output_size - 2)) {
- r_output[i] = input[i + 1];
+ for (const int i : dst.index_range().drop_back(1).drop_front(1)) {
+ dst[i] = src[i + 1];
}
- r_output.first() = input.first();
- r_output.last() = input.last();
+ dst.first() = src.first();
+ dst.last() = src.last();
break;
}
}
@@ -110,20 +107,20 @@ static void copy_attributes(const Spline &input_spline, Spline &output_spline, C
static Vector<float3> create_nurbs_to_bezier_handles(const Span<float3> nurbs_positions,
const KnotsMode knots_mode)
{
- const int nurbs_positions_size = nurbs_positions.size();
+ const int nurbs_positions_num = nurbs_positions.size();
Vector<float3> handle_positions;
if (knots_mode == NURBS_KNOT_MODE_BEZIER) {
- for (const int i : IndexRange(nurbs_positions_size)) {
+ for (const int i : IndexRange(nurbs_positions_num)) {
if (i % 3 == 1) {
continue;
}
handle_positions.append(nurbs_positions[i]);
}
- if (nurbs_positions_size % 3 == 1) {
+ if (nurbs_positions_num % 3 == 1) {
handle_positions.pop_last();
}
- else if (nurbs_positions_size % 3 == 2) {
- const int last_index = nurbs_positions_size - 1;
+ else if (nurbs_positions_num % 3 == 2) {
+ const int last_index = nurbs_positions_num - 1;
handle_positions.append(2 * nurbs_positions[last_index] - nurbs_positions[last_index - 1]);
}
}
@@ -137,11 +134,11 @@ static Vector<float3> create_nurbs_to_bezier_handles(const Span<float3> nurbs_po
handle_positions.append(2 * nurbs_positions[0] - nurbs_positions[1]);
handle_positions.append(nurbs_positions[1]);
}
- const int segments_size = nurbs_positions_size - 1;
- const bool ignore_interior_segment = segments_size == 3 && is_periodic == false;
+ const int segments_num = nurbs_positions_num - 1;
+ const bool ignore_interior_segment = segments_num == 3 && is_periodic == false;
if (ignore_interior_segment == false) {
- const float mid_offset = (float)(segments_size - 1) / 2.0f;
- for (const int i : IndexRange(1, segments_size - 2)) {
+ const float mid_offset = (float)(segments_num - 1) / 2.0f;
+ for (const int i : IndexRange(1, segments_num - 2)) {
const int divisor = is_periodic ?
3 :
std::min(3, (int)(-std::abs(i - mid_offset) + mid_offset + 1.0f));
@@ -154,7 +151,7 @@ static Vector<float3> create_nurbs_to_bezier_handles(const Span<float3> nurbs_po
}
}
}
- const int last_index = nurbs_positions_size - 1;
+ const int last_index = nurbs_positions_num - 1;
if (is_periodic) {
handle_positions.append(
nurbs_positions[last_index - 1] +
@@ -357,7 +354,7 @@ static SplinePtr convert_to_nurbs(const Spline &input)
static void node_geo_exec(GeoNodeExecParams params)
{
const NodeGeometryCurveSplineType &storage = node_storage(params.node());
- const GeometryNodeSplineType output_type = (const GeometryNodeSplineType)storage.spline_type;
+ const GeometryNodeSplineType dst_type = (const GeometryNodeSplineType)storage.spline_type;
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
@@ -371,11 +368,11 @@ static void node_geo_exec(GeoNodeExecParams params)
const std::unique_ptr<CurveEval> curve = curves_to_curve_eval(
*curve_component->get_for_read());
GeometryComponentFieldContext field_context{*curve_component, ATTR_DOMAIN_CURVE};
- const int domain_size = curve_component->attribute_domain_size(ATTR_DOMAIN_CURVE);
+ const int domain_num = curve_component->attribute_domain_num(ATTR_DOMAIN_CURVE);
Span<SplinePtr> src_splines = curve->splines();
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
+ fn::FieldEvaluator selection_evaluator{field_context, domain_num};
selection_evaluator.add(selection_field);
selection_evaluator.evaluate();
const VArray<bool> &selection = selection_evaluator.get_evaluated<bool>(0);
@@ -386,7 +383,7 @@ static void node_geo_exec(GeoNodeExecParams params)
threading::parallel_for(src_splines.index_range(), 512, [&](IndexRange range) {
for (const int i : range) {
if (selection[i]) {
- switch (output_type) {
+ switch (dst_type) {
case GEO_NODE_SPLINE_TYPE_POLY:
new_curve->splines()[i] = convert_to_poly_spline(*src_splines[i]);
break;
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 371556c04f1..4d8745bf79e 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
@@ -30,9 +30,9 @@ static Array<int> get_subdivided_offsets(const Spline &spline,
const VArray<int> &cuts,
const int spline_offset)
{
- Array<int> offsets(spline.segments_size() + 1);
+ Array<int> offsets(spline.segments_num() + 1);
int offset = 0;
- for (const int i : IndexRange(spline.segments_size())) {
+ for (const int i : IndexRange(spline.segments_num())) {
offsets[i] = offset;
offset = offset + std::max(cuts[spline_offset + i], 0) + 1;
}
@@ -46,8 +46,8 @@ static void subdivide_attribute(Span<T> src,
const bool is_cyclic,
MutableSpan<T> dst)
{
- const int src_size = src.size();
- threading::parallel_for(IndexRange(src_size - 1), 1024, [&](IndexRange range) {
+ const int src_num = src.size();
+ threading::parallel_for(IndexRange(src_num - 1), 1024, [&](IndexRange range) {
for (const int i : range) {
const int cuts = offsets[i + 1] - offsets[i];
dst[offsets[i]] = src[i];
@@ -60,7 +60,7 @@ static void subdivide_attribute(Span<T> src,
});
if (is_cyclic) {
- const int i = src_size - 1;
+ const int i = src_num - 1;
const int cuts = offsets[i + 1] - offsets[i];
dst[offsets[i]] = src.last();
const float factor_delta = cuts == 0 ? 1.0f : 1.0f / cuts;
@@ -86,7 +86,7 @@ static void subdivide_attribute(Span<T> src,
static void subdivide_bezier_segment(const BezierSpline &src,
const int index,
const int offset,
- const int result_size,
+ const int result_num,
Span<float3> src_positions,
Span<float3> src_handles_left,
Span<float3> src_handles_right,
@@ -106,11 +106,11 @@ static void subdivide_bezier_segment(const BezierSpline &src,
if (is_last_cyclic_segment) {
dst_type_left.first() = BEZIER_HANDLE_VECTOR;
}
- dst_type_left.slice(offset + 1, result_size).fill(BEZIER_HANDLE_VECTOR);
- dst_type_right.slice(offset, result_size).fill(BEZIER_HANDLE_VECTOR);
+ dst_type_left.slice(offset + 1, result_num).fill(BEZIER_HANDLE_VECTOR);
+ dst_type_right.slice(offset, result_num).fill(BEZIER_HANDLE_VECTOR);
- const float factor_delta = 1.0f / result_size;
- for (const int cut : IndexRange(result_size)) {
+ const float factor_delta = 1.0f / result_num;
+ for (const int cut : IndexRange(result_num)) {
const float factor = cut * factor_delta;
dst_positions[offset + cut] = attribute_math::mix2(
factor, src_positions[index], src_positions[next_index]);
@@ -120,10 +120,10 @@ static void subdivide_bezier_segment(const BezierSpline &src,
if (is_last_cyclic_segment) {
dst_type_left.first() = BEZIER_HANDLE_FREE;
}
- dst_type_left.slice(offset + 1, result_size).fill(BEZIER_HANDLE_FREE);
- dst_type_right.slice(offset, result_size).fill(BEZIER_HANDLE_FREE);
+ dst_type_left.slice(offset + 1, result_num).fill(BEZIER_HANDLE_FREE);
+ dst_type_right.slice(offset, result_num).fill(BEZIER_HANDLE_FREE);
- const int i_segment_last = is_last_cyclic_segment ? 0 : offset + result_size;
+ const int i_segment_last = is_last_cyclic_segment ? 0 : offset + result_num;
/* Create a Bezier segment to update iteratively for every subdivision
* and references to the meaningful values for ease of use. */
@@ -138,8 +138,8 @@ static void subdivide_bezier_segment(const BezierSpline &src,
handle_prev = src_handles_right[index];
handle_next = src_handles_left[next_index];
- for (const int cut : IndexRange(result_size - 1)) {
- const float parameter = 1.0f / (result_size - cut);
+ for (const int cut : IndexRange(result_num - 1)) {
+ const float parameter = 1.0f / (result_num - cut);
const BezierSpline::InsertResult insert = temp.calculate_segment_insertion(0, 1, parameter);
/* Copy relevant temporary data to the result. */
@@ -154,7 +154,7 @@ static void subdivide_bezier_segment(const BezierSpline &src,
}
/* Copy the handles for the last segment from the temporary spline. */
- dst_handles_right[offset + result_size - 1] = handle_prev;
+ dst_handles_right[offset + result_num - 1] = handle_prev;
dst_handles_left[i_segment_last] = handle_next;
}
}
@@ -287,9 +287,9 @@ static SplinePtr subdivide_spline(const Spline &spline,
* of cuts is a real span (especially considering the note below). Using the offset at each
* point facilitates subdividing in parallel later. */
Array<int> offsets = get_subdivided_offsets(spline, cuts, spline_offset);
- const int result_size = offsets.last() + int(!spline.is_cyclic());
+ const int result_num = offsets.last() + int(!spline.is_cyclic());
SplinePtr new_spline = spline.copy_only_settings();
- new_spline->resize(result_size);
+ new_spline->resize(result_num);
subdivide_builtin_attributes(spline, offsets, *new_spline);
subdivide_dynamic_attributes(spline, offsets, *new_spline);
return new_spline;
@@ -334,9 +334,9 @@ static void node_geo_exec(GeoNodeExecParams params)
const CurveComponent &component = *geometry_set.get_component_for_read<CurveComponent>();
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
- const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
+ const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_POINT);
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.add(cuts_field);
evaluator.evaluate();
const VArray<int> &cuts = evaluator.get_evaluated<int>(0);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
index 894580f2932..7d83b4b3ecb 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
@@ -90,7 +90,7 @@ static Array<int> calculate_spline_point_offsets(GeoNodeExecParams &params,
int offset = 0;
for (const int i : IndexRange(size)) {
offsets[i] = offset;
- if (splines[i]->evaluated_points_size() > 0) {
+ if (splines[i]->evaluated_points_num() > 0) {
offset += count;
}
}
@@ -104,7 +104,7 @@ static Array<int> calculate_spline_point_offsets(GeoNodeExecParams &params,
int offset = 0;
for (const int i : IndexRange(size)) {
offsets[i] = offset;
- if (splines[i]->evaluated_points_size() > 0) {
+ if (splines[i]->evaluated_points_num() > 0) {
offset += splines[i]->length() / resolution + 1;
}
}
@@ -120,11 +120,11 @@ static Array<int> calculate_spline_point_offsets(GeoNodeExecParams &params,
}
/**
- * \note: Relies on the fact that all attributes on point clouds are stored contiguously.
+ * \note Relies on the fact that all attributes on point clouds are stored contiguously.
*/
static GMutableSpan ensure_point_attribute(PointCloudComponent &points,
const AttributeIDRef &attribute_id,
- const CustomDataType data_type)
+ const eCustomDataType data_type)
{
points.attribute_try_create(attribute_id, ATTR_DOMAIN_POINT, data_type, AttributeInitDefault());
WriteAttributeLookup attribute = points.attribute_try_get_for_write(attribute_id);
@@ -240,18 +240,18 @@ static void copy_uniform_sample_point_attributes(const Span<SplinePtr> splines,
for (const int i : range) {
const Spline &spline = *splines[i];
const int offset = offsets[i];
- const int size = offsets[i + 1] - offsets[i];
- if (size == 0) {
+ const int num = offsets[i + 1] - offsets[i];
+ if (num == 0) {
continue;
}
- const Array<float> uniform_samples = spline.sample_uniform_index_factors(size);
+ const Array<float> uniform_samples = spline.sample_uniform_index_factors(num);
spline.sample_with_index_factors<float3>(
- spline.evaluated_positions(), uniform_samples, data.positions.slice(offset, size));
+ spline.evaluated_positions(), uniform_samples, data.positions.slice(offset, num));
spline.sample_with_index_factors<float>(spline.interpolate_to_evaluated(spline.radii()),
uniform_samples,
- data.radii.slice(offset, size));
+ data.radii.slice(offset, num));
for (const Map<AttributeIDRef, GMutableSpan>::Item item : data.point_attributes.items()) {
const AttributeIDRef attribute_id = item.key;
@@ -260,14 +260,13 @@ static void copy_uniform_sample_point_attributes(const Span<SplinePtr> splines,
BLI_assert(spline.attributes.get_for_read(attribute_id));
GSpan spline_span = *spline.attributes.get_for_read(attribute_id);
- spline.sample_with_index_factors(spline.interpolate_to_evaluated(spline_span),
- uniform_samples,
- dst.slice(offset, size));
+ spline.sample_with_index_factors(
+ spline.interpolate_to_evaluated(spline_span), uniform_samples, dst.slice(offset, num));
}
if (!data.tangents.is_empty()) {
Span<float3> src_tangents = spline.evaluated_tangents();
- MutableSpan<float3> sampled_tangents = data.tangents.slice(offset, size);
+ MutableSpan<float3> sampled_tangents = data.tangents.slice(offset, num);
spline.sample_with_index_factors<float3>(src_tangents, uniform_samples, sampled_tangents);
for (float3 &vector : sampled_tangents) {
vector = math::normalize(vector);
@@ -276,7 +275,7 @@ static void copy_uniform_sample_point_attributes(const Span<SplinePtr> splines,
if (!data.normals.is_empty()) {
Span<float3> src_normals = spline.evaluated_normals();
- MutableSpan<float3> sampled_normals = data.normals.slice(offset, size);
+ MutableSpan<float3> sampled_normals = data.normals.slice(offset, num);
spline.sample_with_index_factors<float3>(src_normals, uniform_samples, sampled_normals);
for (float3 &vector : sampled_normals) {
vector = math::normalize(vector);
@@ -298,8 +297,8 @@ static void copy_spline_domain_attributes(const CurveEval &curve,
for (const int i : curve.splines().index_range()) {
const int offset = offsets[i];
- const int size = offsets[i + 1] - offsets[i];
- type.fill_assign_n(curve_attribute[i], dst[offset], size);
+ const int num = offsets[i + 1] - offsets[i];
+ type.fill_assign_n(curve_attribute[i], dst[offset], num);
}
return true;
@@ -329,13 +328,13 @@ static void node_geo_exec(GeoNodeExecParams params)
curve->assert_valid_point_attributes();
const Array<int> offsets = calculate_spline_point_offsets(params, mode, *curve, splines);
- const int total_size = offsets.last();
- if (total_size == 0) {
+ const int total_num = offsets.last();
+ if (total_num == 0) {
geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
return;
}
- geometry_set.replace_pointcloud(BKE_pointcloud_new_nomain(total_size));
+ geometry_set.replace_pointcloud(BKE_pointcloud_new_nomain(total_num));
PointCloudComponent &points = geometry_set.get_component_for_write<PointCloudComponent>();
ResultAttributes point_attributes = create_attributes_for_transfer(
points, *curve, attribute_outputs);
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 df360818313..c993a3d305d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
@@ -117,10 +117,10 @@ struct TrimLocation {
};
template<typename T>
-static void shift_slice_to_start(MutableSpan<T> data, const int start_index, const int size)
+static void shift_slice_to_start(MutableSpan<T> data, const int start_index, const int num)
{
- BLI_assert(start_index + size - 1 <= data.size());
- memmove(data.data(), &data[start_index], sizeof(T) * size);
+ BLI_assert(start_index + num - 1 <= data.size());
+ memmove(data.data(), &data[start_index], sizeof(T) * num);
}
/* Shift slice to start of span and modifies start and end data. */
@@ -129,17 +129,17 @@ static void linear_trim_data(const TrimLocation &start,
const TrimLocation &end,
MutableSpan<T> data)
{
- const int size = end.right_index - start.left_index + 1;
+ const int num = end.right_index - start.left_index + 1;
if (start.left_index > 0) {
- shift_slice_to_start<T>(data, start.left_index, size);
+ shift_slice_to_start<T>(data, start.left_index, num);
}
const T start_data = mix2<T>(start.factor, data.first(), data[1]);
- const T end_data = mix2<T>(end.factor, data[size - 2], data[size - 1]);
+ const T end_data = mix2<T>(end.factor, data[num - 2], data[num - 1]);
data.first() = start_data;
- data[size - 1] = end_data;
+ data[num - 1] = end_data;
}
/**
@@ -152,12 +152,12 @@ static void linear_trim_to_output_data(const TrimLocation &start,
Span<T> src,
MutableSpan<T> dst)
{
- const int size = end.right_index - start.left_index + 1;
+ const int num = end.right_index - start.left_index + 1;
const T start_data = mix2<T>(start.factor, src[start.left_index], src[start.right_index]);
const T end_data = mix2<T>(end.factor, src[end.left_index], src[end.right_index]);
- dst.copy_from(src.slice(start.left_index, size));
+ dst.copy_from(src.slice(start.left_index, num));
dst.first() = start_data;
dst.last() = end_data;
}
@@ -175,8 +175,8 @@ static TrimLocation lookup_control_point_position(const Spline::LookupResult &lo
const int right = left == (spline.size() - 1) ? 0 : left + 1;
const float offset_in_segment = lookup.evaluated_index + lookup.factor - offsets[left];
- const int segment_eval_size = offsets[left + 1] - offsets[left];
- const float factor = std::clamp(offset_in_segment / segment_eval_size, 0.0f, 1.0f);
+ const int segment_eval_num = offsets[left + 1] - offsets[left];
+ const float factor = std::clamp(offset_in_segment / segment_eval_num, 0.0f, 1.0f);
return {left, right, factor};
}
@@ -191,7 +191,7 @@ static void trim_poly_spline(Spline &spline,
const TrimLocation end = {
end_lookup.evaluated_index, end_lookup.next_evaluated_index, end_lookup.factor};
- const int size = end.right_index - start.left_index + 1;
+ const int num = end.right_index - start.left_index + 1;
linear_trim_data<float3>(start, end, spline.positions());
linear_trim_data<float>(start, end, spline.radii());
@@ -209,7 +209,7 @@ static void trim_poly_spline(Spline &spline,
},
ATTR_DOMAIN_POINT);
- spline.resize(size);
+ spline.resize(num);
}
/**
@@ -225,11 +225,11 @@ static PolySpline trim_nurbs_spline(const Spline &spline,
const TrimLocation end = {
end_lookup.evaluated_index, end_lookup.next_evaluated_index, end_lookup.factor};
- const int size = end.right_index - start.left_index + 1;
+ const int num = end.right_index - start.left_index + 1;
/* Create poly spline and copy trimmed data to it. */
PolySpline new_spline;
- new_spline.resize(size);
+ new_spline.resize(num);
/* Copy generic attribute data. */
spline.attributes.foreach_attribute(
@@ -283,7 +283,7 @@ static void trim_bezier_spline(Spline &spline,
const Span<int> control_offsets = bezier_spline.control_point_offsets();
/* The number of control points in the resulting spline. */
- const int size = end.right_index - start.left_index + 1;
+ const int num = end.right_index - start.left_index + 1;
/* Trim the spline attributes. Done before end.factor recalculation as it needs
* the original end.factor value. */
@@ -301,10 +301,10 @@ static void trim_bezier_spline(Spline &spline,
},
ATTR_DOMAIN_POINT);
- /* Recalculate end.factor if the size is two, because the adjustment in the
+ /* Recalculate end.factor if the `num` is two, because the adjustment in the
* position of the control point of the spline to the left of the new end point will change the
* factor between them. */
- if (size == 2) {
+ if (num == 2) {
if (start_lookup.factor == 1.0f) {
end.factor = 0.0f;
}
@@ -328,38 +328,38 @@ static void trim_bezier_spline(Spline &spline,
const BezierSpline::InsertResult end_point = bezier_spline.calculate_segment_insertion(
end.left_index, end.right_index, end.factor);
- /* If size is two, then the start point right handle needs to change to reflect the end point
+ /* If `num` is two, then the start point right handle needs to change to reflect the end point
* previous handle update. */
- if (size == 2) {
+ if (num == 2) {
start_point.right_handle = end_point.handle_prev;
}
/* Shift control point position data to start at beginning of array. */
if (start.left_index > 0) {
- shift_slice_to_start(bezier_spline.positions(), start.left_index, size);
- shift_slice_to_start(bezier_spline.handle_positions_left(), start.left_index, size);
- shift_slice_to_start(bezier_spline.handle_positions_right(), start.left_index, size);
+ shift_slice_to_start(bezier_spline.positions(), start.left_index, num);
+ shift_slice_to_start(bezier_spline.handle_positions_left(), start.left_index, num);
+ shift_slice_to_start(bezier_spline.handle_positions_right(), start.left_index, num);
}
bezier_spline.positions().first() = start_point.position;
- bezier_spline.positions()[size - 1] = end_point.position;
+ bezier_spline.positions()[num - 1] = end_point.position;
bezier_spline.handle_positions_left().first() = start_point.left_handle;
- bezier_spline.handle_positions_left()[size - 1] = end_point.left_handle;
+ bezier_spline.handle_positions_left()[num - 1] = end_point.left_handle;
bezier_spline.handle_positions_right().first() = start_point.right_handle;
- bezier_spline.handle_positions_right()[size - 1] = end_point.right_handle;
+ bezier_spline.handle_positions_right()[num - 1] = end_point.right_handle;
/* If there is at least one control point between the endpoints, update the control
* point handle to the right of the start point and to the left of the end point. */
- if (size > 2) {
+ if (num > 2) {
bezier_spline.handle_positions_left()[start.right_index - start.left_index] =
start_point.handle_next;
bezier_spline.handle_positions_right()[end.left_index - start.left_index] =
end_point.handle_prev;
}
- bezier_spline.resize(size);
+ bezier_spline.resize(num);
}
static void trim_spline(SplinePtr &spline,
@@ -506,9 +506,9 @@ static void geometry_set_curve_trim(GeometrySet &geometry_set,
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);
+ const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_CURVE);
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.add(start_field);
evaluator.add(end_field);
evaluator.evaluate();
@@ -527,7 +527,7 @@ static void geometry_set_curve_trim(GeometrySet &geometry_set,
continue;
}
- if (spline->evaluated_edges_size() == 0) {
+ if (spline->evaluated_edges_num() == 0) {
continue;
}
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 8a0c900fbde..5350896e93d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
@@ -57,7 +57,7 @@ static IndexMask index_mask_indices(Span<bool> mask, const bool invert, Vector<i
static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes,
const GeometryComponent &in_component,
GeometryComponent &result_component,
- const Span<AttributeDomain> domains)
+ const Span<eAttrDomain> domains)
{
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
@@ -70,7 +70,7 @@ static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes
if (!domains.contains(attribute.domain)) {
continue;
}
- const CustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
+ const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
OutputAttribute result_attribute = result_component.attribute_try_get_for_output_only(
attribute_id, attribute.domain, data_type);
@@ -96,7 +96,7 @@ static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes
static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKind> &attributes,
const GeometryComponent &in_component,
GeometryComponent &result_component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
const IndexMask mask)
{
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
@@ -110,7 +110,7 @@ static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKin
if (domain != attribute.domain) {
continue;
}
- const CustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
+ const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
OutputAttribute result_attribute = result_component.attribute_try_get_for_output_only(
attribute_id, attribute.domain, data_type);
@@ -132,7 +132,7 @@ static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKin
static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind> &attributes,
const GeometryComponent &in_component,
GeometryComponent &result_component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
const Span<int> index_map)
{
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
@@ -146,7 +146,7 @@ static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind
if (domain != attribute.domain) {
continue;
}
- const CustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
+ const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
OutputAttribute result_attribute = result_component.attribute_try_get_for_output_only(
attribute_id, attribute.domain, data_type);
@@ -400,7 +400,7 @@ static SplinePtr spline_delete(const Spline &spline, const IndexMask mask)
static std::unique_ptr<CurveEval> curve_separate(const CurveEval &input_curve,
const Span<bool> selection,
- const AttributeDomain selection_domain,
+ const eAttrDomain selection_domain,
const bool invert)
{
Span<SplinePtr> input_splines = input_curve.splines();
@@ -463,14 +463,14 @@ static std::unique_ptr<CurveEval> curve_separate(const CurveEval &input_curve,
static void separate_curve_selection(GeometrySet &geometry_set,
const Field<bool> &selection_field,
- const AttributeDomain selection_domain,
+ const eAttrDomain selection_domain,
const bool invert)
{
const CurveComponent &src_component = *geometry_set.get_component_for_read<CurveComponent>();
GeometryComponentFieldContext field_context{src_component, selection_domain};
fn::FieldEvaluator selection_evaluator{field_context,
- src_component.attribute_domain_size(selection_domain)};
+ src_component.attribute_domain_num(selection_domain)};
selection_evaluator.add(selection_field);
selection_evaluator.evaluate();
const VArray_Span<bool> &selection = selection_evaluator.get_evaluated<bool>(0);
@@ -493,7 +493,7 @@ static void separate_point_cloud_selection(GeometrySet &geometry_set,
GeometryComponentFieldContext field_context{src_points, ATTR_DOMAIN_POINT};
fn::FieldEvaluator selection_evaluator{field_context,
- src_points.attribute_domain_size(ATTR_DOMAIN_POINT)};
+ src_points.attribute_domain_num(ATTR_DOMAIN_POINT)};
selection_evaluator.add(selection_field);
selection_evaluator.evaluate();
const VArray_Span<bool> &selection = selection_evaluator.get_evaluated<bool>(0);
@@ -526,8 +526,8 @@ static void separate_instance_selection(GeometrySet &geometry_set,
InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
GeometryComponentFieldContext field_context{instances, ATTR_DOMAIN_INSTANCE};
- const int domain_size = instances.attribute_domain_size(ATTR_DOMAIN_INSTANCE);
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ const int domain_num = instances.attribute_domain_num(ATTR_DOMAIN_INSTANCE);
+ fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.add(selection_field);
evaluator.evaluate();
const VArray_Span<bool> &selection = evaluator.get_evaluated<bool>(0);
@@ -987,7 +987,7 @@ static void do_mesh_separation(GeometrySet &geometry_set,
const MeshComponent &in_component,
const VArray_Span<bool> &selection,
const bool invert,
- const AttributeDomain domain,
+ const eAttrDomain domain,
const GeometryNodeDeleteGeometryMode mode)
{
/* Needed in all cases. */
@@ -1230,7 +1230,7 @@ static void do_mesh_separation(GeometrySet &geometry_set,
static void separate_mesh_selection(GeometrySet &geometry_set,
const Field<bool> &selection_field,
- const AttributeDomain selection_domain,
+ const eAttrDomain selection_domain,
const GeometryNodeDeleteGeometryMode mode,
const bool invert)
{
@@ -1238,7 +1238,7 @@ static void separate_mesh_selection(GeometrySet &geometry_set,
GeometryComponentFieldContext field_context{src_component, selection_domain};
fn::FieldEvaluator selection_evaluator{field_context,
- src_component.attribute_domain_size(selection_domain)};
+ src_component.attribute_domain_num(selection_domain)};
selection_evaluator.add(selection_field);
selection_evaluator.evaluate();
const VArray_Span<bool> &selection = selection_evaluator.get_evaluated<bool>(0);
@@ -1263,7 +1263,7 @@ static void separate_mesh_selection(GeometrySet &geometry_set,
namespace blender::nodes {
void separate_geometry(GeometrySet &geometry_set,
- const AttributeDomain domain,
+ const eAttrDomain domain,
const GeometryNodeDeleteGeometryMode mode,
const Field<bool> &selection_field,
const bool invert,
@@ -1320,7 +1320,7 @@ static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
const bNode *node = static_cast<bNode *>(ptr->data);
const NodeGeometryDeleteGeometry &storage = node_storage(*node);
- const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain);
+ const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain);
uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
/* Only show the mode when it is relevant. */
@@ -1345,7 +1345,7 @@ static void node_geo_exec(GeoNodeExecParams params)
const Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
const NodeGeometryDeleteGeometry &storage = node_storage(params.node());
- const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain);
+ const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain);
const GeometryNodeDeleteGeometryMode mode = (GeometryNodeDeleteGeometryMode)storage.mode;
if (domain == ATTR_DOMAIN_INSTANCE) {
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 d9f29d1ef1c..f95601813a3 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
@@ -247,7 +247,7 @@ BLI_NOINLINE static void eliminate_points_based_on_mask(const Span<bool> elimina
BLI_NOINLINE static void interpolate_attribute(const Mesh &mesh,
const Span<float3> bary_coords,
const Span<int> looptri_indices,
- const AttributeDomain source_domain,
+ const eAttrDomain source_domain,
const GVArray &source_data,
GMutableSpan output_data)
{
@@ -293,7 +293,7 @@ BLI_NOINLINE static void propagate_existing_attributes(
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
- const CustomDataType output_data_type = entry.value.data_type;
+ const eCustomDataType output_data_type = entry.value.data_type;
ReadAttributeLookup source_attribute = mesh_component.attribute_try_get_for_read(attribute_id);
if (!source_attribute) {
@@ -396,13 +396,13 @@ static Array<float> calc_full_density_factors_with_selection(const MeshComponent
const Field<float> &density_field,
const Field<bool> &selection_field)
{
- const AttributeDomain attribute_domain = ATTR_DOMAIN_CORNER;
+ const eAttrDomain attribute_domain = ATTR_DOMAIN_CORNER;
GeometryComponentFieldContext field_context{component, attribute_domain};
- const int domain_size = component.attribute_domain_size(attribute_domain);
+ const int domain_num = component.attribute_domain_num(attribute_domain);
- Array<float> densities(domain_size, 0.0f);
+ Array<float> densities(domain_num, 0.0f);
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.set_selection(selection_field);
evaluator.add_with_destination(density_field, densities.as_mutable_span());
evaluator.evaluate();
diff --git a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc
index dcd9bcfb034..52156b59c51 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc
@@ -153,7 +153,7 @@ static void transfer_attributes(
continue;
}
- AttributeDomain out_domain;
+ eAttrDomain out_domain;
if (src_attribute.domain == ATTR_DOMAIN_FACE) {
out_domain = ATTR_DOMAIN_POINT;
}
@@ -164,7 +164,7 @@ static void transfer_attributes(
/* Edges and Face Corners. */
out_domain = src_attribute.domain;
}
- const CustomDataType data_type = bke::cpp_type_to_custom_data_type(
+ const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(
src_attribute.varray.type());
OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
attribute_id, out_domain, data_type);
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 4730109f3e3..cde40319388 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
@@ -144,7 +144,7 @@ static void threaded_id_offset_copy(const Span<int> offsets,
/** Create the copy indices for the duplication domain. */
static void create_duplicate_index_attribute(GeometryComponent &component,
- const AttributeDomain output_domain,
+ const eAttrDomain output_domain,
const IndexMask selection,
const IndexAttributes &attribute_outputs,
const Span<int> offsets)
@@ -208,8 +208,8 @@ static void copy_point_attributes_without_id(GeometrySet &geometry_set,
if (!src_attribute || src_attribute.domain != ATTR_DOMAIN_POINT) {
continue;
}
- AttributeDomain out_domain = src_attribute.domain;
- const CustomDataType data_type = bke::cpp_type_to_custom_data_type(
+ eAttrDomain out_domain = src_attribute.domain;
+ const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(
src_attribute.varray.type());
OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
attribute_id, out_domain, data_type);
@@ -254,8 +254,8 @@ static void copy_curve_attributes_without_id(const GeometrySet &geometry_set,
continue;
}
- AttributeDomain out_domain = src_attribute.domain;
- const CustomDataType data_type = bke::cpp_type_to_custom_data_type(
+ eAttrDomain out_domain = src_attribute.domain;
+ const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(
src_attribute.varray.type());
OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
attribute_id, out_domain, data_type);
@@ -359,19 +359,19 @@ static void duplicate_curves(GeometrySet &geometry_set,
Array<int> curve_offsets(selection.size() + 1);
Array<int> point_offsets(selection.size() + 1);
- int dst_curves_size = 0;
- int dst_points_size = 0;
+ int dst_curves_num = 0;
+ int dst_points_num = 0;
for (const int i_curve : selection.index_range()) {
const int count = std::max(counts[selection[i_curve]], 0);
- curve_offsets[i_curve] = dst_curves_size;
- point_offsets[i_curve] = dst_points_size;
- dst_curves_size += count;
- dst_points_size += count * curves.points_for_curve(selection[i_curve]).size();
+ curve_offsets[i_curve] = dst_curves_num;
+ point_offsets[i_curve] = dst_points_num;
+ dst_curves_num += count;
+ dst_points_num += count * curves.points_for_curve(selection[i_curve]).size();
}
- curve_offsets.last() = dst_curves_size;
- point_offsets.last() = dst_points_size;
+ curve_offsets.last() = dst_curves_num;
+ point_offsets.last() = dst_points_num;
- Curves *new_curves_id = bke::curves_new_nomain(dst_points_size, dst_curves_size);
+ Curves *new_curves_id = bke::curves_new_nomain(dst_points_num, dst_curves_num);
bke::CurvesGeometry &new_curves = bke::CurvesGeometry::wrap(new_curves_id->geometry);
MutableSpan<int> all_dst_offsets = new_curves.offsets_for_write();
@@ -387,7 +387,7 @@ static void duplicate_curves(GeometrySet &geometry_set,
}
}
});
- all_dst_offsets.last() = dst_points_size;
+ all_dst_offsets.last() = dst_points_num;
CurveComponent dst_component;
dst_component.replace(new_curves_id, GeometryOwnershipType::Editable);
@@ -435,8 +435,8 @@ static void copy_face_attributes_without_id(GeometrySet &geometry_set,
continue;
}
- AttributeDomain out_domain = src_attribute.domain;
- const CustomDataType data_type = bke::cpp_type_to_custom_data_type(
+ eAttrDomain out_domain = src_attribute.domain;
+ const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(
src_attribute.varray.type());
OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
attribute_id, out_domain, data_type);
@@ -648,8 +648,8 @@ static void copy_edge_attributes_without_id(GeometrySet &geometry_set,
continue;
}
- const AttributeDomain out_domain = src_attribute.domain;
- const CustomDataType data_type = bke::cpp_type_to_custom_data_type(
+ const eAttrDomain out_domain = src_attribute.domain;
+ const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(
src_attribute.varray.type());
OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
attribute_id, out_domain, data_type);
@@ -818,23 +818,23 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
Array<int> offsets = accumulate_counts_to_offsets(selection, counts);
- const int dst_size = offsets.last();
+ const int dst_num = offsets.last();
Array<int> point_to_curve_map(src_curves.points_num());
threading::parallel_for(src_curves.curves_range(), 1024, [&](const IndexRange range) {
for (const int i_curve : range) {
- const IndexRange point_range = src_curves.points_for_curve(i_curve);
- point_to_curve_map.as_mutable_span().slice(point_range).fill(i_curve);
+ const IndexRange points = src_curves.points_for_curve(i_curve);
+ point_to_curve_map.as_mutable_span().slice(points).fill(i_curve);
}
});
- Curves *new_curves_id = bke::curves_new_nomain(dst_size, dst_size);
+ Curves *new_curves_id = bke::curves_new_nomain(dst_num, dst_num);
bke::CurvesGeometry &new_curves = bke::CurvesGeometry::wrap(new_curves_id->geometry);
MutableSpan<int> new_curve_offsets = new_curves.offsets_for_write();
for (const int i : new_curves.curves_range()) {
new_curve_offsets[i] = i;
}
- new_curve_offsets.last() = dst_size;
+ new_curve_offsets.last() = dst_num;
CurveComponent dst_component;
dst_component.replace(new_curves_id, GeometryOwnershipType::Editable);
@@ -849,8 +849,8 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
continue;
}
- AttributeDomain domain = src_attribute.domain;
- const CustomDataType data_type = bke::cpp_type_to_custom_data_type(
+ eAttrDomain domain = src_attribute.domain;
+ const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(
src_attribute.varray.type());
OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
attribute_id, domain, data_type);
@@ -956,10 +956,10 @@ static void duplicate_points_pointcloud(GeometrySet &geometry_set,
{
const PointCloudComponent &src_points =
*geometry_set.get_component_for_read<PointCloudComponent>();
- const int point_size = src_points.attribute_domain_size(ATTR_DOMAIN_POINT);
+ const int point_num = src_points.attribute_domain_num(ATTR_DOMAIN_POINT);
GeometryComponentFieldContext field_context{src_points, ATTR_DOMAIN_POINT};
- FieldEvaluator evaluator{field_context, point_size};
+ FieldEvaluator evaluator{field_context, point_num};
evaluator.add(count_field);
evaluator.set_selection(selection_field);
evaluator.evaluate();
@@ -1047,7 +1047,7 @@ static void duplicate_instances(GeometrySet &geometry_set,
*geometry_set.get_component_for_read<InstancesComponent>();
GeometryComponentFieldContext field_context{src_instances, ATTR_DOMAIN_INSTANCE};
- FieldEvaluator evaluator{field_context, src_instances.instances_amount()};
+ FieldEvaluator evaluator{field_context, src_instances.instances_num()};
evaluator.add(count_field);
evaluator.set_selection(selection_field);
evaluator.evaluate();
@@ -1103,7 +1103,7 @@ static void node_geo_exec(GeoNodeExecParams params)
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
const NodeGeometryDuplicateElements &storage = node_storage(params.node());
- const AttributeDomain duplicate_domain = AttributeDomain(storage.domain);
+ const eAttrDomain duplicate_domain = eAttrDomain(storage.domain);
Field<int> count_field = params.extract_input<Field<int>>("Amount");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
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..94fbec66bfe 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc
@@ -57,8 +57,8 @@ static void node_geo_exec(GeoNodeExecParams params)
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};
+ const int domain_num = mesh_component.attribute_domain_num(ATTR_DOMAIN_EDGE);
+ fn::FieldEvaluator selection_evaluator{field_context, domain_num};
selection_evaluator.add(selection_field);
selection_evaluator.evaluate();
const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
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 75c29ca969c..3e2e07cb772 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
@@ -63,7 +63,7 @@ struct AttributeOutputs {
static void save_selection_as_attribute(MeshComponent &component,
const AnonymousAttributeID *id,
- const AttributeDomain domain,
+ const eAttrDomain domain,
const IndexMask selection)
{
BLI_assert(!component.attribute_exists(id));
@@ -109,7 +109,7 @@ static MutableSpan<MLoop> mesh_loops(Mesh &mesh)
}
/**
- * \note: Some areas in this file rely on the new sections of attributes from #CustomData_realloc
+ * \note Some areas in this file rely on the new sections of attributes from #CustomData_realloc
* to be zeroed.
*/
static void expand_mesh(Mesh &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 77be98f169e..58281df43d3 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
@@ -42,7 +42,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
- const CustomDataType data_type = static_cast<CustomDataType>(node->custom2);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(node->custom2);
bNodeSocket *sock_index = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *sock_in_float = sock_index->next;
@@ -74,10 +74,10 @@ class FieldAtIndex final : public GeometryFieldInput {
private:
Field<int> index_field_;
GField value_field_;
- AttributeDomain value_field_domain_;
+ eAttrDomain value_field_domain_;
public:
- FieldAtIndex(Field<int> index_field, GField value_field, AttributeDomain value_field_domain)
+ FieldAtIndex(Field<int> index_field, GField value_field, eAttrDomain value_field_domain)
: GeometryFieldInput(value_field.cpp_type(), "Field at Index"),
index_field_(std::move(index_field)),
value_field_(std::move(value_field)),
@@ -86,12 +86,12 @@ class FieldAtIndex final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask mask) const final
{
const GeometryComponentFieldContext value_field_context{component, value_field_domain_};
FieldEvaluator value_evaluator{value_field_context,
- component.attribute_domain_size(value_field_domain_)};
+ component.attribute_domain_num(value_field_domain_)};
value_evaluator.add(value_field_);
value_evaluator.evaluate();
const GVArray &values = value_evaluator.get_evaluated(0);
@@ -125,7 +125,7 @@ class FieldAtIndex final : public GeometryFieldInput {
}
};
-static StringRefNull identifier_suffix(CustomDataType data_type)
+static StringRefNull identifier_suffix(eCustomDataType data_type)
{
switch (data_type) {
case CD_PROP_BOOL:
@@ -147,8 +147,8 @@ static StringRefNull identifier_suffix(CustomDataType data_type)
static void node_geo_exec(GeoNodeExecParams params)
{
const bNode &node = params.node();
- const AttributeDomain domain = static_cast<AttributeDomain>(node.custom1);
- const CustomDataType data_type = static_cast<CustomDataType>(node.custom2);
+ const eAttrDomain domain = static_cast<eAttrDomain>(node.custom1);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(node.custom2);
Field<int> index_field = params.extract_input<Field<int>>("Index");
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
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 34c3169065c..0484017cf3b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc
@@ -22,11 +22,11 @@ static void node_declare(NodeDeclarationBuilder &b)
static void mesh_flip_faces(MeshComponent &component, 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) {
+ const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_FACE);
+ if (domain_num == 0) {
return;
}
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
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_input_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc
index 3ba1378abe1..da249278867 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
@@ -26,7 +26,7 @@ class HandlePositionFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask mask) const final
{
if (component.type() != GEO_COMPONENT_TYPE_CURVE) {
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 60640bcb112..f27e0305c7d 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
@@ -61,7 +61,7 @@ class AngleFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask UNUSED(mask)) const final
{
if (component.type() != GEO_COMPONENT_TYPE_MESH) {
@@ -115,7 +115,7 @@ class SignedAngleFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask UNUSED(mask)) const final
{
if (component.type() != GEO_COMPONENT_TYPE_MESH) {
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 92172ce7ebd..cbc2ebc3e68 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
@@ -25,7 +25,7 @@ class EdgeNeighborCountFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask UNUSED(mask)) const final
{
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
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 213a692d80f..6201ad26bfb 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
@@ -29,7 +29,7 @@ enum VertexNumber { VERTEX_ONE, VERTEX_TWO };
static VArray<int> construct_edge_vertices_gvarray(const MeshComponent &component,
const VertexNumber vertex,
- const AttributeDomain domain)
+ const eAttrDomain domain)
{
const Mesh *mesh = component.get_for_read();
if (mesh == nullptr) {
@@ -58,7 +58,7 @@ class EdgeVerticesFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask UNUSED(mask)) const final
{
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
@@ -85,7 +85,7 @@ class EdgeVerticesFieldInput final : public GeometryFieldInput {
static VArray<float3> construct_edge_positions_gvarray(const MeshComponent &component,
const VertexNumber vertex,
- const AttributeDomain domain)
+ const eAttrDomain domain)
{
const Mesh *mesh = component.get_for_read();
if (mesh == nullptr) {
@@ -120,7 +120,7 @@ class EdgePositionFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask UNUSED(mask)) const final
{
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
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 6f58d28100a..7a0e3e37a65 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
@@ -17,7 +17,7 @@ static void node_declare(NodeDeclarationBuilder &b)
}
static VArray<float> construct_face_area_gvarray(const MeshComponent &component,
- const AttributeDomain domain)
+ const eAttrDomain domain)
{
const Mesh *mesh = component.get_for_read();
if (mesh == nullptr) {
@@ -41,7 +41,7 @@ class FaceAreaFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask UNUSED(mask)) const final
{
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
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 62af0476057..c400760f902 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
@@ -34,7 +34,7 @@ class PlanarFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
[[maybe_unused]] IndexMask mask) const final
{
if (component.type() != GEO_COMPONENT_TYPE_MESH) {
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 9968c53f649..67a21cb06f0 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
@@ -20,7 +20,7 @@ static void node_declare(NodeDeclarationBuilder &b)
}
static VArray<int> construct_neighbor_count_gvarray(const MeshComponent &component,
- const AttributeDomain domain)
+ const eAttrDomain domain)
{
const Mesh *mesh = component.get_for_read();
if (mesh == nullptr) {
@@ -53,7 +53,7 @@ class FaceNeighborCountFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask UNUSED(mask)) const final
{
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
@@ -76,7 +76,7 @@ class FaceNeighborCountFieldInput final : public GeometryFieldInput {
};
static VArray<int> construct_vertex_count_gvarray(const MeshComponent &component,
- const AttributeDomain domain)
+ const eAttrDomain domain)
{
const Mesh *mesh = component.get_for_read();
if (mesh == nullptr) {
@@ -98,7 +98,7 @@ class FaceVertexCountFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask UNUSED(mask)) const final
{
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
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 d39291a2a7e..bd57924d685 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
@@ -30,7 +30,7 @@ class IslandFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask UNUSED(mask)) const final
{
if (component.type() != GEO_COMPONENT_TYPE_MESH) {
@@ -78,7 +78,7 @@ class IslandCountFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask UNUSED(mask)) const final
{
if (component.type() != GEO_COMPONENT_TYPE_MESH) {
@@ -101,8 +101,7 @@ class IslandCountFieldInput final : public GeometryFieldInput {
island_list.add(root);
}
- return VArray<int>::ForSingle(island_list.size(),
- mesh_component.attribute_domain_size(domain));
+ return VArray<int>::ForSingle(island_list.size(), mesh_component.attribute_domain_num(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 b81016eda18..62b3f9d0e92 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
@@ -21,7 +21,7 @@ static void node_declare(NodeDeclarationBuilder &b)
}
static VArray<int> construct_vertex_count_gvarray(const MeshComponent &component,
- const AttributeDomain domain)
+ const eAttrDomain domain)
{
const Mesh *mesh = component.get_for_read();
if (mesh == nullptr) {
@@ -47,7 +47,7 @@ class VertexCountFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask UNUSED(mask)) const final
{
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
@@ -70,7 +70,7 @@ class VertexCountFieldInput final : public GeometryFieldInput {
};
static VArray<int> construct_face_count_gvarray(const MeshComponent &component,
- const AttributeDomain domain)
+ const eAttrDomain domain)
{
const Mesh *mesh = component.get_for_read();
if (mesh == nullptr) {
@@ -96,7 +96,7 @@ class VertexFaceCountFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask UNUSED(mask)) const final
{
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc
index 72dfff7cb39..122c7b352c7 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc
@@ -37,7 +37,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryInputNamedAttribute &storage = node_storage(*node);
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
bNodeSocket *socket_vector = (bNodeSocket *)node->outputs.first;
bNodeSocket *socket_float = socket_vector->next;
@@ -58,7 +58,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
search_link_ops_for_declarations(params, declaration.inputs());
if (params.in_out() == SOCK_OUT) {
- const std::optional<CustomDataType> type = node_data_type_to_custom_data_type(
+ const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type(
static_cast<eNodeSocketDatatype>(params.other_socket().type));
if (type && *type != CD_PROP_STRING) {
/* The input and output sockets have the same name. */
@@ -74,7 +74,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
static void node_geo_exec(GeoNodeExecParams params)
{
const NodeGeometryInputNamedAttribute &storage = node_storage(params.node());
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
const std::string name = params.extract_input<std::string>("Name");
@@ -82,8 +82,13 @@ static void node_geo_exec(GeoNodeExecParams params)
params.set_default_remaining_outputs();
return;
}
+ if (!bke::allow_procedural_attribute_access(name)) {
+ params.error_message_add(NodeWarningType::Info, TIP_(bke::no_procedural_access_message));
+ params.set_default_remaining_outputs();
+ return;
+ }
- params.used_named_attribute(name, NamedAttributeUsage::Read);
+ params.used_named_attribute(name, eNamedAttrUsage::Read);
switch (data_type) {
case CD_PROP_FLOAT:
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 6c24f86b63b..def82eefca5 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
@@ -4,71 +4,6 @@
#include "BKE_curves.hh"
-namespace blender::nodes {
-
-/* --------------------------------------------------------------------
- * Spline Length
- */
-
-static VArray<float> construct_spline_length_gvarray(const CurveComponent &component,
- const AttributeDomain domain)
-{
- if (!component.has_curves()) {
- return {};
- }
- const Curves &curves_id = *component.get_for_read();
- const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
-
- curves.ensure_evaluated_lengths();
-
- VArray<bool> cyclic = curves.cyclic();
- VArray<float> lengths = VArray<float>::ForFunc(
- curves.curves_num(), [&curves, cyclic = std::move(cyclic)](int64_t index) {
- return curves.evaluated_length_total_for_curve(index, cyclic[index]);
- });
-
- if (domain == ATTR_DOMAIN_CURVE) {
- return lengths;
- }
-
- if (domain == ATTR_DOMAIN_POINT) {
- return component.attribute_try_adapt_domain<float>(
- std::move(lengths), ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT);
- }
-
- return {};
-}
-
-SplineLengthFieldInput::SplineLengthFieldInput()
- : GeometryFieldInput(CPPType::get<float>(), "Spline Length node")
-{
- category_ = Category::Generated;
-}
-
-GVArray SplineLengthFieldInput::get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
- IndexMask UNUSED(mask)) const
-{
- if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
- const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
- return construct_spline_length_gvarray(curve_component, domain);
- }
- return {};
-}
-
-uint64_t SplineLengthFieldInput::hash() const
-{
- /* Some random constant hash. */
- return 3549623580;
-}
-
-bool SplineLengthFieldInput::is_equal_to(const fn::FieldNode &other) const
-{
- return dynamic_cast<const SplineLengthFieldInput *>(&other) != nullptr;
-}
-
-} // namespace blender::nodes
-
namespace blender::nodes::node_geo_input_spline_length_cc {
static void node_declare(NodeDeclarationBuilder &b)
@@ -81,8 +16,8 @@ static void node_declare(NodeDeclarationBuilder &b)
* Spline Count
*/
-static VArray<int> construct_spline_count_gvarray(const CurveComponent &component,
- const AttributeDomain domain)
+static VArray<int> construct_curve_point_count_gvarray(const CurveComponent &component,
+ const eAttrDomain domain)
{
if (!component.has_curves()) {
return {};
@@ -112,12 +47,12 @@ class SplineCountFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ 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_spline_count_gvarray(curve_component, domain);
+ return construct_curve_point_count_gvarray(curve_component, domain);
}
return {};
}
@@ -136,7 +71,7 @@ class SplineCountFieldInput final : public GeometryFieldInput {
static void node_geo_exec(GeoNodeExecParams params)
{
- Field<float> spline_length_field{std::make_shared<SplineLengthFieldInput>()};
+ Field<float> spline_length_field{std::make_shared<bke::CurveLengthFieldInput>()};
Field<int> spline_count_field{std::make_shared<SplineCountFieldInput>()};
params.set_output("Length", std::move(spline_length_field));
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 039d6b69585..f5831941094 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
@@ -64,7 +64,7 @@ static Array<float3> curve_tangent_point_domain(const bke::CurvesGeometry &curve
}
static VArray<float3> construct_curve_tangent_gvarray(const CurveComponent &component,
- const AttributeDomain domain)
+ const eAttrDomain domain)
{
if (!component.has_curves()) {
return {};
@@ -101,7 +101,7 @@ class TangentFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask UNUSED(mask)) const final
{
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
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 61f719ade4e..21ef8765e43 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
@@ -49,8 +49,8 @@ static void add_instances_from_component(
const GeoNodeExecParams &params,
const Map<AttributeIDRef, AttributeKind> &attributes_to_propagate)
{
- const AttributeDomain domain = ATTR_DOMAIN_POINT;
- const int domain_size = src_component.attribute_domain_size(domain);
+ const eAttrDomain domain = ATTR_DOMAIN_POINT;
+ const int domain_num = src_component.attribute_domain_num(domain);
VArray<bool> pick_instance;
VArray<int> indices;
@@ -59,7 +59,7 @@ static void add_instances_from_component(
GeometryComponentFieldContext field_context{src_component, domain};
const Field<bool> selection_field = params.get_input<Field<bool>>("Selection");
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.set_selection(selection_field);
/* The evaluator could use the component's stable IDs as a destination directly, but only the
* selected indices should be copied. */
@@ -73,7 +73,7 @@ static void add_instances_from_component(
/* The initial size of the component might be non-zero when this function is called for multiple
* component types. */
- const int start_len = dst_component.instances_amount();
+ const int start_len = dst_component.instances_num();
const int select_len = selection.index_range().size();
dst_component.resize(start_len + select_len);
@@ -119,12 +119,12 @@ static void add_instances_from_component(
const bool use_individual_instance = pick_instance[i];
if (use_individual_instance) {
if (src_instances != nullptr) {
- const int src_instances_amount = src_instances->instances_amount();
+ const int src_instances_num = src_instances->instances_num();
const int original_index = indices[i];
/* Use #mod_i instead of `%` to get the desirable wrap around behavior where -1
* refers to the last element. */
- const int index = mod_i(original_index, std::max(src_instances_amount, 1));
- if (index < src_instances_amount) {
+ const int index = mod_i(original_index, std::max(src_instances_num, 1));
+ if (index < src_instances_num) {
/* Get the reference to the source instance. */
const int src_handle = src_instances->instance_reference_handles()[index];
dst_handle = handle_mapping[src_handle];
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 e35f152ce49..2126a5cc329 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
@@ -40,9 +40,9 @@ 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.attribute_domain_size(ATTR_DOMAIN_INSTANCE);
+ const int domain_num = instances.attribute_domain_num(ATTR_DOMAIN_INSTANCE);
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_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_join_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
index 0e2803cd035..0c56b0e9804 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
@@ -47,8 +47,8 @@ static Map<AttributeIDRef, AttributeMetaData> get_final_attribute_info(
static void fill_new_attribute(Span<const GeometryComponent *> src_components,
const AttributeIDRef &attribute_id,
- const CustomDataType data_type,
- const AttributeDomain domain,
+ const eCustomDataType data_type,
+ const eAttrDomain domain,
GMutableSpan dst_span)
{
const CPPType *cpp_type = bke::custom_data_type_to_cpp_type(data_type);
@@ -56,8 +56,8 @@ static void fill_new_attribute(Span<const GeometryComponent *> src_components,
int offset = 0;
for (const GeometryComponent *component : src_components) {
- const int domain_size = component->attribute_domain_size(domain);
- if (domain_size == 0) {
+ const int domain_num = component->attribute_domain_num(domain);
+ if (domain_num == 0) {
continue;
}
GVArray read_attribute = component->attribute_get_for_read(
@@ -66,9 +66,9 @@ static void fill_new_attribute(Span<const GeometryComponent *> src_components,
GVArray_GSpan src_span{read_attribute};
const void *src_buffer = src_span.data();
void *dst_buffer = dst_span[offset];
- cpp_type->copy_assign_n(src_buffer, dst_buffer, domain_size);
+ cpp_type->copy_assign_n(src_buffer, dst_buffer, domain_num);
- offset += domain_size;
+ offset += domain_num;
}
}
@@ -101,7 +101,7 @@ static void join_components(Span<const InstancesComponent *> src_components, Geo
int tot_instances = 0;
for (const InstancesComponent *src_component : src_components) {
- tot_instances += src_component->instances_amount();
+ tot_instances += src_component->instances_num();
}
dst_component.reserve(tot_instances);
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 c245260f259..5875606da97 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
@@ -51,7 +51,7 @@ class MaterialSelectionFieldInput final : public GeometryFieldInput {
}
GVArray get_varray_for_context(const GeometryComponent &component,
- const AttributeDomain domain,
+ const eAttrDomain domain,
IndexMask mask) const final
{
if (component.type() != GEO_COMPONENT_TYPE_MESH) {
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 1ec97858d4d..1def4089115 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
@@ -39,9 +39,9 @@ static PointCloud *pointcloud_merge_by_distance(const PointCloudComponent &src_p
const float merge_distance,
const Field<bool> &selection_field)
{
- const int src_size = src_points.attribute_domain_size(ATTR_DOMAIN_POINT);
+ const int src_num = src_points.attribute_domain_num(ATTR_DOMAIN_POINT);
GeometryComponentFieldContext context{src_points, ATTR_DOMAIN_POINT};
- FieldEvaluator evaluator{context, src_size};
+ FieldEvaluator evaluator{context, src_num};
evaluator.add(selection_field);
evaluator.evaluate();
@@ -57,10 +57,10 @@ static std::optional<Mesh *> mesh_merge_by_distance_connected(const MeshComponen
const float merge_distance,
const Field<bool> &selection_field)
{
- const int src_size = mesh_component.attribute_domain_size(ATTR_DOMAIN_POINT);
- Array<bool> selection(src_size);
+ const int src_num = mesh_component.attribute_domain_num(ATTR_DOMAIN_POINT);
+ Array<bool> selection(src_num);
GeometryComponentFieldContext context{mesh_component, ATTR_DOMAIN_POINT};
- FieldEvaluator evaluator{context, src_size};
+ FieldEvaluator evaluator{context, src_num};
evaluator.add_with_destination(selection_field, selection.as_mutable_span());
evaluator.evaluate();
@@ -72,9 +72,9 @@ static std::optional<Mesh *> mesh_merge_by_distance_all(const MeshComponent &mes
const float merge_distance,
const Field<bool> &selection_field)
{
- const int src_size = mesh_component.attribute_domain_size(ATTR_DOMAIN_POINT);
+ const int src_num = mesh_component.attribute_domain_num(ATTR_DOMAIN_POINT);
GeometryComponentFieldContext context{mesh_component, ATTR_DOMAIN_POINT};
- FieldEvaluator evaluator{context, src_size};
+ FieldEvaluator evaluator{context, src_num};
evaluator.add(selection_field);
evaluator.evaluate();
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc
index 636ecb8ab41..0029b547375 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc
@@ -6,414 +6,9 @@
#include "BKE_material.h"
#include "BKE_mesh.h"
-#include "node_geometry_util.hh"
-
-namespace blender::nodes {
-
-struct CuboidConfig {
- float3 size;
- int verts_x;
- int verts_y;
- int verts_z;
- int edges_x;
- int edges_y;
- int edges_z;
- int vertex_count;
- int poly_count;
- int loop_count;
-
- CuboidConfig(float3 size, int verts_x, int verts_y, int verts_z)
- : size(size),
- verts_x(verts_x),
- verts_y(verts_y),
- verts_z(verts_z),
- edges_x(verts_x - 1),
- edges_y(verts_y - 1),
- edges_z(verts_z - 1)
- {
- BLI_assert(edges_x > 0 && edges_y > 0 && edges_z > 0);
- this->vertex_count = this->get_vertex_count();
- this->poly_count = this->get_poly_count();
- this->loop_count = this->poly_count * 4;
- }
-
- private:
- int get_vertex_count()
- {
- const int inner_position_count = (verts_x - 2) * (verts_y - 2) * (verts_z - 2);
- return verts_x * verts_y * verts_z - inner_position_count;
- }
-
- int get_poly_count()
- {
- return 2 * (edges_x * edges_y + edges_y * edges_z + edges_z * edges_x);
- }
-};
-
-static void calculate_vertices(const CuboidConfig &config, MutableSpan<MVert> verts)
-{
- const float z_bottom = -config.size.z / 2.0f;
- const float z_delta = config.size.z / config.edges_z;
-
- const float x_left = -config.size.x / 2.0f;
- const float x_delta = config.size.x / config.edges_x;
-
- const float y_front = -config.size.y / 2.0f;
- const float y_delta = config.size.y / config.edges_y;
-
- int vert_index = 0;
-
- for (const int z : IndexRange(config.verts_z)) {
- if (ELEM(z, 0, config.edges_z)) {
- /* Fill bottom and top. */
- const float z_pos = z_bottom + z_delta * z;
- for (const int y : IndexRange(config.verts_y)) {
- const float y_pos = y_front + y_delta * y;
- for (const int x : IndexRange(config.verts_x)) {
- const float x_pos = x_left + x_delta * x;
- copy_v3_v3(verts[vert_index++].co, float3(x_pos, y_pos, z_pos));
- }
- }
- }
- else {
- for (const int y : IndexRange(config.verts_y)) {
- if (ELEM(y, 0, config.edges_y)) {
- /* Fill y-sides. */
- const float y_pos = y_front + y_delta * y;
- const float z_pos = z_bottom + z_delta * z;
- for (const int x : IndexRange(config.verts_x)) {
- const float x_pos = x_left + x_delta * x;
- copy_v3_v3(verts[vert_index++].co, float3(x_pos, y_pos, z_pos));
- }
- }
- else {
- /* Fill x-sides. */
- const float x_pos = x_left;
- const float y_pos = y_front + y_delta * y;
- const float z_pos = z_bottom + z_delta * z;
- copy_v3_v3(verts[vert_index++].co, float3(x_pos, y_pos, z_pos));
- const float x_pos2 = x_left + x_delta * config.edges_x;
- copy_v3_v3(verts[vert_index++].co, float3(x_pos2, y_pos, z_pos));
- }
- }
- }
- }
-}
-
-/* vert_1 = bottom left, vert_2 = bottom right, vert_3 = top right, vert_4 = top left.
- * Hence they are passed as 1,4,3,2 when calculating polys clockwise, and 1,2,3,4 for
- * anti-clockwise.
- */
-static void define_quad(MutableSpan<MPoly> polys,
- MutableSpan<MLoop> loops,
- const int poly_index,
- const int loop_index,
- const int vert_1,
- const int vert_2,
- const int vert_3,
- const int vert_4)
-{
- MPoly &poly = polys[poly_index];
- poly.loopstart = loop_index;
- poly.totloop = 4;
-
- MLoop &loop_1 = loops[loop_index];
- loop_1.v = vert_1;
- MLoop &loop_2 = loops[loop_index + 1];
- loop_2.v = vert_2;
- MLoop &loop_3 = loops[loop_index + 2];
- loop_3.v = vert_3;
- MLoop &loop_4 = loops[loop_index + 3];
- loop_4.v = vert_4;
-}
-
-static void calculate_polys(const CuboidConfig &config,
- MutableSpan<MPoly> polys,
- MutableSpan<MLoop> loops)
-{
- int loop_index = 0;
- int poly_index = 0;
-
- /* Number of vertices in an XY cross-section of the cube (barring top and bottom faces). */
- const int xy_cross_section_vert_count = config.verts_x * config.verts_y -
- (config.verts_x - 2) * (config.verts_y - 2);
+#include "GEO_mesh_primitive_cuboid.hh"
- /* Calculate polys for Bottom faces. */
- int vert_1_start = 0;
-
- for ([[maybe_unused]] const int y : IndexRange(config.edges_y)) {
- for (const int x : IndexRange(config.edges_x)) {
- const int vert_1 = vert_1_start + x;
- const int vert_2 = vert_1_start + config.verts_x + x;
- const int vert_3 = vert_2 + 1;
- const int vert_4 = vert_1 + 1;
-
- define_quad(polys, loops, poly_index, loop_index, vert_1, vert_2, vert_3, vert_4);
- loop_index += 4;
- poly_index++;
- }
- vert_1_start += config.verts_x;
- }
-
- /* Calculate polys for Front faces. */
- vert_1_start = 0;
- int vert_2_start = config.verts_x * config.verts_y;
-
- for ([[maybe_unused]] const int z : IndexRange(config.edges_z)) {
- for (const int x : IndexRange(config.edges_x)) {
- define_quad(polys,
- loops,
- poly_index,
- loop_index,
- vert_1_start + x,
- vert_1_start + x + 1,
- vert_2_start + x + 1,
- vert_2_start + x);
- loop_index += 4;
- poly_index++;
- }
- vert_1_start = vert_2_start;
- vert_2_start += config.verts_x * config.verts_y - (config.verts_x - 2) * (config.verts_y - 2);
- }
-
- /* Calculate polys for Top faces. */
- vert_1_start = config.verts_x * config.verts_y +
- (config.verts_z - 2) * (config.verts_x * config.verts_y -
- (config.verts_x - 2) * (config.verts_y - 2));
- vert_2_start = vert_1_start + config.verts_x;
-
- for ([[maybe_unused]] const int y : IndexRange(config.edges_y)) {
- for (const int x : IndexRange(config.edges_x)) {
- define_quad(polys,
- loops,
- poly_index,
- loop_index,
- vert_1_start + x,
- vert_1_start + x + 1,
- vert_2_start + x + 1,
- vert_2_start + x);
- loop_index += 4;
- poly_index++;
- }
- vert_2_start += config.verts_x;
- vert_1_start += config.verts_x;
- }
-
- /* Calculate polys for Back faces. */
- vert_1_start = config.verts_x * config.edges_y;
- vert_2_start = vert_1_start + xy_cross_section_vert_count;
-
- for (const int z : IndexRange(config.edges_z)) {
- if (z == (config.edges_z - 1)) {
- vert_2_start += (config.verts_x - 2) * (config.verts_y - 2);
- }
- for (const int x : IndexRange(config.edges_x)) {
- define_quad(polys,
- loops,
- poly_index,
- loop_index,
- vert_1_start + x,
- vert_2_start + x,
- vert_2_start + x + 1,
- vert_1_start + x + 1);
- loop_index += 4;
- poly_index++;
- }
- vert_2_start += xy_cross_section_vert_count;
- vert_1_start += xy_cross_section_vert_count;
- }
-
- /* Calculate polys for Left faces. */
- vert_1_start = 0;
- vert_2_start = config.verts_x * config.verts_y;
-
- for (const int z : IndexRange(config.edges_z)) {
- for (const int y : IndexRange(config.edges_y)) {
- int vert_1;
- int vert_2;
- int vert_3;
- int vert_4;
-
- if (z == 0 || y == 0) {
- vert_1 = vert_1_start + config.verts_x * y;
- vert_4 = vert_1 + config.verts_x;
- }
- else {
- vert_1 = vert_1_start + 2 * y;
- vert_1 += config.verts_x - 2;
- vert_4 = vert_1 + 2;
- }
-
- if (y == 0 || z == (config.edges_z - 1)) {
- vert_2 = vert_2_start + config.verts_x * y;
- vert_3 = vert_2 + config.verts_x;
- }
- else {
- vert_2 = vert_2_start + 2 * y;
- vert_2 += config.verts_x - 2;
- vert_3 = vert_2 + 2;
- }
-
- define_quad(polys, loops, poly_index, loop_index, vert_1, vert_2, vert_3, vert_4);
- loop_index += 4;
- poly_index++;
- }
- if (z == 0) {
- vert_1_start += config.verts_x * config.verts_y;
- }
- else {
- vert_1_start += xy_cross_section_vert_count;
- }
- vert_2_start += xy_cross_section_vert_count;
- }
-
- /* Calculate polys for Right faces. */
- vert_1_start = config.edges_x;
- vert_2_start = vert_1_start + config.verts_x * config.verts_y;
-
- for (const int z : IndexRange(config.edges_z)) {
- for (const int y : IndexRange(config.edges_y)) {
- int vert_1 = vert_1_start;
- int vert_2 = vert_2_start;
- int vert_3 = vert_2_start + 2;
- int vert_4 = vert_1 + config.verts_x;
-
- if (z == 0) {
- vert_1 = vert_1_start + config.verts_x * y;
- vert_4 = vert_1 + config.verts_x;
- }
- else {
- vert_1 = vert_1_start + 2 * y;
- vert_4 = vert_1 + 2;
- }
-
- if (z == (config.edges_z - 1)) {
- vert_2 = vert_2_start + config.verts_x * y;
- vert_3 = vert_2 + config.verts_x;
- }
- else {
- vert_2 = vert_2_start + 2 * y;
- vert_3 = vert_2 + 2;
- }
-
- if (y == (config.edges_y - 1)) {
- vert_3 = vert_2 + config.verts_x;
- vert_4 = vert_1 + config.verts_x;
- }
-
- define_quad(polys, loops, poly_index, loop_index, vert_1, vert_4, vert_3, vert_2);
- loop_index += 4;
- poly_index++;
- }
- if (z == 0) {
- vert_1_start += config.verts_x * config.verts_y;
- }
- else {
- vert_1_start += xy_cross_section_vert_count;
- }
- vert_2_start += xy_cross_section_vert_count;
- }
-}
-
-static void calculate_uvs(const CuboidConfig &config, Mesh *mesh)
-{
- MeshComponent mesh_component;
- mesh_component.replace(mesh, GeometryOwnershipType::Editable);
- OutputAttribute_Typed<float2> uv_attribute =
- mesh_component.attribute_try_get_for_output_only<float2>("uv_map", ATTR_DOMAIN_CORNER);
- MutableSpan<float2> uvs = uv_attribute.as_span();
-
- int loop_index = 0;
-
- const float x_delta = 0.25f / static_cast<float>(config.edges_x);
- const float y_delta = 0.25f / static_cast<float>(config.edges_y);
- const float z_delta = 0.25f / static_cast<float>(config.edges_z);
-
- /* Calculate bottom face UVs. */
- for (const int y : IndexRange(config.edges_y)) {
- for (const int x : IndexRange(config.edges_x)) {
- uvs[loop_index++] = float2(0.25f + x * x_delta, 0.375f - y * y_delta);
- uvs[loop_index++] = float2(0.25f + x * x_delta, 0.375f - (y + 1) * y_delta);
- uvs[loop_index++] = float2(0.25f + (x + 1) * x_delta, 0.375f - (y + 1) * y_delta);
- uvs[loop_index++] = float2(0.25f + (x + 1) * x_delta, 0.375f - y * y_delta);
- }
- }
-
- /* Calculate front face UVs. */
- for (const int z : IndexRange(config.edges_z)) {
- for (const int x : IndexRange(config.edges_x)) {
- uvs[loop_index++] = float2(0.25f + x * x_delta, 0.375f + z * z_delta);
- uvs[loop_index++] = float2(0.25f + (x + 1) * x_delta, 0.375f + z * z_delta);
- uvs[loop_index++] = float2(0.25f + (x + 1) * x_delta, 0.375f + (z + 1) * z_delta);
- uvs[loop_index++] = float2(0.25f + x * x_delta, 0.375f + (z + 1) * z_delta);
- }
- }
-
- /* Calculate top face UVs. */
- for (const int y : IndexRange(config.edges_y)) {
- for (const int x : IndexRange(config.edges_x)) {
- uvs[loop_index++] = float2(0.25f + x * x_delta, 0.625f + y * y_delta);
- uvs[loop_index++] = float2(0.25f + (x + 1) * x_delta, 0.625f + y * y_delta);
- uvs[loop_index++] = float2(0.25f + (x + 1) * x_delta, 0.625f + (y + 1) * y_delta);
- uvs[loop_index++] = float2(0.25f + x * x_delta, 0.625f + (y + 1) * y_delta);
- }
- }
-
- /* Calculate back face UVs. */
- for (const int z : IndexRange(config.edges_z)) {
- for (const int x : IndexRange(config.edges_x)) {
- uvs[loop_index++] = float2(1.0f - x * x_delta, 0.375f + z * z_delta);
- uvs[loop_index++] = float2(1.0f - x * x_delta, 0.375f + (z + 1) * z_delta);
- uvs[loop_index++] = float2(1.0f - (x + 1) * x_delta, 0.375f + (z + 1) * z_delta);
- uvs[loop_index++] = float2(1.0f - (x + 1) * x_delta, 0.375f + z * z_delta);
- }
- }
-
- /* Calculate left face UVs. */
- for (const int z : IndexRange(config.edges_z)) {
- for (const int y : IndexRange(config.edges_y)) {
- uvs[loop_index++] = float2(0.25f - y * y_delta, 0.375f + z * z_delta);
- uvs[loop_index++] = float2(0.25f - y * y_delta, 0.375f + (z + 1) * z_delta);
- uvs[loop_index++] = float2(0.25f - (y + 1) * y_delta, 0.375f + (z + 1) * z_delta);
- uvs[loop_index++] = float2(0.25f - (y + 1) * y_delta, 0.375f + z * z_delta);
- }
- }
-
- /* Calculate right face UVs. */
- for (const int z : IndexRange(config.edges_z)) {
- for (const int y : IndexRange(config.edges_y)) {
- uvs[loop_index++] = float2(0.50f + y * y_delta, 0.375f + z * z_delta);
- uvs[loop_index++] = float2(0.50f + (y + 1) * y_delta, 0.375f + z * z_delta);
- uvs[loop_index++] = float2(0.50f + (y + 1) * y_delta, 0.375f + (z + 1) * z_delta);
- uvs[loop_index++] = float2(0.50f + y * y_delta, 0.375f + (z + 1) * z_delta);
- }
- }
-
- uv_attribute.save();
-}
-
-Mesh *create_cuboid_mesh(const float3 size,
- const int verts_x,
- const int verts_y,
- const int verts_z)
-{
- const CuboidConfig config(size, verts_x, verts_y, verts_z);
-
- Mesh *mesh = BKE_mesh_new_nomain(
- config.vertex_count, 0, 0, config.loop_count, config.poly_count);
- BKE_id_material_eval_ensure_default_slot(&mesh->id);
-
- calculate_vertices(config, {mesh->mvert, mesh->totvert});
-
- calculate_polys(config, {mesh->mpoly, mesh->totpoly}, {mesh->mloop, mesh->totloop});
- BKE_mesh_calc_edges(mesh, false, false);
-
- calculate_uvs(config, mesh);
-
- return mesh;
-}
-
-} // namespace blender::nodes
+#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_mesh_primitive_cube_cc {
@@ -442,6 +37,16 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Mesh"));
}
+static Mesh *create_cuboid_mesh(const float3 &size,
+ const int verts_x,
+ const int verts_y,
+ const int verts_z)
+{
+ Mesh *mesh = geometry::create_cuboid_mesh(size, verts_x, verts_y, verts_z, "uv_map");
+ BKE_id_material_eval_ensure_default_slot(&mesh->id);
+ return mesh;
+}
+
static Mesh *create_cube_mesh(const float3 size,
const int verts_x,
const int verts_y,
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 f6ee3d00dee..ec6acf55dd8 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
@@ -25,7 +25,7 @@ static void node_geo_exec(GeoNodeExecParams params)
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)};
+ fn::FieldEvaluator evaluator{context, component.attribute_domain_num(ATTR_DOMAIN_EDGE)};
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 1a0cc53cb6c..7463eb01471 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
@@ -1,5 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "BLI_task.hh"
+
#include "DNA_pointcloud_types.h"
#include "BKE_attribute_math.hh"
@@ -41,21 +43,22 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
node->storage = data;
}
-template<typename T>
-static void copy_attribute_to_points(const VArray<T> &src,
- const IndexMask mask,
- MutableSpan<T> dst)
+static void materialize_compressed_to_uninitialized_threaded(const GVArray &src,
+ const IndexMask mask,
+ GMutableSpan dst)
{
- for (const int i : mask.index_range()) {
- dst[i] = src[mask[i]];
- }
+ BLI_assert(src.type() == dst.type());
+ BLI_assert(mask.size() == dst.size());
+ threading::parallel_for(mask.index_range(), 4096, [&](IndexRange range) {
+ src.materialize_compressed_to_uninitialized(mask.slice(range), dst.slice(range).data());
+ });
}
static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
Field<float3> &position_field,
Field<float> &radius_field,
Field<bool> &selection_field,
- const AttributeDomain domain)
+ const eAttrDomain domain)
{
const MeshComponent *mesh_component = geometry_set.get_component_for_read<MeshComponent>();
if (mesh_component == nullptr) {
@@ -63,12 +66,12 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
return;
}
GeometryComponentFieldContext field_context{*mesh_component, domain};
- const int domain_size = mesh_component->attribute_domain_size(domain);
- if (domain_size == 0) {
+ const int domain_num = mesh_component->attribute_domain_num(domain);
+ if (domain_num == 0) {
geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
return;
}
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
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
@@ -79,16 +82,21 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
PointCloud *pointcloud = BKE_pointcloud_new_nomain(selection.size());
- uninitialized_fill_n(pointcloud->radius, pointcloud->totpoint, 0.05f);
geometry_set.replace_pointcloud(pointcloud);
PointCloudComponent &point_component =
geometry_set.get_component_for_write<PointCloudComponent>();
- copy_attribute_to_points(evaluator.get_evaluated<float3>(0),
- selection,
- {(float3 *)pointcloud->co, pointcloud->totpoint});
- copy_attribute_to_points(
- evaluator.get_evaluated<float>(1), selection, {pointcloud->radius, pointcloud->totpoint});
+ OutputAttribute position = point_component.attribute_try_get_for_output_only(
+ "position", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
+ materialize_compressed_to_uninitialized_threaded(
+ evaluator.get_evaluated(0), selection, position.as_span());
+ position.save();
+
+ OutputAttribute radius = point_component.attribute_try_get_for_output_only(
+ "radius", ATTR_DOMAIN_POINT, CD_PROP_FLOAT);
+ materialize_compressed_to_uninitialized_threaded(
+ evaluator.get_evaluated(1), selection, radius.as_span());
+ radius.save();
Map<AttributeIDRef, AttributeKind> attributes;
geometry_set.gather_attributes_for_propagation(
@@ -97,16 +105,12 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
- const CustomDataType data_type = entry.value.data_type;
+ const eCustomDataType data_type = entry.value.data_type;
GVArray src = mesh_component->attribute_get_for_read(attribute_id, domain, data_type);
OutputAttribute dst = point_component.attribute_try_get_for_output_only(
attribute_id, ATTR_DOMAIN_POINT, data_type);
if (dst && src) {
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
- using T = decltype(dummy);
- VArray<T> src_typed = src.typed<T>();
- copy_attribute_to_points(src_typed, selection, dst.as_span().typed<T>());
- });
+ materialize_compressed_to_uninitialized_threaded(src, selection, dst.as_span());
dst.save();
}
}
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 0f6586617bc..00b3d167755 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
@@ -38,13 +38,13 @@ static void geometry_set_points_to_vertices(GeometrySet &geometry_set,
}
GeometryComponentFieldContext field_context{*point_component, ATTR_DOMAIN_POINT};
- const int domain_size = point_component->attribute_domain_size(ATTR_DOMAIN_POINT);
- if (domain_size == 0) {
+ const int domain_num = point_component->attribute_domain_num(ATTR_DOMAIN_POINT);
+ if (domain_num == 0) {
geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
return;
}
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
+ fn::FieldEvaluator selection_evaluator{field_context, domain_num};
selection_evaluator.add(selection_field);
selection_evaluator.evaluate();
const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
@@ -59,7 +59,7 @@ static void geometry_set_points_to_vertices(GeometrySet &geometry_set,
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
- const CustomDataType data_type = entry.value.data_type;
+ const eCustomDataType data_type = entry.value.data_type;
GVArray src = point_component->attribute_get_for_read(
attribute_id, ATTR_DOMAIN_POINT, data_type);
OutputAttribute dst = mesh_component.attribute_try_get_for_output_only(
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 c99b51ffd4c..42cee4c0efe 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
@@ -168,14 +168,14 @@ static void gather_point_data_from_component(GeoNodeExecParams &params,
Field<float> radius_field = params.get_input<Field<float>>("Radius");
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
- const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
+ const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_POINT);
- r_positions.resize(r_positions.size() + domain_size);
- positions.materialize(r_positions.as_mutable_span().take_back(domain_size));
+ r_positions.resize(r_positions.size() + domain_num);
+ positions.materialize(r_positions.as_mutable_span().take_back(domain_num));
- r_radii.resize(r_radii.size() + domain_size);
- fn::FieldEvaluator evaluator{field_context, domain_size};
- evaluator.add_with_destination(radius_field, r_radii.as_mutable_span().take_back(domain_size));
+ r_radii.resize(r_radii.size() + domain_num);
+ fn::FieldEvaluator evaluator{field_context, domain_num};
+ evaluator.add_with_destination(radius_field, r_radii.as_mutable_span().take_back(domain_num));
evaluator.evaluate();
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc
index 368954447c9..a92cee2d066 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc
@@ -70,7 +70,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryRaycast &storage = node_storage(*node);
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
bNodeSocket *socket_vector = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
bNodeSocket *socket_float = socket_vector->next;
@@ -104,7 +104,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
search_link_ops_for_declarations(params, declaration.inputs().take_back(3));
search_link_ops_for_declarations(params, declaration.outputs().take_front(4));
- const std::optional<CustomDataType> type = node_data_type_to_custom_data_type(
+ const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type(
(eNodeSocketDatatype)params.other_socket().type);
if (type && *type != CD_PROP_STRING) {
/* The input and output sockets have the same name. */
@@ -215,7 +215,7 @@ class RaycastFunction : public fn::MultiFunction {
/* Always evaluate the target domain data on the face corner domain because it contains the most
* information. Eventually this could be exposed as an option or determined automatically from
* the field inputs for better performance. */
- const AttributeDomain domain_ = ATTR_DOMAIN_CORNER;
+ const eAttrDomain domain_ = ATTR_DOMAIN_CORNER;
fn::MFSignature signature_;
@@ -312,15 +312,15 @@ class RaycastFunction : public fn::MultiFunction {
}
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_);
- target_evaluator_ = std::make_unique<FieldEvaluator>(*target_context_, domain_size);
+ const int domain_num = mesh_component.attribute_domain_num(domain_);
+ target_evaluator_ = std::make_unique<FieldEvaluator>(*target_context_, domain_num);
target_evaluator_->add(std::move(src_field));
target_evaluator_->evaluate();
target_data_ = &target_evaluator_->get_evaluated(0);
}
};
-static GField get_input_attribute_field(GeoNodeExecParams &params, const CustomDataType data_type)
+static GField get_input_attribute_field(GeoNodeExecParams &params, const eCustomDataType data_type)
{
switch (data_type) {
case CD_PROP_FLOAT:
@@ -387,7 +387,7 @@ static void node_geo_exec(GeoNodeExecParams params)
GeometrySet target = params.extract_input<GeometrySet>("Target Geometry");
const NodeGeometryRaycast &storage = node_storage(params.node());
const GeometryNodeRaycastMapMode mapping = (GeometryNodeRaycastMapMode)storage.mapping;
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
if (target.is_empty()) {
params.set_default_remaining_outputs();
diff --git a/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc
index effeac5a37f..da42b8c5ee0 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc
@@ -21,6 +21,11 @@ static void node_geo_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
return;
}
+ if (!bke::allow_procedural_attribute_access(name)) {
+ params.error_message_add(NodeWarningType::Info, TIP_(bke::no_procedural_access_message));
+ params.set_output("Geometry", std::move(geometry_set));
+ return;
+ }
std::atomic<bool> attribute_exists = false;
std::atomic<bool> cannot_delete = false;
@@ -50,7 +55,7 @@ static void node_geo_exec(GeoNodeExecParams params)
});
if (attribute_exists && !cannot_delete) {
- params.used_named_attribute(name, NamedAttributeUsage::Remove);
+ params.used_named_attribute(name, eNamedAttrUsage::Remove);
}
if (!attribute_exists) {
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 6eb95859e50..59e203afd08 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc
@@ -19,9 +19,9 @@ static void node_declare(NodeDeclarationBuilder &b)
static void rotate_instances(GeoNodeExecParams &params, InstancesComponent &instances_component)
{
GeometryComponentFieldContext field_context{instances_component, ATTR_DOMAIN_INSTANCE};
- const int domain_size = instances_component.instances_amount();
+ const int domain_num = instances_component.instances_num();
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_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 7923ad6264d..698efa8865d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc
@@ -397,7 +397,7 @@ static void scale_edges_on_axis(MeshComponent &mesh_component, const AxisScaleFi
static void node_geo_exec(GeoNodeExecParams params)
{
const bNode &node = params.node();
- const AttributeDomain domain = static_cast<AttributeDomain>(node.custom1);
+ const eAttrDomain domain = static_cast<eAttrDomain>(node.custom1);
const GeometryNodeScaleElementsMode scale_mode = static_cast<GeometryNodeScaleElementsMode>(
node.custom2);
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 4ca21874f8f..d4716a6b6f0 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc
@@ -23,7 +23,7 @@ static void scale_instances(GeoNodeExecParams &params, InstancesComponent &insta
{
GeometryComponentFieldContext field_context{instances_component, ATTR_DOMAIN_INSTANCE};
- fn::FieldEvaluator evaluator{field_context, instances_component.instances_amount()};
+ fn::FieldEvaluator evaluator{field_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_separate_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc
index a48d422e4c0..22712c873a3 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc
@@ -43,7 +43,7 @@ static void node_geo_exec(GeoNodeExecParams params)
const Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
const NodeGeometrySeparateGeometry &storage = node_storage(params.node());
- const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain);
+ const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain);
auto separate_geometry_maybe_recursively = [&](GeometrySet &geometry_set, bool invert) {
bool is_error;
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 73e49c7d037..d2082924fa7 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
@@ -75,12 +75,12 @@ static void set_position_in_component(CurveComponent &component,
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) {
+ const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_POINT);
+ if (domain_num == 0) {
return;
}
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.set_selection(selection_field);
evaluator.add(position_field);
evaluator.add(offset_field);
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 a23a6c09551..4c84093bfcb 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
@@ -21,15 +21,15 @@ static void set_radius_in_component(GeometryComponent &component,
const Field<float> &radius_field)
{
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
- const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
- if (domain_size == 0) {
+ const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_POINT);
+ if (domain_num == 0) {
return;
}
OutputAttribute_Typed<float> radii = component.attribute_try_get_for_output_only<float>(
"radius", ATTR_DOMAIN_POINT);
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.set_selection(selection_field);
evaluator.add_with_destination(radius_field, radii.varray());
evaluator.evaluate();
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 1155c97dc38..8b1e5935a61 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
@@ -17,15 +17,15 @@ static void set_tilt_in_component(GeometryComponent &component,
const Field<float> &tilt_field)
{
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
- const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
- if (domain_size == 0) {
+ const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_POINT);
+ if (domain_num == 0) {
return;
}
OutputAttribute_Typed<float> tilts = component.attribute_try_get_for_output_only<float>(
"tilt", ATTR_DOMAIN_POINT);
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.set_selection(selection_field);
evaluator.add_with_destination(tilt_field, tilts.varray());
evaluator.evaluate();
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 0892e068ce2..87d48daddea 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_id.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_id.cc
@@ -16,16 +16,16 @@ static void set_id_in_component(GeometryComponent &component,
const Field<bool> &selection_field,
const Field<int> &id_field)
{
- const AttributeDomain domain = (component.type() == GEO_COMPONENT_TYPE_INSTANCES) ?
- ATTR_DOMAIN_INSTANCE :
- ATTR_DOMAIN_POINT;
+ const eAttrDomain domain = (component.type() == GEO_COMPONENT_TYPE_INSTANCES) ?
+ ATTR_DOMAIN_INSTANCE :
+ ATTR_DOMAIN_POINT;
GeometryComponentFieldContext field_context{component, domain};
- const int domain_size = component.attribute_domain_size(domain);
- if (domain_size == 0) {
+ const int domain_num = component.attribute_domain_num(domain);
+ if (domain_num == 0) {
return;
}
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.set_selection(selection_field);
/* Since adding the ID attribute can change the result of the field evaluation (the random value
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 a0b38209f97..58613dae832 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
@@ -17,15 +17,15 @@ static void set_material_index_in_component(GeometryComponent &component,
const Field<int> &index_field)
{
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_FACE};
- const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_FACE);
- if (domain_size == 0) {
+ const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_FACE);
+ if (domain_num == 0) {
return;
}
OutputAttribute_Typed<int> indices = component.attribute_try_get_for_output_only<int>(
"material_index", ATTR_DOMAIN_FACE);
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.set_selection(selection_field);
evaluator.add_with_destination(index_field, indices.varray());
evaluator.evaluate();
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 93024fd81d6..571bead9743 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
@@ -21,15 +21,15 @@ static void set_radius_in_component(GeometryComponent &component,
const Field<float> &radius_field)
{
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
- const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
- if (domain_size == 0) {
+ const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_POINT);
+ if (domain_num == 0) {
return;
}
OutputAttribute_Typed<float> radii = component.attribute_try_get_for_output_only<float>(
"radius", ATTR_DOMAIN_POINT);
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.set_selection(selection_field);
evaluator.add_with_destination(radius_field, radii.varray());
evaluator.evaluate();
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 d2ff9753897..e9ed87e552f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
@@ -25,7 +25,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static void set_computed_position_and_offset(GeometryComponent &component,
const VArray<float3> &in_positions,
const VArray<float3> &in_offsets,
- const AttributeDomain domain,
+ const eAttrDomain domain,
const IndexMask selection)
{
@@ -139,16 +139,15 @@ static void set_position_in_component(GeometryComponent &component,
const Field<float3> &position_field,
const Field<float3> &offset_field)
{
- AttributeDomain domain = component.type() == GEO_COMPONENT_TYPE_INSTANCES ?
- ATTR_DOMAIN_INSTANCE :
- ATTR_DOMAIN_POINT;
+ eAttrDomain domain = component.type() == GEO_COMPONENT_TYPE_INSTANCES ? ATTR_DOMAIN_INSTANCE :
+ ATTR_DOMAIN_POINT;
GeometryComponentFieldContext field_context{component, domain};
- const int domain_size = component.attribute_domain_size(domain);
- if (domain_size == 0) {
+ const int domain_num = component.attribute_domain_num(domain);
+ if (domain_num == 0) {
return;
}
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.set_selection(selection_field);
evaluator.add(position_field);
evaluator.add(offset_field);
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 3420e17cc10..b98fbd0a0fe 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
@@ -17,15 +17,15 @@ static void set_smooth_in_component(GeometryComponent &component,
const Field<bool> &shade_field)
{
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_FACE};
- const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_FACE);
- if (domain_size == 0) {
+ const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_FACE);
+ if (domain_num == 0) {
return;
}
OutputAttribute_Typed<bool> shades = component.attribute_try_get_for_output_only<bool>(
"shade_smooth", ATTR_DOMAIN_FACE);
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.set_selection(selection_field);
evaluator.add_with_destination(shade_field, shades.varray());
evaluator.evaluate();
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 dc7f3b1343a..976857883f0 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
@@ -17,15 +17,15 @@ static void set_cyclic_in_component(GeometryComponent &component,
const Field<bool> &cyclic_field)
{
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_CURVE};
- const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_CURVE);
- if (domain_size == 0) {
+ const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_CURVE);
+ if (domain_num == 0) {
return;
}
OutputAttribute_Typed<bool> cyclics = component.attribute_try_get_for_output_only<bool>(
"cyclic", ATTR_DOMAIN_CURVE);
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.set_selection(selection_field);
evaluator.add_with_destination(cyclic_field, cyclics.varray());
evaluator.evaluate();
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 f3031ff3678..8b665376c01 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
@@ -17,15 +17,15 @@ static void set_resolution_in_component(GeometryComponent &component,
const Field<int> &resolution_field)
{
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_CURVE};
- const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_CURVE);
- if (domain_size == 0) {
+ const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_CURVE);
+ if (domain_num == 0) {
return;
}
OutputAttribute_Typed<int> resolutions = component.attribute_try_get_for_output_only<int>(
"resolution", ATTR_DOMAIN_CURVE);
- fn::FieldEvaluator evaluator{field_context, domain_size};
+ fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.set_selection(selection_field);
evaluator.add_with_destination(resolution_field, resolutions.varray());
evaluator.evaluate();
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 de206be5367..7ccdae2e5a6 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
@@ -45,7 +45,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryStoreNamedAttribute &storage = node_storage(*node);
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
bNodeSocket *socket_geometry = (bNodeSocket *)node->inputs.first;
bNodeSocket *socket_name = socket_geometry->next;
@@ -69,7 +69,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
search_link_ops_for_declarations(params, declaration.inputs().take_front(2));
if (params.in_out() == SOCK_OUT) {
- const std::optional<CustomDataType> type = node_data_type_to_custom_data_type(
+ const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type(
static_cast<eNodeSocketDatatype>(params.other_socket().type));
if (type && *type != CD_PROP_STRING) {
/* The input and output sockets have the same name. */
@@ -84,23 +84,23 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
static void try_capture_field_on_geometry(GeometryComponent &component,
const StringRef name,
- const AttributeDomain domain,
+ const eAttrDomain domain,
const GField &field)
{
GeometryComponentFieldContext field_context{component, domain};
- const int domain_size = component.attribute_domain_size(domain);
- const IndexMask mask{IndexMask(domain_size)};
+ const int domain_num = component.attribute_domain_num(domain);
+ const IndexMask mask{IndexMask(domain_num)};
const CPPType &type = field.cpp_type();
- const CustomDataType data_type = bke::cpp_type_to_custom_data_type(type);
+ const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(type);
/* Could avoid allocating a new buffer if:
* - We are writing to an attribute that exists already.
* - The field does not depend on that attribute (we can't easily check for that yet). */
- void *buffer = MEM_mallocN(type.size() * domain_size, __func__);
+ void *buffer = MEM_mallocN(type.size() * domain_num, __func__);
fn::FieldEvaluator evaluator{field_context, &mask};
- evaluator.add_with_destination(field, GMutableSpan{type, buffer, domain_size});
+ evaluator.add_with_destination(field, GMutableSpan{type, buffer, domain_num});
evaluator.evaluate();
component.attribute_try_delete(name);
@@ -114,7 +114,7 @@ static void try_capture_field_on_geometry(GeometryComponent &component,
else {
/* Cannot change type of built-in attribute. */
}
- type.destruct_n(buffer, domain_size);
+ type.destruct_n(buffer, domain_num);
MEM_freeN(buffer);
}
else {
@@ -131,12 +131,17 @@ static void node_geo_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
return;
}
+ if (!bke::allow_procedural_attribute_access(name)) {
+ params.error_message_add(NodeWarningType::Info, TIP_(bke::no_procedural_access_message));
+ params.set_output("Geometry", std::move(geometry_set));
+ return;
+ }
- params.used_named_attribute(name, NamedAttributeUsage::Write);
+ params.used_named_attribute(name, eNamedAttrUsage::Write);
const NodeGeometryStoreNamedAttribute &storage = node_storage(params.node());
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
- const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
+ const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain);
GField field;
switch (data_type) {
diff --git a/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc
index 658de02fdab..33f5eccd719 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc
@@ -97,12 +97,8 @@ static void node_update(bNodeTree *ntree, bNode *node)
ntree, socket_remainder, overflow == GEO_NODE_STRING_TO_CURVES_MODE_TRUNCATE);
bNodeSocket *height_socket = (bNodeSocket *)node->inputs.last;
- bNodeSocket *width_socket = height_socket->prev;
nodeSetSocketAvailability(
ntree, height_socket, overflow != GEO_NODE_STRING_TO_CURVES_MODE_OVERFLOW);
- node_sock_label(width_socket,
- overflow == GEO_NODE_STRING_TO_CURVES_MODE_OVERFLOW ? N_("Max Width") :
- N_("Text Box Width"));
}
static float3 get_pivot_point(GeoNodeExecParams &params, CurveEval &curve)
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 4832feac5bd..9eda5bb34ff 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
@@ -1,5 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "BLI_task.hh"
+
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -21,7 +23,13 @@ static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
b.add_input<decl::Int>(N_("Level")).default_value(1).min(0).max(6);
- b.add_input<decl::Float>(N_("Crease"))
+ b.add_input<decl::Float>(N_("Edge Crease"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .supports_field()
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Vertex Crease"))
.default_value(0.0f)
.min(0.0f)
.max(1.0f)
@@ -44,6 +52,45 @@ static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = data;
}
+#ifdef WITH_OPENSUBDIV
+static void materialize_and_clamp_creases(const VArray<float> &crease_varray,
+ MutableSpan<float> creases)
+{
+ threading::parallel_for(creases.index_range(), 1024, [&](IndexRange range) {
+ crease_varray.materialize(range, creases);
+ for (const int i : range) {
+ creases[i] = std::clamp(creases[i], 0.0f, 1.0f);
+ }
+ });
+}
+
+static void write_vertex_creases(Mesh &mesh, const VArray<float> &crease_varray)
+{
+ float *crease;
+ if (CustomData_has_layer(&mesh.vdata, CD_CREASE)) {
+ crease = static_cast<float *>(CustomData_get_layer(&mesh.vdata, CD_CREASE));
+ }
+ else {
+ crease = static_cast<float *>(
+ CustomData_add_layer(&mesh.vdata, CD_CREASE, CD_DEFAULT, nullptr, mesh.totvert));
+ }
+ materialize_and_clamp_creases(crease_varray, {crease, mesh.totvert});
+}
+
+static void write_edge_creases(MeshComponent &mesh, const VArray<float> &crease_varray)
+{
+ OutputAttribute_Typed<float> attribute = mesh.attribute_try_get_for_output_only<float>(
+ "crease", ATTR_DOMAIN_EDGE);
+ materialize_and_clamp_creases(crease_varray, attribute.as_span());
+ attribute.save();
+}
+
+static bool varray_is_nonzero(const VArray<float> &varray)
+{
+ return !(varray.is_single() && varray.get_internal_single() == 0.0f);
+}
+#endif
+
static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
@@ -51,7 +98,8 @@ static void node_geo_exec(GeoNodeExecParams params)
params.error_message_add(NodeWarningType::Error,
TIP_("Disabled, Blender was compiled without OpenSubdiv"));
#else
- Field<float> crease_field = params.extract_input<Field<float>>("Crease");
+ Field<float> edge_crease_field = params.extract_input<Field<float>>("Edge Crease");
+ Field<float> vertex_crease_field = params.extract_input<Field<float>>("Vertex Crease");
const NodeGeometrySubdivisionSurface &storage = node_storage(params.node());
const int uv_smooth = storage.uv_smooth;
@@ -69,27 +117,31 @@ static void node_geo_exec(GeoNodeExecParams params)
return;
}
- MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
- AttributeDomain domain = ATTR_DOMAIN_EDGE;
- GeometryComponentFieldContext field_context{mesh_component, domain};
- const int domain_size = mesh_component.attribute_domain_size(domain);
-
- if (domain_size == 0) {
+ const MeshComponent &mesh_component = *geometry_set.get_component_for_read<MeshComponent>();
+ const int verts_num = mesh_component.attribute_domain_num(ATTR_DOMAIN_POINT);
+ const int edges_num = mesh_component.attribute_domain_num(ATTR_DOMAIN_EDGE);
+ if (verts_num == 0 || edges_num == 0) {
return;
}
- FieldEvaluator evaluator(field_context, domain_size);
- evaluator.add(crease_field);
- evaluator.evaluate();
- const VArray<float> &creases = evaluator.get_evaluated<float>(0);
+ GeometryComponentFieldContext point_context{mesh_component, ATTR_DOMAIN_POINT};
+ FieldEvaluator point_evaluator(point_context, verts_num);
+ 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);
+ edge_evaluator.add(edge_crease_field);
+ edge_evaluator.evaluate();
+ const VArray<float> edge_creases = edge_evaluator.get_evaluated<float>(0);
+
+ const bool use_creases = varray_is_nonzero(vertex_creases) || varray_is_nonzero(edge_creases);
- OutputAttribute_Typed<float> crease = mesh_component.attribute_try_get_for_output_only<float>(
- "crease", domain);
- MutableSpan<float> crease_span = crease.as_span();
- for (auto i : creases.index_range()) {
- crease_span[i] = std::clamp(creases[i], 0.0f, 1.0f);
+ if (use_creases) {
+ write_vertex_creases(*geometry_set.get_mesh_for_write(), vertex_creases);
+ write_edge_creases(geometry_set.get_component_for_write<MeshComponent>(), edge_creases);
}
- crease.save();
/* Initialize mesh settings. */
SubdivToMeshSettings mesh_settings;
@@ -100,7 +152,7 @@ static void node_geo_exec(GeoNodeExecParams params)
SubdivSettings subdiv_settings;
subdiv_settings.is_simple = false;
subdiv_settings.is_adaptive = false;
- subdiv_settings.use_creases = !(creases.is_single() && creases.get_internal_single() == 0.0f);
+ subdiv_settings.use_creases = use_creases;
subdiv_settings.level = subdiv_level;
subdiv_settings.vtx_boundary_interpolation =
@@ -108,19 +160,19 @@ static void node_geo_exec(GeoNodeExecParams params)
subdiv_settings.fvar_linear_interpolation = BKE_subdiv_fvar_interpolation_from_uv_smooth(
uv_smooth);
- Mesh *mesh_in = mesh_component.get_for_write();
+ 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);
/* 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_in);
- mesh_component.replace(mesh_out);
+ geometry_set.replace_mesh(mesh_out);
BKE_subdiv_free(subdiv);
});
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 12e306ba480..0af6c76feaf 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc
@@ -81,7 +81,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryTransferAttribute &storage = node_storage(*node);
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
const GeometryNodeAttributeTransferMode mapping = (GeometryNodeAttributeTransferMode)
storage.mode;
@@ -123,7 +123,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
search_link_ops_for_declarations(params, declaration.inputs().take_back(2));
search_link_ops_for_declarations(params, declaration.inputs().take_front(1));
- const std::optional<CustomDataType> type = node_data_type_to_custom_data_type(
+ const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type(
(eNodeSocketDatatype)params.other_socket().type);
if (type && *type != CD_PROP_STRING) {
/* The input and output sockets have the same name. */
@@ -356,7 +356,7 @@ void copy_with_indices_and_comparison(const VArray<T> &src_1,
static bool component_is_available(const GeometrySet &geometry,
const GeometryComponentType type,
- const AttributeDomain domain)
+ const eAttrDomain domain)
{
if (!geometry.has(type)) {
return false;
@@ -365,7 +365,7 @@ static bool component_is_available(const GeometrySet &geometry,
if (component.is_empty()) {
return false;
}
- return component.attribute_domain_size(domain) != 0;
+ return component.attribute_domain_num(domain) != 0;
}
/**
@@ -383,7 +383,7 @@ class NearestInterpolatedTransferFunction : public fn::MultiFunction {
* future, it should be possible to use the most complex domain required by the field inputs, to
* simplify sampling and avoid domain conversions.
*/
- AttributeDomain domain_ = ATTR_DOMAIN_CORNER;
+ eAttrDomain domain_ = ATTR_DOMAIN_CORNER;
fn::MFSignature signature_;
@@ -433,8 +433,8 @@ class NearestInterpolatedTransferFunction : public fn::MultiFunction {
{
const MeshComponent &mesh_component = *source_.get_component_for_read<MeshComponent>();
source_context_.emplace(GeometryComponentFieldContext{mesh_component, domain_});
- const int domain_size = mesh_component.attribute_domain_size(domain_);
- source_evaluator_ = std::make_unique<FieldEvaluator>(*source_context_, domain_size);
+ const int domain_num = mesh_component.attribute_domain_num(domain_);
+ source_evaluator_ = std::make_unique<FieldEvaluator>(*source_context_, domain_num);
source_evaluator_->add(src_field_);
source_evaluator_->evaluate();
source_data_ = &source_evaluator_->get_evaluated(0);
@@ -449,7 +449,7 @@ class NearestInterpolatedTransferFunction : public fn::MultiFunction {
class NearestTransferFunction : public fn::MultiFunction {
GeometrySet source_;
GField src_field_;
- AttributeDomain domain_;
+ eAttrDomain domain_;
fn::MFSignature signature_;
@@ -466,7 +466,7 @@ class NearestTransferFunction : public fn::MultiFunction {
const GVArray *point_data_;
public:
- NearestTransferFunction(GeometrySet geometry, GField src_field, AttributeDomain domain)
+ NearestTransferFunction(GeometrySet geometry, GField src_field, eAttrDomain domain)
: source_(std::move(geometry)), src_field_(std::move(src_field)), domain_(domain)
{
source_.ensure_owns_direct_data();
@@ -578,9 +578,9 @@ class NearestTransferFunction : public fn::MultiFunction {
{
if (use_mesh_) {
const MeshComponent &mesh = *source_.get_component_for_read<MeshComponent>();
- const int domain_size = mesh.attribute_domain_size(domain_);
+ const int domain_num = mesh.attribute_domain_num(domain_);
mesh_context_.emplace(GeometryComponentFieldContext(mesh, domain_));
- mesh_evaluator_ = std::make_unique<FieldEvaluator>(*mesh_context_, domain_size);
+ mesh_evaluator_ = std::make_unique<FieldEvaluator>(*mesh_context_, domain_num);
mesh_evaluator_->add(src_field_);
mesh_evaluator_->evaluate();
mesh_data_ = &mesh_evaluator_->get_evaluated(0);
@@ -588,9 +588,9 @@ class NearestTransferFunction : public fn::MultiFunction {
if (use_points_) {
const PointCloudComponent &points = *source_.get_component_for_read<PointCloudComponent>();
- const int domain_size = points.attribute_domain_size(domain_);
+ const int domain_num = points.attribute_domain_num(domain_);
point_context_.emplace(GeometryComponentFieldContext(points, domain_));
- point_evaluator_ = std::make_unique<FieldEvaluator>(*point_context_, domain_size);
+ point_evaluator_ = std::make_unique<FieldEvaluator>(*point_context_, domain_num);
point_evaluator_->add(src_field_);
point_evaluator_->evaluate();
point_data_ = &point_evaluator_->get_evaluated(0);
@@ -599,7 +599,7 @@ class NearestTransferFunction : public fn::MultiFunction {
};
static const GeometryComponent *find_source_component(const GeometrySet &geometry,
- const AttributeDomain domain)
+ const eAttrDomain domain)
{
/* Choose the other component based on a consistent order, rather than some more complicated
* heuristic. This is the same order visible in the spreadsheet and used in the ray-cast node. */
@@ -624,7 +624,7 @@ static const GeometryComponent *find_source_component(const GeometrySet &geometr
class IndexTransferFunction : public fn::MultiFunction {
GeometrySet src_geometry_;
GField src_field_;
- AttributeDomain domain_;
+ eAttrDomain domain_;
fn::MFSignature signature_;
@@ -633,7 +633,7 @@ class IndexTransferFunction : public fn::MultiFunction {
const GVArray *src_data_ = nullptr;
public:
- IndexTransferFunction(GeometrySet geometry, GField src_field, const AttributeDomain domain)
+ IndexTransferFunction(GeometrySet geometry, GField src_field, const eAttrDomain domain)
: src_geometry_(std::move(geometry)), src_field_(std::move(src_field)), domain_(domain)
{
src_geometry_.ensure_owns_direct_data();
@@ -658,9 +658,9 @@ class IndexTransferFunction : public fn::MultiFunction {
if (component == nullptr) {
return;
}
- const int domain_size = component->attribute_domain_size(domain_);
+ const int domain_num = component->attribute_domain_num(domain_);
geometry_context_.emplace(GeometryComponentFieldContext(*component, domain_));
- evaluator_ = std::make_unique<FieldEvaluator>(*geometry_context_, domain_size);
+ evaluator_ = std::make_unique<FieldEvaluator>(*geometry_context_, domain_num);
evaluator_->add(src_field_);
evaluator_->evaluate();
src_data_ = &evaluator_->get_evaluated(0);
@@ -684,7 +684,7 @@ class IndexTransferFunction : public fn::MultiFunction {
}
};
-static GField get_input_attribute_field(GeoNodeExecParams &params, const CustomDataType data_type)
+static GField get_input_attribute_field(GeoNodeExecParams &params, const eCustomDataType data_type)
{
switch (data_type) {
case CD_PROP_FLOAT:
@@ -737,8 +737,8 @@ static void node_geo_exec(GeoNodeExecParams params)
const NodeGeometryTransferAttribute &storage = node_storage(params.node());
const GeometryNodeAttributeTransferMode mapping = (GeometryNodeAttributeTransferMode)
storage.mode;
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
- const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
+ const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain);
GField field = get_input_attribute_field(params, data_type);
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 a5ca1cba28f..258c1ac3fba 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc
@@ -19,7 +19,7 @@ static void translate_instances(GeoNodeExecParams &params, InstancesComponent &i
{
GeometryComponentFieldContext field_context{instances_component, ATTR_DOMAIN_INSTANCE};
- fn::FieldEvaluator evaluator{field_context, instances_component.instances_amount()};
+ fn::FieldEvaluator evaluator{field_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 992470e8279..e47dc22da04 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc
@@ -83,9 +83,9 @@ static void node_geo_exec(GeoNodeExecParams params)
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);
+ const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_FACE);
GeometryComponentFieldContext context{component, ATTR_DOMAIN_FACE};
- FieldEvaluator evaluator{context, domain_size};
+ FieldEvaluator evaluator{context, domain_num};
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_viewer.cc b/source/blender/nodes/geometry/nodes/node_geo_viewer.cc
index 8e9d7b0e46d..6979693e215 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_viewer.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_viewer.cc
@@ -39,7 +39,7 @@ static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
}
-static eNodeSocketDatatype custom_data_type_to_socket_type(const CustomDataType type)
+static eNodeSocketDatatype custom_data_type_to_socket_type(const eCustomDataType type)
{
switch (type) {
case CD_PROP_FLOAT:
@@ -61,7 +61,7 @@ static eNodeSocketDatatype custom_data_type_to_socket_type(const CustomDataType
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryViewer &storage = node_storage(*node);
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
const eNodeSocketDatatype socket_type = custom_data_type_to_socket_type(data_type);
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
@@ -82,7 +82,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
ED_spreadsheet_context_paths_set_geometry_node(bmain, snode, &viewer_node);
};
- const std::optional<CustomDataType> type = node_socket_to_custom_data_type(
+ const std::optional<eCustomDataType> type = node_socket_to_custom_data_type(
params.other_socket());
if (params.in_out() == SOCK_OUT) {
/* The viewer node only has inputs. */
diff --git a/source/blender/nodes/intern/geometry_nodes_eval_log.cc b/source/blender/nodes/intern/geometry_nodes_eval_log.cc
index 378bac894e8..85dfdf03b82 100644
--- a/source/blender/nodes/intern/geometry_nodes_eval_log.cc
+++ b/source/blender/nodes/intern/geometry_nodes_eval_log.cc
@@ -241,27 +241,27 @@ GeometryValueLog::GeometryValueLog(const GeometrySet &geometry_set, bool log_ful
case GEO_COMPONENT_TYPE_MESH: {
const MeshComponent &mesh_component = *(const MeshComponent *)component;
MeshInfo &info = this->mesh_info.emplace();
- info.tot_verts = mesh_component.attribute_domain_size(ATTR_DOMAIN_POINT);
- info.tot_edges = mesh_component.attribute_domain_size(ATTR_DOMAIN_EDGE);
- info.tot_faces = mesh_component.attribute_domain_size(ATTR_DOMAIN_FACE);
+ info.verts_num = mesh_component.attribute_domain_num(ATTR_DOMAIN_POINT);
+ info.edges_num = mesh_component.attribute_domain_num(ATTR_DOMAIN_EDGE);
+ info.faces_num = mesh_component.attribute_domain_num(ATTR_DOMAIN_FACE);
break;
}
case GEO_COMPONENT_TYPE_CURVE: {
const CurveComponent &curve_component = *(const CurveComponent *)component;
CurveInfo &info = this->curve_info.emplace();
- info.tot_splines = curve_component.attribute_domain_size(ATTR_DOMAIN_CURVE);
+ info.splines_num = curve_component.attribute_domain_num(ATTR_DOMAIN_CURVE);
break;
}
case GEO_COMPONENT_TYPE_POINT_CLOUD: {
const PointCloudComponent &pointcloud_component = *(const PointCloudComponent *)component;
PointCloudInfo &info = this->pointcloud_info.emplace();
- info.tot_points = pointcloud_component.attribute_domain_size(ATTR_DOMAIN_POINT);
+ info.points_num = pointcloud_component.attribute_domain_num(ATTR_DOMAIN_POINT);
break;
}
case GEO_COMPONENT_TYPE_INSTANCES: {
const InstancesComponent &instances_component = *(const InstancesComponent *)component;
InstancesInfo &info = this->instances_info.emplace();
- info.tot_instances = instances_component.instances_amount();
+ info.instances_num = instances_component.instances_num();
break;
}
case GEO_COMPONENT_TYPE_VOLUME: {
@@ -495,7 +495,7 @@ void LocalGeoLogger::log_execution_time(DNode node, std::chrono::microseconds ex
void LocalGeoLogger::log_used_named_attribute(DNode node,
std::string attribute_name,
- NamedAttributeUsage usage)
+ eNamedAttrUsage usage)
{
used_named_attributes_.append({node, {std::move(attribute_name), usage}});
}
diff --git a/source/blender/nodes/intern/node_geometry_exec.cc b/source/blender/nodes/intern/node_geometry_exec.cc
index cea3084a418..27ad12ba252 100644
--- a/source/blender/nodes/intern/node_geometry_exec.cc
+++ b/source/blender/nodes/intern/node_geometry_exec.cc
@@ -24,7 +24,7 @@ void GeoNodeExecParams::error_message_add(const NodeWarningType type, std::strin
}
void GeoNodeExecParams::used_named_attribute(std::string attribute_name,
- const NamedAttributeUsage usage)
+ const eNamedAttrUsage usage)
{
if (provider_->logger == nullptr) {
return;
@@ -37,7 +37,7 @@ void GeoNodeExecParams::check_input_geometry_set(StringRef identifier,
const GeometrySet &geometry_set) const
{
const SocketDeclaration &decl =
- *provider_->dnode->input_by_identifier(identifier).bsocket()->declaration;
+ *provider_->dnode->input_by_identifier(identifier).bsocket()->runtime->declaration;
const decl::Geometry *geo_decl = dynamic_cast<const decl::Geometry *>(&decl);
if (geo_decl == nullptr) {
return;
@@ -112,21 +112,21 @@ const bNodeSocket *GeoNodeExecParams::find_available_socket(const StringRef name
GVArray GeoNodeExecParams::get_input_attribute(const StringRef name,
const GeometryComponent &component,
- const AttributeDomain domain,
- const CustomDataType type,
+ const eAttrDomain domain,
+ const eCustomDataType type,
const void *default_value) const
{
const bNodeSocket *found_socket = this->find_available_socket(name);
BLI_assert(found_socket != nullptr); /* There should always be available socket for the name. */
const CPPType *cpp_type = bke::custom_data_type_to_cpp_type(type);
- const int64_t domain_size = component.attribute_domain_size(domain);
+ const int64_t domain_num = component.attribute_domain_num(domain);
if (default_value == nullptr) {
default_value = cpp_type->default_value();
}
if (found_socket == nullptr) {
- return GVArray::ForSingle(*cpp_type, domain_size, default_value);
+ return GVArray::ForSingle(*cpp_type, domain_num, default_value);
}
if (found_socket->type == SOCK_STRING) {
@@ -140,46 +140,46 @@ GVArray GeoNodeExecParams::get_input_attribute(const StringRef name,
/* If the attribute doesn't exist, use the default value and output an error message
* (except when the field is empty, to avoid spamming error messages, and not when
* the domain is empty and we don't expect an attribute anyway). */
- if (!name.empty() && component.attribute_domain_size(domain) != 0) {
+ if (!name.empty() && component.attribute_domain_num(domain) != 0) {
this->error_message_add(NodeWarningType::Error,
TIP_("No attribute with name \"") + name + "\"");
}
- return GVArray::ForSingle(*cpp_type, domain_size, default_value);
+ return GVArray::ForSingle(*cpp_type, domain_num, default_value);
}
const bke::DataTypeConversions &conversions = bke::get_implicit_type_conversions();
if (found_socket->type == SOCK_FLOAT) {
const float value = this->get_input<float>(found_socket->identifier);
BUFFER_FOR_CPP_TYPE_VALUE(*cpp_type, buffer);
conversions.convert_to_uninitialized(CPPType::get<float>(), *cpp_type, &value, buffer);
- return GVArray::ForSingle(*cpp_type, domain_size, buffer);
+ return GVArray::ForSingle(*cpp_type, domain_num, buffer);
}
if (found_socket->type == SOCK_INT) {
const int value = this->get_input<int>(found_socket->identifier);
BUFFER_FOR_CPP_TYPE_VALUE(*cpp_type, buffer);
conversions.convert_to_uninitialized(CPPType::get<int>(), *cpp_type, &value, buffer);
- return GVArray::ForSingle(*cpp_type, domain_size, buffer);
+ return GVArray::ForSingle(*cpp_type, domain_num, buffer);
}
if (found_socket->type == SOCK_VECTOR) {
const float3 value = this->get_input<float3>(found_socket->identifier);
BUFFER_FOR_CPP_TYPE_VALUE(*cpp_type, buffer);
conversions.convert_to_uninitialized(CPPType::get<float3>(), *cpp_type, &value, buffer);
- return GVArray::ForSingle(*cpp_type, domain_size, buffer);
+ return GVArray::ForSingle(*cpp_type, domain_num, buffer);
}
if (found_socket->type == SOCK_RGBA) {
const ColorGeometry4f value = this->get_input<ColorGeometry4f>(found_socket->identifier);
BUFFER_FOR_CPP_TYPE_VALUE(*cpp_type, buffer);
conversions.convert_to_uninitialized(
CPPType::get<ColorGeometry4f>(), *cpp_type, &value, buffer);
- return GVArray::ForSingle(*cpp_type, domain_size, buffer);
+ return GVArray::ForSingle(*cpp_type, domain_num, buffer);
}
BLI_assert(false);
- return GVArray::ForSingle(*cpp_type, domain_size, default_value);
+ return GVArray::ForSingle(*cpp_type, domain_num, default_value);
}
-CustomDataType GeoNodeExecParams::get_input_attribute_data_type(
+eCustomDataType GeoNodeExecParams::get_input_attribute_data_type(
const StringRef name,
const GeometryComponent &component,
- const CustomDataType default_type) const
+ const eCustomDataType default_type) const
{
const bNodeSocket *found_socket = this->find_available_socket(name);
BLI_assert(found_socket != nullptr); /* There should always be available socket for the name. */
@@ -212,12 +212,12 @@ CustomDataType GeoNodeExecParams::get_input_attribute_data_type(
return default_type;
}
-AttributeDomain GeoNodeExecParams::get_highest_priority_input_domain(
+eAttrDomain GeoNodeExecParams::get_highest_priority_input_domain(
Span<std::string> names,
const GeometryComponent &component,
- const AttributeDomain default_domain) const
+ const eAttrDomain default_domain) const
{
- Vector<AttributeDomain, 8> input_domains;
+ Vector<eAttrDomain, 8> input_domains;
for (const std::string &name : names) {
const bNodeSocket *found_socket = this->find_available_socket(name);
BLI_assert(found_socket != nullptr); /* A socket should be available socket for the name. */
diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc
index 0ab446d8b0c..098f766589d 100644
--- a/source/blender/nodes/intern/node_socket.cc
+++ b/source/blender/nodes/intern/node_socket.cc
@@ -19,6 +19,7 @@
#include "BKE_geometry_set.hh"
#include "BKE_lib_id.h"
#include "BKE_node.h"
+#include "BKE_node_runtime.hh"
#include "DNA_collection_types.h"
#include "DNA_material_types.h"
@@ -261,8 +262,8 @@ void node_verify_sockets(bNodeTree *ntree, bNode *node, bool do_id_user)
}
if (ntype->declare != nullptr) {
nodeDeclarationEnsureOnOutdatedNode(ntree, node);
- if (!node->declaration->matches(*node)) {
- refresh_node(*ntree, *node, *node->declaration, do_id_user);
+ if (!node->runtime->declaration->matches(*node)) {
+ refresh_node(*ntree, *node, *node->runtime->declaration, do_id_user);
}
nodeSocketDeclarationsUpdate(node);
return;
diff --git a/source/blender/nodes/intern/node_socket_declarations.cc b/source/blender/nodes/intern/node_socket_declarations.cc
index 06925761bc7..b9fb75f30c7 100644
--- a/source/blender/nodes/intern/node_socket_declarations.cc
+++ b/source/blender/nodes/intern/node_socket_declarations.cc
@@ -4,6 +4,7 @@
#include "NOD_socket_declarations_geometry.hh"
#include "BKE_node.h"
+#include "BKE_node_runtime.hh"
#include "BLI_math_vector.h"
@@ -33,14 +34,14 @@ static bool sockets_can_connect(const SocketDeclaration &socket_decl,
return false;
}
- if (other_socket.declaration) {
+ if (other_socket.runtime->declaration) {
if (socket_decl.in_out() == SOCK_IN) {
- if (!field_types_are_compatible(socket_decl, *other_socket.declaration)) {
+ if (!field_types_are_compatible(socket_decl, *other_socket.runtime->declaration)) {
return false;
}
}
else {
- if (!field_types_are_compatible(*other_socket.declaration, socket_decl)) {
+ if (!field_types_are_compatible(*other_socket.runtime->declaration, socket_decl)) {
return false;
}
}
diff --git a/source/blender/nodes/intern/node_util.c b/source/blender/nodes/intern/node_util.c
index 5d2e1663ae3..e8be093c606 100644
--- a/source/blender/nodes/intern/node_util.c
+++ b/source/blender/nodes/intern/node_util.c
@@ -226,6 +226,39 @@ void node_filter_label(const bNodeTree *UNUSED(ntree), const bNode *node, char *
BLI_strncpy(label, IFACE_(name), maxlen);
}
+void node_combsep_color_label(const ListBase *sockets, NodeCombSepColorMode mode)
+{
+ bNodeSocket *sock1 = (bNodeSocket *)sockets->first;
+ bNodeSocket *sock2 = sock1->next;
+ bNodeSocket *sock3 = sock2->next;
+
+ node_sock_label_clear(sock1);
+ node_sock_label_clear(sock2);
+ node_sock_label_clear(sock3);
+
+ switch (mode) {
+ case NODE_COMBSEP_COLOR_RGB:
+ node_sock_label(sock1, "Red");
+ node_sock_label(sock2, "Green");
+ node_sock_label(sock3, "Blue");
+ break;
+ case NODE_COMBSEP_COLOR_HSL:
+ node_sock_label(sock1, "Hue");
+ node_sock_label(sock2, "Saturation");
+ node_sock_label(sock3, "Lightness");
+ break;
+ case NODE_COMBSEP_COLOR_HSV:
+ node_sock_label(sock1, "Hue");
+ node_sock_label(sock2, "Saturation");
+ node_sock_label(sock3, "Value");
+ break;
+ default: {
+ BLI_assert_unreachable();
+ break;
+ }
+ }
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/nodes/intern/node_util.h b/source/blender/nodes/intern/node_util.h
index de03a176c0c..0a2a7a70091 100644
--- a/source/blender/nodes/intern/node_util.h
+++ b/source/blender/nodes/intern/node_util.h
@@ -65,6 +65,7 @@ void node_filter_label(const struct bNodeTree *ntree,
const struct bNode *node,
char *label,
int maxlen);
+void node_combsep_color_label(const ListBase *sockets, NodeCombSepColorMode mode);
/*** Link Handling */
diff --git a/source/blender/nodes/shader/CMakeLists.txt b/source/blender/nodes/shader/CMakeLists.txt
index 9b4ea0e0db6..3e90f185168 100644
--- a/source/blender/nodes/shader/CMakeLists.txt
+++ b/source/blender/nodes/shader/CMakeLists.txt
@@ -82,6 +82,7 @@ set(SRC
nodes/node_shader_rgb.cc
nodes/node_shader_rgb_to_bw.cc
nodes/node_shader_script.cc
+ nodes/node_shader_sepcomb_color.cc
nodes/node_shader_sepcomb_hsv.cc
nodes/node_shader_sepcomb_rgb.cc
nodes/node_shader_sepcomb_xyz.cc
diff --git a/source/blender/nodes/shader/node_shader_tree.cc b/source/blender/nodes/shader/node_shader_tree.cc
index ec97637ccd2..f107ec73c60 100644
--- a/source/blender/nodes/shader/node_shader_tree.cc
+++ b/source/blender/nodes/shader/node_shader_tree.cc
@@ -587,7 +587,7 @@ static bNode *ntree_shader_copy_branch(bNodeTree *ntree,
}
}
}
- /* Recreate links between copied nodes AND incomming links to the copied nodes. */
+ /* Recreate links between copied nodes AND incoming links to the copied nodes. */
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
if (link->tonode->tmp_flag >= 0) {
bool from_node_copied = link->fromnode->tmp_flag >= 0;
diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.cc b/source/blender/nodes/shader/nodes/node_shader_curves.cc
index b1db0248d9f..eb47059063d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.cc
@@ -28,48 +28,34 @@ static int gpu_shader_curve_vec(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
- float *array, layer;
- int size;
-
- CurveMapping *cumap = (CurveMapping *)node->storage;
-
- BKE_curvemapping_init(cumap);
- BKE_curvemapping_table_RGBA(cumap, &array, &size);
- GPUNodeLink *tex = GPU_color_band(mat, size, array, &layer);
-
- float ext_xyz[3][4];
- float range_xyz[3];
-
- for (int a = 0; a < 3; a++) {
- const CurveMap *cm = &cumap->cm[a];
- ext_xyz[a][0] = cm->mintable;
- ext_xyz[a][2] = cm->maxtable;
- range_xyz[a] = 1.0f / max_ff(1e-8f, cm->maxtable - cm->mintable);
- /* Compute extrapolation gradients. */
- if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) != 0) {
- ext_xyz[a][1] = (cm->ext_in[0] != 0.0f) ? (cm->ext_in[1] / (cm->ext_in[0] * range_xyz[a])) :
- 1e8f;
- ext_xyz[a][3] = (cm->ext_out[0] != 0.0f) ?
- (cm->ext_out[1] / (cm->ext_out[0] * range_xyz[a])) :
- 1e8f;
- }
- else {
- ext_xyz[a][1] = 0.0f;
- ext_xyz[a][3] = 0.0f;
- }
- }
+ CurveMapping *curve_mapping = (CurveMapping *)node->storage;
+
+ BKE_curvemapping_init(curve_mapping);
+ float *band_values;
+ int band_size;
+ BKE_curvemapping_table_RGBA(curve_mapping, &band_values, &band_size);
+ float band_layer;
+ GPUNodeLink *band_texture = GPU_color_band(mat, band_size, band_values, &band_layer);
+
+ float start_slopes[CM_TOT];
+ float end_slopes[CM_TOT];
+ BKE_curvemapping_compute_slopes(curve_mapping, start_slopes, end_slopes);
+ float range_minimums[CM_TOT];
+ BKE_curvemapping_get_range_minimums(curve_mapping, range_minimums);
+ float range_dividers[CM_TOT];
+ BKE_curvemapping_compute_range_dividers(curve_mapping, range_dividers);
return GPU_stack_link(mat,
node,
- "curves_vec",
+ "curves_vector_mixed",
in,
out,
- tex,
- GPU_constant(&layer),
- GPU_uniform(range_xyz),
- GPU_uniform(ext_xyz[0]),
- GPU_uniform(ext_xyz[1]),
- GPU_uniform(ext_xyz[2]));
+ band_texture,
+ GPU_constant(&band_layer),
+ GPU_uniform(range_minimums),
+ GPU_uniform(range_dividers),
+ GPU_uniform(start_slopes),
+ GPU_uniform(end_slopes));
}
class CurveVecFunction : public fn::MultiFunction {
@@ -157,72 +143,59 @@ static int gpu_shader_curve_rgb(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
- float *array, layer;
- int size;
- bool use_opti = true;
-
- CurveMapping *cumap = (CurveMapping *)node->storage;
-
- BKE_curvemapping_init(cumap);
- BKE_curvemapping_table_RGBA(cumap, &array, &size);
- GPUNodeLink *tex = GPU_color_band(mat, size, array, &layer);
-
- float ext_rgba[4][4];
- float range_rgba[4];
-
- for (int a = 0; a < CM_TOT; a++) {
- const CurveMap *cm = &cumap->cm[a];
- ext_rgba[a][0] = cm->mintable;
- ext_rgba[a][2] = cm->maxtable;
- range_rgba[a] = 1.0f / max_ff(1e-8f, cm->maxtable - cm->mintable);
- /* Compute extrapolation gradients. */
- if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) != 0) {
- ext_rgba[a][1] = (cm->ext_in[0] != 0.0f) ?
- (cm->ext_in[1] / (cm->ext_in[0] * range_rgba[a])) :
- 1e8f;
- ext_rgba[a][3] = (cm->ext_out[0] != 0.0f) ?
- (cm->ext_out[1] / (cm->ext_out[0] * range_rgba[a])) :
- 1e8f;
- }
- else {
- ext_rgba[a][1] = 0.0f;
- ext_rgba[a][3] = 0.0f;
- }
-
- /* Check if rgb comps are just linear. */
- if (a < 3) {
- if (range_rgba[a] != 1.0f || ext_rgba[a][1] != 1.0f || ext_rgba[a][2] != 1.0f ||
- cm->totpoint != 2 || cm->curve[0].x != 0.0f || cm->curve[0].y != 0.0f ||
- cm->curve[1].x != 1.0f || cm->curve[1].y != 1.0f) {
- use_opti = false;
- }
- }
- }
-
- if (use_opti) {
+ CurveMapping *curve_mapping = (CurveMapping *)node->storage;
+
+ BKE_curvemapping_init(curve_mapping);
+ float *band_values;
+ int band_size;
+ BKE_curvemapping_table_RGBA(curve_mapping, &band_values, &band_size);
+ float band_layer;
+ GPUNodeLink *band_texture = GPU_color_band(mat, band_size, band_values, &band_layer);
+
+ float start_slopes[CM_TOT];
+ float end_slopes[CM_TOT];
+ BKE_curvemapping_compute_slopes(curve_mapping, start_slopes, end_slopes);
+ float range_minimums[CM_TOT];
+ BKE_curvemapping_get_range_minimums(curve_mapping, range_minimums);
+ float range_dividers[CM_TOT];
+ BKE_curvemapping_compute_range_dividers(curve_mapping, range_dividers);
+
+ /* Shader nodes don't do white balancing. */
+ float black_level[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ float white_level[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+
+ /* If the RGB curves do nothing, use a function that skips RGB computations. */
+ if (BKE_curvemapping_is_map_identity(curve_mapping, 0) &&
+ BKE_curvemapping_is_map_identity(curve_mapping, 1) &&
+ BKE_curvemapping_is_map_identity(curve_mapping, 2)) {
return GPU_stack_link(mat,
node,
- "curves_rgb_opti",
+ "curves_combined_only",
in,
out,
- tex,
- GPU_constant(&layer),
- GPU_uniform(range_rgba),
- GPU_uniform(ext_rgba[3]));
+ GPU_constant(black_level),
+ GPU_constant(white_level),
+ band_texture,
+ GPU_constant(&band_layer),
+ GPU_uniform(&range_minimums[3]),
+ GPU_uniform(&range_dividers[3]),
+ GPU_uniform(&start_slopes[3]),
+ GPU_uniform(&end_slopes[3]));
}
return GPU_stack_link(mat,
node,
- "curves_rgb",
+ "curves_combined_rgb",
in,
out,
- tex,
- GPU_constant(&layer),
- GPU_uniform(range_rgba),
- GPU_uniform(ext_rgba[0]),
- GPU_uniform(ext_rgba[1]),
- GPU_uniform(ext_rgba[2]),
- GPU_uniform(ext_rgba[3]));
+ GPU_constant(black_level),
+ GPU_constant(white_level),
+ band_texture,
+ GPU_constant(&band_layer),
+ GPU_uniform(range_minimums),
+ GPU_uniform(range_dividers),
+ GPU_uniform(start_slopes),
+ GPU_uniform(end_slopes));
}
class CurveRGBFunction : public fn::MultiFunction {
@@ -316,40 +289,34 @@ static int gpu_shader_curve_float(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
- float *array, layer;
- int size;
-
- CurveMapping *cumap = (CurveMapping *)node->storage;
+ CurveMapping *curve_mapping = (CurveMapping *)node->storage;
+
+ BKE_curvemapping_init(curve_mapping);
+ float *band_values;
+ int band_size;
+ BKE_curvemapping_table_RGBA(curve_mapping, &band_values, &band_size);
+ float band_layer;
+ GPUNodeLink *band_texture = GPU_color_band(mat, band_size, band_values, &band_layer);
+
+ float start_slopes[CM_TOT];
+ float end_slopes[CM_TOT];
+ BKE_curvemapping_compute_slopes(curve_mapping, start_slopes, end_slopes);
+ float range_minimums[CM_TOT];
+ BKE_curvemapping_get_range_minimums(curve_mapping, range_minimums);
+ float range_dividers[CM_TOT];
+ BKE_curvemapping_compute_range_dividers(curve_mapping, range_dividers);
- BKE_curvemapping_init(cumap);
- BKE_curvemapping_table_F(cumap, &array, &size);
- GPUNodeLink *tex = GPU_color_band(mat, size, array, &layer);
-
- float ext_xyz[4];
- float range_x;
-
- const CurveMap *cm = &cumap->cm[0];
- ext_xyz[0] = cm->mintable;
- ext_xyz[2] = cm->maxtable;
- range_x = 1.0f / max_ff(1e-8f, cm->maxtable - cm->mintable);
- /* Compute extrapolation gradients. */
- if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) != 0) {
- ext_xyz[1] = (cm->ext_in[0] != 0.0f) ? (cm->ext_in[1] / (cm->ext_in[0] * range_x)) : 1e8f;
- ext_xyz[3] = (cm->ext_out[0] != 0.0f) ? (cm->ext_out[1] / (cm->ext_out[0] * range_x)) : 1e8f;
- }
- else {
- ext_xyz[1] = 0.0f;
- ext_xyz[3] = 0.0f;
- }
return GPU_stack_link(mat,
node,
- "curve_float",
+ "curves_float_mixed",
in,
out,
- tex,
- GPU_constant(&layer),
- GPU_uniform(&range_x),
- GPU_uniform(ext_xyz));
+ band_texture,
+ GPU_constant(&band_layer),
+ GPU_uniform(range_minimums),
+ GPU_uniform(range_dividers),
+ GPU_uniform(start_slopes),
+ GPU_uniform(end_slopes));
}
class CurveFloatFunction : public fn::MultiFunction {
diff --git a/source/blender/nodes/shader/nodes/node_shader_map_range.cc b/source/blender/nodes/shader/nodes/node_shader_map_range.cc
index a487e07bd5a..5fc69987c67 100644
--- a/source/blender/nodes/shader/nodes/node_shader_map_range.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_map_range.cc
@@ -53,7 +53,7 @@ static void node_shader_buts_map_range(uiLayout *layout, bContext *UNUSED(C), Po
static int node_shader_map_range_ui_class(const bNode *node)
{
const NodeMapRange &storage = node_storage(*node);
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
if (data_type == CD_PROP_FLOAT3) {
return NODE_CLASS_OP_VECTOR;
}
@@ -63,7 +63,7 @@ static int node_shader_map_range_ui_class(const bNode *node)
static void node_shader_update_map_range(bNodeTree *ntree, bNode *node)
{
const NodeMapRange &storage = node_storage(*node);
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+ const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
const int type = (data_type == CD_PROP_FLOAT) ? SOCK_FLOAT : SOCK_VECTOR;
Array<bool> new_input_availability(BLI_listbase_count(&node->inputs));
@@ -108,7 +108,7 @@ static void node_shader_init_map_range(bNodeTree *UNUSED(ntree), bNode *node)
class SocketSearchOp {
public:
std::string socket_name;
- CustomDataType data_type;
+ eCustomDataType data_type;
int interpolation_type = NODE_MAP_RANGE_LINEAR;
void operator()(LinkSearchOpParams &params)
@@ -120,7 +120,7 @@ class SocketSearchOp {
}
};
-static std::optional<CustomDataType> node_type_from_other_socket(const bNodeSocket &socket)
+static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSocket &socket)
{
switch (socket.type) {
case SOCK_FLOAT:
@@ -137,7 +137,7 @@ static std::optional<CustomDataType> node_type_from_other_socket(const bNodeSock
static void node_map_range_gather_link_searches(GatherLinkSearchOpParams &params)
{
- const std::optional<CustomDataType> type = node_type_from_other_socket(params.other_socket());
+ const std::optional<eCustomDataType> type = node_type_from_other_socket(params.other_socket());
if (!type) {
return;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_color.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_color.cc
new file mode 100644
index 00000000000..8e378ebabce
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_color.cc
@@ -0,0 +1,162 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup shdnodes
+ */
+
+#include "node_shader_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+static void node_combsep_color_init(bNodeTree *UNUSED(tree), bNode *node)
+{
+ NodeCombSepColor *data = MEM_cnew<NodeCombSepColor>(__func__);
+ data->mode = NODE_COMBSEP_COLOR_RGB;
+ node->storage = data;
+}
+
+/* **************** SEPARATE COLOR ******************** */
+
+namespace blender::nodes::node_shader_separate_color_cc {
+
+NODE_STORAGE_FUNCS(NodeCombSepColor)
+
+static void sh_node_sepcolor_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_output<decl::Float>(N_("Red"));
+ b.add_output<decl::Float>(N_("Green"));
+ b.add_output<decl::Float>(N_("Blue"));
+}
+
+static void node_sepcolor_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ const NodeCombSepColor &storage = node_storage(*node);
+ node_combsep_color_label(&node->outputs, (NodeCombSepColorMode)storage.mode);
+}
+
+static const char *gpu_shader_get_name(int mode)
+{
+ switch (mode) {
+ case NODE_COMBSEP_COLOR_RGB:
+ return "separate_color_rgb";
+ case NODE_COMBSEP_COLOR_HSV:
+ return "separate_color_hsv";
+ case NODE_COMBSEP_COLOR_HSL:
+ return "separate_color_hsl";
+ }
+
+ return nullptr;
+}
+
+static int gpu_shader_sepcolor(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ const NodeCombSepColor &storage = node_storage(*node);
+ const char *name = gpu_shader_get_name(storage.mode);
+ if (name != nullptr) {
+ return GPU_stack_link(mat, node, name, in, out);
+ }
+
+ return 0;
+}
+
+} // namespace blender::nodes::node_shader_separate_color_cc
+
+void register_node_type_sh_sepcolor()
+{
+ namespace file_ns = blender::nodes::node_shader_separate_color_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_SEPARATE_COLOR, "Separate Color", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::sh_node_sepcolor_declare;
+ node_type_update(&ntype, file_ns::node_sepcolor_update);
+ node_type_init(&ntype, node_combsep_color_init);
+ node_type_storage(
+ &ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
+ node_type_gpu(&ntype, file_ns::gpu_shader_sepcolor);
+
+ nodeRegisterType(&ntype);
+}
+
+/* **************** COMBINE COLOR ******************** */
+
+namespace blender::nodes::node_shader_combine_color_cc {
+
+NODE_STORAGE_FUNCS(NodeCombSepColor)
+
+static void sh_node_combcolor_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("Red")).default_value(0.0f).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Green"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Blue"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_output<decl::Color>(N_("Color"));
+}
+
+static void node_combcolor_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ const NodeCombSepColor &storage = node_storage(*node);
+ node_combsep_color_label(&node->inputs, (NodeCombSepColorMode)storage.mode);
+}
+
+static const char *gpu_shader_get_name(int mode)
+{
+ switch (mode) {
+ case NODE_COMBSEP_COLOR_RGB:
+ return "combine_color_rgb";
+ case NODE_COMBSEP_COLOR_HSV:
+ return "combine_color_hsv";
+ case NODE_COMBSEP_COLOR_HSL:
+ return "combine_color_hsl";
+ }
+
+ return nullptr;
+}
+
+static int gpu_shader_combcolor(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ const NodeCombSepColor &storage = node_storage(*node);
+ const char *name = gpu_shader_get_name(storage.mode);
+ if (name != nullptr) {
+ return GPU_stack_link(mat, node, name, in, out);
+ }
+
+ return 0;
+}
+
+} // namespace blender::nodes::node_shader_combine_color_cc
+
+void register_node_type_sh_combcolor()
+{
+ namespace file_ns = blender::nodes::node_shader_combine_color_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_COMBINE_COLOR, "Combine Color", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::sh_node_combcolor_declare;
+ node_type_update(&ntype, file_ns::node_combcolor_update);
+ node_type_init(&ntype, node_combsep_color_init);
+ node_type_storage(
+ &ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
+ node_type_gpu(&ntype, file_ns::gpu_shader_combcolor);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_hsv.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_hsv.cc
index 129c8cf4b97..6dfabe48292 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_hsv.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_hsv.cc
@@ -36,7 +36,7 @@ void register_node_type_sh_sephsv()
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_SEPHSV, "Separate HSV", NODE_CLASS_CONVERTER);
+ sh_node_type_base(&ntype, SH_NODE_SEPHSV_LEGACY, "Separate HSV", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare_sephsv;
node_type_gpu(&ntype, file_ns::gpu_shader_sephsv);
@@ -72,7 +72,7 @@ void register_node_type_sh_combhsv()
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_COMBHSV, "Combine HSV", NODE_CLASS_CONVERTER);
+ sh_node_type_base(&ntype, SH_NODE_COMBHSV_LEGACY, "Combine HSV", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare_combhsv;
node_type_gpu(&ntype, file_ns::gpu_shader_combhsv);
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc
index 657f591a50c..28b55047633 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc
@@ -76,7 +76,7 @@ void register_node_type_sh_seprgb()
static bNodeType ntype;
- sh_fn_node_type_base(&ntype, SH_NODE_SEPRGB, "Separate RGB", NODE_CLASS_CONVERTER);
+ sh_fn_node_type_base(&ntype, SH_NODE_SEPRGB_LEGACY, "Separate RGB", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_seprgb_declare;
node_type_gpu(&ntype, file_ns::gpu_shader_seprgb);
ntype.build_multi_function = file_ns::sh_node_seprgb_build_multi_function;
@@ -119,7 +119,7 @@ void register_node_type_sh_combrgb()
static bNodeType ntype;
- sh_fn_node_type_base(&ntype, SH_NODE_COMBRGB, "Combine RGB", NODE_CLASS_CONVERTER);
+ sh_fn_node_type_base(&ntype, SH_NODE_COMBRGB_LEGACY, "Combine RGB", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_combrgb_declare;
node_type_gpu(&ntype, file_ns::gpu_shader_combrgb);
ntype.build_multi_function = file_ns::sh_node_combrgb_build_multi_function;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc
index 06c238fead0..c9588949761 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc
@@ -74,7 +74,7 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
const char *gpu_node_name = use_cubic ? "node_tex_tile_cubic" : "node_tex_tile_linear";
GPUNodeLink *gpu_image = GPU_image_tiled(mat, ima, iuser, sampler_state);
GPUNodeLink *gpu_image_tile_mapping = GPU_image_tiled_mapping(mat, ima, iuser);
- /* UDIM tiles needs a samper2DArray and sampler1DArray for tile mapping. */
+ /* UDIM tiles needs a `sampler2DArray` and `sampler1DArray` for tile mapping. */
GPU_stack_link(mat, node, gpu_node_name, in, out, gpu_image, gpu_image_tile_mapping);
}
else {
diff --git a/source/blender/nodes/shader/nodes/node_shader_uvmap.cc b/source/blender/nodes/shader/nodes/node_shader_uvmap.cc
index 91d89952da7..53228f0a314 100644
--- a/source/blender/nodes/shader/nodes/node_shader_uvmap.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_uvmap.cc
@@ -46,7 +46,7 @@ static int node_shader_gpu_uvmap(GPUMaterial *mat,
NodeShaderUVMap *attr = static_cast<NodeShaderUVMap *>(node->storage);
/* NOTE: using CD_AUTO_FROM_NAME instead of CD_MTFACE as geometry nodes may overwrite data which
- * will also change the CustomDataType. This will also make EEVEE and Cycles consistent. See
+ * will also change the eCustomDataType. This will also make EEVEE and Cycles consistent. See
* T93179. */
GPUNodeLink *mtface = GPU_attribute(mat, CD_AUTO_FROM_NAME, attr->uv_map);
diff --git a/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc
index cba944c671c..830f02d8df1 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc
@@ -43,7 +43,7 @@ static int node_shader_gpu_vertex_color(GPUMaterial *mat,
{
NodeShaderVertexColor *vertexColor = (NodeShaderVertexColor *)node->storage;
/* NOTE: using CD_AUTO_FROM_NAME instead of CD_MCOL or CD_PROP_COLOR for named attributes
- * as geometry nodes may overwrite data which will also change the CustomDataType.
+ * as geometry nodes may overwrite data which will also change the eCustomDataType.
* This will also make EEVEE and Cycles
* consistent. See T93179. */
diff --git a/source/blender/nodes/texture/CMakeLists.txt b/source/blender/nodes/texture/CMakeLists.txt
index 7706f118507..5bed54ebfd7 100644
--- a/source/blender/nodes/texture/CMakeLists.txt
+++ b/source/blender/nodes/texture/CMakeLists.txt
@@ -24,6 +24,7 @@ set(SRC
nodes/node_texture_at.c
nodes/node_texture_bricks.c
nodes/node_texture_checker.c
+ nodes/node_texture_combine_color.c
nodes/node_texture_common.c
nodes/node_texture_compose.c
nodes/node_texture_coord.c
@@ -39,6 +40,7 @@ set(SRC
nodes/node_texture_proc.c
nodes/node_texture_rotate.c
nodes/node_texture_scale.c
+ nodes/node_texture_separate_color.c
nodes/node_texture_texture.c
nodes/node_texture_translate.c
nodes/node_texture_valToNor.c
diff --git a/source/blender/nodes/texture/node_texture_util.c b/source/blender/nodes/texture/node_texture_util.c
index 76208104a8c..248114f242a 100644
--- a/source/blender/nodes/texture/node_texture_util.c
+++ b/source/blender/nodes/texture/node_texture_util.c
@@ -49,7 +49,7 @@ static void tex_call_delegate(TexDelegate *dg, float *out, TexParams *params, sh
}
}
-static void tex_input(float *out, int sz, bNodeStack *in, TexParams *params, short thread)
+static void tex_input(float *out, int num, bNodeStack *in, TexParams *params, short thread)
{
TexDelegate *dg = in->data;
if (dg) {
@@ -59,7 +59,7 @@ static void tex_input(float *out, int sz, bNodeStack *in, TexParams *params, sho
in->vec[1] = in->vec[2] = in->vec[0];
}
}
- memcpy(out, in->vec, sz * sizeof(float));
+ memcpy(out, in->vec, num * sizeof(float));
}
void tex_input_vec(float *out, bNodeStack *in, TexParams *params, short thread)
diff --git a/source/blender/nodes/texture/nodes/node_texture_combine_color.c b/source/blender/nodes/texture/nodes/node_texture_combine_color.c
new file mode 100644
index 00000000000..459553bc950
--- /dev/null
+++ b/source/blender/nodes/texture/nodes/node_texture_combine_color.c
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup texnodes
+ */
+
+#include "BLI_listbase.h"
+#include "NOD_texture.h"
+#include "node_texture_util.h"
+
+static bNodeSocketTemplate inputs[] = {
+ {SOCK_FLOAT, N_("Red"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ {SOCK_FLOAT, N_("Green"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ {SOCK_FLOAT, N_("Blue"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ {SOCK_FLOAT, N_("Alpha"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ {-1, ""},
+};
+static bNodeSocketTemplate outputs[] = {
+ {SOCK_RGBA, N_("Color")},
+ {-1, ""},
+};
+
+static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
+{
+ int i;
+ for (i = 0; i < 4; i++) {
+ out[i] = tex_input_value(in[i], p, thread);
+ }
+ /* Apply color space if required. */
+ switch (node->custom1) {
+ case NODE_COMBSEP_COLOR_RGB: {
+ /* Pass */
+ break;
+ }
+ case NODE_COMBSEP_COLOR_HSV: {
+ hsv_to_rgb_v(out, out);
+ break;
+ }
+ case NODE_COMBSEP_COLOR_HSL: {
+ hsl_to_rgb_v(out, out);
+ break;
+ }
+ default: {
+ BLI_assert_unreachable();
+ break;
+ }
+ }
+}
+
+static void update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node_combsep_color_label(&node->inputs, (NodeCombSepColorMode)node->custom1);
+}
+
+static void exec(void *data,
+ int UNUSED(thread),
+ bNode *node,
+ bNodeExecData *execdata,
+ bNodeStack **in,
+ bNodeStack **out)
+{
+ tex_output(node, execdata, in, out[0], &colorfn, data);
+}
+
+void register_node_type_tex_combine_color(void)
+{
+ static bNodeType ntype;
+
+ tex_node_type_base(&ntype, TEX_NODE_COMBINE_COLOR, "Combine Color", NODE_CLASS_OP_COLOR);
+ node_type_socket_templates(&ntype, inputs, outputs);
+ node_type_exec(&ntype, NULL, NULL, exec);
+ node_type_update(&ntype, update);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/texture/nodes/node_texture_compose.c b/source/blender/nodes/texture/nodes/node_texture_compose.c
index e341b65ac97..ef14062c72d 100644
--- a/source/blender/nodes/texture/nodes/node_texture_compose.c
+++ b/source/blender/nodes/texture/nodes/node_texture_compose.c
@@ -42,7 +42,7 @@ void register_node_type_tex_compose(void)
{
static bNodeType ntype;
- tex_node_type_base(&ntype, TEX_NODE_COMPOSE, "Combine RGBA", NODE_CLASS_OP_COLOR);
+ tex_node_type_base(&ntype, TEX_NODE_COMPOSE_LEGACY, "Combine RGBA", NODE_CLASS_OP_COLOR);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
diff --git a/source/blender/nodes/texture/nodes/node_texture_decompose.c b/source/blender/nodes/texture/nodes/node_texture_decompose.c
index 21c3944e255..2d42fa4602e 100644
--- a/source/blender/nodes/texture/nodes/node_texture_decompose.c
+++ b/source/blender/nodes/texture/nodes/node_texture_decompose.c
@@ -62,7 +62,7 @@ void register_node_type_tex_decompose(void)
{
static bNodeType ntype;
- tex_node_type_base(&ntype, TEX_NODE_DECOMPOSE, "Separate RGBA", NODE_CLASS_OP_COLOR);
+ tex_node_type_base(&ntype, TEX_NODE_DECOMPOSE_LEGACY, "Separate RGBA", NODE_CLASS_OP_COLOR);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
diff --git a/source/blender/nodes/texture/nodes/node_texture_separate_color.c b/source/blender/nodes/texture/nodes/node_texture_separate_color.c
new file mode 100644
index 00000000000..a482a3f3421
--- /dev/null
+++ b/source/blender/nodes/texture/nodes/node_texture_separate_color.c
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup texnodes
+ */
+
+#include "BLI_listbase.h"
+#include "NOD_texture.h"
+#include "node_texture_util.h"
+#include <math.h>
+
+static bNodeSocketTemplate inputs[] = {
+ {SOCK_RGBA, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f},
+ {-1, ""},
+};
+static bNodeSocketTemplate outputs[] = {
+ {SOCK_FLOAT, N_("Red")},
+ {SOCK_FLOAT, N_("Green")},
+ {SOCK_FLOAT, N_("Blue")},
+ {SOCK_FLOAT, N_("Alpha")},
+ {-1, ""},
+};
+
+static void apply_color_space(float *out, NodeCombSepColorMode type)
+{
+ switch (type) {
+ case NODE_COMBSEP_COLOR_RGB: {
+ /* Pass */
+ break;
+ }
+ case NODE_COMBSEP_COLOR_HSV: {
+ rgb_to_hsv_v(out, out);
+ break;
+ }
+ case NODE_COMBSEP_COLOR_HSL: {
+ rgb_to_hsl_v(out, out);
+ break;
+ }
+ default: {
+ BLI_assert_unreachable();
+ break;
+ }
+ }
+}
+
+static void valuefn_r(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
+{
+ tex_input_rgba(out, in[0], p, thread);
+ apply_color_space(out, (NodeCombSepColorMode)node->custom1);
+ *out = out[0];
+}
+
+static void valuefn_g(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
+{
+ tex_input_rgba(out, in[0], p, thread);
+ apply_color_space(out, (NodeCombSepColorMode)node->custom1);
+ *out = out[1];
+}
+
+static void valuefn_b(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
+{
+ tex_input_rgba(out, in[0], p, thread);
+ apply_color_space(out, (NodeCombSepColorMode)node->custom1);
+ *out = out[2];
+}
+
+static void valuefn_a(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
+{
+ tex_input_rgba(out, in[0], p, thread);
+ *out = out[3];
+}
+
+static void update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node_combsep_color_label(&node->outputs, (NodeCombSepColorMode)node->custom1);
+}
+
+static void exec(void *data,
+ int UNUSED(thread),
+ bNode *node,
+ bNodeExecData *execdata,
+ bNodeStack **in,
+ bNodeStack **out)
+{
+ tex_output(node, execdata, in, out[0], &valuefn_r, data);
+ tex_output(node, execdata, in, out[1], &valuefn_g, data);
+ tex_output(node, execdata, in, out[2], &valuefn_b, data);
+ tex_output(node, execdata, in, out[3], &valuefn_a, data);
+}
+
+void register_node_type_tex_separate_color(void)
+{
+ static bNodeType ntype;
+
+ tex_node_type_base(&ntype, TEX_NODE_SEPARATE_COLOR, "Separate Color", NODE_CLASS_OP_COLOR);
+ node_type_socket_templates(&ntype, inputs, outputs);
+ node_type_exec(&ntype, NULL, NULL, exec);
+ node_type_update(&ntype, update);
+
+ nodeRegisterType(&ntype);
+}