28 b.use_custom_socket_order();
29 b.allow_any_socket_order();
31 .supported_type(GeometryComponent::Type::Mesh)
32 .description(
"Mesh to subdivide");
33 b.add_output<
decl::Geometry>(
"Mesh").propagate_all().align_with_previous();
50 "Place vertices at the surface that would be produced with infinite "
51 "levels of subdivision (smoothest possible shape)");
56 .description(
"Controls how smoothing is applied to UVs");
61 .description(
"Controls how open boundaries are smoothed");
75 attributes.
remove(
"crease_vert");
82 attributes.
remove(
"crease_edge");
88 if (
const std::optional<float> value = varray.
get_if_single()) {
89 return *value == 0.0f;
94static fn::Field<float> clamp_crease(fn::Field<float> crease_field)
96 static auto clamp_fn = mf::build::SI1_SO<float, float>(
98 [](
float value) {
return std::clamp(value, 0.0f, 1.0f); },
99 mf::build::exec_presets::AllSpanOrSingle());
103static Mesh *mesh_subsurf_calc(
const Mesh *mesh,
105 const Field<float> &vert_crease_field,
106 const Field<float> &edge_crease_field,
107 const int boundary_smooth,
109 const bool use_limit_surface)
111 const bke::MeshFieldContext point_context{*mesh, AttrDomain::Point};
112 FieldEvaluator point_evaluator(point_context, mesh->
verts_num);
113 point_evaluator.add(clamp_crease(vert_crease_field));
114 point_evaluator.evaluate();
116 const bke::MeshFieldContext edge_context{*mesh, AttrDomain::Edge};
117 FieldEvaluator edge_evaluator(edge_context, mesh->
edges_num);
118 edge_evaluator.add(clamp_crease(edge_crease_field));
119 edge_evaluator.evaluate();
121 const VArray<float> vert_creases = point_evaluator.get_evaluated<
float>(0);
122 const VArray<float> edge_creases = edge_evaluator.get_evaluated<
float>(0);
123 const bool use_creases = !varray_is_single_zero(vert_creases) ||
124 !varray_is_single_zero(edge_creases);
126 Mesh *mesh_copy =
nullptr;
132 write_vert_creases(*mesh_copy, vert_creases);
133 write_edge_creases(*mesh_copy, edge_creases);
137 bke::subdiv::ToMeshSettings mesh_settings;
138 mesh_settings.resolution = (1 << level) + 1;
139 mesh_settings.use_optimal_display =
false;
141 bke::subdiv::Settings subdiv_settings;
142 subdiv_settings.is_simple =
false;
143 subdiv_settings.is_adaptive = use_limit_surface;
144 subdiv_settings.use_creases = use_creases;
145 subdiv_settings.level = level;
146 subdiv_settings.vtx_boundary_interpolation =
163 result->attributes_for_write().remove(
"crease_vert");
164 result->attributes_for_write().remove(
"crease_edge");
181#ifdef WITH_OPENSUBDIV
187 const int level = std::max(
params.extract_input<
int>(
"Level"), 0);
188 const bool use_limit_surface =
params.extract_input<
bool>(
"Limit Surface");
190 params.set_output(
"Mesh", std::move(geometry_set));
196 params.set_default_remaining_outputs();
203 mesh, level, vert_crease, edge_crease, boundary_smooth, uv_smooth, use_limit_surface));
208 TIP_(
"Disabled, Blender was compiled without OpenSubdiv"));
211 params.set_output(
"Mesh", std::move(geometry_set));
219 ntype.
ui_name =
"Subdivision Surface";
221 "Divide mesh faces to form a smooth surface, using the Catmull-Clark subdivision method";
229 "NodeGeometrySubdivisionSurface",
void node_type_storage(bNodeType &ntype, std::optional< StringRefNull > storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))