32 b.use_custom_socket_order();
33 b.allow_any_socket_order();
34 b.add_default_layout();
35 b.add_input<
decl::Geometry>(
"Mesh").supported_type(GeometryComponent::Type::Mesh);
36 b.add_output<
decl::Geometry>(
"Mesh").propagate_all().align_with_previous();
53 "Place vertices at the surface that would be produced with infinite "
54 "levels of subdivision (smoothest possible shape)");
76 attributes.
remove(
"crease_vert");
83 attributes.
remove(
"crease_edge");
89 if (
const std::optional<float> value = varray.
get_if_single()) {
90 return *value == 0.0f;
95static fn::Field<float> clamp_crease(fn::Field<float> crease_field)
97 static auto clamp_fn = mf::build::SI1_SO<float, float>(
99 [](
float value) {
return std::clamp(value, 0.0f, 1.0f); },
100 mf::build::exec_presets::AllSpanOrSingle());
104static Mesh *mesh_subsurf_calc(
const Mesh *mesh,
106 const Field<float> &vert_crease_field,
107 const Field<float> &edge_crease_field,
108 const int boundary_smooth,
110 const bool use_limit_surface)
112 const bke::MeshFieldContext point_context{*mesh, AttrDomain::Point};
113 FieldEvaluator point_evaluator(point_context, mesh->
verts_num);
114 point_evaluator.add(clamp_crease(vert_crease_field));
115 point_evaluator.evaluate();
117 const bke::MeshFieldContext edge_context{*mesh, AttrDomain::Edge};
118 FieldEvaluator edge_evaluator(edge_context, mesh->
edges_num);
119 edge_evaluator.add(clamp_crease(edge_crease_field));
120 edge_evaluator.evaluate();
122 const VArray<float> vert_creases = point_evaluator.get_evaluated<
float>(0);
123 const VArray<float> edge_creases = edge_evaluator.get_evaluated<
float>(0);
124 const bool use_creases = !varray_is_single_zero(vert_creases) ||
125 !varray_is_single_zero(edge_creases);
127 Mesh *mesh_copy =
nullptr;
133 write_vert_creases(*mesh_copy, vert_creases);
134 write_edge_creases(*mesh_copy, edge_creases);
138 bke::subdiv::ToMeshSettings mesh_settings;
139 mesh_settings.resolution = (1 << level) + 1;
140 mesh_settings.use_optimal_display =
false;
142 bke::subdiv::Settings subdiv_settings;
143 subdiv_settings.is_simple =
false;
144 subdiv_settings.is_adaptive = use_limit_surface;
145 subdiv_settings.use_creases = use_creases;
146 subdiv_settings.level = level;
147 subdiv_settings.vtx_boundary_interpolation =
164 result->attributes_for_write().remove(
"crease_vert");
165 result->attributes_for_write().remove(
"crease_edge");
182#ifdef WITH_OPENSUBDIV
187 const int uv_smooth = storage.uv_smooth;
188 const int boundary_smooth = storage.boundary_smooth;
189 const int level = std::max(
params.extract_input<
int>(
"Level"), 0);
190 const bool use_limit_surface =
params.extract_input<
bool>(
"Limit Surface");
192 params.set_output(
"Mesh", std::move(geometry_set));
198 params.set_default_remaining_outputs();
205 mesh, level, vert_crease, edge_crease, boundary_smooth, uv_smooth, use_limit_surface));
210 TIP_(
"Disabled, Blender was compiled without OpenSubdiv"));
213 params.set_output(
"Mesh", std::move(geometry_set));
221 "Controls how smoothing is applied to UVs",
231 "Controls how open boundaries are smoothed",
244 ntype.
ui_name =
"Subdivision Surface";
246 "Divide mesh faces to form a smooth surface, using the Catmull-Clark subdivision method";
255 "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
#define GEO_NODE_SUBDIVISION_SURFACE
@ SUBSURF_BOUNDARY_SMOOTH_ALL
@ SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_storage_enum_accessors(member)
BMesh const char void * data
std::optional< T > get_if_single() const
bool remove(const StringRef attribute_id)
bool add(const StringRef attribute_id, const AttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer)
static std::shared_ptr< FieldOperation > Create(std::shared_ptr< const mf::MultiFunction > function, Vector< GField > inputs={})
void * MEM_callocN(size_t len, const char *str)
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_register_type(bNodeType &ntype)
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))
void node_type_size_preset(bNodeType &ntype, eNodeSizePreset size)
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, std::string idname, const std::optional< int16_t > legacy_type)
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 replace_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
std::string ui_description
void(* initfunc)(bNodeTree *ntree, bNode *node)
NodeGeometryExecFunction geometry_node_execute
const char * enum_name_legacy
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
NodeDeclareFunction declare
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)