From c17cb50ae282f0f04d399ac4f9fa2f3c5eb548bb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 10 Jul 2018 14:36:04 +0200 Subject: [PATCH] OpenSubdiv: Make more flexible C-API to specify FVar interpolation --- intern/opensubdiv/opensubdiv_converter.cc | 48 +++++++++++++------ intern/opensubdiv/opensubdiv_converter_capi.h | 15 ++++-- .../intern/CCGSubSurf_opensubdiv_converter.c | 26 ++++++---- 3 files changed, 63 insertions(+), 26 deletions(-) diff --git a/intern/opensubdiv/opensubdiv_converter.cc b/intern/opensubdiv/opensubdiv_converter.cc index ea41a56768f..fec15b118ae 100644 --- a/intern/opensubdiv/opensubdiv_converter.cc +++ b/intern/opensubdiv/opensubdiv_converter.cc @@ -542,7 +542,7 @@ namespace { OpenSubdiv::Sdc::SchemeType get_capi_scheme_type(OpenSubdiv_SchemeType type) { - switch(type) { + switch (type) { case OSD_SCHEME_BILINEAR: return OpenSubdiv::Sdc::SCHEME_BILINEAR; case OSD_SCHEME_CATMARK: @@ -550,10 +550,29 @@ OpenSubdiv::Sdc::SchemeType get_capi_scheme_type(OpenSubdiv_SchemeType type) case OSD_SCHEME_LOOP: return OpenSubdiv::Sdc::SCHEME_LOOP; } - assert(!"Unknown sceme type passed via C-API"); + assert(!"Unknown scheme type passed via C-API"); return OpenSubdiv::Sdc::SCHEME_CATMARK; } +OpenSubdiv::Sdc::Options::FVarLinearInterpolation +get_capi_fvar_linear_interpolation( + OpenSubdiv_FVarLinearInterpolation linear_interpolation) +{ + typedef OpenSubdiv::Sdc::Options Options; + switch (linear_interpolation) { + case OSD_FVAR_LINEAR_INTERPOLATION_NONE: + return Options::FVAR_LINEAR_NONE; + case OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY: + return Options::FVAR_LINEAR_CORNERS_ONLY; + case OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES: + return Options::FVAR_LINEAR_BOUNDARIES; + case OSD_FVAR_LINEAR_INTERPOLATION_ALL: + return Options::FVAR_LINEAR_ALL; + } + assert(!"Unknown fvar linear interpolation passed via C-API"); + return Options::FVAR_LINEAR_NONE; +} + } /* namespace */ struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_createTopologyRefinerDescr( @@ -562,17 +581,15 @@ struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_createTopologyRefinerDescr( typedef OpenSubdiv::Sdc::Options Options; using OpenSubdiv::Far::TopologyRefinerFactory; - OpenSubdiv::Sdc::SchemeType scheme_type = - get_capi_scheme_type(converter->get_type(converter)); + const OpenSubdiv::Sdc::SchemeType scheme_type = + get_capi_scheme_type(converter->get_scheme_type(converter)); + const Options::FVarLinearInterpolation linear_interpolation = + get_capi_fvar_linear_interpolation( + converter->get_fvar_linear_interpolation(converter)); Options options; options.SetVtxBoundaryInterpolation(Options::VTX_BOUNDARY_EDGE_ONLY); options.SetCreasingMethod(Options::CREASE_UNIFORM); - if (converter->get_subdiv_uvs(converter)) { - options.SetFVarLinearInterpolation(Options::FVAR_LINEAR_CORNERS_ONLY); - } - else { - options.SetFVarLinearInterpolation(Options::FVAR_LINEAR_ALL); - } + options.SetFVarLinearInterpolation(linear_interpolation); TopologyRefinerFactory::Options topology_options(scheme_type, options); @@ -663,14 +680,17 @@ int openSubdiv_topologyRefnerCompareConverter( const int num_faces = base_level.GetNumFaces(); /* Quick preliminary check. */ OpenSubdiv::Sdc::SchemeType scheme_type = - get_capi_scheme_type(converter->get_type(converter)); + get_capi_scheme_type(converter->get_scheme_type(converter)); if (scheme_type != refiner->GetSchemeType()) { return false; } const Options options = refiner->GetSchemeOptions(); - Options::FVarLinearInterpolation interp = options.GetFVarLinearInterpolation(); - const bool subdiv_uvs = (interp != Options::FVAR_LINEAR_ALL); - if (converter->get_subdiv_uvs(converter) != subdiv_uvs) { + const Options::FVarLinearInterpolation interp = + options.GetFVarLinearInterpolation(); + const Options::FVarLinearInterpolation new_interp = + get_capi_fvar_linear_interpolation( + converter->get_fvar_linear_interpolation(converter)); + if (new_interp != interp) { return false; } if (converter->get_num_verts(converter) != num_verts || diff --git a/intern/opensubdiv/opensubdiv_converter_capi.h b/intern/opensubdiv/opensubdiv_converter_capi.h index 6eda6ae5d8a..ea4f20c5961 100644 --- a/intern/opensubdiv/opensubdiv_converter_capi.h +++ b/intern/opensubdiv/opensubdiv_converter_capi.h @@ -41,13 +41,22 @@ typedef enum OpenSubdiv_SchemeType { OSD_SCHEME_LOOP, } OpenSubdiv_SchemeType; +typedef enum OpenSubdiv_FVarLinearInterpolation { + OSD_FVAR_LINEAR_INTERPOLATION_NONE, + OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY, + OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES, + OSD_FVAR_LINEAR_INTERPOLATION_ALL, +} OpenSubdiv_FVarLinearInterpolation; + typedef struct OpenSubdiv_Converter { /* TODO(sergey): Needs to be implemented. */ /* OpenSubdiv::Sdc::Options get_options() const; */ - OpenSubdiv_SchemeType (*get_type)(const OpenSubdiv_Converter *converter); + OpenSubdiv_SchemeType (*get_scheme_type)( + const OpenSubdiv_Converter *converter); - bool (*get_subdiv_uvs)(const OpenSubdiv_Converter *converter); + OpenSubdiv_FVarLinearInterpolation (*get_fvar_linear_interpolation)( + const OpenSubdiv_Converter *converter); int (*get_num_faces)(const OpenSubdiv_Converter *converter); int (*get_num_edges)(const OpenSubdiv_Converter *converter); @@ -86,7 +95,6 @@ typedef struct OpenSubdiv_Converter { int *vert_faces); /* Face-varying data. */ - int (*get_num_uv_layers)(const OpenSubdiv_Converter *converter); void (*precalc_uv_layer)(const OpenSubdiv_Converter *converter, int layer); @@ -99,6 +107,7 @@ typedef struct OpenSubdiv_Converter { int face, int corner); + /* User data associated with this converter. */ void (*free_user_data)(const OpenSubdiv_Converter *converter); void *user_data; } OpenSubdiv_Converter; diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c index f1f82f458aa..8c1ba0c3782 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c +++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c @@ -84,11 +84,14 @@ static OpenSubdiv_SchemeType conv_dm_get_type( return OSD_SCHEME_CATMARK; } -static bool conv_dm_get_subdiv_uvs( +static OpenSubdiv_FVarLinearInterpolation conv_dm_get_fvar_linear_interpolation( const OpenSubdiv_Converter *converter) { ConvDMStorage *storage = converter->user_data; - return (storage->ss->osd_subdiv_uvs); + if (storage->ss->osd_subdiv_uvs) { + return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY; + } + return OSD_FVAR_LINEAR_INTERPOLATION_ALL; } static int conv_dm_get_num_faces(const OpenSubdiv_Converter *converter) @@ -429,9 +432,10 @@ void ccgSubSurf_converter_setup_from_derivedmesh( { ConvDMStorage *user_data; - converter->get_type = conv_dm_get_type; + converter->get_scheme_type = conv_dm_get_type; - converter->get_subdiv_uvs = conv_dm_get_subdiv_uvs; + converter->get_fvar_linear_interpolation = + conv_dm_get_fvar_linear_interpolation; converter->get_num_faces = conv_dm_get_num_faces; converter->get_num_edges = conv_dm_get_num_edges; @@ -526,11 +530,14 @@ static OpenSubdiv_SchemeType conv_ccg_get_bilinear_type( } } -static bool conv_ccg_get_subdiv_uvs( - const OpenSubdiv_Converter *converter) +static OpenSubdiv_FVarLinearInterpolation +conv_ccg_get_fvar_linear_interpolation(const OpenSubdiv_Converter *converter) { CCGSubSurf *ss = converter->user_data; - return (ss->osd_subdiv_uvs); + if (ss->osd_subdiv_uvs) { + return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY; + } + return OSD_FVAR_LINEAR_INTERPOLATION_ALL; } static int conv_ccg_get_num_faces(const OpenSubdiv_Converter *converter) @@ -710,9 +717,10 @@ static int conv_ccg_get_face_corner_uv_index(const OpenSubdiv_Converter *UNUSED( void ccgSubSurf_converter_setup_from_ccg(CCGSubSurf *ss, OpenSubdiv_Converter *converter) { - converter->get_type = conv_ccg_get_bilinear_type; + converter->get_scheme_type = conv_ccg_get_bilinear_type; - converter->get_subdiv_uvs = conv_ccg_get_subdiv_uvs; + converter->get_fvar_linear_interpolation = + conv_ccg_get_fvar_linear_interpolation; converter->get_num_faces = conv_ccg_get_num_faces; converter->get_num_edges = conv_ccg_get_num_edges;