OpenSubdiv: Add stub implementation of C-API
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 13 Aug 2018 10:21:29 +0000 (12:21 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 13 Aug 2018 10:37:18 +0000 (12:37 +0200)
C-API is way smaller than the rest of the code which uses it.
So better to conditionally compile stub implementation than
to keep adding ifdef everywhere.

14 files changed:
intern/CMakeLists.txt
intern/opensubdiv/CMakeLists.txt
intern/opensubdiv/internal/opensubdiv_gl_mesh.cc
intern/opensubdiv/stub/opensubdiv_evaluator_stub.cc [new file with mode: 0644]
intern/opensubdiv/stub/opensubdiv_gl_mesh_stub.cc [new file with mode: 0644]
intern/opensubdiv/stub/opensubdiv_stub.cc [new file with mode: 0644]
intern/opensubdiv/stub/opensubdiv_topology_refiner_stub.cc [new file with mode: 0644]
source/blender/blenkernel/BKE_subdiv.h
source/blender/blenkernel/CMakeLists.txt
source/blender/blenkernel/intern/subdiv.c
source/blender/blenkernel/intern/subdiv_converter.c
source/blender/blenkernel/intern/subdiv_converter_mesh.c
source/blender/blenkernel/intern/subdiv_eval.c
source/blender/blenkernel/intern/subdiv_mesh.c

index 1459100d41583d334add5d744b7d7141c90fedde..c7f0f414fb1f63fda51a621b64c9bf2ebd0a63ca 100644 (file)
@@ -31,6 +31,7 @@ add_subdirectory(guardedalloc)
 add_subdirectory(libmv)
 add_subdirectory(memutil)
 add_subdirectory(opencolorio)
+add_subdirectory(opensubdiv)
 add_subdirectory(mikktspace)
 add_subdirectory(glew-mx)
 add_subdirectory(eigen)
@@ -71,10 +72,6 @@ if(WITH_BULLET)
        add_subdirectory(rigidbody)
 endif()
 
-if(WITH_OPENSUBDIV)
-       add_subdirectory(opensubdiv)
-endif()
-
 # only windows needs utf16 converter
 if(WIN32)
        add_subdirectory(utfconv)
index 887eb399224896e966a658e280385802b6a8be41..f11d9b4613aab402f9429b7e7876fdc80e762500 100644 (file)
@@ -29,39 +29,9 @@ set(INC
 )
 
 set(INC_SYS
-       ${OPENSUBDIV_INCLUDE_DIR}
-       ${GLEW_INCLUDE_PATH}
 )
 
 set(SRC
-       internal/opensubdiv.cc
-       internal/opensubdiv_converter_factory.cc
-       internal/opensubdiv_converter_internal.cc
-       internal/opensubdiv_converter_orient.cc
-       internal/opensubdiv_device_context_cuda.cc
-       internal/opensubdiv_device_context_opencl.cc
-       internal/opensubdiv_evaluator.cc
-       internal/opensubdiv_evaluator_internal.cc
-       internal/opensubdiv_gl_mesh.cc
-       internal/opensubdiv_gl_mesh_draw.cc
-       internal/opensubdiv_gl_mesh_fvar.cc
-       internal/opensubdiv_gl_mesh_internal.cc
-       internal/opensubdiv_topology_refiner.cc
-       internal/opensubdiv_topology_refiner_internal.cc
-       internal/opensubdiv_util.cc
-
-       internal/opensubdiv_converter_internal.h
-       internal/opensubdiv_converter_orient.h
-       internal/opensubdiv_converter_orient_impl.h
-       internal/opensubdiv_device_context_cuda.h
-       internal/opensubdiv_device_context_opencl.h
-       internal/opensubdiv_evaluator_internal.h
-       internal/opensubdiv_gl_mesh_fvar.h
-       internal/opensubdiv_gl_mesh_internal.h
-       internal/opensubdiv_internal.h
-       internal/opensubdiv_topology_refiner_internal.h
-       internal/opensubdiv_util.h
-
        opensubdiv_capi.h
        opensubdiv_capi_type.h
        opensubdiv_converter_capi.h
@@ -70,44 +40,88 @@ set(SRC
        opensubdiv_topology_refiner_capi.h
 )
 
-macro(OPENSUBDIV_DEFINE_COMPONENT component)
-       if(${${component}})
-               add_definitions(-D${component})
-       endif()
-endmacro()
+if(WITH_OPENSUBDIV)
+       macro(OPENSUBDIV_DEFINE_COMPONENT component)
+               if(${${component}})
+                       add_definitions(-D${component})
+               endif()
+       endmacro()
 
-OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_OPENMP)
-# TODO(sergey): OpenCL is not tested and totally unstable atm.
-# OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_OPENCL)
-# TODO(sergey): CUDA stays disabled for util it's ported to drievr API.
-# OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_CUDA)
-OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK)
-OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_COMPUTE)
+       list(APPEND INC_SYS
+               ${OPENSUBDIV_INCLUDE_DIR}
+               ${GLEW_INCLUDE_PATH}
+       )
 
-data_to_c_simple(shader/gpu_shader_opensubdiv_vertex.glsl SRC)
-data_to_c_simple(shader/gpu_shader_opensubdiv_geometry.glsl SRC)
-data_to_c_simple(shader/gpu_shader_opensubdiv_fragment.glsl SRC)
+       list(APPEND SRC
+               internal/opensubdiv.cc
+               internal/opensubdiv_converter_factory.cc
+               internal/opensubdiv_converter_internal.cc
+               internal/opensubdiv_converter_orient.cc
+               internal/opensubdiv_device_context_cuda.cc
+               internal/opensubdiv_device_context_opencl.cc
+               internal/opensubdiv_evaluator.cc
+               internal/opensubdiv_evaluator_internal.cc
+               internal/opensubdiv_gl_mesh.cc
+               internal/opensubdiv_gl_mesh_draw.cc
+               internal/opensubdiv_gl_mesh_fvar.cc
+               internal/opensubdiv_gl_mesh_internal.cc
+               internal/opensubdiv_topology_refiner.cc
+               internal/opensubdiv_topology_refiner_internal.cc
+               internal/opensubdiv_util.cc
 
-add_definitions(-DGLEW_STATIC)
+               internal/opensubdiv_converter_internal.h
+               internal/opensubdiv_converter_orient.h
+               internal/opensubdiv_converter_orient_impl.h
+               internal/opensubdiv_device_context_cuda.h
+               internal/opensubdiv_device_context_opencl.h
+               internal/opensubdiv_evaluator_internal.h
+               internal/opensubdiv_gl_mesh_fvar.h
+               internal/opensubdiv_gl_mesh_internal.h
+               internal/opensubdiv_internal.h
+               internal/opensubdiv_topology_refiner_internal.h
+               internal/opensubdiv_util.h
+       )
 
-if(WIN32)
-       add_definitions(-DNOMINMAX)
-       add_definitions(-D_USE_MATH_DEFINES)
-endif()
+       OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_OPENMP)
+       # TODO(sergey): OpenCL is not tested and totally unstable atm.
+       # OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_OPENCL)
+       # TODO(sergey): CUDA stays disabled for util it's ported to drievr API.
+       # OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_CUDA)
+       OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK)
+       OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_COMPUTE)
 
-# TODO(sergey): Put CUEW back when CUDA is officially supported by OSD.
-#if(OPENSUBDIV_HAS_CUDA)
-#      list(APPEND INC
-#              ../../extern/cuew/include
-#      )
-#      add_definitions(-DOPENSUBDIV_HAS_CUEW)
-#endif()
+       data_to_c_simple(shader/gpu_shader_opensubdiv_vertex.glsl SRC)
+       data_to_c_simple(shader/gpu_shader_opensubdiv_geometry.glsl SRC)
+       data_to_c_simple(shader/gpu_shader_opensubdiv_fragment.glsl SRC)
 
-if(OPENSUBDIV_HAS_OPENCL)
-       list(APPEND INC
-               ../../extern/clew/include
+       add_definitions(-DGLEW_STATIC)
+
+       if(WIN32)
+               add_definitions(-DNOMINMAX)
+               add_definitions(-D_USE_MATH_DEFINES)
+       endif()
+
+       # TODO(sergey): Put CUEW back when CUDA is officially supported by OSD.
+       #if(OPENSUBDIV_HAS_CUDA)
+       #       list(APPEND INC
+       #               ../../extern/cuew/include
+       #       )
+       #       add_definitions(-DOPENSUBDIV_HAS_CUEW)
+       #endif()
+
+       if(OPENSUBDIV_HAS_OPENCL)
+               list(APPEND INC
+                       ../../extern/clew/include
+               )
+               add_definitions(-DOPENSUBDIV_HAS_CLEW)
+       endif()
+else()
+       list(APPEND SRC
+               stub/opensubdiv_stub.cc
+               stub/opensubdiv_evaluator_stub.cc
+               stub/opensubdiv_gl_mesh_stub.cc
+               stub/opensubdiv_topology_refiner_stub.cc
        )
-       add_definitions(-DOPENSUBDIV_HAS_CLEW)
 endif()
 
 blender_add_lib(bf_intern_opensubdiv "${SRC}" "${INC}" "${INC_SYS}")
index 34d27591d0b33e114266147c63055ce4a5f91f82..649c5ce7b7d7943fed18207b6bdbc95bbc237b66 100644 (file)
@@ -281,7 +281,7 @@ struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
   return gl_mesh;
 }
 
-void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh *gl_mesh) {
+void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMeshgl_mesh) {
   delete gl_mesh->internal;
   OBJECT_GUARDED_DELETE(gl_mesh, OpenSubdiv_GLMesh);
 }
diff --git a/intern/opensubdiv/stub/opensubdiv_evaluator_stub.cc b/intern/opensubdiv/stub/opensubdiv_evaluator_stub.cc
new file mode 100644 (file)
index 0000000..86c80fe
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2018 Blender Foundation. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// Author: Sergey Sharybin
+
+#include "opensubdiv_evaluator_capi.h"
+
+#include <cstddef>
+
+OpenSubdiv_Evaluator* openSubdiv_createEvaluatorFromTopologyRefiner(
+    struct OpenSubdiv_TopologyRefiner* /*topology_refiner*/) {
+  return NULL;
+}
+
+void openSubdiv_deleteEvaluator(OpenSubdiv_Evaluator* /*evaluator*/) {
+}
diff --git a/intern/opensubdiv/stub/opensubdiv_gl_mesh_stub.cc b/intern/opensubdiv/stub/opensubdiv_gl_mesh_stub.cc
new file mode 100644 (file)
index 0000000..8f14a23
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright 2018 Blender Foundation. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// Author: Sergey Sharybin
+
+#include "opensubdiv_gl_mesh_capi.h"
+
+#include <cstddef>
+
+struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
+    OpenSubdiv_TopologyRefiner* /*topology_refiner*/,
+    eOpenSubdivEvaluator /*evaluator_type*/) {
+  return NULL;
+}
+
+void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh* /*gl_mesh*/) {
+}
+
+bool openSubdiv_initGLMeshDrawingResources(void) {
+  return false;
+}
+
+void openSubdiv_deinitGLMeshDrawingResources(void) {
+}
diff --git a/intern/opensubdiv/stub/opensubdiv_stub.cc b/intern/opensubdiv/stub/opensubdiv_stub.cc
new file mode 100644 (file)
index 0000000..f03f0a0
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2018 Blender Foundation. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// Author: Sergey Sharybin
+
+#include "opensubdiv_capi.h"
+
+#include <cstddef>
+
+void openSubdiv_init(void) {
+}
+
+void openSubdiv_cleanup(void) {
+}
+
+int openSubdiv_getAvailableEvaluators(void) {
+  return 0;
+}
+
+int openSubdiv_getVersionHex(void) {
+  return 0;
+}
diff --git a/intern/opensubdiv/stub/opensubdiv_topology_refiner_stub.cc b/intern/opensubdiv/stub/opensubdiv_topology_refiner_stub.cc
new file mode 100644 (file)
index 0000000..de98b0b
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright 2018 Blender Foundation. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// Author: Sergey Sharybin
+
+#include "opensubdiv_topology_refiner_capi.h"
+
+#include <cstddef>
+
+OpenSubdiv_TopologyRefiner* openSubdiv_createTopologyRefinerFromConverter(
+    OpenSubdiv_Converter* /*converter*/,
+    const OpenSubdiv_TopologyRefinerSettings* /*settings*/) {
+  return NULL;     
+}
+
+void openSubdiv_deleteTopologyRefiner(
+    OpenSubdiv_TopologyRefiner* /*topology_refiner*/) {
+}
+
+bool openSubdiv_topologyRefinerCompareWithConverter(
+    const OpenSubdiv_TopologyRefiner* /*topology_refiner*/,
+    const OpenSubdiv_Converter* /*converter*/) {
+  return false;
+}
index cd1e3adbc216166d8eb0d6f9f07c98e5d840a791..d81047563a71de85c8380ffacebfce797f028a41 100644 (file)
@@ -130,8 +130,9 @@ void BKE_subdiv_free(Subdiv *subdiv);
 
 /* ============================= EVALUATION API ============================= */
 
-void BKE_subdiv_eval_begin(Subdiv *subdiv);
-void BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const struct Mesh *mesh);
+/* Returns true if evaluator is ready for use. */
+bool BKE_subdiv_eval_begin(Subdiv *subdiv);
+bool BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const struct Mesh *mesh);
 
 /* Single point queries. */
 
index 7169597f100bdbd42a1bbf953d7df09ba7227c4a..646665cdec2b1c1e34ec571e7947149081851621 100644 (file)
@@ -53,6 +53,7 @@ set(INC
        ../../../intern/atomic
        ../../../intern/clog
        ../../../intern/libmv
+       ../../../intern/opensubdiv
        ../../../extern/curve_fit_nd
 )
 
@@ -530,7 +531,6 @@ endif()
 if(WITH_OPENSUBDIV)
        add_definitions(-DWITH_OPENSUBDIV)
        list(APPEND INC_SYS
-               ../../../intern/opensubdiv
                ${OPENSUBDIV_INCLUDE_DIRS}
        )
 endif()
index bae5491c079f522f29aff9e8b4f34242967a1ffb..207fdf43c55a306595daf4f1304b2d58f524ae29 100644 (file)
 
 #include "subdiv_converter.h"
 
-#ifdef WITH_OPENSUBDIV
-#  include "opensubdiv_capi.h"
-#  include "opensubdiv_converter_capi.h"
-#  include "opensubdiv_evaluator_capi.h"
-#  include "opensubdiv_topology_refiner_capi.h"
-#endif
+#include "opensubdiv_capi.h"
+#include "opensubdiv_converter_capi.h"
+#include "opensubdiv_evaluator_capi.h"
+#include "opensubdiv_topology_refiner_capi.h"
 
 Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings,
                                       struct OpenSubdiv_Converter *converter)
 {
-#ifdef WITH_OPENSUBDIV
        SubdivStats stats;
        BKE_subdiv_stats_init(&stats);
        BKE_subdiv_stats_begin(&stats, SUBDIV_STATS_TOPOLOGY_REFINER_CREATION_TIME);
@@ -74,16 +71,11 @@ Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings,
        BKE_subdiv_stats_end(&stats, SUBDIV_STATS_TOPOLOGY_REFINER_CREATION_TIME);
        subdiv->stats = stats;
        return subdiv;
-#else
-       UNUSED_VARS(settings, converter);
-       return NULL;
-#endif
 }
 
 Subdiv *BKE_subdiv_new_from_mesh(const SubdivSettings *settings,
                                  struct Mesh *mesh)
 {
-#ifdef WITH_OPENSUBDIV
        if (mesh->totvert == 0) {
                return NULL;
        }
@@ -92,15 +84,10 @@ Subdiv *BKE_subdiv_new_from_mesh(const SubdivSettings *settings,
        Subdiv *subdiv = BKE_subdiv_new_from_converter(settings, &converter);
        BKE_subdiv_converter_free(&converter);
        return subdiv;
-#else
-       UNUSED_VARS(settings, mesh);
-       return NULL;
-#endif
 }
 
 void BKE_subdiv_free(Subdiv *subdiv)
 {
-#ifdef WITH_OPENSUBDIV
        if (subdiv->evaluator != NULL) {
                openSubdiv_deleteEvaluator(subdiv->evaluator);
        }
@@ -108,7 +95,4 @@ void BKE_subdiv_free(Subdiv *subdiv)
                openSubdiv_deleteTopologyRefiner(subdiv->topology_refiner);
        }
        MEM_freeN(subdiv);
-#else
-       UNUSED_VARS(subdiv);
-#endif
 }
index f6dabfa1c80d0aa97c0018d27371502751729858..0ef32200bd34b2a4fb861416880613417ea8a7b1 100644 (file)
 
 #include "BLI_utildefines.h"
 
-#ifdef WITH_OPENSUBDIV
-#  include "opensubdiv_converter_capi.h"
-#endif
+#include "opensubdiv_converter_capi.h"
 
 void BKE_subdiv_converter_free(struct OpenSubdiv_Converter *converter)
 {
-#ifdef WITH_OPENSUBDIV
        if (converter->freeUserData) {
                converter->freeUserData(converter);
        }
-#else
-       UNUSED_VARS(converter);
-#endif
 }
 
 /*OpenSubdiv_FVarLinearInterpolation*/ int
 BKE_subdiv_converter_fvar_linear_from_settings(const SubdivSettings *settings)
 {
-#ifdef WITH_OPENSUBDIV
        switch (settings->fvar_linear_interpolation) {
                case SUBDIV_FVAR_LINEAR_INTERPOLATION_NONE:
                        return OSD_FVAR_LINEAR_INTERPOLATION_NONE;
@@ -58,8 +51,4 @@ BKE_subdiv_converter_fvar_linear_from_settings(const SubdivSettings *settings)
        }
        BLI_assert(!"Unknown fvar linear interpolation");
        return OSD_FVAR_LINEAR_INTERPOLATION_NONE;
-#else
-       UNUSED_VARS(settings);
-       return 0;
-#endif
 }
index c5fb8afb6cd23a09a155f1ac4528fedba7a04951..32e829a943969013c0295d51552e8210960640fa 100644 (file)
 
 #include "MEM_guardedalloc.h"
 
-#ifdef WITH_OPENSUBDIV
-#  include "opensubdiv_capi.h"
-#  include "opensubdiv_converter_capi.h"
-#endif
+#include "opensubdiv_capi.h"
+#include "opensubdiv_converter_capi.h"
 
-#ifdef WITH_OPENSUBDIV
 typedef struct ConverterStorage {
        SubdivSettings settings;
        const Mesh *mesh;
@@ -391,16 +388,11 @@ static void init_user_data(OpenSubdiv_Converter *converter,
        initialize_manifold_indices(user_data);
        converter->user_data = user_data;
 }
-#endif
 
 void BKE_subdiv_converter_init_for_mesh(struct OpenSubdiv_Converter *converter,
                                         const SubdivSettings *settings,
                                         const Mesh *mesh)
 {
-#ifdef WITH_OPENSUBDIV
        init_functions(converter);
        init_user_data(converter, settings, mesh);
-#else
-       UNUSED_VARS(converter, settings, mesh);
-#endif
 }
index e23be84ee265eb04234d06081ca765b88e6eca64..e3754655ea6b23f80b67f58ea8c1c5000c691ae5 100644 (file)
 
 #include "MEM_guardedalloc.h"
 
-#ifdef WITH_OPENSUBDIV
-#  include "opensubdiv_evaluator_capi.h"
-#  include "opensubdiv_topology_refiner_capi.h"
-#endif
+#include "opensubdiv_evaluator_capi.h"
+#include "opensubdiv_topology_refiner_capi.h"
 
-void BKE_subdiv_eval_begin(Subdiv *subdiv)
+bool BKE_subdiv_eval_begin(Subdiv *subdiv)
 {
-#ifdef WITH_OPENSUBDIV
        if (subdiv->topology_refiner == NULL) {
-               /* Happens on input mesh with just loose geometry. */
+               /* Happens on input mesh with just loose geometry,
+                * or when OpenSubdiv is disabled
+                */
+               return false;
        }
        else if (subdiv->evaluator == NULL) {
                BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE);
                subdiv->evaluator = openSubdiv_createEvaluatorFromTopologyRefiner(
                        subdiv->topology_refiner);
                BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE);
+               if (subdiv->evaluator == NULL) {
+                       return false;
+               }
        }
        else {
                /* TODO(sergey): Check for topology change. */
        }
-#else
-       UNUSED_VARS(subdiv);
-#endif
+       return true;
 }
 
-#ifdef WITH_OPENSUBDIV
 static void set_coarse_positions(Subdiv *subdiv, const Mesh *mesh)
 {
        const MVert *mvert = mesh->mvert;
@@ -130,14 +130,16 @@ static void set_face_varying_data_from_uv(Subdiv *subdiv,
                }
        }
 }
-#endif
 
-void BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const Mesh *mesh)
+bool BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const Mesh *mesh)
 {
-#ifdef WITH_OPENSUBDIV
-       BKE_subdiv_eval_begin(subdiv);
+       if (!BKE_subdiv_eval_begin(subdiv)) {
+               return false;
+       }
        if (subdiv->evaluator == NULL) {
-               return;
+               /* NOTE: This situation is supposed to be handled by begin(). */
+               BLI_assert(!"Is not supposed to happen");
+               return false;
        }
        /* Set coordinates of base mesh vertices. */
        set_coarse_positions(subdiv, mesh);
@@ -153,9 +155,7 @@ void BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const Mesh *mesh)
        BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_REFINE);
        subdiv->evaluator->refine(subdiv->evaluator);
        BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_REFINE);
-#else
-       UNUSED_VARS(subdiv, mesh);
-#endif
+       return true;
 }
 
 /* ========================== Single point queries ========================== */
@@ -178,14 +178,10 @@ void BKE_subdiv_eval_limit_point_and_derivatives(
         const float u, const float v,
         float P[3], float dPdu[3], float dPdv[3])
 {
-#ifdef WITH_OPENSUBDIV
        subdiv->evaluator->evaluateLimit(subdiv->evaluator,
                                         ptex_face_index,
                                         u, v,
                                         P, dPdu, dPdv);
-#else
-       UNUSED_VARS(subdiv, ptex_face_index, u, v, P, dPdu, dPdv);
-#endif
 }
 
 void BKE_subdiv_eval_limit_point_and_normal(
@@ -224,15 +220,11 @@ void BKE_subdiv_eval_face_varying(
         const float u, const float v,
         float face_varying[2])
 {
-#ifdef WITH_OPENSUBDIV
        subdiv->evaluator->evaluateFaceVarying(subdiv->evaluator,
                                               face_varying_channel,
                                               ptex_face_index,
                                               u, v,
                                               face_varying);
-#else
-       UNUSED_VARS(subdiv, face_varying_channel, ptex_face_index, u, v, face_varying);
-#endif
 }
 
 /* ===================  Patch queries at given resolution =================== */
index bb27cb6a31e0b9de139490962850a5f2ea17c221..3bc39732118cee881936e14791b3f0ba74b3cda0 100644 (file)
@@ -227,7 +227,7 @@ static void subdiv_mesh_ctx_count(SubdivMeshContext *ctx)
                                num_polys_per_ptex_get(no_quad_patch_resolution);
                }
        }
-       /* Calculate extra edges createdd by loose edges. */
+       /* Calculate extra vertices createdd by loose edges. */
        for (int edge_index = 0; edge_index < coarse_mesh->totedge; edge_index++) {
                if (!BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, edge_index)) {
                        ctx->num_subdiv_vertices += num_subdiv_vertices_per_coarse_edge;
@@ -2388,7 +2388,18 @@ Mesh *BKE_subdiv_to_mesh(
        /* Make sure evaluator is up to date with possible new topology, and that
         * is is refined for the new positions of coarse vertices.
         */
-       BKE_subdiv_eval_update_from_mesh(subdiv, coarse_mesh);
+       if (!BKE_subdiv_eval_update_from_mesh(subdiv, coarse_mesh)) {
+               /* This could happen in two situations:
+                * - OpenSubdiv is disabled.
+                * - Something totally bad happened, and OpenSubdiv rejected our
+                *   topology.
+                * In either way, we can't safely continue.
+                */
+               if (coarse_mesh->totpoly) {
+                       BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH);
+                       return NULL;
+               }
+       }
        SubdivMeshContext ctx = {0};
        ctx.coarse_mesh = coarse_mesh;
        ctx.subdiv = subdiv;