1
1

Geometry Nodes: Add UV Smooth, Boundary Smooth options to subdivision node

Replaces the boolean option with enum menus for consistency
with the subdivision modifier (rB66151b5de3ff,rB3d3b6d94e6e).
Adds all UV interpolation options.
Original patch by Eitan. Updated by Himanshi Kalra <calra>.
{F9883204}

Reviewed By: HooglyBoogly

Differential Revision: https://developer.blender.org/D10417
This commit is contained in:
Eitan
2021-08-16 14:25:10 +05:30
committed by Himanshi Kalra
parent ddecd7aaca
commit fecec1644c
6 changed files with 106 additions and 53 deletions

View File

@@ -1328,6 +1328,13 @@ typedef struct NodeAttributeConvert {
int8_t domain;
} NodeAttributeConvert;
typedef struct NodeGeometrySubdivisionSurface {
/* eSubsurfUVSmooth. */
uint8_t uv_smooth;
/* eSubsurfBoundarySmooth. */
uint8_t boundary_smooth;
} NodeGeometrySubdivisionSurface;
typedef struct NodeGeometryMeshCircle {
/* GeometryNodeMeshCircleFillType. */
uint8_t fill_type;

View File

@@ -245,6 +245,8 @@ extern const EnumPropertyItem *rna_enum_attribute_domain_itemf(struct ID *id, bo
extern const EnumPropertyItem rna_enum_collection_color_items[];
extern const EnumPropertyItem rna_enum_subdivision_uv_smooth_items[];
extern const EnumPropertyItem rna_enum_subdivision_boundary_smooth_items[];
/**
* For ID filters (#FILTER_ID_AC, #FILTER_ID_AR, ...) an int isn't enough. This version allows 64
* bit integers. So can't use the regular #EnumPropertyItem. Would be nice if RNA supported this

View File

@@ -595,6 +595,44 @@ const EnumPropertyItem rna_enum_axis_flag_xyz_items[] = {
{0, NULL, 0, NULL, NULL},
};
const EnumPropertyItem rna_enum_subdivision_uv_smooth_items[] = {
{SUBSURF_UV_SMOOTH_NONE, "NONE", 0, "None", "UVs are not smoothed, boundaries are kept sharp"},
{SUBSURF_UV_SMOOTH_PRESERVE_CORNERS,
"PRESERVE_CORNERS",
0,
"Keep Corners",
"UVs are smoothed, corners on discontinuous boundary are kept sharp"},
{SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_AND_JUNCTIONS,
"PRESERVE_CORNERS_AND_JUNCTIONS",
0,
"Keep Corners, Junctions",
"UVs are smoothed, corners on discontinuous boundary and "
"junctions of 3 or more regions are kept sharp"},
{SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_JUNCTIONS_AND_CONCAVE,
"PRESERVE_CORNERS_JUNCTIONS_AND_CONCAVE",
0,
"Keep Corners, Junctions, Concave",
"UVs are smoothed, corners on discontinuous boundary, "
"junctions of 3 or more regions and darts and concave corners are kept sharp"},
{SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES,
"PRESERVE_BOUNDARIES",
0,
"Keep Boundaries",
"UVs are smoothed, boundaries are kept sharp"},
{SUBSURF_UV_SMOOTH_ALL, "SMOOTH_ALL", 0, "All", "UVs and boundaries are smoothed"},
{0, NULL, 0, NULL, NULL},
};
const EnumPropertyItem rna_enum_subdivision_boundary_smooth_items[] = {
{SUBSURF_BOUNDARY_SMOOTH_PRESERVE_CORNERS,
"PRESERVE_CORNERS",
0,
"Keep Corners",
"Smooth boundaries, but corners are kept sharp"},
{SUBSURF_BOUNDARY_SMOOTH_ALL, "ALL", 0, "All", "Smooth boundaries, including corners"},
{0, NULL, 0, NULL, NULL},
};
#ifdef RNA_RUNTIME
# include "DNA_curve_types.h"
# include "DNA_fluid_types.h"
@@ -1631,55 +1669,12 @@ static IDProperty **rna_NodesModifier_properties(PointerRNA *ptr)
static void rna_def_property_subdivision_common(StructRNA *srna)
{
static const EnumPropertyItem prop_uv_smooth_items[] = {
{SUBSURF_UV_SMOOTH_NONE,
"NONE",
0,
"None",
"UVs are not smoothed, boundaries are kept sharp"},
{SUBSURF_UV_SMOOTH_PRESERVE_CORNERS,
"PRESERVE_CORNERS",
0,
"Keep Corners",
"UVs are smoothed, corners on discontinuous boundary are kept sharp"},
{SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_AND_JUNCTIONS,
"PRESERVE_CORNERS_AND_JUNCTIONS",
0,
"Keep Corners, Junctions",
"UVs are smoothed, corners on discontinuous boundary and "
"junctions of 3 or more regions are kept sharp"},
{SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_JUNCTIONS_AND_CONCAVE,
"PRESERVE_CORNERS_JUNCTIONS_AND_CONCAVE",
0,
"Keep Corners, Junctions, Concave",
"UVs are smoothed, corners on discontinuous boundary, "
"junctions of 3 or more regions and darts and concave corners are kept sharp"},
{SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES,
"PRESERVE_BOUNDARIES",
0,
"Keep Boundaries",
"UVs are smoothed, boundaries are kept sharp"},
{SUBSURF_UV_SMOOTH_ALL, "SMOOTH_ALL", 0, "All", "UVs and boundaries are smoothed"},
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem prop_boundary_smooth_items[] = {
{SUBSURF_BOUNDARY_SMOOTH_PRESERVE_CORNERS,
"PRESERVE_CORNERS",
0,
"Keep Corners",
"Smooth boundaries, but corners are kept sharp"},
{SUBSURF_BOUNDARY_SMOOTH_ALL, "ALL", 0, "All", "Smooth boundaries, including corners"},
{0, NULL, 0, NULL, NULL},
};
PropertyRNA *prop;
RNA_define_lib_overridable(true);
prop = RNA_def_property(srna, "uv_smooth", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "uv_smooth");
RNA_def_property_enum_items(prop, prop_uv_smooth_items);
RNA_def_property_enum_items(prop, rna_enum_subdivision_uv_smooth_items);
RNA_def_property_ui_text(prop, "UV Smooth", "Controls how smoothing is applied to UVs");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
@@ -1693,7 +1688,7 @@ static void rna_def_property_subdivision_common(StructRNA *srna)
prop = RNA_def_property(srna, "boundary_smooth", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "boundary_smooth");
RNA_def_property_enum_items(prop, prop_boundary_smooth_items);
RNA_def_property_enum_items(prop, rna_enum_subdivision_boundary_smooth_items);
RNA_def_property_ui_text(prop, "Boundary Smooth", "Controls how open boundaries are smoothed");
RNA_def_property_update(prop, 0, "rna_Modifier_update");

View File

@@ -9095,6 +9095,26 @@ static void def_geo_triangulate(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_geo_subdivision_surface(StructRNA *srna)
{
PropertyRNA *prop;
RNA_def_struct_sdna_from(srna, "NodeGeometrySubdivisionSurface", "storage");
prop = RNA_def_property(srna, "uv_smooth", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "uv_smooth");
RNA_def_property_enum_items(prop, rna_enum_subdivision_uv_smooth_items);
RNA_def_property_enum_default(prop, SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES);
RNA_def_property_ui_text(prop, "UV Smooth", "Controls how smoothing is applied to UVs");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "boundary_smooth", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "boundary_smooth");
RNA_def_property_enum_items(prop, rna_enum_subdivision_boundary_smooth_items);
RNA_def_property_enum_default(prop, SUBSURF_BOUNDARY_SMOOTH_ALL);
RNA_def_property_ui_text(prop, "Boundary Smooth", "Controls how open boundaries are smoothed");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_geo_attribute_randomize(StructRNA *srna)
{
PropertyRNA *prop;

View File

@@ -337,7 +337,7 @@ DefNode(GeometryNode, GEO_NODE_POINTS_TO_VOLUME, def_geo_points_to_volume, "POIN
DefNode(GeometryNode, GEO_NODE_RAYCAST, def_geo_raycast, "RAYCAST", Raycast, "Raycast", "")
DefNode(GeometryNode, GEO_NODE_SELECT_BY_MATERIAL, 0, "SELECT_BY_MATERIAL", SelectByMaterial, "Select by Material", "")
DefNode(GeometryNode, GEO_NODE_SEPARATE_COMPONENTS, 0, "SEPARATE_COMPONENTS", SeparateComponents, "Separate Components", "")
DefNode(GeometryNode, GEO_NODE_SUBDIVISION_SURFACE, 0, "SUBDIVISION_SURFACE", SubdivisionSurface, "Subdivision Surface", "")
DefNode(GeometryNode, GEO_NODE_SUBDIVISION_SURFACE, def_geo_subdivision_surface, "SUBDIVISION_SURFACE", SubdivisionSurface, "Subdivision Surface", "")
DefNode(GeometryNode, GEO_NODE_SWITCH, def_geo_switch, "SWITCH", Switch, "Switch", "")
DefNode(GeometryNode, GEO_NODE_TRANSFORM, 0, "TRANSFORM", Transform, "Transform", "")
DefNode(GeometryNode, GEO_NODE_TRIANGULATE, def_geo_triangulate, "TRIANGULATE", Triangulate, "Triangulate", "")

View File

@@ -20,15 +20,13 @@
#include "UI_interface.h"
#include "UI_resources.h"
#include "DNA_modifier_types.h"
#include "node_geometry_util.hh"
static bNodeSocketTemplate geo_node_subdivision_surface_in[] = {
{SOCK_GEOMETRY, N_("Geometry")},
{SOCK_INT, N_("Level"), 1, 0, 0, 0, 0, 6},
{SOCK_BOOLEAN, N_("Use Creases")},
{SOCK_BOOLEAN, N_("Boundary Smooth"), true},
{SOCK_BOOLEAN, N_("Smooth UVs")},
{-1, ""},
};
@@ -37,6 +35,29 @@ static bNodeSocketTemplate geo_node_subdivision_surface_out[] = {
{-1, ""},
};
static void geo_node_subdivision_surface_layout(uiLayout *layout,
bContext *UNUSED(C),
PointerRNA *ptr)
{
#ifndef WITH_OPENSUBDIV
uiItemL(layout, IFACE_("Disabled, built without OpenSubdiv"), ICON_ERROR);
#else
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
uiItemR(layout, ptr, "uv_smooth", 0, nullptr, ICON_NONE);
uiItemR(layout, ptr, "boundary_smooth", 0, nullptr, ICON_NONE);
#endif
}
static void geo_node_subdivision_surface_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeGeometrySubdivisionSurface *data = (NodeGeometrySubdivisionSurface *)MEM_callocN(
sizeof(NodeGeometrySubdivisionSurface), __func__);
data->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES;
data->boundary_smooth = SUBSURF_BOUNDARY_SMOOTH_ALL;
node->storage = data;
}
namespace blender::nodes {
static void geo_node_subdivision_surface_exec(GeoNodeExecParams params)
{
@@ -53,6 +74,9 @@ static void geo_node_subdivision_surface_exec(GeoNodeExecParams params)
params.error_message_add(NodeWarningType::Error,
TIP_("Disabled, Blender was compiled without OpenSubdiv"));
#else
const NodeGeometrySubdivisionSurface &storage = *(const NodeGeometrySubdivisionSurface *)params.node().storage;
const int uv_smooth = storage.uv_smooth;
const int boundary_smooth = storage.boundary_smooth;
const int subdiv_level = clamp_i(params.extract_input<int>("Level"), 0, 30);
/* Only process subdivision if level is greater than 0. */
@@ -62,8 +86,6 @@ static void geo_node_subdivision_surface_exec(GeoNodeExecParams params)
}
const bool use_crease = params.extract_input<bool>("Use Creases");
const bool boundary_smooth = params.extract_input<bool>("Boundary Smooth");
const bool smooth_uvs = params.extract_input<bool>("Smooth UVs");
const Mesh *mesh_in = geometry_set.get_mesh_for_read();
/* Initialize mesh settings. */
@@ -79,9 +101,9 @@ static void geo_node_subdivision_surface_exec(GeoNodeExecParams params)
subdiv_settings.level = subdiv_level;
subdiv_settings.vtx_boundary_interpolation = BKE_subdiv_vtx_boundary_interpolation_from_subsurf(
!boundary_smooth);
boundary_smooth);
subdiv_settings.fvar_linear_interpolation = BKE_subdiv_fvar_interpolation_from_uv_smooth(
smooth_uvs);
uv_smooth);
/* Apply subdivision to mesh. */
Subdiv *subdiv = BKE_subdiv_update_from_mesh(nullptr, &subdiv_settings, mesh_in);
@@ -117,5 +139,12 @@ void register_node_type_geo_subdivision_surface()
node_type_socket_templates(
&ntype, geo_node_subdivision_surface_in, geo_node_subdivision_surface_out);
ntype.geometry_node_execute = blender::nodes::geo_node_subdivision_surface_exec;
ntype.draw_buttons = geo_node_subdivision_surface_layout;
node_type_init(&ntype, geo_node_subdivision_surface_init);
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
node_type_storage(
&ntype, "NodeGeometrySubdivisionSurface", node_free_standard_storage, node_copy_standard_storage);
node_type_socket_templates(
&ntype, geo_node_subdivision_surface_in, geo_node_subdivision_surface_out);
nodeRegisterType(&ntype);
}