Fix T58227: Subdivision Surface Type Simple messes up UVs
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 4 Dec 2018 14:15:14 +0000 (15:15 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 4 Dec 2018 14:18:37 +0000 (15:18 +0100)
This seems to be a bug in OpenSubdiv. For now simply use Catmark
subdivision scheme with infinitely sharp edges.

Later on it's either gets fixed in OpenSubdiv or we do bilinear
subdivision on our side.

source/blender/blenkernel/intern/multires_subdiv.c
source/blender/blenkernel/intern/subdiv_converter_mesh.c
source/blender/modifiers/intern/MOD_subsurf.c

index 3de007dec75063d4355452432c657477b6bb84dd..150e71929347d109520dda6047e8052f9199d0c5 100644 (file)
@@ -46,8 +46,8 @@ void BKE_multires_subdiv_settings_init(
         const MultiresModifierData *mmd)
 {
        settings->is_simple = (mmd->simple != 0);
-       settings->is_adaptive = !settings->is_simple;
-       settings->level = mmd->quality;
+       settings->is_adaptive = true;
+       settings->level = settings->is_simple ? 1 : 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);
index 5941de682f4aae37c3d559371e2809c75df9ac73..0dad259b0014bcaf50343648a1ef39c9c534a3c2 100644 (file)
 #include "opensubdiv_capi.h"
 #include "opensubdiv_converter_capi.h"
 
+/* Enable work-around for non-working CPU evaluator when using bilinear scheme.
+ * This forces Catmark scheme with all edges marked as infinitely sharp. */
+#define BUGGY_SIMPLE_SCHEME_WORKAROUND 1
+
 typedef struct ConverterStorage {
        SubdivSettings settings;
        const Mesh *mesh;
@@ -78,6 +82,10 @@ typedef struct ConverterStorage {
 static OpenSubdiv_SchemeType get_scheme_type(
         const OpenSubdiv_Converter *converter)
 {
+#if BUGGY_SIMPLE_SCHEME_WORKAROUND
+       (void) converter;
+       return OSD_SCHEME_CATMARK;
+#else
        ConverterStorage *storage = converter->user_data;
        if (storage->settings.is_simple) {
                return OSD_SCHEME_BILINEAR;
@@ -85,6 +93,7 @@ static OpenSubdiv_SchemeType get_scheme_type(
        else {
                return OSD_SCHEME_CATMARK;
        }
+#endif
 }
 
 static OpenSubdiv_VtxBoundaryInterpolation get_vtx_boundary_interpolation(
@@ -161,6 +170,11 @@ static float get_edge_sharpness(const OpenSubdiv_Converter *converter,
                                 int manifold_edge_index)
 {
        ConverterStorage *storage = converter->user_data;
+#if BUGGY_SIMPLE_SCHEME_WORKAROUND
+       if (storage->settings.is_simple) {
+               return 10.0f;
+       }
+#endif
        const int edge_index =
                storage->manifold_edge_index_reverse[manifold_edge_index];
        const MEdge *medge = storage->mesh->medge;
@@ -168,11 +182,15 @@ static float get_edge_sharpness(const OpenSubdiv_Converter *converter,
        return edge_crease * edge_crease * 10.0f;
 }
 
-
 static bool is_infinite_sharp_vertex(const OpenSubdiv_Converter *converter,
                                      int manifold_vertex_index)
 {
        ConverterStorage *storage = converter->user_data;
+#if BUGGY_SIMPLE_SCHEME_WORKAROUND
+       if (storage->settings.is_simple) {
+               return true;
+       }
+#endif
        const int vertex_index =
                storage->manifold_vertex_index_reverse[manifold_vertex_index];
        return BLI_BITMAP_TEST_BOOL(storage->infinite_sharp_vertices_map,
index 3b81ec116be1703486ee09818f502b730aacf279..e66b3fdbafb3cb3cf8e7d64f52d7499489c2e0c8 100644 (file)
@@ -115,8 +115,8 @@ static void subdiv_settings_init(SubdivSettings *settings,
                                  const SubsurfModifierData *smd)
 {
        settings->is_simple = (smd->subdivType == SUBSURF_TYPE_SIMPLE);
-       settings->is_adaptive = !settings->is_simple;
-       settings->level = smd->quality;
+       settings->is_adaptive = true;
+       settings->level = settings->is_simple ? 1 : 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);