From 01fa0eac63715eb080f3a6fb363f6ea0f0caafed Mon Sep 17 00:00:00 2001 From: Dirk Van Gelder Date: Wed, 1 Jan 2014 21:02:56 -0800 Subject: [PATCH] Add C compatible API to access the adaptiveEvaluator class from non-C++. This is the case with blender. --- opensubdiv/osdutil/CMakeLists.txt | 5 +- opensubdiv/osdutil/evaluator_capi.cpp | 147 ++++++++++++++++++++++++++ opensubdiv/osdutil/evaluator_capi.h | 39 +++++++ 3 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 opensubdiv/osdutil/evaluator_capi.cpp create mode 100644 opensubdiv/osdutil/evaluator_capi.h diff --git a/opensubdiv/osdutil/CMakeLists.txt b/opensubdiv/osdutil/CMakeLists.txt index 6c302f1a..8043c54a 100644 --- a/opensubdiv/osdutil/CMakeLists.txt +++ b/opensubdiv/osdutil/CMakeLists.txt @@ -35,6 +35,7 @@ set(PUBLIC_HEADER_FILES batch.h drawItem.h drawController.h + evaluator_capi.h mesh.h refiner.h topology.h @@ -43,7 +44,9 @@ set(PUBLIC_HEADER_FILES add_library(osdutil adaptiveEvaluator.h - adaptiveEvaluator.cpp + adaptiveEvaluator.cpp + evaluator_capi.h + evaluator_capi.cpp mesh.h mesh.cpp refiner.h diff --git a/opensubdiv/osdutil/evaluator_capi.cpp b/opensubdiv/osdutil/evaluator_capi.cpp new file mode 100644 index 00000000..60506b52 --- /dev/null +++ b/opensubdiv/osdutil/evaluator_capi.cpp @@ -0,0 +1,147 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * The Original Code is Copyright (C) 2013 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin. + * Brecht van Lommel + * Dirk Van Gelder + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "evaluator_capi.h" + +#include + +#include "adaptiveEvaluator.h" +#include "topology.h" + +#if !defined(WITH_ASSERT_ABORT) +# define OSD_abort() +#else +# include +# define OSD_abort() abort() +#endif + +#if defined(_MSC_VER) +# define __func__ __FUNCTION__ +#endif + +/* Define this when you want to have additional verbosity + * about what's being passed to OpenSubdiv. + */ +#undef DEBUG_PRINT + +using namespace OpenSubdiv; + +/* **************** Types declaration **************** */ + +typedef struct OpenSubdiv_EvaluatorDescr { + PxOsdUtilSubdivTopology topology; + PxOsdUtilAdaptiveEvaluator evaluator; + std::vector coarsePositions; +} OpenSubdiv_EvaluatorDescr; + + +/* **************** Mesh descriptor functions **************** */ + +OpenSubdiv_EvaluatorDescr *openSubdiv_createEvaluatorDescr(int numVertices) +{ + OpenSubdiv_EvaluatorDescr *evaluator_descr = + new OpenSubdiv_EvaluatorDescr(); + + evaluator_descr->topology.numVertices = numVertices; + + return evaluator_descr; +} + +void openSubdiv_deleteEvaluatorDescr( + OpenSubdiv_EvaluatorDescr *evaluator_descr) +{ + delete(evaluator_descr); +} + +void openSubdiv_createEvaluatorDescrFace(OpenSubdiv_EvaluatorDescr *evaluator_descr, int num_vertices, int *indices) +{ +#ifdef DEBUG_PRINT + printf("Adding face index:%d vertices:", (int)evaluator_descr->topology.nverts.size()); + for (int i = 0; i < num_vertices; i++) { + printf("%d ", indices[i]); + } + printf("\n"); +#endif + + evaluator_descr->topology.nverts.push_back(num_vertices); + for (int i = 0; i < num_vertices; i++) { + evaluator_descr->topology.indices.push_back(indices[i]); + } +} + +void openSubdiv_finishEvaluatorDescr(OpenSubdiv_EvaluatorDescr *evaluator_descr, + int refinementLevel) +{ + std::string errorMessage; + evaluator_descr->topology.refinementLevel = refinementLevel; + + if (not evaluator_descr->topology.IsValid(&errorMessage)) { + std::cout <<"OpenSubdiv topology is not valid due to " << errorMessage << std::endl; + } else { + if (not evaluator_descr->evaluator.Initialize( + evaluator_descr->topology, &errorMessage)) { + std::cout <<"OpenSubdiv uniform evaluator initialization failed due to " << errorMessage << std::endl; + } + } +} + + +int openSubdiv_setEvaluatorCoarsePositions( + struct OpenSubdiv_EvaluatorDescr *evaluator_descr, + const float *positions, int numVertices) +{ + std::string errorMessage; + + // TODO: returns void, need error check on length of positions? + evaluator_descr->evaluator.SetCoarsePositions( + &evaluator_descr->coarsePositions[0], + (int)evaluator_descr->coarsePositions.size(), + &errorMessage); + + // Refine with 1 thread for now + if (not evaluator_descr->evaluator.Refine(1, &errorMessage)) { + std::cout << "OpenSubdiv refinement failed due to " << errorMessage << std::endl; + return 0; + } + + return 1; +} + + +void openSubdiv_evaluateLimit( + struct OpenSubdiv_EvaluatorDescr *evaluation_descr, + int face_id, float u, float v, + float P[3], float dPdu[3], float dPdv[3]) +{ + OsdEvalCoords coords; + coords.u = u; + coords.v = v; + coords.face = face_id; + + evaluation_descr->evaluator.EvaluateLimit(coords, P, dPdu, dPdv); +} + diff --git a/opensubdiv/osdutil/evaluator_capi.h b/opensubdiv/osdutil/evaluator_capi.h new file mode 100644 index 00000000..fe6ac4d1 --- /dev/null +++ b/opensubdiv/osdutil/evaluator_capi.h @@ -0,0 +1,39 @@ +#ifndef __OPENSUBDIV_OSDUTIL_EVALUATOR_CAPI_H__ +#define __OPENSUBDIV_OSDUTIL_EVALUATOR_CAPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Types declaration. */ +struct OpenSubdiv_EvaluationDescr; + +/* Methods to create and delete evaluators. */ +struct OpenSubdiv_EvaluatorDescr *openSubdiv_createEvaluatorDescr(int numVertices); +void openSubdiv_deleteEvaluatorDescr(struct OpenSubdiv_EvaluatorDescr *evaluator_descr); +void openSubdiv_createEvaluatorDescrFace(struct OpenSubdiv_EvaluatorDescr *evaluator_descr, int num_vertices, int *indices); +void openSubdiv_finishEvaluatorDescr(struct OpenSubdiv_EvaluatorDescr *evaluator_descr, int refinementLevel); + +/* Set the positions of points on the coarse mesh and refine. This method */ +/* will perform catmull/clark refinement on the CVs to be ready to call */ +/* openSubdiv_evaluateDescr. Points here are 3 floats/point. */ +int openSubdiv_setEvaluatorCoarsePositions( + struct OpenSubdiv_EvaluatorDescr *evaluator_descr, + const float *positions, int numVertices); + +/* Evaluate the subdivision limit surface at the given ptex face and u/v, */ +/* return position and derivative information. Derivative pointers can be */ +/* NULL. Note that face index here is the ptex index, or the index into */ +/* faces after turning all the faces on the original mesh into quads. */ +void openSubdiv_evaluateLimit( + struct OpenSubdiv_EvaluatorDescr *evaluation_descr, + int face_id, float u, float v, + float P[3], float dPdu[3], float dPdv[3]); + + + +#ifdef __cplusplus +} +#endif + +#endif /* __OPENSUBDIV_CAPI_H__ */