OpenSubdiv: Add stub implementation of C-API

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.
This commit is contained in:
Sergey Sharybin 2018-08-13 12:21:29 +02:00
parent 33fbc4fbea
commit f8a499b596
14 changed files with 263 additions and 145 deletions

View 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)

View 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)
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)
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
list(APPEND INC_SYS
${OPENSUBDIV_INCLUDE_DIR}
${GLEW_INCLUDE_PATH}
)
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
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_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)
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)
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}")

View File

@ -281,7 +281,7 @@ struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
return gl_mesh;
}
void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh *gl_mesh) {
void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh* gl_mesh) {
delete gl_mesh->internal;
OBJECT_GUARDED_DELETE(gl_mesh, OpenSubdiv_GLMesh);
}

View File

@ -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*/) {
}

View File

@ -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) {
}

View File

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

View File

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

View 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. */

View 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()

View File

@ -37,17 +37,14 @@
#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
}

View File

@ -27,25 +27,18 @@
#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
}

View File

@ -40,12 +40,9 @@
#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
}

View File

@ -40,32 +40,32 @@
#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 =================== */

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