diff options
Diffstat (limited to 'source/blender/nodes')
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 ¶ms) { 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 ¶ms) { - 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 ¶ms) 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 ¶ms) 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 ¶ms) 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 ¶ms, 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 ¶ms, 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 ¶ms, } /** - * \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 ¶ms) 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 ¶ms) 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 ¶ms, 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 ¶ms, 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 ¶ms) 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 ¶ms, const CustomDataType data_type) +static GField get_input_attribute_field(GeoNodeExecParams ¶ms, 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 ¶ms, 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 ¶ms, 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 ¶ms) 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 ¶ms) 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 ¶ms, 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 ¶ms) 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 ¶ms, const CustomDataType data_type) +static GField get_input_attribute_field(GeoNodeExecParams ¶ms, 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 ¶ms, 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 ¶ms) 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 ¶ms) @@ -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 ¶ms) { - 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); +} |