OpenSubdiv: Make more flexible C-API to specify FVar interpolation

This commit is contained in:
Sergey Sharybin 2018-07-10 14:36:04 +02:00
parent 80373bc4d2
commit c17cb50ae2
3 changed files with 63 additions and 26 deletions

View File

@ -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<TopologyRefinerData>::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 ||

View File

@ -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;

View File

@ -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;