OpenSubdiv: Make more flexible C-API to specify FVar interpolation
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 10 Jul 2018 12:36:04 +0000 (14:36 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 10 Jul 2018 12:40:45 +0000 (14:40 +0200)
intern/opensubdiv/opensubdiv_converter.cc
intern/opensubdiv/opensubdiv_converter_capi.h
source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c

index ea41a56768fd3c62329b09b588553ba8f3d857b9..fec15b118aedc8614ab2c80bc8c9a651bbc4ad84 100644 (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 ||
index 6eda6ae5d8ab79efefb23cfa77591e460e69d56a..ea4f20c5961606cfbcb00a8b4a0d907639447511 100644 (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;
index f1f82f458aa2c4af5ce2845bdd5fc62a52aa1465..8c1ba0c3782f5edba9bb3252590469c9b19c6bac 100644 (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;