33 b.add_input<
decl::Int>(
"Level").default_value(1).min(0).max(6);
68 attributes.
remove(
"crease_vert");
75 attributes.
remove(
"crease_edge");
79static bool varray_is_single_zero(
const VArray<float> &varray)
81 if (
const std::optional<float> value = varray.get_if_single()) {
82 return *value == 0.0f;
87static fn::Field<float> clamp_crease(fn::Field<float> crease_field)
89 static auto clamp_fn = mf::build::SI1_SO<float, float>(
91 [](
float value) {
return std::clamp(value, 0.0f, 1.0f); },
92 mf::build::exec_presets::AllSpanOrSingle());
96static Mesh *mesh_subsurf_calc(
const Mesh *mesh,
98 const Field<float> &vert_crease_field,
99 const Field<float> &edge_crease_field,
100 const int boundary_smooth,
103 const bke::MeshFieldContext point_context{*
mesh, AttrDomain::Point};
104 FieldEvaluator point_evaluator(point_context, mesh->verts_num);
105 point_evaluator.add(clamp_crease(vert_crease_field));
106 point_evaluator.evaluate();
108 const bke::MeshFieldContext edge_context{*
mesh, AttrDomain::Edge};
109 FieldEvaluator edge_evaluator(edge_context, mesh->edges_num);
110 edge_evaluator.add(clamp_crease(edge_crease_field));
111 edge_evaluator.evaluate();
113 const VArray<float> vert_creases = point_evaluator.get_evaluated<
float>(0);
114 const VArray<float> edge_creases = edge_evaluator.get_evaluated<
float>(0);
115 const bool use_creases = !varray_is_single_zero(vert_creases) ||
116 !varray_is_single_zero(edge_creases);
118 Mesh *mesh_copy =
nullptr;
124 write_vert_creases(*mesh_copy, vert_creases);
125 write_edge_creases(*mesh_copy, edge_creases);
129 bke::subdiv::ToMeshSettings mesh_settings;
130 mesh_settings.resolution = (1 << level) + 1;
131 mesh_settings.use_optimal_display =
false;
133 bke::subdiv::Settings subdiv_settings;
134 subdiv_settings.is_simple =
false;
135 subdiv_settings.is_adaptive =
false;
136 subdiv_settings.use_creases = use_creases;
137 subdiv_settings.level = level;
138 subdiv_settings.vtx_boundary_interpolation =
155 result->attributes_for_write().remove(
"crease_vert");
156 result->attributes_for_write().remove(
"crease_edge");
173#ifdef WITH_OPENSUBDIV
178 const int uv_smooth = storage.uv_smooth;
179 const int boundary_smooth = storage.boundary_smooth;
180 const int level = std::clamp(
params.extract_input<
int>(
"Level"), 0, 11);
182 params.set_output(
"Mesh", std::move(geometry_set));
188 geometry_set.replace_mesh(
189 mesh_subsurf_calc(mesh, level, vert_crease, edge_crease, boundary_smooth, uv_smooth));
193 params.error_message_add(NodeWarningType::Error,
194 TIP_(
"Disabled, Blender was compiled without OpenSubdiv"));
197 params.set_output(
"Mesh", std::move(geometry_set));
205 "Controls how smoothing is applied to UVs",
215 "Controls how open boundaries are smoothed",
235 "NodeGeometrySubdivisionSurface",
void BKE_id_free(Main *bmain, void *idv)
Mesh * BKE_mesh_copy_for_eval(const Mesh &source)
#define NODE_STORAGE_FUNCS(StorageT)
#define NODE_CLASS_GEOMETRY
@ SUBSURF_BOUNDARY_SMOOTH_ALL
@ SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_storage_enum_accessors(member)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
bool remove(const StringRef attribute_id)
static std::shared_ptr< FieldOperation > Create(std::shared_ptr< const mf::MultiFunction > function, Vector< GField > inputs={})
local_group_size(16, 16) .push_constant(Type b
void free(Subdiv *subdiv)
Subdiv * new_from_mesh(const Settings *settings, const Mesh *mesh)
FVarLinearInterpolation fvar_interpolation_from_uv_smooth(int uv_smooth)
VtxBoundaryInterpolation vtx_boundary_interpolation_from_subsurf(int boundary_smooth)
Mesh * subdiv_to_mesh(Subdiv *subdiv, const ToMeshSettings *settings, const Mesh *coarse_mesh)
void node_type_size_preset(bNodeType *ntype, eNodeSizePreset size)
void node_type_storage(bNodeType *ntype, const char *storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
void node_register_type(bNodeType *ntype)
void debug_randomize_mesh_order(Mesh *mesh)
static void node_geo_exec(GeoNodeExecParams params)
static void node_register()
static void node_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
static void node_init(bNodeTree *, bNode *node)
static void node_declare(NodeDeclarationBuilder &b)
static void node_rna(StructRNA *srna)
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, int type, const char *name, short nclass)
void node_free_standard_storage(bNode *node)
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
const EnumPropertyItem rna_enum_subdivision_uv_smooth_items[]
const EnumPropertyItem rna_enum_subdivision_boundary_smooth_items[]
const Mesh * get_mesh() const
void modify_geometry_sets(ForeachSubGeometryCallback callback)
void(* initfunc)(bNodeTree *ntree, bNode *node)
NodeGeometryExecFunction geometry_node_execute
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
NodeDeclareFunction declare