Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2015-07-20 16:27:47 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-07-20 23:29:25 +0300
commit2466c4f8cebd3977f29524d79050feff44b40fff (patch)
treeeccd394a6182ab4ffb9fe3e1dfbd7fe4c1d46866 /source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c
parenta040157e5dd7227fc61ee2608f30f2492db167be (diff)
OpenSubdiv: Add OpenSubdiv files which are related on the CCGSubSurf and GPU
Those files are still not in use (SCons will tyr to compile new CCGSubSurf files but no code will be in use at all because those new files are fully wrapped by ifdef WITH_OPENSUBDIV check).
Diffstat (limited to 'source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c')
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c502
1 files changed, 502 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c
new file mode 100644
index 00000000000..c66425b3ba8
--- /dev/null
+++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c
@@ -0,0 +1,502 @@
+/*
+ * ***** 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c
+ * \ingroup bke
+ */
+
+#ifdef WITH_OPENSUBDIV
+
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+#include "BLI_sys_types.h" // for intptr_t support
+
+#include "BLI_utildefines.h" /* for BLI_assert */
+#include "BLI_math.h"
+
+#include "CCGSubSurf.h"
+#include "CCGSubSurf_intern.h"
+
+#include "BKE_DerivedMesh.h"
+
+#include "opensubdiv_capi.h"
+#include "opensubdiv_converter_capi.h"
+
+/**
+ * Converter from DerivedMesh.
+ */
+
+typedef struct ConvDMStorage {
+ CCGSubSurf *ss;
+ DerivedMesh *dm;
+} ConvDMStorage;
+
+/* TODO(sergey): Optimize this by using mesh_map, so we don't
+ * do full mesh lookup for every geometry primitive.
+ */
+
+static OpenSubdiv_SchemeType conv_dm_get_type(
+ const OpenSubdiv_Converter *converter)
+{
+ ConvDMStorage *storage = converter->user_data;
+ if (storage->ss->meshIFC.simpleSubdiv)
+ return OSD_SCHEME_BILINEAR;
+ else
+ return OSD_SCHEME_CATMARK;
+}
+
+static int conv_dm_get_num_faces(const OpenSubdiv_Converter *converter)
+{
+ ConvDMStorage *storage = converter->user_data;
+ DerivedMesh *dm = storage->dm;
+ return dm->getNumPolys(dm);
+}
+
+static int conv_dm_get_num_edges(const OpenSubdiv_Converter *converter)
+{
+ ConvDMStorage *storage = converter->user_data;
+ DerivedMesh *dm = storage->dm;
+ return dm->getNumEdges(dm);
+}
+
+static int conv_dm_get_num_verts(const OpenSubdiv_Converter *converter)
+{
+ ConvDMStorage *storage = converter->user_data;
+ DerivedMesh *dm = storage->dm;
+ return dm->getNumVerts(dm);
+}
+
+static int conv_dm_get_num_face_verts(const OpenSubdiv_Converter *converter,
+ int face)
+{
+ ConvDMStorage *storage = converter->user_data;
+ DerivedMesh *dm = storage->dm;
+ const MPoly *mp = dm->getPolyArray(dm);
+ const MPoly *mpoly = &mp[face];
+ return mpoly->totloop;
+}
+
+static void conv_dm_get_face_verts(const OpenSubdiv_Converter *converter,
+ int face,
+ int *face_verts)
+{
+ ConvDMStorage *storage = converter->user_data;
+ DerivedMesh *dm = storage->dm;
+ const MLoop *ml = dm->getLoopArray(dm);
+ const MPoly *mp = dm->getPolyArray(dm);
+ const MPoly *mpoly = &mp[face];
+ int loop;
+ for (loop = 0; loop < mpoly->totloop; loop++) {
+ face_verts[loop] = ml[mpoly->loopstart + loop].v;
+ }
+}
+
+static void conv_dm_get_face_edges(const OpenSubdiv_Converter *converter,
+ int face,
+ int *face_edges)
+{
+ ConvDMStorage *storage = converter->user_data;
+ DerivedMesh *dm = storage->dm;
+ const MLoop *ml = dm->getLoopArray(dm);
+ const MPoly *mp = dm->getPolyArray(dm);
+ const MPoly *mpoly = &mp[face];
+ int loop;
+ for (loop = 0; loop < mpoly->totloop; loop++) {
+ face_edges[loop] = ml[mpoly->loopstart + loop].e;
+ }
+}
+
+static void conv_dm_get_edge_verts(const OpenSubdiv_Converter *converter,
+ int edge,
+ int *edge_verts)
+{
+ ConvDMStorage *storage = converter->user_data;
+ DerivedMesh *dm = storage->dm;
+ const MEdge *me = dm->getEdgeArray(dm);
+ const MEdge *medge = &me[edge];
+ edge_verts[0] = medge->v1;
+ edge_verts[1] = medge->v2;
+}
+
+static int conv_dm_get_num_edge_faces(const OpenSubdiv_Converter *converter,
+ int edge)
+{
+ ConvDMStorage *storage = converter->user_data;
+ DerivedMesh *dm = storage->dm;
+ const MLoop *ml = dm->getLoopArray(dm);
+ const MPoly *mp = dm->getPolyArray(dm);
+ int num = 0, poly;
+ for (poly = 0; poly < dm->getNumPolys(dm); poly++) {
+ const MPoly *mpoly = &mp[poly];
+ int loop;
+ for (loop = 0; loop < mpoly->totloop; loop++) {
+ const MLoop *mloop = &ml[mpoly->loopstart + loop];
+ if (mloop->e == edge) {
+ ++num;
+ break;
+ }
+ }
+ }
+ return num;
+}
+
+static void conv_dm_get_edge_faces(const OpenSubdiv_Converter *converter,
+ int edge,
+ int *edge_faces)
+{
+ ConvDMStorage *storage = converter->user_data;
+ DerivedMesh *dm = storage->dm;
+ const MLoop *ml = dm->getLoopArray(dm);
+ const MPoly *mp = dm->getPolyArray(dm);
+ int num = 0, poly;
+ for (poly = 0; poly < dm->getNumPolys(dm); poly++) {
+ const MPoly *mpoly = &mp[poly];
+ int loop;
+ for (loop = 0; loop < mpoly->totloop; loop++) {
+ const MLoop *mloop = &ml[mpoly->loopstart + loop];
+ if (mloop->e == edge) {
+ edge_faces[num++] = poly;
+ break;
+ }
+ }
+ }
+}
+
+static float conv_dm_get_edge_sharpness(const OpenSubdiv_Converter *converter,
+ int edge)
+{
+ ConvDMStorage *storage = converter->user_data;
+ DerivedMesh *dm = storage->dm;
+ CCGSubSurf *ss = storage->ss;
+ const MEdge *medge = dm->getEdgeArray(dm);
+ return (float)medge[edge].crease / 255.0f * ss->subdivLevels;
+}
+
+static int conv_dm_get_num_vert_edges(const OpenSubdiv_Converter *converter,
+ int vert)
+{
+ ConvDMStorage *storage = converter->user_data;
+ DerivedMesh *dm = storage->dm;
+ const MEdge *me = dm->getEdgeArray(dm);
+ int num = 0, edge;
+ for (edge = 0; edge < dm->getNumEdges(dm); edge++) {
+ const MEdge *medge = &me[edge];
+ if (medge->v1 == vert || medge->v2 == vert) {
+ ++num;
+ }
+ }
+ return num;
+}
+
+static void conv_dm_get_vert_edges(const OpenSubdiv_Converter *converter,
+ int vert,
+ int *vert_edges)
+{
+ ConvDMStorage *storage = converter->user_data;
+ DerivedMesh *dm = storage->dm;
+ const MEdge *me = dm->getEdgeArray(dm);
+ int num = 0, edge;
+ for (edge = 0; edge < dm->getNumEdges(dm); edge++) {
+ const MEdge *medge = &me[edge];
+ if (medge->v1 == vert || medge->v2 == vert) {
+ vert_edges[num++] = edge;
+ }
+ }
+}
+
+static int conv_dm_get_num_vert_faces(const OpenSubdiv_Converter *converter,
+ int vert)
+{
+ ConvDMStorage *storage = converter->user_data;
+ DerivedMesh *dm = storage->dm;
+ const MLoop *ml = dm->getLoopArray(dm);
+ const MPoly *mp = dm->getPolyArray(dm);
+ int num = 0, poly;
+ for (poly = 0; poly < dm->getNumPolys(dm); poly++) {
+ const MPoly *mpoly = &mp[poly];
+ int loop;
+ for (loop = 0; loop < mpoly->totloop; loop++) {
+ const MLoop *mloop = &ml[mpoly->loopstart + loop];
+ if (mloop->v == vert) {
+ ++num;
+ break;
+ }
+ }
+ }
+ return num;
+}
+
+static void conv_dm_get_vert_faces(const OpenSubdiv_Converter *converter,
+ int vert,
+ int *vert_faces)
+{
+ ConvDMStorage *storage = converter->user_data;
+ DerivedMesh *dm = storage->dm;
+ const MLoop *ml = dm->getLoopArray(dm);
+ const MPoly *mp = dm->getPolyArray(dm);
+ int num = 0, poly;
+ for (poly = 0; poly < dm->getNumPolys(dm); poly++) {
+ const MPoly *mpoly = &mp[poly];
+ int loop;
+ for (loop = 0; loop < mpoly->totloop; loop++) {
+ const MLoop *mloop = &ml[mpoly->loopstart + loop];
+ if (mloop->v == vert) {
+ vert_faces[num++] = poly;
+ break;
+ }
+ }
+ }
+}
+
+static void conv_dm_free_user_data(const OpenSubdiv_Converter *converter)
+{
+ MEM_freeN(converter->user_data);
+}
+
+void ccgSubSurf_converter_setup_from_derivedmesh(
+ CCGSubSurf *ss,
+ DerivedMesh *dm,
+ OpenSubdiv_Converter *converter)
+{
+ ConvDMStorage *user_data;
+
+ converter->get_type = conv_dm_get_type;
+
+ 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;
+
+ converter->get_num_face_verts = conv_dm_get_num_face_verts;
+ converter->get_face_verts = conv_dm_get_face_verts;
+ converter->get_face_edges = conv_dm_get_face_edges;
+
+ converter->get_edge_verts = conv_dm_get_edge_verts;
+ converter->get_num_edge_faces = conv_dm_get_num_edge_faces;
+ converter->get_edge_faces = conv_dm_get_edge_faces;
+ converter->get_edge_sharpness = conv_dm_get_edge_sharpness;
+
+ converter->get_num_vert_edges = conv_dm_get_num_vert_edges;
+ converter->get_vert_edges = conv_dm_get_vert_edges;
+ converter->get_num_vert_faces = conv_dm_get_num_vert_faces;
+ converter->get_vert_faces = conv_dm_get_vert_faces;
+
+ user_data = MEM_mallocN(sizeof(ConvDMStorage), __func__);
+ user_data->ss = ss;
+ user_data->dm = dm;
+ converter->free_user_data = conv_dm_free_user_data;
+ converter->user_data = user_data;
+}
+
+/**
+ * Converter from CCGSubSurf
+ */
+
+static OpenSubdiv_SchemeType conv_ccg_get_bilinear_type(
+ const OpenSubdiv_Converter *converter)
+{
+ CCGSubSurf *ss = converter->user_data;
+ if (ss->meshIFC.simpleSubdiv) {
+ return OSD_SCHEME_BILINEAR;
+ }
+ else {
+ return OSD_SCHEME_CATMARK;
+ }
+}
+
+static int conv_ccg_get_num_faces(const OpenSubdiv_Converter *converter)
+{
+ CCGSubSurf *ss = converter->user_data;
+ return ss->fMap->numEntries;
+}
+
+static int conv_ccg_get_num_edges(const OpenSubdiv_Converter *converter)
+{
+ CCGSubSurf *ss = converter->user_data;
+ return ss->eMap->numEntries;
+}
+
+static int conv_ccg_get_num_verts(const OpenSubdiv_Converter *converter)
+{
+ CCGSubSurf *ss = converter->user_data;
+ return ss->vMap->numEntries;
+}
+
+static int conv_ccg_get_num_face_verts(const OpenSubdiv_Converter *converter,
+ int face)
+{
+ CCGSubSurf *ss = converter->user_data;
+ CCGFace *ccg_face = ccgSubSurf_getFace(ss, SET_INT_IN_POINTER(face));
+ return ccgSubSurf_getFaceNumVerts(ccg_face);
+}
+
+static void conv_ccg_get_face_verts(const OpenSubdiv_Converter *converter,
+ int face,
+ int *face_verts)
+{
+ CCGSubSurf *ss = converter->user_data;
+ CCGFace *ccg_face = ccgSubSurf_getFace(ss, SET_INT_IN_POINTER(face));
+ int num_face_verts = ccgSubSurf_getFaceNumVerts(ccg_face);
+ int loop;
+ for (loop = 0; loop < num_face_verts; loop++) {
+ CCGVert *ccg_vert = ccgSubSurf_getFaceVert(ccg_face, loop);
+ face_verts[loop] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ccg_vert));
+ }
+}
+
+static void conv_ccg_get_face_edges(const OpenSubdiv_Converter *converter,
+ int face,
+ int *face_edges)
+{
+ CCGSubSurf *ss = converter->user_data;
+ CCGFace *ccg_face = ccgSubSurf_getFace(ss, SET_INT_IN_POINTER(face));
+ int num_face_verts = ccgSubSurf_getFaceNumVerts(ccg_face);
+ int loop;
+ for (loop = 0; loop < num_face_verts; loop++) {
+ CCGEdge *ccg_edge = ccgSubSurf_getFaceEdge(ccg_face, loop);
+ face_edges[loop] = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ccg_edge));
+ }
+}
+
+static void conv_ccg_get_edge_verts(const OpenSubdiv_Converter *converter,
+ int edge,
+ int *edge_verts)
+{
+ CCGSubSurf *ss = converter->user_data;
+ CCGEdge *ccg_edge = ccgSubSurf_getEdge(ss, SET_INT_IN_POINTER(edge));
+ CCGVert *ccg_vert0 = ccgSubSurf_getEdgeVert0(ccg_edge);
+ CCGVert *ccg_vert1 = ccgSubSurf_getEdgeVert1(ccg_edge);
+ edge_verts[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ccg_vert0));
+ edge_verts[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ccg_vert1));
+}
+
+static int conv_ccg_get_num_edge_faces(const OpenSubdiv_Converter *converter,
+ int edge)
+{
+ CCGSubSurf *ss = converter->user_data;
+ CCGEdge *ccg_edge = ccgSubSurf_getEdge(ss, SET_INT_IN_POINTER(edge));
+ return ccgSubSurf_getEdgeNumFaces(ccg_edge);
+}
+
+static void conv_ccg_get_edge_faces(const OpenSubdiv_Converter *converter,
+ int edge,
+ int *edge_faces)
+{
+ CCGSubSurf *ss = converter->user_data;
+ CCGEdge *ccg_edge = ccgSubSurf_getEdge(ss, SET_INT_IN_POINTER(edge));
+ int num_edge_faces = ccgSubSurf_getEdgeNumFaces(ccg_edge);
+ int face;
+ for (face = 0; face < num_edge_faces; face++) {
+ CCGFace *ccg_face = ccgSubSurf_getEdgeFace(ccg_edge, face);
+ edge_faces[face] = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ccg_face));
+ }
+}
+
+static float conv_ccg_get_edge_sharpness(const OpenSubdiv_Converter *converter,
+ int edge)
+{
+ CCGSubSurf *ss = converter->user_data;
+ CCGEdge *ccg_edge = ccgSubSurf_getEdge(ss, SET_INT_IN_POINTER(edge));
+ /* TODO(sergey): Multiply by subdivision level once CPU evaluator
+ * is switched to uniform subdivision type.
+ */
+ return ccg_edge->crease;
+}
+
+static int conv_ccg_get_num_vert_edges(const OpenSubdiv_Converter *converter,
+ int vert)
+{
+ CCGSubSurf *ss = converter->user_data;
+ CCGVert *ccg_vert = ccgSubSurf_getVert(ss, SET_INT_IN_POINTER(vert));
+ return ccgSubSurf_getVertNumEdges(ccg_vert);
+}
+
+static void conv_ccg_get_vert_edges(const OpenSubdiv_Converter *converter,
+ int vert,
+ int *vert_edges)
+{
+ CCGSubSurf *ss = converter->user_data;
+ CCGVert *ccg_vert = ccgSubSurf_getVert(ss, SET_INT_IN_POINTER(vert));
+ int num_vert_edges = ccgSubSurf_getVertNumEdges(ccg_vert);
+ int edge;
+ for (edge = 0; edge < num_vert_edges; edge++) {
+ CCGEdge *ccg_edge = ccgSubSurf_getVertEdge(ccg_vert, edge);
+ vert_edges[edge] = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ccg_edge));
+ }
+}
+
+static int conv_ccg_get_num_vert_faces(const OpenSubdiv_Converter *converter,
+ int vert)
+{
+ CCGSubSurf *ss = converter->user_data;
+ CCGVert *ccg_vert = ccgSubSurf_getVert(ss, SET_INT_IN_POINTER(vert));
+ return ccgSubSurf_getVertNumFaces(ccg_vert);
+}
+
+static void conv_ccg_get_vert_faces(const OpenSubdiv_Converter *converter,
+ int vert,
+ int *vert_faces)
+{
+ CCGSubSurf *ss = converter->user_data;
+ CCGVert *ccg_vert = ccgSubSurf_getVert(ss, SET_INT_IN_POINTER(vert));
+ int num_vert_faces = ccgSubSurf_getVertNumFaces(ccg_vert);
+ int face;
+ for (face = 0; face < num_vert_faces; face++) {
+ CCGFace *ccg_face = ccgSubSurf_getVertFace(ccg_vert, face);
+ vert_faces[face] = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ccg_face));
+ }
+}
+
+void ccgSubSurf_converter_setup_from_ccg(CCGSubSurf *ss,
+ OpenSubdiv_Converter *converter)
+{
+ converter->get_type = conv_ccg_get_bilinear_type;
+
+ 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;
+
+ converter->get_num_face_verts = conv_ccg_get_num_face_verts;
+ converter->get_face_verts = conv_ccg_get_face_verts;
+ converter->get_face_edges = conv_ccg_get_face_edges;
+
+ converter->get_edge_verts = conv_ccg_get_edge_verts;
+ converter->get_num_edge_faces = conv_ccg_get_num_edge_faces;
+ converter->get_edge_faces = conv_ccg_get_edge_faces;
+ converter->get_edge_sharpness = conv_ccg_get_edge_sharpness;
+
+ converter->get_num_vert_edges = conv_ccg_get_num_vert_edges;
+ converter->get_vert_edges = conv_ccg_get_vert_edges;
+ converter->get_num_vert_faces = conv_ccg_get_num_vert_faces;
+ converter->get_vert_faces = conv_ccg_get_vert_faces;
+
+ converter->free_user_data = NULL;
+ converter->user_data = ss;
+}
+
+void ccgSubSurf_converter_free(
+ struct OpenSubdiv_Converter *converter)
+{
+ if (converter->free_user_data) {
+ converter->free_user_data(converter);
+ }
+}
+
+#endif /* WITH_OPENSUBDIV */