From 164575af29f94d8db78265df1520a3f7bfd3c72d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 22 Jul 2016 17:52:30 +0200 Subject: OpenSubdiv: Properly respect Subdivide UVs option --- intern/opensubdiv/opensubdiv_converter.cc | 16 +++++++++++++--- intern/opensubdiv/opensubdiv_converter_capi.h | 2 ++ source/blender/blenkernel/intern/CCGSubSurf.c | 1 + source/blender/blenkernel/intern/CCGSubSurf.h | 2 ++ source/blender/blenkernel/intern/CCGSubSurf_intern.h | 2 ++ .../blender/blenkernel/intern/CCGSubSurf_opensubdiv.c | 5 +++++ .../intern/CCGSubSurf_opensubdiv_converter.c | 18 ++++++++++++++++++ source/blender/blenkernel/intern/subsurf_ccg.c | 14 ++++++++------ 8 files changed, 51 insertions(+), 9 deletions(-) diff --git a/intern/opensubdiv/opensubdiv_converter.cc b/intern/opensubdiv/opensubdiv_converter.cc index 9b2fb19808c..ea41a56768f 100644 --- a/intern/opensubdiv/opensubdiv_converter.cc +++ b/intern/opensubdiv/opensubdiv_converter.cc @@ -567,9 +567,12 @@ struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_createTopologyRefinerDescr( Options options; options.SetVtxBoundaryInterpolation(Options::VTX_BOUNDARY_EDGE_ONLY); options.SetCreasingMethod(Options::CREASE_UNIFORM); - /* TODO(sergey): Get proper UV subdivide flag. */ - // options.SetFVarLinearInterpolation(Options::FVAR_LINEAR_ALL); - options.SetFVarLinearInterpolation(Options::FVAR_LINEAR_CORNERS_ONLY); + if (converter->get_subdiv_uvs(converter)) { + options.SetFVarLinearInterpolation(Options::FVAR_LINEAR_CORNERS_ONLY); + } + else { + options.SetFVarLinearInterpolation(Options::FVAR_LINEAR_ALL); + } TopologyRefinerFactory::Options topology_options(scheme_type, options); @@ -649,6 +652,7 @@ int openSubdiv_topologyRefnerCompareConverter( const OpenSubdiv_TopologyRefinerDescr *topology_refiner, OpenSubdiv_Converter *converter) { + typedef OpenSubdiv::Sdc::Options Options; using OpenSubdiv::Far::ConstIndexArray; using OpenSubdiv::Far::TopologyRefiner; using OpenSubdiv::Far::TopologyLevel; @@ -663,6 +667,12 @@ int openSubdiv_topologyRefnerCompareConverter( 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) { + return false; + } if (converter->get_num_verts(converter) != num_verts || converter->get_num_edges(converter) != num_edges || converter->get_num_faces(converter) != num_faces) diff --git a/intern/opensubdiv/opensubdiv_converter_capi.h b/intern/opensubdiv/opensubdiv_converter_capi.h index 4448f108e8a..6eda6ae5d8a 100644 --- a/intern/opensubdiv/opensubdiv_converter_capi.h +++ b/intern/opensubdiv/opensubdiv_converter_capi.h @@ -47,6 +47,8 @@ typedef struct OpenSubdiv_Converter { OpenSubdiv_SchemeType (*get_type)(const OpenSubdiv_Converter *converter); + bool (*get_subdiv_uvs)(const OpenSubdiv_Converter *converter); + int (*get_num_faces)(const OpenSubdiv_Converter *converter); int (*get_num_edges)(const OpenSubdiv_Converter *converter); int (*get_num_verts)(const OpenSubdiv_Converter *converter); diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index c4886a21740..792e9195f12 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -316,6 +316,7 @@ CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *a ss->osd_next_face_ptex_index = 0; ss->osd_coarse_coords = NULL; ss->osd_num_coarse_coords = 0; + ss->osd_subdiv_uvs = false; #endif return ss; diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h index 72f386bf246..4c913e79586 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.h +++ b/source/blender/blenkernel/intern/CCGSubSurf.h @@ -244,6 +244,8 @@ void ccgSubSurf_free_osd_mesh(CCGSubSurf *ss); void ccgSubSurf_getMinMax(CCGSubSurf *ss, float r_min[3], float r_max[3]); +void ccgSubSurf__sync_subdivUvs(CCGSubSurf *ss, bool subsurf_uvs); + #endif #endif /* __CCGSUBSURF_H__ */ diff --git a/source/blender/blenkernel/intern/CCGSubSurf_intern.h b/source/blender/blenkernel/intern/CCGSubSurf_intern.h index 7e8059e62fc..9df1c9021ef 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf_intern.h +++ b/source/blender/blenkernel/intern/CCGSubSurf_intern.h @@ -254,6 +254,8 @@ struct CCGSubSurf { * to fill in PTex index of CCGFace. */ int osd_next_face_ptex_index; + + bool osd_subdiv_uvs; #endif }; diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c index 9dc1a71adab..65cf899b42b 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c +++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c @@ -984,6 +984,11 @@ void ccgSubSurf__delete_pending(void) BLI_spin_unlock(&delete_spin); } +void ccgSubSurf__sync_subdivUvs(CCGSubSurf *ss, bool subdiv_uvs) +{ + ss->osd_subdiv_uvs = subdiv_uvs; +} + /* ** Public API ** */ void BKE_subsurf_osd_init(void) diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c index 5c68e500300..f1f82f458aa 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 bool conv_dm_get_subdiv_uvs( + const OpenSubdiv_Converter *converter) +{ + ConvDMStorage *storage = converter->user_data; + return (storage->ss->osd_subdiv_uvs); +} + static int conv_dm_get_num_faces(const OpenSubdiv_Converter *converter) { ConvDMStorage *storage = converter->user_data; @@ -424,6 +431,8 @@ void ccgSubSurf_converter_setup_from_derivedmesh( converter->get_type = conv_dm_get_type; + converter->get_subdiv_uvs = conv_dm_get_subdiv_uvs; + converter->get_num_faces = conv_dm_get_num_faces; converter->get_num_edges = conv_dm_get_num_edges; converter->get_num_verts = conv_dm_get_num_verts; @@ -517,6 +526,13 @@ static OpenSubdiv_SchemeType conv_ccg_get_bilinear_type( } } +static bool conv_ccg_get_subdiv_uvs( + const OpenSubdiv_Converter *converter) +{ + CCGSubSurf *ss = converter->user_data; + return (ss->osd_subdiv_uvs); +} + static int conv_ccg_get_num_faces(const OpenSubdiv_Converter *converter) { CCGSubSurf *ss = converter->user_data; @@ -696,6 +712,8 @@ void ccgSubSurf_converter_setup_from_ccg(CCGSubSurf *ss, { converter->get_type = conv_ccg_get_bilinear_type; + converter->get_subdiv_uvs = conv_ccg_get_subdiv_uvs; + converter->get_num_faces = conv_ccg_get_num_faces; converter->get_num_edges = conv_ccg_get_num_edges; converter->get_num_verts = conv_ccg_get_num_verts; diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 7239566b59d..02e529542be 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -794,7 +794,8 @@ static void ss_sync_osd_from_derivedmesh(CCGSubSurf *ss, static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm, float (*vertexCos)[3], - int use_flat_subdiv) + int use_flat_subdiv, + bool use_subdiv_uvs) { #ifdef WITH_OPENSUBDIV /* Reset all related descriptors if actual mesh topology changed or if @@ -802,6 +803,7 @@ static void ss_sync_from_derivedmesh(CCGSubSurf *ss, */ if (!ccgSubSurf_needGrids(ss)) { /* TODO(sergey): Use vertex coordinates and flat subdiv flag. */ + ccgSubSurf__sync_subdivUvs(ss, use_subdiv_uvs); ccgSubSurf_checkTopologyChanged(ss, dm); ss_sync_osd_from_derivedmesh(ss, dm); } @@ -5029,7 +5031,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( #ifdef WITH_OPENSUBDIV ccgSubSurf_setSkipGrids(smd->emCache, use_gpu_backend); #endif - ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple); + ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple, useSubsurfUv); result = getCCGDerivedMesh(smd->emCache, drawInteriorEdges, useSubsurfUv, dm, use_gpu_backend); @@ -5044,7 +5046,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( ss = _getSubSurf(NULL, levels, 3, useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS); - ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); + ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv); result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm, false); @@ -5075,7 +5077,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( if (useIncremental && (flags & SUBSURF_IS_FINAL_CALC)) { smd->mCache = ss = _getSubSurf(smd->mCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS); - ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); + ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv); result = getCCGDerivedMesh(smd->mCache, drawInteriorEdges, @@ -5115,7 +5117,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( #ifdef WITH_OPENSUBDIV ccgSubSurf_setSkipGrids(ss, use_gpu_backend); #endif - ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); + ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv); result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm, use_gpu_backend); @@ -5144,7 +5146,7 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3]) CCGVertIterator vi; DerivedMesh *dm = CDDM_from_mesh(me); - ss_sync_from_derivedmesh(ss, dm, NULL, 0); + ss_sync_from_derivedmesh(ss, dm, NULL, 0, 0); for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) { CCGVert *v = ccgVertIterator_getCurrent(&vi); -- cgit v1.2.3