Blender V5.0
node_geo_set_shade_smooth.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "DNA_mesh_types.h"
6
8#include "UI_resources.hh"
9
10#include "NOD_rna_define.hh"
11
12#include "RNA_enum_types.hh"
13
15
16#include "node_geometry_util.hh"
17
19
21{
22 b.use_custom_socket_order();
23 b.allow_any_socket_order();
24 b.add_default_layout();
25 b.add_input<decl::Geometry>("Mesh", "Geometry")
26 .supported_type(GeometryComponent::Type::Mesh)
27 .description("Geometry to set the smoothness of");
28 b.add_output<decl::Geometry>("Mesh", "Geometry").propagate_all().align_with_previous();
29 b.add_input<decl::Bool>("Selection").default_value(true).hide_value().field_on_all();
30 b.add_input<decl::Bool>("Shade Smooth").default_value(true).field_on_all();
31}
32
33static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
34{
35 layout->prop(ptr, "domain", UI_ITEM_R_EXPAND, std::nullopt, ICON_NONE);
36}
37
38static void node_init(bNodeTree * /*tree*/, bNode *node)
39{
40 node->custom1 = int16_t(AttrDomain::Face);
41}
42
49 const StringRef name,
50 const Field<bool> &selection,
51 const Field<bool> &sharpness)
52{
53 if (selection.node().depends_on_input() || sharpness.node().depends_on_input()) {
54 return false;
55 }
56 if (!fn::evaluate_constant_field(selection)) {
57 return true;
58 }
59 if (fn::evaluate_constant_field(sharpness)) {
60 return false;
61 }
62 mesh.attributes_for_write().remove(name);
63 return true;
64}
65
66static void set_sharp(Mesh &mesh,
67 const AttrDomain domain,
68 const StringRef name,
69 const Field<bool> &selection,
70 const Field<bool> &sharpness)
71{
72 const int domain_size = mesh.attributes().domain_size(domain);
73 if (domain_size == 0) {
74 return;
75 }
76 if (try_removing_sharp_attribute(mesh, name, selection, sharpness)) {
77 return;
78 }
79 bke::try_capture_field_on_geometry(mesh.attributes_for_write(),
80 bke::MeshFieldContext(mesh, domain),
81 name,
82 domain,
83 selection,
84 sharpness);
85}
86
88{
89 GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
90 const AttrDomain domain = AttrDomain(params.node().custom1);
91 const Field<bool> selection = params.extract_input<Field<bool>>("Selection");
92 const Field<bool> smooth_field = params.extract_input<Field<bool>>("Shade Smooth");
93
94 geometry::foreach_real_geometry(geometry_set, [&](GeometrySet &geometry_set) {
95 if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
96 set_sharp(*mesh,
97 domain,
98 domain == AttrDomain::Face ? "sharp_face" : "sharp_edge",
99 selection,
100 fn::invert_boolean_field(smooth_field));
101 }
102 });
103 params.set_output("Geometry", std::move(geometry_set));
104}
105
106static void node_rna(StructRNA *srna)
107{
109 "domain",
110 "Domain",
111 "",
114}
115
116static void node_register()
117{
118 static blender::bke::bNodeType ntype;
119
120 geo_node_type_base(&ntype, "GeometryNodeSetShadeSmooth", GEO_NODE_SET_SHADE_SMOOTH);
121 ntype.ui_name = "Set Shade Smooth";
122 ntype.ui_description =
123 "Control the smoothness of mesh normals around each face by changing the \"shade smooth\" "
124 "attribute";
125 ntype.enum_name_legacy = "SET_SHADE_SMOOTH";
128 ntype.declare = node_declare;
129 ntype.initfunc = node_init;
132
133 node_rna(ntype.rna_ext.srna);
134}
136
137} // namespace blender::nodes::node_geo_set_shade_smooth_cc
#define NODE_CLASS_GEOMETRY
Definition BKE_node.hh:461
#define GEO_NODE_SET_SHADE_SMOOTH
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_inline_enum_accessors(member)
@ UI_ITEM_R_EXPAND
AttributeSet attributes
bool depends_on_input() const
Definition FN_field.hh:554
const FieldNode & node() const
Definition FN_field.hh:135
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
bool try_capture_field_on_geometry(MutableAttributeAccessor attributes, const fn::FieldContext &field_context, const StringRef attribute_id, AttrDomain domain, const fn::Field< bool > &selection, const fn::GField &field)
Field< bool > invert_boolean_field(const Field< bool > &field)
Definition field.cc:520
void evaluate_constant_field(const GField &field, void *r_value)
Definition field.cc:493
void foreach_real_geometry(bke::GeometrySet &geometry, FunctionRef< void(bke::GeometrySet &geometry_set)> fn)
static void node_declare(NodeDeclarationBuilder &b)
static void set_sharp(Mesh &mesh, const AttrDomain domain, const StringRef name, const Field< bool > &selection, const Field< bool > &sharpness)
static void node_init(bNodeTree *, bNode *node)
static bool try_removing_sharp_attribute(Mesh &mesh, const StringRef name, const Field< bool > &selection, const Field< bool > &sharpness)
static void node_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
static void node_geo_exec(GeoNodeExecParams params)
PropertyRNA * RNA_def_node_enum(StructRNA *srna, const char *identifier, const char *ui_name, const char *ui_description, const EnumPropertyItem *static_items, const EnumRNAAccessors accessors, std::optional< int > default_value, const EnumPropertyItemFunc item_func, const bool allow_animation)
void geo_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
const char * name
const EnumPropertyItem rna_enum_attribute_domain_edge_face_items[]
StructRNA * srna
int16_t custom1
Defines a node type.
Definition BKE_node.hh:238
std::string ui_description
Definition BKE_node.hh:244
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:289
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:354
const char * enum_name_legacy
Definition BKE_node.hh:247
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:259
NodeDeclareFunction declare
Definition BKE_node.hh:362
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
PointerRNA * ptr
Definition wm_files.cc:4238