diff --git a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc index 901a421314a..4f3fb1462f3 100644 --- a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc +++ b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc @@ -441,6 +441,26 @@ inline void TopologyRefinerFactory::reportInvalidTopology( namespace opensubdiv_capi { +namespace { + +OpenSubdiv::Sdc::Options::VtxBoundaryInterpolation +getVtxBoundaryInterpolationFromCAPI( + OpenSubdiv_VtxBoundaryInterpolation boundary_interpolation) { + using OpenSubdiv::Sdc::Options; + switch (boundary_interpolation) { + case OSD_VTX_BOUNDARY_NONE: + return Options::VTX_BOUNDARY_NONE; + case OSD_VTX_BOUNDARY_EDGE_ONLY: + return Options::VTX_BOUNDARY_EDGE_ONLY; + case OSD_VTX_BOUNDARY_EDGE_AND_CORNER: + return Options::VTX_BOUNDARY_EDGE_AND_CORNER; + } + assert(!"Unknown veretx boundary interpolation."); + return Options::VTX_BOUNDARY_EDGE_ONLY; +} + +} // namespace + OpenSubdiv::Far::TopologyRefiner* createOSDTopologyRefinerFromConverter( OpenSubdiv_Converter* converter) { using OpenSubdiv::Sdc::Options; @@ -451,7 +471,9 @@ OpenSubdiv::Far::TopologyRefiner* createOSDTopologyRefinerFromConverter( getFVarLinearInterpolationFromCAPI( converter->getFVarLinearInterpolation(converter)); Options options; - options.SetVtxBoundaryInterpolation(Options::VTX_BOUNDARY_EDGE_ONLY); + options.SetVtxBoundaryInterpolation( + getVtxBoundaryInterpolationFromCAPI( + converter->getVtxBoundaryInterpolation(converter))); options.SetCreasingMethod(Options::CREASE_UNIFORM); options.SetFVarLinearInterpolation(linear_interpolation); diff --git a/intern/opensubdiv/opensubdiv_capi_type.h b/intern/opensubdiv/opensubdiv_capi_type.h index b326e53e168..57f62fd9888 100644 --- a/intern/opensubdiv/opensubdiv_capi_type.h +++ b/intern/opensubdiv/opensubdiv_capi_type.h @@ -40,6 +40,15 @@ typedef enum OpenSubdiv_SchemeType { OSD_SCHEME_LOOP, } OpenSubdiv_SchemeType; +typedef enum OpenSubdiv_VtxBoundaryInterpolation { + // Do not interpolate boundaries + OSD_VTX_BOUNDARY_NONE, + // Sharpen edges. + OSD_VTX_BOUNDARY_EDGE_ONLY, + // sharpen edges and corners, + OSD_VTX_BOUNDARY_EDGE_AND_CORNER, +} OpenSubdiv_VtxBoundaryInterpolation; + typedef enum OpenSubdiv_FVarLinearInterpolation { OSD_FVAR_LINEAR_INTERPOLATION_NONE, OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY, diff --git a/intern/opensubdiv/opensubdiv_converter_capi.h b/intern/opensubdiv/opensubdiv_converter_capi.h index 9f559ee208b..389e16e0f3f 100644 --- a/intern/opensubdiv/opensubdiv_converter_capi.h +++ b/intern/opensubdiv/opensubdiv_converter_capi.h @@ -31,6 +31,8 @@ typedef struct OpenSubdiv_Converter { OpenSubdiv_SchemeType (*getSchemeType)( const struct OpenSubdiv_Converter* converter); + OpenSubdiv_VtxBoundaryInterpolation (*getVtxBoundaryInterpolation)( + const struct OpenSubdiv_Converter* converter); OpenSubdiv_FVarLinearInterpolation (*getFVarLinearInterpolation)( const struct OpenSubdiv_Converter* converter); diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h index 09fcce369d4..06d57062b59 100644 --- a/source/blender/blenkernel/BKE_subdiv.h +++ b/source/blender/blenkernel/BKE_subdiv.h @@ -43,7 +43,16 @@ struct OpenSubdiv_TopologyRefiner; struct Subdiv; struct SubdivToMeshSettings; -typedef enum { +typedef enum eSubdivVtxBoundaryInterpolation { + /* Do not interpolate boundaries. */ + SUBDIV_VTX_BOUNDARY_NONE, + /* Sharpen edges. */ + SUBDIV_VTX_BOUNDARY_EDGE_ONLY, + /* sharpen edges and corners, */ + SUBDIV_VTX_BOUNDARY_EDGE_AND_CORNER, +} eSubdivVtxBoundaryInterpolation; + +typedef enum eSubdivFVarLinearInterpolation { SUBDIV_FVAR_LINEAR_INTERPOLATION_NONE, SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY, SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_AND_JUNCTIONS, @@ -56,6 +65,7 @@ typedef struct SubdivSettings { bool is_simple; bool is_adaptive; int level; + eSubdivVtxBoundaryInterpolation vtx_boundary_interpolation; eSubdivFVarLinearInterpolation fvar_linear_interpolation; } SubdivSettings; diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c index f81a1d9eec9..0301582b303 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c +++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c @@ -84,6 +84,13 @@ static OpenSubdiv_SchemeType conv_dm_get_type( return OSD_SCHEME_CATMARK; } +static OpenSubdiv_VtxBoundaryInterpolation +conv_dm_get_vtx_boundary_interpolation( + const OpenSubdiv_Converter *UNUSED(converter)) +{ + return OSD_VTX_BOUNDARY_EDGE_ONLY; +} + static OpenSubdiv_FVarLinearInterpolation conv_dm_get_fvar_linear_interpolation( const OpenSubdiv_Converter *converter) { @@ -448,6 +455,8 @@ void ccgSubSurf_converter_setup_from_derivedmesh( converter->getSchemeType = conv_dm_get_type; + converter->getVtxBoundaryInterpolation = + conv_dm_get_vtx_boundary_interpolation; converter->getFVarLinearInterpolation = conv_dm_get_fvar_linear_interpolation; converter->specifiesFullTopology = conv_dm_specifies_full_topology; @@ -546,6 +555,13 @@ static OpenSubdiv_SchemeType conv_ccg_get_bilinear_type( } } +static OpenSubdiv_VtxBoundaryInterpolation +conv_ccg_get_vtx_boundary_interpolation( + const OpenSubdiv_Converter *UNUSED(converter)) +{ + return OSD_VTX_BOUNDARY_EDGE_ONLY; +} + static OpenSubdiv_FVarLinearInterpolation conv_ccg_get_fvar_linear_interpolation(const OpenSubdiv_Converter *converter) { @@ -750,6 +766,8 @@ void ccgSubSurf_converter_setup_from_ccg(CCGSubSurf *ss, { converter->getSchemeType = conv_ccg_get_bilinear_type; + converter->getVtxBoundaryInterpolation = + conv_ccg_get_vtx_boundary_interpolation; converter->getFVarLinearInterpolation = conv_ccg_get_fvar_linear_interpolation; converter->specifiesFullTopology = conv_ccg_specifies_full_topology; diff --git a/source/blender/blenkernel/intern/multires_subdiv.c b/source/blender/blenkernel/intern/multires_subdiv.c index f745418295d..e0b316d49de 100644 --- a/source/blender/blenkernel/intern/multires_subdiv.c +++ b/source/blender/blenkernel/intern/multires_subdiv.c @@ -48,6 +48,7 @@ void BKE_multires_subdiv_settings_init( settings->is_simple = (mmd->simple != 0); settings->is_adaptive = !settings->is_simple; settings->level = mmd->quality; + settings->vtx_boundary_interpolation = SUBDIV_VTX_BOUNDARY_EDGE_ONLY; settings->fvar_linear_interpolation = BKE_subdiv_fvar_interpolation_from_uv_smooth(mmd->uv_smooth); } diff --git a/source/blender/blenkernel/intern/subdiv_converter.c b/source/blender/blenkernel/intern/subdiv_converter.c index 47e87bfdd78..b3eab1565d7 100644 --- a/source/blender/blenkernel/intern/subdiv_converter.c +++ b/source/blender/blenkernel/intern/subdiv_converter.c @@ -40,6 +40,21 @@ void BKE_subdiv_converter_free(struct OpenSubdiv_Converter *converter) } } +int BKE_subdiv_converter_vtx_boundary_interpolation_from_settings( + const SubdivSettings *settings) +{ + switch (settings->vtx_boundary_interpolation) { + case SUBDIV_VTX_BOUNDARY_NONE: + return OSD_VTX_BOUNDARY_NONE; + case SUBDIV_VTX_BOUNDARY_EDGE_ONLY: + return OSD_VTX_BOUNDARY_EDGE_ONLY; + case SUBDIV_VTX_BOUNDARY_EDGE_AND_CORNER: + return OSD_VTX_BOUNDARY_EDGE_AND_CORNER; + } + BLI_assert(!"Unknown vtx boundary interpolation"); + return OSD_VTX_BOUNDARY_EDGE_ONLY; +} + /*OpenSubdiv_FVarLinearInterpolation*/ int BKE_subdiv_converter_fvar_linear_from_settings(const SubdivSettings *settings) { diff --git a/source/blender/blenkernel/intern/subdiv_converter.h b/source/blender/blenkernel/intern/subdiv_converter.h index 0326c9e504c..17172bc29f7 100644 --- a/source/blender/blenkernel/intern/subdiv_converter.h +++ b/source/blender/blenkernel/intern/subdiv_converter.h @@ -52,6 +52,12 @@ void BKE_subdiv_converter_free(struct OpenSubdiv_Converter *converter); /* ============================ INTERNAL HELPERS ============================ */ +/* TODO(sergey): Find a way to make it OpenSubdiv_VtxBoundaryInterpolation, + * without breaking compilation without OpenSubdiv. + */ +int BKE_subdiv_converter_vtx_boundary_interpolation_from_settings( + const SubdivSettings *settings); + /* TODO(sergey): Find a way to make it OpenSubdiv_FVarLinearInterpolation, * without breaking compilation without OpenSubdiv. */ diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c index d17ee49ca0c..34675da063e 100644 --- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c @@ -87,6 +87,13 @@ static OpenSubdiv_SchemeType get_scheme_type( } } +static OpenSubdiv_VtxBoundaryInterpolation get_vtx_boundary_interpolation( + const struct OpenSubdiv_Converter* converter) { + ConverterStorage *storage = converter->user_data; + return BKE_subdiv_converter_vtx_boundary_interpolation_from_settings( + &storage->settings); +} + static OpenSubdiv_FVarLinearInterpolation get_fvar_linear_interpolation( const OpenSubdiv_Converter *converter) { @@ -264,6 +271,7 @@ static void free_user_data(const OpenSubdiv_Converter *converter) static void init_functions(OpenSubdiv_Converter *converter) { converter->getSchemeType = get_scheme_type; + converter->getVtxBoundaryInterpolation = get_vtx_boundary_interpolation; converter->getFVarLinearInterpolation = get_fvar_linear_interpolation; converter->specifiesFullTopology = specifies_full_topology; diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index 4aee0ba589e..dee9089d7d3 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -158,6 +158,7 @@ static void subdiv_settings_init(SubdivSettings *settings, settings->is_simple = (smd->subdivType == SUBSURF_TYPE_SIMPLE); settings->is_adaptive = !settings->is_simple; settings->level = smd->quality; + settings->vtx_boundary_interpolation = SUBDIV_VTX_BOUNDARY_EDGE_ONLY; settings->fvar_linear_interpolation = BKE_subdiv_fvar_interpolation_from_uv_smooth(smd->uv_smooth); }