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:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/blenkernel/intern/subsurf_ccg.c
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/blenkernel/intern/subsurf_ccg.c')
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c4910
1 files changed, 2457 insertions, 2453 deletions
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index b383c049e2e..cba391a90a8 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -89,310 +89,311 @@ static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm);
static void *arena_alloc(CCGAllocatorHDL a, int numBytes)
{
- return BLI_memarena_alloc(a, numBytes);
+ return BLI_memarena_alloc(a, numBytes);
}
static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize)
{
- void *p2 = BLI_memarena_alloc(a, newSize);
- if (ptr) {
- memcpy(p2, ptr, oldSize);
- }
- return p2;
+ void *p2 = BLI_memarena_alloc(a, newSize);
+ if (ptr) {
+ memcpy(p2, ptr, oldSize);
+ }
+ return p2;
}
static void arena_free(CCGAllocatorHDL UNUSED(a), void *UNUSED(ptr))
{
- /* do nothing */
+ /* do nothing */
}
static void arena_release(CCGAllocatorHDL a)
{
- BLI_memarena_free(a);
+ BLI_memarena_free(a);
}
typedef enum {
- CCG_USE_AGING = 1,
- CCG_USE_ARENA = 2,
- CCG_CALC_NORMALS = 4,
- /* add an extra four bytes for a mask layer */
- CCG_ALLOC_MASK = 8,
- CCG_SIMPLE_SUBDIV = 16,
+ CCG_USE_AGING = 1,
+ CCG_USE_ARENA = 2,
+ CCG_CALC_NORMALS = 4,
+ /* add an extra four bytes for a mask layer */
+ CCG_ALLOC_MASK = 8,
+ CCG_SIMPLE_SUBDIV = 16,
} CCGFlags;
-static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels,
- int numLayers, CCGFlags flags)
-{
- CCGMeshIFC ifc;
- CCGSubSurf *ccgSS;
- int useAging = !!(flags & CCG_USE_AGING);
- int useArena = flags & CCG_USE_ARENA;
- int normalOffset = 0;
-
- /* (subdivLevels == 0) is not allowed */
- subdivLevels = MAX2(subdivLevels, 1);
-
- if (prevSS) {
- int oldUseAging;
-
- ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
-
- if ((oldUseAging != useAging) ||
- (ccgSubSurf_getSimpleSubdiv(prevSS) != !!(flags & CCG_SIMPLE_SUBDIV)))
- {
- ccgSubSurf_free(prevSS);
- }
- else {
- ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels);
-
- return prevSS;
- }
- }
-
- if (useAging) {
- ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12;
- }
- else {
- ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
- }
- ifc.numLayers = numLayers;
- ifc.vertDataSize = sizeof(float) * numLayers;
- normalOffset += sizeof(float) * numLayers;
- if (flags & CCG_CALC_NORMALS)
- ifc.vertDataSize += sizeof(float) * 3;
- if (flags & CCG_ALLOC_MASK)
- ifc.vertDataSize += sizeof(float);
- ifc.simpleSubdiv = !!(flags & CCG_SIMPLE_SUBDIV);
-
- if (useArena) {
- CCGAllocatorIFC allocatorIFC;
- CCGAllocatorHDL allocator = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "subsurf arena");
-
- allocatorIFC.alloc = arena_alloc;
- allocatorIFC.realloc = arena_realloc;
- allocatorIFC.free = arena_free;
- allocatorIFC.release = arena_release;
-
- ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator);
- }
- else {
- ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL);
- }
-
- if (useAging) {
- ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
- }
-
- if (flags & CCG_ALLOC_MASK) {
- normalOffset += sizeof(float);
- /* mask is allocated after regular layers */
- ccgSubSurf_setAllocMask(ccgSS, 1, sizeof(float) * numLayers);
- }
-
- if (flags & CCG_CALC_NORMALS)
- ccgSubSurf_setCalcVertexNormals(ccgSS, 1, normalOffset);
- else
- ccgSubSurf_setCalcVertexNormals(ccgSS, 0, 0);
-
- return ccgSS;
+static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int numLayers, CCGFlags flags)
+{
+ CCGMeshIFC ifc;
+ CCGSubSurf *ccgSS;
+ int useAging = !!(flags & CCG_USE_AGING);
+ int useArena = flags & CCG_USE_ARENA;
+ int normalOffset = 0;
+
+ /* (subdivLevels == 0) is not allowed */
+ subdivLevels = MAX2(subdivLevels, 1);
+
+ if (prevSS) {
+ int oldUseAging;
+
+ ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
+
+ if ((oldUseAging != useAging) ||
+ (ccgSubSurf_getSimpleSubdiv(prevSS) != !!(flags & CCG_SIMPLE_SUBDIV))) {
+ ccgSubSurf_free(prevSS);
+ }
+ else {
+ ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels);
+
+ return prevSS;
+ }
+ }
+
+ if (useAging) {
+ ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12;
+ }
+ else {
+ ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
+ }
+ ifc.numLayers = numLayers;
+ ifc.vertDataSize = sizeof(float) * numLayers;
+ normalOffset += sizeof(float) * numLayers;
+ if (flags & CCG_CALC_NORMALS)
+ ifc.vertDataSize += sizeof(float) * 3;
+ if (flags & CCG_ALLOC_MASK)
+ ifc.vertDataSize += sizeof(float);
+ ifc.simpleSubdiv = !!(flags & CCG_SIMPLE_SUBDIV);
+
+ if (useArena) {
+ CCGAllocatorIFC allocatorIFC;
+ CCGAllocatorHDL allocator = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "subsurf arena");
+
+ allocatorIFC.alloc = arena_alloc;
+ allocatorIFC.realloc = arena_realloc;
+ allocatorIFC.free = arena_free;
+ allocatorIFC.release = arena_release;
+
+ ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator);
+ }
+ else {
+ ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL);
+ }
+
+ if (useAging) {
+ ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
+ }
+
+ if (flags & CCG_ALLOC_MASK) {
+ normalOffset += sizeof(float);
+ /* mask is allocated after regular layers */
+ ccgSubSurf_setAllocMask(ccgSS, 1, sizeof(float) * numLayers);
+ }
+
+ if (flags & CCG_CALC_NORMALS)
+ ccgSubSurf_setCalcVertexNormals(ccgSS, 1, normalOffset);
+ else
+ ccgSubSurf_setCalcVertexNormals(ccgSS, 0, 0);
+
+ return ccgSS;
}
static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize)
{
- CCGVert *v0 = ccgSubSurf_getEdgeVert0(e);
- CCGVert *v1 = ccgSubSurf_getEdgeVert1(e);
- int v0idx = *((int *) ccgSubSurf_getVertUserData(ss, v0));
- int v1idx = *((int *) ccgSubSurf_getVertUserData(ss, v1));
- int edgeBase = *((int *) ccgSubSurf_getEdgeUserData(ss, e));
-
- if (x == 0) {
- return v0idx;
- }
- else if (x == edgeSize - 1) {
- return v1idx;
- }
- else {
- return edgeBase + x - 1;
- }
-}
-
-static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize)
-{
- int faceBase = *((int *) ccgSubSurf_getFaceUserData(ss, f));
- int numVerts = ccgSubSurf_getFaceNumVerts(f);
-
- if (x == gridSize - 1 && y == gridSize - 1) {
- CCGVert *v = ccgSubSurf_getFaceVert(f, S);
- return *((int *) ccgSubSurf_getVertUserData(ss, v));
- }
- else if (x == gridSize - 1) {
- CCGVert *v = ccgSubSurf_getFaceVert(f, S);
- CCGEdge *e = ccgSubSurf_getFaceEdge(f, S);
- int edgeBase = *((int *) ccgSubSurf_getEdgeUserData(ss, e));
- if (v == ccgSubSurf_getEdgeVert0(e)) {
- return edgeBase + (gridSize - 1 - y) - 1;
- }
- else {
- return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - y) - 1);
- }
- }
- else if (y == gridSize - 1) {
- CCGVert *v = ccgSubSurf_getFaceVert(f, S);
- CCGEdge *e = ccgSubSurf_getFaceEdge(f, (S + numVerts - 1) % numVerts);
- int edgeBase = *((int *) ccgSubSurf_getEdgeUserData(ss, e));
- if (v == ccgSubSurf_getEdgeVert0(e)) {
- return edgeBase + (gridSize - 1 - x) - 1;
- }
- else {
- return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - x) - 1);
- }
- }
- else if (x == 0 && y == 0) {
- return faceBase;
- }
- else if (x == 0) {
- S = (S + numVerts - 1) % numVerts;
- return faceBase + 1 + (gridSize - 2) * S + (y - 1);
- }
- else if (y == 0) {
- return faceBase + 1 + (gridSize - 2) * S + (x - 1);
- }
- else {
- return faceBase + 1 + (gridSize - 2) * numVerts + S * (gridSize - 2) * (gridSize - 2) + (y - 1) * (gridSize - 2) + (x - 1);
- }
-}
-
-static void get_face_uv_map_vert(UvVertMap *vmap, struct MPoly *mpoly, struct MLoop *ml, int fi, CCGVertHDL *fverts)
-{
- UvMapVert *v, *nv;
- int j, nverts = mpoly[fi].totloop;
-
- for (j = 0; j < nverts; j++) {
- for (nv = v = BKE_mesh_uv_vert_map_get_vert(vmap, ml[j].v); v; v = v->next) {
- if (v->separate)
- nv = v;
- if (v->poly_index == fi)
- break;
- }
-
- fverts[j] = POINTER_FROM_UINT(mpoly[nv->poly_index].loopstart + nv->loop_of_poly_index);
- }
+ CCGVert *v0 = ccgSubSurf_getEdgeVert0(e);
+ CCGVert *v1 = ccgSubSurf_getEdgeVert1(e);
+ int v0idx = *((int *)ccgSubSurf_getVertUserData(ss, v0));
+ int v1idx = *((int *)ccgSubSurf_getVertUserData(ss, v1));
+ int edgeBase = *((int *)ccgSubSurf_getEdgeUserData(ss, e));
+
+ if (x == 0) {
+ return v0idx;
+ }
+ else if (x == edgeSize - 1) {
+ return v1idx;
+ }
+ else {
+ return edgeBase + x - 1;
+ }
+}
+
+static int getFaceIndex(
+ CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize)
+{
+ int faceBase = *((int *)ccgSubSurf_getFaceUserData(ss, f));
+ int numVerts = ccgSubSurf_getFaceNumVerts(f);
+
+ if (x == gridSize - 1 && y == gridSize - 1) {
+ CCGVert *v = ccgSubSurf_getFaceVert(f, S);
+ return *((int *)ccgSubSurf_getVertUserData(ss, v));
+ }
+ else if (x == gridSize - 1) {
+ CCGVert *v = ccgSubSurf_getFaceVert(f, S);
+ CCGEdge *e = ccgSubSurf_getFaceEdge(f, S);
+ int edgeBase = *((int *)ccgSubSurf_getEdgeUserData(ss, e));
+ if (v == ccgSubSurf_getEdgeVert0(e)) {
+ return edgeBase + (gridSize - 1 - y) - 1;
+ }
+ else {
+ return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - y) - 1);
+ }
+ }
+ else if (y == gridSize - 1) {
+ CCGVert *v = ccgSubSurf_getFaceVert(f, S);
+ CCGEdge *e = ccgSubSurf_getFaceEdge(f, (S + numVerts - 1) % numVerts);
+ int edgeBase = *((int *)ccgSubSurf_getEdgeUserData(ss, e));
+ if (v == ccgSubSurf_getEdgeVert0(e)) {
+ return edgeBase + (gridSize - 1 - x) - 1;
+ }
+ else {
+ return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - x) - 1);
+ }
+ }
+ else if (x == 0 && y == 0) {
+ return faceBase;
+ }
+ else if (x == 0) {
+ S = (S + numVerts - 1) % numVerts;
+ return faceBase + 1 + (gridSize - 2) * S + (y - 1);
+ }
+ else if (y == 0) {
+ return faceBase + 1 + (gridSize - 2) * S + (x - 1);
+ }
+ else {
+ return faceBase + 1 + (gridSize - 2) * numVerts + S * (gridSize - 2) * (gridSize - 2) +
+ (y - 1) * (gridSize - 2) + (x - 1);
+ }
+}
+
+static void get_face_uv_map_vert(
+ UvVertMap *vmap, struct MPoly *mpoly, struct MLoop *ml, int fi, CCGVertHDL *fverts)
+{
+ UvMapVert *v, *nv;
+ int j, nverts = mpoly[fi].totloop;
+
+ for (j = 0; j < nverts; j++) {
+ for (nv = v = BKE_mesh_uv_vert_map_get_vert(vmap, ml[j].v); v; v = v->next) {
+ if (v->separate)
+ nv = v;
+ if (v->poly_index == fi)
+ break;
+ }
+
+ fverts[j] = POINTER_FROM_UINT(mpoly[nv->poly_index].loopstart + nv->loop_of_poly_index);
+ }
}
static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, MLoopUV *mloopuv)
{
- MPoly *mpoly = dm->getPolyArray(dm);
- MLoop *mloop = dm->getLoopArray(dm);
- int totvert = dm->getNumVerts(dm);
- int totface = dm->getNumPolys(dm);
- int i, seam;
- UvMapVert *v;
- UvVertMap *vmap;
- float limit[2];
+ MPoly *mpoly = dm->getPolyArray(dm);
+ MLoop *mloop = dm->getLoopArray(dm);
+ int totvert = dm->getNumVerts(dm);
+ int totface = dm->getNumPolys(dm);
+ int i, seam;
+ UvMapVert *v;
+ UvVertMap *vmap;
+ float limit[2];
#ifndef USE_DYNSIZE
- CCGVertHDL *fverts = NULL;
- BLI_array_declare(fverts);
+ CCGVertHDL *fverts = NULL;
+ BLI_array_declare(fverts);
#endif
- EdgeSet *eset;
- float uv[3] = {0.0f, 0.0f, 0.0f}; /* only first 2 values are written into */
-
- limit[0] = limit[1] = STD_UV_CONNECT_LIMIT;
- /* previous behavior here is without accounting for winding, however this causes stretching in
- * UV map in really simple cases with mirror + subsurf, see second part of T44530. Also, initially
- * intention is to treat merged vertices from mirror modifier as seams.
- * This fixes a very old regression (2.49 was correct here) */
- vmap = BKE_mesh_uv_vert_map_create(mpoly, mloop, mloopuv, totface, totvert, limit, false, true);
- if (!vmap)
- return 0;
-
- ccgSubSurf_initFullSync(ss);
-
- /* create vertices */
- for (i = 0; i < totvert; i++) {
- if (!BKE_mesh_uv_vert_map_get_vert(vmap, i))
- continue;
-
- for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i)->next; v; v = v->next)
- if (v->separate)
- break;
-
- seam = (v != NULL);
-
- for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i); v; v = v->next) {
- if (v->separate) {
- CCGVert *ssv;
- int loopid = mpoly[v->poly_index].loopstart + v->loop_of_poly_index;
- CCGVertHDL vhdl = POINTER_FROM_INT(loopid);
-
- copy_v2_v2(uv, mloopuv[loopid].uv);
-
- ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv);
- }
- }
- }
-
- /* create edges */
- eset = BLI_edgeset_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totface));
-
- for (i = 0; i < totface; i++) {
- MPoly *mp = &mpoly[i];
- int nverts = mp->totloop;
- int j, j_next;
- CCGFace *origf = ccgSubSurf_getFace(origss, POINTER_FROM_INT(i));
- /* unsigned int *fv = &mp->v1; */
- MLoop *ml = mloop + mp->loopstart;
+ EdgeSet *eset;
+ float uv[3] = {0.0f, 0.0f, 0.0f}; /* only first 2 values are written into */
+
+ limit[0] = limit[1] = STD_UV_CONNECT_LIMIT;
+ /* previous behavior here is without accounting for winding, however this causes stretching in
+ * UV map in really simple cases with mirror + subsurf, see second part of T44530. Also, initially
+ * intention is to treat merged vertices from mirror modifier as seams.
+ * This fixes a very old regression (2.49 was correct here) */
+ vmap = BKE_mesh_uv_vert_map_create(mpoly, mloop, mloopuv, totface, totvert, limit, false, true);
+ if (!vmap)
+ return 0;
+
+ ccgSubSurf_initFullSync(ss);
+
+ /* create vertices */
+ for (i = 0; i < totvert; i++) {
+ if (!BKE_mesh_uv_vert_map_get_vert(vmap, i))
+ continue;
+
+ for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i)->next; v; v = v->next)
+ if (v->separate)
+ break;
+
+ seam = (v != NULL);
+
+ for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i); v; v = v->next) {
+ if (v->separate) {
+ CCGVert *ssv;
+ int loopid = mpoly[v->poly_index].loopstart + v->loop_of_poly_index;
+ CCGVertHDL vhdl = POINTER_FROM_INT(loopid);
+
+ copy_v2_v2(uv, mloopuv[loopid].uv);
+
+ ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv);
+ }
+ }
+ }
+
+ /* create edges */
+ eset = BLI_edgeset_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totface));
+
+ for (i = 0; i < totface; i++) {
+ MPoly *mp = &mpoly[i];
+ int nverts = mp->totloop;
+ int j, j_next;
+ CCGFace *origf = ccgSubSurf_getFace(origss, POINTER_FROM_INT(i));
+ /* unsigned int *fv = &mp->v1; */
+ MLoop *ml = mloop + mp->loopstart;
#ifdef USE_DYNSIZE
- CCGVertHDL fverts[nverts];
+ CCGVertHDL fverts[nverts];
#else
- BLI_array_clear(fverts);
- BLI_array_grow_items(fverts, nverts);
+ BLI_array_clear(fverts);
+ BLI_array_grow_items(fverts, nverts);
#endif
- get_face_uv_map_vert(vmap, mpoly, ml, i, fverts);
+ get_face_uv_map_vert(vmap, mpoly, ml, i, fverts);
- for (j = 0, j_next = nverts - 1; j < nverts; j_next = j++) {
- unsigned int v0 = POINTER_AS_UINT(fverts[j_next]);
- unsigned int v1 = POINTER_AS_UINT(fverts[j]);
+ for (j = 0, j_next = nverts - 1; j < nverts; j_next = j++) {
+ unsigned int v0 = POINTER_AS_UINT(fverts[j_next]);
+ unsigned int v1 = POINTER_AS_UINT(fverts[j]);
- if (BLI_edgeset_add(eset, v0, v1)) {
- CCGEdge *e, *orige = ccgSubSurf_getFaceEdge(origf, j_next);
- CCGEdgeHDL ehdl = POINTER_FROM_INT(mp->loopstart + j_next);
- float crease = ccgSubSurf_getEdgeCrease(orige);
+ if (BLI_edgeset_add(eset, v0, v1)) {
+ CCGEdge *e, *orige = ccgSubSurf_getFaceEdge(origf, j_next);
+ CCGEdgeHDL ehdl = POINTER_FROM_INT(mp->loopstart + j_next);
+ float crease = ccgSubSurf_getEdgeCrease(orige);
- ccgSubSurf_syncEdge(ss, ehdl, fverts[j_next], fverts[j], crease, &e);
- }
- }
- }
+ ccgSubSurf_syncEdge(ss, ehdl, fverts[j_next], fverts[j], crease, &e);
+ }
+ }
+ }
- BLI_edgeset_free(eset);
+ BLI_edgeset_free(eset);
- /* create faces */
- for (i = 0; i < totface; i++) {
- MPoly *mp = &mpoly[i];
- MLoop *ml = &mloop[mp->loopstart];
- int nverts = mp->totloop;
- CCGFace *f;
+ /* create faces */
+ for (i = 0; i < totface; i++) {
+ MPoly *mp = &mpoly[i];
+ MLoop *ml = &mloop[mp->loopstart];
+ int nverts = mp->totloop;
+ CCGFace *f;
#ifdef USE_DYNSIZE
- CCGVertHDL fverts[nverts];
+ CCGVertHDL fverts[nverts];
#else
- BLI_array_clear(fverts);
- BLI_array_grow_items(fverts, nverts);
+ BLI_array_clear(fverts);
+ BLI_array_grow_items(fverts, nverts);
#endif
- get_face_uv_map_vert(vmap, mpoly, ml, i, fverts);
- ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), nverts, fverts, &f);
- }
+ get_face_uv_map_vert(vmap, mpoly, ml, i, fverts);
+ ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), nverts, fverts, &f);
+ }
#ifndef USE_DYNSIZE
- BLI_array_free(fverts);
+ BLI_array_free(fverts);
#endif
- BKE_mesh_uv_vert_map_free(vmap);
- ccgSubSurf_processSync(ss);
+ BKE_mesh_uv_vert_map_free(vmap);
+ ccgSubSurf_processSync(ss);
- return 1;
+ return 1;
}
#ifdef WITH_OPENSUBDIV
@@ -401,179 +402,169 @@ static void UNUSED_FUNCTION(set_subsurf_osd_ccg_uv)(CCGSubSurf *ss,
DerivedMesh *result,
int layer_index)
{
- CCGFace **faceMap;
- MTFace *tf;
- MLoopUV *mluv;
- CCGFaceIterator fi;
- int index, gridSize, gridFaces, totface, x, y, S;
- MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, layer_index);
- /* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with
- * just tface except applying the modifier then looses subsurf UV */
- MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, layer_index);
- MLoopUV *mloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, layer_index);
-
- if (dmloopuv == NULL || (tface == NULL && mloopuv == NULL)) {
- return;
- }
-
- ccgSubSurf_evaluatorSetFVarUV(ss, dm, layer_index);
-
- /* get some info from CCGSubSurf */
- totface = ccgSubSurf_getNumFaces(ss);
- gridSize = ccgSubSurf_getGridSize(ss);
- gridFaces = gridSize - 1;
-
- /* make a map from original faces to CCGFaces */
- faceMap = MEM_mallocN(totface * sizeof(*faceMap), "facemapuv");
- for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(&fi);
- faceMap[POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f))] = f;
- }
-
- /* load coordinates from uvss into tface */
- tf = tface;
- mluv = mloopuv;
- for (index = 0; index < totface; index++) {
- CCGFace *f = faceMap[index];
- int numVerts = ccgSubSurf_getFaceNumVerts(f);
- for (S = 0; S < numVerts; S++) {
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
- const int delta[4][2] = {{0, 0},
- {0, 1},
- {1, 1},
- {1, 0}};
- float uv[4][2];
- int i;
- for (i = 0; i < 4; i++) {
- const int dx = delta[i][0],
- dy = delta[i][1];
- const float grid_u = ((float)(x + dx)) / (gridSize - 1),
- grid_v = ((float)(y + dy)) / (gridSize - 1);
- ccgSubSurf_evaluatorFVarUV(ss,
- index,
- S,
- grid_u, grid_v,
- uv[i]);
- }
- if (tf) {
- copy_v2_v2(tf->uv[0], uv[0]);
- copy_v2_v2(tf->uv[1], uv[1]);
- copy_v2_v2(tf->uv[2], uv[2]);
- copy_v2_v2(tf->uv[3], uv[3]);
- tf++;
- }
- if (mluv) {
- copy_v2_v2(mluv[0].uv, uv[0]);
- copy_v2_v2(mluv[1].uv, uv[1]);
- copy_v2_v2(mluv[2].uv, uv[2]);
- copy_v2_v2(mluv[3].uv, uv[3]);
- mluv += 4;
- }
- }
- }
- }
- }
- MEM_freeN(faceMap);
-}
-#endif /* WITH_OPENSUBDIV */
+ CCGFace **faceMap;
+ MTFace *tf;
+ MLoopUV *mluv;
+ CCGFaceIterator fi;
+ int index, gridSize, gridFaces, totface, x, y, S;
+ MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, layer_index);
+ /* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with
+ * just tface except applying the modifier then looses subsurf UV */
+ MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, layer_index);
+ MLoopUV *mloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, layer_index);
+
+ if (dmloopuv == NULL || (tface == NULL && mloopuv == NULL)) {
+ return;
+ }
+
+ ccgSubSurf_evaluatorSetFVarUV(ss, dm, layer_index);
+
+ /* get some info from CCGSubSurf */
+ totface = ccgSubSurf_getNumFaces(ss);
+ gridSize = ccgSubSurf_getGridSize(ss);
+ gridFaces = gridSize - 1;
+
+ /* make a map from original faces to CCGFaces */
+ faceMap = MEM_mallocN(totface * sizeof(*faceMap), "facemapuv");
+ for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi);
+ ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
+ faceMap[POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f))] = f;
+ }
+
+ /* load coordinates from uvss into tface */
+ tf = tface;
+ mluv = mloopuv;
+ for (index = 0; index < totface; index++) {
+ CCGFace *f = faceMap[index];
+ int numVerts = ccgSubSurf_getFaceNumVerts(f);
+ for (S = 0; S < numVerts; S++) {
+ for (y = 0; y < gridFaces; y++) {
+ for (x = 0; x < gridFaces; x++) {
+ const int delta[4][2] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
+ float uv[4][2];
+ int i;
+ for (i = 0; i < 4; i++) {
+ const int dx = delta[i][0], dy = delta[i][1];
+ const float grid_u = ((float)(x + dx)) / (gridSize - 1),
+ grid_v = ((float)(y + dy)) / (gridSize - 1);
+ ccgSubSurf_evaluatorFVarUV(ss, index, S, grid_u, grid_v, uv[i]);
+ }
+ if (tf) {
+ copy_v2_v2(tf->uv[0], uv[0]);
+ copy_v2_v2(tf->uv[1], uv[1]);
+ copy_v2_v2(tf->uv[2], uv[2]);
+ copy_v2_v2(tf->uv[3], uv[3]);
+ tf++;
+ }
+ if (mluv) {
+ copy_v2_v2(mluv[0].uv, uv[0]);
+ copy_v2_v2(mluv[1].uv, uv[1]);
+ copy_v2_v2(mluv[2].uv, uv[2]);
+ copy_v2_v2(mluv[3].uv, uv[3]);
+ mluv += 4;
+ }
+ }
+ }
+ }
+ }
+ MEM_freeN(faceMap);
+}
+#endif /* WITH_OPENSUBDIV */
static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n)
{
- CCGSubSurf *uvss;
- CCGFace **faceMap;
- MTFace *tf;
- MLoopUV *mluv;
- CCGFaceIterator fi;
- int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S;
- MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, n);
- /* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with
- * just tface except applying the modifier then looses subsurf UV */
- MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n);
- MLoopUV *mloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, n);
-
- if (!dmloopuv || (!tface && !mloopuv))
- return;
-
- /* create a CCGSubSurf from uv's */
- uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 2, CCG_USE_ARENA);
-
- if (!ss_sync_from_uv(uvss, ss, dm, dmloopuv)) {
- ccgSubSurf_free(uvss);
- return;
- }
-
- /* get some info from CCGSubSurf */
- totface = ccgSubSurf_getNumFaces(uvss);
- /* edgeSize = ccgSubSurf_getEdgeSize(uvss); */ /*UNUSED*/
- gridSize = ccgSubSurf_getGridSize(uvss);
- gridFaces = gridSize - 1;
-
- /* make a map from original faces to CCGFaces */
- faceMap = MEM_mallocN(totface * sizeof(*faceMap), "facemapuv");
- for (ccgSubSurf_initFaceIterator(uvss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(&fi);
- faceMap[POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f))] = f;
- }
-
- /* load coordinates from uvss into tface */
- tf = tface;
- mluv = mloopuv;
-
- for (index = 0; index < totface; index++) {
- CCGFace *f = faceMap[index];
- int numVerts = ccgSubSurf_getFaceNumVerts(f);
-
- for (S = 0; S < numVerts; S++) {
- float (*faceGridData)[2] = ccgSubSurf_getFaceGridDataArray(uvss, f, S);
-
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
- float *a = faceGridData[(y + 0) * gridSize + x + 0];
- float *b = faceGridData[(y + 0) * gridSize + x + 1];
- float *c = faceGridData[(y + 1) * gridSize + x + 1];
- float *d = faceGridData[(y + 1) * gridSize + x + 0];
-
- if (tf) {
- copy_v2_v2(tf->uv[0], a);
- copy_v2_v2(tf->uv[1], d);
- copy_v2_v2(tf->uv[2], c);
- copy_v2_v2(tf->uv[3], b);
- tf++;
- }
-
- if (mluv) {
- copy_v2_v2(mluv[0].uv, a);
- copy_v2_v2(mluv[1].uv, d);
- copy_v2_v2(mluv[2].uv, c);
- copy_v2_v2(mluv[3].uv, b);
- mluv += 4;
- }
-
- }
- }
- }
- }
-
- ccgSubSurf_free(uvss);
- MEM_freeN(faceMap);
-}
-
-static void set_subsurf_uv(CCGSubSurf *ss,
- DerivedMesh *dm,
- DerivedMesh *result,
- int layer_index)
+ CCGSubSurf *uvss;
+ CCGFace **faceMap;
+ MTFace *tf;
+ MLoopUV *mluv;
+ CCGFaceIterator fi;
+ int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S;
+ MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, n);
+ /* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with
+ * just tface except applying the modifier then looses subsurf UV */
+ MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n);
+ MLoopUV *mloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, n);
+
+ if (!dmloopuv || (!tface && !mloopuv))
+ return;
+
+ /* create a CCGSubSurf from uv's */
+ uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 2, CCG_USE_ARENA);
+
+ if (!ss_sync_from_uv(uvss, ss, dm, dmloopuv)) {
+ ccgSubSurf_free(uvss);
+ return;
+ }
+
+ /* get some info from CCGSubSurf */
+ totface = ccgSubSurf_getNumFaces(uvss);
+ /* edgeSize = ccgSubSurf_getEdgeSize(uvss); */ /*UNUSED*/
+ gridSize = ccgSubSurf_getGridSize(uvss);
+ gridFaces = gridSize - 1;
+
+ /* make a map from original faces to CCGFaces */
+ faceMap = MEM_mallocN(totface * sizeof(*faceMap), "facemapuv");
+ for (ccgSubSurf_initFaceIterator(uvss, &fi); !ccgFaceIterator_isStopped(&fi);
+ ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
+ faceMap[POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f))] = f;
+ }
+
+ /* load coordinates from uvss into tface */
+ tf = tface;
+ mluv = mloopuv;
+
+ for (index = 0; index < totface; index++) {
+ CCGFace *f = faceMap[index];
+ int numVerts = ccgSubSurf_getFaceNumVerts(f);
+
+ for (S = 0; S < numVerts; S++) {
+ float(*faceGridData)[2] = ccgSubSurf_getFaceGridDataArray(uvss, f, S);
+
+ for (y = 0; y < gridFaces; y++) {
+ for (x = 0; x < gridFaces; x++) {
+ float *a = faceGridData[(y + 0) * gridSize + x + 0];
+ float *b = faceGridData[(y + 0) * gridSize + x + 1];
+ float *c = faceGridData[(y + 1) * gridSize + x + 1];
+ float *d = faceGridData[(y + 1) * gridSize + x + 0];
+
+ if (tf) {
+ copy_v2_v2(tf->uv[0], a);
+ copy_v2_v2(tf->uv[1], d);
+ copy_v2_v2(tf->uv[2], c);
+ copy_v2_v2(tf->uv[3], b);
+ tf++;
+ }
+
+ if (mluv) {
+ copy_v2_v2(mluv[0].uv, a);
+ copy_v2_v2(mluv[1].uv, d);
+ copy_v2_v2(mluv[2].uv, c);
+ copy_v2_v2(mluv[3].uv, b);
+ mluv += 4;
+ }
+ }
+ }
+ }
+ }
+
+ ccgSubSurf_free(uvss);
+ MEM_freeN(faceMap);
+}
+
+static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int layer_index)
{
#ifdef WITH_OPENSUBDIV
- if (!ccgSubSurf_needGrids(ss)) {
- /* GPU backend is used, no need to evaluate UVs on CPU. */
- /* TODO(sergey): Think of how to support edit mode of UVs. */
- }
- else
+ if (!ccgSubSurf_needGrids(ss)) {
+ /* GPU backend is used, no need to evaluate UVs on CPU. */
+ /* TODO(sergey): Think of how to support edit mode of UVs. */
+ }
+ else
#endif
- {
- set_subsurf_legacy_uv(ss, dm, result, layer_index);
- }
+ {
+ set_subsurf_legacy_uv(ss, dm, result, layer_index);
+ }
}
/* face weighting */
@@ -581,82 +572,83 @@ static void set_subsurf_uv(CCGSubSurf *ss,
typedef float FaceVertWeight[SUB_ELEMS_FACE][SUB_ELEMS_FACE];
typedef struct FaceVertWeightEntry {
- FaceVertWeight *weight;
- float *w;
- int valid;
+ FaceVertWeight *weight;
+ float *w;
+ int valid;
} FaceVertWeightEntry;
typedef struct WeightTable {
- FaceVertWeightEntry *weight_table;
- int len;
+ FaceVertWeightEntry *weight_table;
+ int len;
} WeightTable;
static float *get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen)
{
- int x, y, i, j;
- float *w, w1, w2, w4, fac, fac2, fx, fy;
+ int x, y, i, j;
+ float *w, w1, w2, w4, fac, fac2, fx, fy;
- if (wtable->len <= faceLen) {
- void *tmp = MEM_callocN(sizeof(FaceVertWeightEntry) * (faceLen + 1), "weight table alloc 2");
+ if (wtable->len <= faceLen) {
+ void *tmp = MEM_callocN(sizeof(FaceVertWeightEntry) * (faceLen + 1), "weight table alloc 2");
- if (wtable->len) {
- memcpy(tmp, wtable->weight_table, sizeof(FaceVertWeightEntry) * wtable->len);
- MEM_freeN(wtable->weight_table);
- }
+ if (wtable->len) {
+ memcpy(tmp, wtable->weight_table, sizeof(FaceVertWeightEntry) * wtable->len);
+ MEM_freeN(wtable->weight_table);
+ }
- wtable->weight_table = tmp;
- wtable->len = faceLen + 1;
- }
+ wtable->weight_table = tmp;
+ wtable->len = faceLen + 1;
+ }
- if (!wtable->weight_table[faceLen].valid) {
- wtable->weight_table[faceLen].valid = 1;
- wtable->weight_table[faceLen].w = w = MEM_callocN(sizeof(float) * faceLen * faceLen * (gridCuts + 2) * (gridCuts + 2), "weight table alloc");
- fac = 1.0f / (float)faceLen;
+ if (!wtable->weight_table[faceLen].valid) {
+ wtable->weight_table[faceLen].valid = 1;
+ wtable->weight_table[faceLen].w = w = MEM_callocN(
+ sizeof(float) * faceLen * faceLen * (gridCuts + 2) * (gridCuts + 2), "weight table alloc");
+ fac = 1.0f / (float)faceLen;
- for (i = 0; i < faceLen; i++) {
- for (x = 0; x < gridCuts + 2; x++) {
- for (y = 0; y < gridCuts + 2; y++) {
- fx = 0.5f - (float)x / (float)(gridCuts + 1) / 2.0f;
- fy = 0.5f - (float)y / (float)(gridCuts + 1) / 2.0f;
+ for (i = 0; i < faceLen; i++) {
+ for (x = 0; x < gridCuts + 2; x++) {
+ for (y = 0; y < gridCuts + 2; y++) {
+ fx = 0.5f - (float)x / (float)(gridCuts + 1) / 2.0f;
+ fy = 0.5f - (float)y / (float)(gridCuts + 1) / 2.0f;
- fac2 = faceLen - 4;
- w1 = (1.0f - fx) * (1.0f - fy) + (-fac2 * fx * fy * fac);
- w2 = (1.0f - fx + fac2 * fx * -fac) * (fy);
- w4 = (fx) * (1.0f - fy + -fac2 * fy * fac);
+ fac2 = faceLen - 4;
+ w1 = (1.0f - fx) * (1.0f - fy) + (-fac2 * fx * fy * fac);
+ w2 = (1.0f - fx + fac2 * fx * -fac) * (fy);
+ w4 = (fx) * (1.0f - fy + -fac2 * fy * fac);
- /* these values aren't used for tri's and cause divide by zero */
- if (faceLen > 3) {
- fac2 = 1.0f - (w1 + w2 + w4);
- fac2 = fac2 / (float)(faceLen - 3);
- for (j = 0; j < faceLen; j++) {
- w[j] = fac2;
- }
- }
+ /* these values aren't used for tri's and cause divide by zero */
+ if (faceLen > 3) {
+ fac2 = 1.0f - (w1 + w2 + w4);
+ fac2 = fac2 / (float)(faceLen - 3);
+ for (j = 0; j < faceLen; j++) {
+ w[j] = fac2;
+ }
+ }
- w[i] = w1;
- w[(i - 1 + faceLen) % faceLen] = w2;
- w[(i + 1) % faceLen] = w4;
+ w[i] = w1;
+ w[(i - 1 + faceLen) % faceLen] = w2;
+ w[(i + 1) % faceLen] = w4;
- w += faceLen;
- }
- }
- }
- }
+ w += faceLen;
+ }
+ }
+ }
+ }
- return wtable->weight_table[faceLen].w;
+ return wtable->weight_table[faceLen].w;
}
static void free_ss_weights(WeightTable *wtable)
{
- int i;
+ int i;
- for (i = 0; i < wtable->len; i++) {
- if (wtable->weight_table[i].valid)
- MEM_freeN(wtable->weight_table[i].w);
- }
+ for (i = 0; i < wtable->len; i++) {
+ if (wtable->weight_table[i].valid)
+ MEM_freeN(wtable->weight_table[i].w);
+ }
- if (wtable->weight_table)
- MEM_freeN(wtable->weight_table);
+ if (wtable->weight_table)
+ MEM_freeN(wtable->weight_table);
}
static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss,
@@ -664,113 +656,110 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss,
float (*vertexCos)[3],
int useFlatSubdiv)
{
- float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
+ float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss);
#ifndef USE_DYNSIZE
- CCGVertHDL *fVerts = NULL;
- BLI_array_declare(fVerts);
+ CCGVertHDL *fVerts = NULL;
+ BLI_array_declare(fVerts);
#endif
- MVert *mvert = dm->getVertArray(dm);
- MEdge *medge = dm->getEdgeArray(dm);
- /* MFace *mface = dm->getTessFaceArray(dm); */ /* UNUSED */
- MVert *mv;
- MEdge *me;
- MLoop *mloop = dm->getLoopArray(dm), *ml;
- MPoly *mpoly = dm->getPolyArray(dm), *mp;
- /*MFace *mf;*/ /*UNUSED*/
- int totvert = dm->getNumVerts(dm);
- int totedge = dm->getNumEdges(dm);
- /*int totface = dm->getNumTessFaces(dm);*/ /*UNUSED*/
- /*int totpoly = dm->getNumFaces(dm);*/ /*UNUSED*/
- int i, j;
- int *index;
-
- ccgSubSurf_initFullSync(ss);
-
- mv = mvert;
- index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
- for (i = 0; i < totvert; i++, mv++) {
- CCGVert *v;
-
- if (vertexCos) {
- ccgSubSurf_syncVert(ss, POINTER_FROM_INT(i), vertexCos[i], 0, &v);
- }
- else {
- ccgSubSurf_syncVert(ss, POINTER_FROM_INT(i), mv->co, 0, &v);
- }
-
- ((int *)ccgSubSurf_getVertUserData(ss, v))[1] = (index) ? *index++ : i;
- }
-
- me = medge;
- index = (int *)dm->getEdgeDataArray(dm, CD_ORIGINDEX);
- for (i = 0; i < totedge; i++, me++) {
- CCGEdge *e;
- float crease;
-
- crease = useFlatSubdiv ? creaseFactor :
- me->crease * creaseFactor / 255.0f;
-
- ccgSubSurf_syncEdge(ss, POINTER_FROM_INT(i), POINTER_FROM_UINT(me->v1),
- POINTER_FROM_UINT(me->v2), crease, &e);
-
- ((int *)ccgSubSurf_getEdgeUserData(ss, e))[1] = (index) ? *index++ : i;
- }
-
- mp = mpoly;
- index = (int *)dm->getPolyDataArray(dm, CD_ORIGINDEX);
- for (i = 0; i < dm->numPolyData; i++, mp++) {
- CCGFace *f;
+ MVert *mvert = dm->getVertArray(dm);
+ MEdge *medge = dm->getEdgeArray(dm);
+ /* MFace *mface = dm->getTessFaceArray(dm); */ /* UNUSED */
+ MVert *mv;
+ MEdge *me;
+ MLoop *mloop = dm->getLoopArray(dm), *ml;
+ MPoly *mpoly = dm->getPolyArray(dm), *mp;
+ /*MFace *mf;*/ /*UNUSED*/
+ int totvert = dm->getNumVerts(dm);
+ int totedge = dm->getNumEdges(dm);
+ /*int totface = dm->getNumTessFaces(dm);*/ /*UNUSED*/
+ /*int totpoly = dm->getNumFaces(dm);*/ /*UNUSED*/
+ int i, j;
+ int *index;
+
+ ccgSubSurf_initFullSync(ss);
+
+ mv = mvert;
+ index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
+ for (i = 0; i < totvert; i++, mv++) {
+ CCGVert *v;
+
+ if (vertexCos) {
+ ccgSubSurf_syncVert(ss, POINTER_FROM_INT(i), vertexCos[i], 0, &v);
+ }
+ else {
+ ccgSubSurf_syncVert(ss, POINTER_FROM_INT(i), mv->co, 0, &v);
+ }
+
+ ((int *)ccgSubSurf_getVertUserData(ss, v))[1] = (index) ? *index++ : i;
+ }
+
+ me = medge;
+ index = (int *)dm->getEdgeDataArray(dm, CD_ORIGINDEX);
+ for (i = 0; i < totedge; i++, me++) {
+ CCGEdge *e;
+ float crease;
+
+ crease = useFlatSubdiv ? creaseFactor : me->crease * creaseFactor / 255.0f;
+
+ ccgSubSurf_syncEdge(
+ ss, POINTER_FROM_INT(i), POINTER_FROM_UINT(me->v1), POINTER_FROM_UINT(me->v2), crease, &e);
+
+ ((int *)ccgSubSurf_getEdgeUserData(ss, e))[1] = (index) ? *index++ : i;
+ }
+
+ mp = mpoly;
+ index = (int *)dm->getPolyDataArray(dm, CD_ORIGINDEX);
+ for (i = 0; i < dm->numPolyData; i++, mp++) {
+ CCGFace *f;
#ifdef USE_DYNSIZE
- CCGVertHDL fVerts[mp->totloop];
+ CCGVertHDL fVerts[mp->totloop];
#else
- BLI_array_clear(fVerts);
- BLI_array_grow_items(fVerts, mp->totloop);
+ BLI_array_clear(fVerts);
+ BLI_array_grow_items(fVerts, mp->totloop);
#endif
- ml = mloop + mp->loopstart;
- for (j = 0; j < mp->totloop; j++, ml++) {
- fVerts[j] = POINTER_FROM_UINT(ml->v);
- }
+ ml = mloop + mp->loopstart;
+ for (j = 0; j < mp->totloop; j++, ml++) {
+ fVerts[j] = POINTER_FROM_UINT(ml->v);
+ }
- /* this is very bad, means mesh is internally inconsistent.
- * it is not really possible to continue without modifying
- * other parts of code significantly to handle missing faces.
- * since this really shouldn't even be possible we just bail.*/
- if (ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), mp->totloop,
- fVerts, &f) == eCCGError_InvalidValue)
- {
- static int hasGivenError = 0;
+ /* this is very bad, means mesh is internally inconsistent.
+ * it is not really possible to continue without modifying
+ * other parts of code significantly to handle missing faces.
+ * since this really shouldn't even be possible we just bail.*/
+ if (ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), mp->totloop, fVerts, &f) ==
+ eCCGError_InvalidValue) {
+ static int hasGivenError = 0;
- if (!hasGivenError) {
- //XXX error("Unrecoverable error in SubSurf calculation,"
- // " mesh is inconsistent.");
+ if (!hasGivenError) {
+ //XXX error("Unrecoverable error in SubSurf calculation,"
+ // " mesh is inconsistent.");
- hasGivenError = 1;
- }
+ hasGivenError = 1;
+ }
- return;
- }
+ return;
+ }
- ((int *)ccgSubSurf_getFaceUserData(ss, f))[1] = (index) ? *index++ : i;
- }
+ ((int *)ccgSubSurf_getFaceUserData(ss, f))[1] = (index) ? *index++ : i;
+ }
- ccgSubSurf_processSync(ss);
+ ccgSubSurf_processSync(ss);
#ifndef USE_DYNSIZE
- BLI_array_free(fVerts);
+ BLI_array_free(fVerts);
#endif
}
#ifdef WITH_OPENSUBDIV
-static void ss_sync_osd_from_derivedmesh(CCGSubSurf *ss,
- DerivedMesh *dm)
+static void ss_sync_osd_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm)
{
- ccgSubSurf_initFullSync(ss);
- ccgSubSurf_prepareTopologyRefiner(ss, dm);
- ccgSubSurf_processSync(ss);
+ ccgSubSurf_initFullSync(ss);
+ ccgSubSurf_prepareTopologyRefiner(ss, dm);
+ ccgSubSurf_processSync(ss);
}
-#endif /* WITH_OPENSUBDIV */
+#endif /* WITH_OPENSUBDIV */
static void ss_sync_from_derivedmesh(CCGSubSurf *ss,
DerivedMesh *dm,
@@ -779,1680 +768,1711 @@ static void ss_sync_from_derivedmesh(CCGSubSurf *ss,
bool use_subdiv_uvs)
{
#ifndef WITH_OPENSUBDIV
- UNUSED_VARS(use_subdiv_uvs);
+ UNUSED_VARS(use_subdiv_uvs);
#endif
#ifdef WITH_OPENSUBDIV
- /* Reset all related descriptors if actual mesh topology changed or if
- * other evaluation-related settings changed.
- */
- if (!ccgSubSurf_needGrids(ss)) {
- /* TODO(sergey): Use vertex coordinates and flat subdiv flag. */
- ccgSubSurf__sync_subdivUvs(ss, use_subdiv_uvs);
- ccgSubSurf_checkTopologyChanged(ss, dm);
- ss_sync_osd_from_derivedmesh(ss, dm);
- }
- else
+ /* Reset all related descriptors if actual mesh topology changed or if
+ * other evaluation-related settings changed.
+ */
+ if (!ccgSubSurf_needGrids(ss)) {
+ /* TODO(sergey): Use vertex coordinates and flat subdiv flag. */
+ ccgSubSurf__sync_subdivUvs(ss, use_subdiv_uvs);
+ ccgSubSurf_checkTopologyChanged(ss, dm);
+ ss_sync_osd_from_derivedmesh(ss, dm);
+ }
+ else
#endif
- {
- ss_sync_ccg_from_derivedmesh(ss, dm, vertexCos, use_flat_subdiv);
- }
+ {
+ ss_sync_ccg_from_derivedmesh(ss, dm, vertexCos, use_flat_subdiv);
+ }
}
/***/
static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v)
{
- return ((int *) ccgSubSurf_getVertUserData(ss, v))[1];
+ return ((int *)ccgSubSurf_getVertUserData(ss, v))[1];
}
static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e)
{
- return ((int *) ccgSubSurf_getEdgeUserData(ss, e))[1];
+ return ((int *)ccgSubSurf_getEdgeUserData(ss, e))[1];
}
static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f)
{
- return ((int *) ccgSubSurf_getFaceUserData(ss, f))[1];
+ return ((int *)ccgSubSurf_getFaceUserData(ss, f))[1];
}
static void minmax_v3_v3v3(const float vec[3], float min[3], float max[3])
{
- if (min[0] > vec[0]) min[0] = vec[0];
- if (min[1] > vec[1]) min[1] = vec[1];
- if (min[2] > vec[2]) min[2] = vec[2];
- if (max[0] < vec[0]) max[0] = vec[0];
- if (max[1] < vec[1]) max[1] = vec[1];
- if (max[2] < vec[2]) max[2] = vec[2];
+ if (min[0] > vec[0])
+ min[0] = vec[0];
+ if (min[1] > vec[1])
+ min[1] = vec[1];
+ if (min[2] > vec[2])
+ min[2] = vec[2];
+ if (max[0] < vec[0])
+ max[0] = vec[0];
+ if (max[1] < vec[1])
+ max[1] = vec[1];
+ if (max[2] < vec[2])
+ max[2] = vec[2];
}
static void ccgDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3])
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGVertIterator vi;
- CCGEdgeIterator ei;
- CCGFaceIterator fi;
- CCGKey key;
- int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
- int gridSize = ccgSubSurf_getGridSize(ss);
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ CCGVertIterator vi;
+ CCGEdgeIterator ei;
+ CCGFaceIterator fi;
+ CCGKey key;
+ int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
+ int gridSize = ccgSubSurf_getGridSize(ss);
#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- ccgSubSurf_getMinMax(ccgdm->ss, r_min, r_max);
- return;
- }
+ if (ccgdm->useGpuBackend) {
+ ccgSubSurf_getMinMax(ccgdm->ss, r_min, r_max);
+ return;
+ }
#endif
- CCG_key_top_level(&key, ss);
+ CCG_key_top_level(&key, ss);
- if (!ccgSubSurf_getNumVerts(ss))
- r_min[0] = r_min[1] = r_min[2] = r_max[0] = r_max[1] = r_max[2] = 0.0;
+ if (!ccgSubSurf_getNumVerts(ss))
+ r_min[0] = r_min[1] = r_min[2] = r_max[0] = r_max[1] = r_max[2] = 0.0;
- for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
- CCGVert *v = ccgVertIterator_getCurrent(&vi);
- float *co = ccgSubSurf_getVertData(ss, v);
+ for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi);
+ ccgVertIterator_next(&vi)) {
+ CCGVert *v = ccgVertIterator_getCurrent(&vi);
+ float *co = ccgSubSurf_getVertData(ss, v);
- minmax_v3_v3v3(co, r_min, r_max);
- }
+ minmax_v3_v3v3(co, r_min, r_max);
+ }
- for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
- CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
+ for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei);
+ ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
+ CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
- for (i = 0; i < edgeSize; i++)
- minmax_v3_v3v3(CCG_elem_offset_co(&key, edgeData, i), r_min, r_max);
- }
+ for (i = 0; i < edgeSize; i++)
+ minmax_v3_v3v3(CCG_elem_offset_co(&key, edgeData, i), r_min, r_max);
+ }
- for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(&fi);
- int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
+ for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi);
+ ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
+ int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
- for (S = 0; S < numVerts; S++) {
- CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
+ for (S = 0; S < numVerts; S++) {
+ CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
- for (y = 0; y < gridSize; y++)
- for (x = 0; x < gridSize; x++)
- minmax_v3_v3v3(CCG_grid_elem_co(&key, faceGridData, x, y), r_min, r_max);
- }
- }
+ for (y = 0; y < gridSize; y++)
+ for (x = 0; x < gridSize; x++)
+ minmax_v3_v3v3(CCG_grid_elem_co(&key, faceGridData, x, y), r_min, r_max);
+ }
+ }
}
static int ccgDM_getNumVerts(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
+ return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
}
static int ccgDM_getNumEdges(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- return ccgSubSurf_getNumFinalEdges(ccgdm->ss);
+ return ccgSubSurf_getNumFinalEdges(ccgdm->ss);
}
static int ccgDM_getNumPolys(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
+ return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
}
static int ccgDM_getNumTessFaces(DerivedMesh *dm)
{
- return dm->numTessFaceData;
+ return dm->numTessFaceData;
}
static int ccgDM_getNumLoops(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- /* All subsurf faces are quads */
- return 4 * ccgSubSurf_getNumFinalFaces(ccgdm->ss);
+ /* All subsurf faces are quads */
+ return 4 * ccgSubSurf_getNumFinalFaces(ccgdm->ss);
}
static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGElem *vd;
- CCGKey key;
- int i;
-
- CCG_key_top_level(&key, ss);
- memset(mv, 0, sizeof(*mv));
-
- if ((vertNum < ccgdm->edgeMap[0].startVert) && (ccgSubSurf_getNumFaces(ss) > 0)) {
- /* this vert comes from face data */
- int lastface = ccgSubSurf_getNumFaces(ss) - 1;
- CCGFace *f;
- int x, y, grid, numVerts;
- int offset;
- int gridSize = ccgSubSurf_getGridSize(ss);
- int gridSideVerts;
- int gridInternalVerts;
- int gridSideEnd;
- int gridInternalEnd;
-
- i = 0;
- while (i < lastface && vertNum >= ccgdm->faceMap[i + 1].startVert) {
- i++;
- }
-
- f = ccgdm->faceMap[i].face;
- numVerts = ccgSubSurf_getFaceNumVerts(f);
-
- gridSideVerts = gridSize - 2;
- gridInternalVerts = gridSideVerts * gridSideVerts;
-
- gridSideEnd = 1 + numVerts * gridSideVerts;
- gridInternalEnd = gridSideEnd + numVerts * gridInternalVerts;
-
- offset = vertNum - ccgdm->faceMap[i].startVert;
- if (offset < 1) {
- vd = ccgSubSurf_getFaceCenterData(f);
- copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
- normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
- }
- else if (offset < gridSideEnd) {
- offset -= 1;
- grid = offset / gridSideVerts;
- x = offset % gridSideVerts + 1;
- vd = ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x);
- copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
- normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
- }
- else if (offset < gridInternalEnd) {
- offset -= gridSideEnd;
- grid = offset / gridInternalVerts;
- offset %= gridInternalVerts;
- y = offset / gridSideVerts + 1;
- x = offset % gridSideVerts + 1;
- vd = ccgSubSurf_getFaceGridData(ss, f, grid, x, y);
- copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
- normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
- }
- }
- else if ((vertNum < ccgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) {
- /* this vert comes from edge data */
- CCGEdge *e;
- int lastedge = ccgSubSurf_getNumEdges(ss) - 1;
- int x;
-
- i = 0;
- while (i < lastedge && vertNum >= ccgdm->edgeMap[i + 1].startVert) {
- i++;
- }
-
- e = ccgdm->edgeMap[i].edge;
-
- x = vertNum - ccgdm->edgeMap[i].startVert + 1;
- vd = ccgSubSurf_getEdgeData(ss, e, x);
- copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
- normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
- }
- else {
- /* this vert comes from vert data */
- CCGVert *v;
- i = vertNum - ccgdm->vertMap[0].startVert;
-
- v = ccgdm->vertMap[i].vert;
- vd = ccgSubSurf_getVertData(ss, v);
- copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
- normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
- }
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ CCGElem *vd;
+ CCGKey key;
+ int i;
+
+ CCG_key_top_level(&key, ss);
+ memset(mv, 0, sizeof(*mv));
+
+ if ((vertNum < ccgdm->edgeMap[0].startVert) && (ccgSubSurf_getNumFaces(ss) > 0)) {
+ /* this vert comes from face data */
+ int lastface = ccgSubSurf_getNumFaces(ss) - 1;
+ CCGFace *f;
+ int x, y, grid, numVerts;
+ int offset;
+ int gridSize = ccgSubSurf_getGridSize(ss);
+ int gridSideVerts;
+ int gridInternalVerts;
+ int gridSideEnd;
+ int gridInternalEnd;
+
+ i = 0;
+ while (i < lastface && vertNum >= ccgdm->faceMap[i + 1].startVert) {
+ i++;
+ }
+
+ f = ccgdm->faceMap[i].face;
+ numVerts = ccgSubSurf_getFaceNumVerts(f);
+
+ gridSideVerts = gridSize - 2;
+ gridInternalVerts = gridSideVerts * gridSideVerts;
+
+ gridSideEnd = 1 + numVerts * gridSideVerts;
+ gridInternalEnd = gridSideEnd + numVerts * gridInternalVerts;
+
+ offset = vertNum - ccgdm->faceMap[i].startVert;
+ if (offset < 1) {
+ vd = ccgSubSurf_getFaceCenterData(f);
+ copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
+ normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
+ }
+ else if (offset < gridSideEnd) {
+ offset -= 1;
+ grid = offset / gridSideVerts;
+ x = offset % gridSideVerts + 1;
+ vd = ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x);
+ copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
+ normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
+ }
+ else if (offset < gridInternalEnd) {
+ offset -= gridSideEnd;
+ grid = offset / gridInternalVerts;
+ offset %= gridInternalVerts;
+ y = offset / gridSideVerts + 1;
+ x = offset % gridSideVerts + 1;
+ vd = ccgSubSurf_getFaceGridData(ss, f, grid, x, y);
+ copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
+ normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
+ }
+ }
+ else if ((vertNum < ccgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) {
+ /* this vert comes from edge data */
+ CCGEdge *e;
+ int lastedge = ccgSubSurf_getNumEdges(ss) - 1;
+ int x;
+
+ i = 0;
+ while (i < lastedge && vertNum >= ccgdm->edgeMap[i + 1].startVert) {
+ i++;
+ }
+
+ e = ccgdm->edgeMap[i].edge;
+
+ x = vertNum - ccgdm->edgeMap[i].startVert + 1;
+ vd = ccgSubSurf_getEdgeData(ss, e, x);
+ copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
+ normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
+ }
+ else {
+ /* this vert comes from vert data */
+ CCGVert *v;
+ i = vertNum - ccgdm->vertMap[0].startVert;
+
+ v = ccgdm->vertMap[i].vert;
+ vd = ccgSubSurf_getVertData(ss, v);
+ copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
+ normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
+ }
}
static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float r_co[3])
{
- MVert mvert;
+ MVert mvert;
- ccgDM_getFinalVert(dm, vertNum, &mvert);
- copy_v3_v3(r_co, mvert.co);
+ ccgDM_getFinalVert(dm, vertNum, &mvert);
+ copy_v3_v3(r_co, mvert.co);
}
static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float r_no[3])
{
- MVert mvert;
+ MVert mvert;
- ccgDM_getFinalVert(dm, vertNum, &mvert);
- normal_short_to_float_v3(r_no, mvert.no);
+ ccgDM_getFinalVert(dm, vertNum, &mvert);
+ normal_short_to_float_v3(r_no, mvert.no);
}
static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- int i;
-
- memset(med, 0, sizeof(*med));
-
- if (edgeNum < ccgdm->edgeMap[0].startEdge) {
- /* this edge comes from face data */
- int lastface = ccgSubSurf_getNumFaces(ss) - 1;
- CCGFace *f;
- int x, y, grid /*, numVerts*/;
- int offset;
- int gridSize = ccgSubSurf_getGridSize(ss);
- int edgeSize = ccgSubSurf_getEdgeSize(ss);
- int gridSideEdges;
- int gridInternalEdges;
-
- i = 0;
- while (i < lastface && edgeNum >= ccgdm->faceMap[i + 1].startEdge) {
- i++;
- }
-
- f = ccgdm->faceMap[i].face;
- /* numVerts = ccgSubSurf_getFaceNumVerts(f); */ /*UNUSED*/
-
- gridSideEdges = gridSize - 1;
- gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
-
- offset = edgeNum - ccgdm->faceMap[i].startEdge;
- grid = offset / (gridSideEdges + gridInternalEdges);
- offset %= (gridSideEdges + gridInternalEdges);
-
- if (offset < gridSideEdges) {
- x = offset;
- med->v1 = getFaceIndex(ss, f, grid, x, 0, edgeSize, gridSize);
- med->v2 = getFaceIndex(ss, f, grid, x + 1, 0, edgeSize, gridSize);
- }
- else {
- offset -= gridSideEdges;
- x = (offset / 2) / gridSideEdges + 1;
- y = (offset / 2) % gridSideEdges;
- if (offset % 2 == 0) {
- med->v1 = getFaceIndex(ss, f, grid, x, y, edgeSize, gridSize);
- med->v2 = getFaceIndex(ss, f, grid, x, y + 1, edgeSize, gridSize);
- }
- else {
- med->v1 = getFaceIndex(ss, f, grid, y, x, edgeSize, gridSize);
- med->v2 = getFaceIndex(ss, f, grid, y + 1, x, edgeSize, gridSize);
- }
- }
- }
- else {
- /* this vert comes from edge data */
- CCGEdge *e;
- int edgeSize = ccgSubSurf_getEdgeSize(ss);
- int x;
- short *edgeFlag;
- unsigned int flags = 0;
-
- i = (edgeNum - ccgdm->edgeMap[0].startEdge) / (edgeSize - 1);
-
- e = ccgdm->edgeMap[i].edge;
-
- if (!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
-
- x = edgeNum - ccgdm->edgeMap[i].startEdge;
-
- med->v1 = getEdgeIndex(ss, e, x, edgeSize);
- med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
-
- edgeFlag = (ccgdm->edgeFlags) ? &ccgdm->edgeFlags[i] : NULL;
- if (edgeFlag)
- flags |= (*edgeFlag & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER;
- else
- flags |= ME_EDGEDRAW | ME_EDGERENDER;
-
- med->flag = flags;
- }
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ int i;
+
+ memset(med, 0, sizeof(*med));
+
+ if (edgeNum < ccgdm->edgeMap[0].startEdge) {
+ /* this edge comes from face data */
+ int lastface = ccgSubSurf_getNumFaces(ss) - 1;
+ CCGFace *f;
+ int x, y, grid /*, numVerts*/;
+ int offset;
+ int gridSize = ccgSubSurf_getGridSize(ss);
+ int edgeSize = ccgSubSurf_getEdgeSize(ss);
+ int gridSideEdges;
+ int gridInternalEdges;
+
+ i = 0;
+ while (i < lastface && edgeNum >= ccgdm->faceMap[i + 1].startEdge) {
+ i++;
+ }
+
+ f = ccgdm->faceMap[i].face;
+ /* numVerts = ccgSubSurf_getFaceNumVerts(f); */ /*UNUSED*/
+
+ gridSideEdges = gridSize - 1;
+ gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
+
+ offset = edgeNum - ccgdm->faceMap[i].startEdge;
+ grid = offset / (gridSideEdges + gridInternalEdges);
+ offset %= (gridSideEdges + gridInternalEdges);
+
+ if (offset < gridSideEdges) {
+ x = offset;
+ med->v1 = getFaceIndex(ss, f, grid, x, 0, edgeSize, gridSize);
+ med->v2 = getFaceIndex(ss, f, grid, x + 1, 0, edgeSize, gridSize);
+ }
+ else {
+ offset -= gridSideEdges;
+ x = (offset / 2) / gridSideEdges + 1;
+ y = (offset / 2) % gridSideEdges;
+ if (offset % 2 == 0) {
+ med->v1 = getFaceIndex(ss, f, grid, x, y, edgeSize, gridSize);
+ med->v2 = getFaceIndex(ss, f, grid, x, y + 1, edgeSize, gridSize);
+ }
+ else {
+ med->v1 = getFaceIndex(ss, f, grid, y, x, edgeSize, gridSize);
+ med->v2 = getFaceIndex(ss, f, grid, y + 1, x, edgeSize, gridSize);
+ }
+ }
+ }
+ else {
+ /* this vert comes from edge data */
+ CCGEdge *e;
+ int edgeSize = ccgSubSurf_getEdgeSize(ss);
+ int x;
+ short *edgeFlag;
+ unsigned int flags = 0;
+
+ i = (edgeNum - ccgdm->edgeMap[0].startEdge) / (edgeSize - 1);
+
+ e = ccgdm->edgeMap[i].edge;
+
+ if (!ccgSubSurf_getEdgeNumFaces(e))
+ flags |= ME_LOOSEEDGE;
+
+ x = edgeNum - ccgdm->edgeMap[i].startEdge;
+
+ med->v1 = getEdgeIndex(ss, e, x, edgeSize);
+ med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
+
+ edgeFlag = (ccgdm->edgeFlags) ? &ccgdm->edgeFlags[i] : NULL;
+ if (edgeFlag)
+ flags |= (*edgeFlag & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER;
+ else
+ flags |= ME_EDGEDRAW | ME_EDGERENDER;
+
+ med->flag = flags;
+ }
}
static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- int gridSize = ccgSubSurf_getGridSize(ss);
- int edgeSize = ccgSubSurf_getEdgeSize(ss);
- int gridSideEdges = gridSize - 1;
- int gridFaces = gridSideEdges * gridSideEdges;
- int i;
- CCGFace *f;
- /*int numVerts;*/
- int offset;
- int grid;
- int x, y;
- /*int lastface = ccgSubSurf_getNumFaces(ss) - 1;*/ /*UNUSED*/
- DMFlagMat *faceFlags = ccgdm->faceFlags;
-
- memset(mf, 0, sizeof(*mf));
- if (faceNum >= ccgdm->dm.numTessFaceData)
- return;
-
- i = ccgdm->reverseFaceMap[faceNum];
-
- f = ccgdm->faceMap[i].face;
- /*numVerts = ccgSubSurf_getFaceNumVerts(f);*/ /*UNUSED*/
-
- offset = faceNum - ccgdm->faceMap[i].startFace;
- grid = offset / gridFaces;
- offset %= gridFaces;
- y = offset / gridSideEdges;
- x = offset % gridSideEdges;
-
- mf->v1 = getFaceIndex(ss, f, grid, x + 0, y + 0, edgeSize, gridSize);
- mf->v2 = getFaceIndex(ss, f, grid, x + 0, y + 1, edgeSize, gridSize);
- mf->v3 = getFaceIndex(ss, f, grid, x + 1, y + 1, edgeSize, gridSize);
- mf->v4 = getFaceIndex(ss, f, grid, x + 1, y + 0, edgeSize, gridSize);
-
- if (faceFlags) {
- mf->flag = faceFlags[i].flag;
- mf->mat_nr = faceFlags[i].mat_nr;
- }
- else {
- mf->flag = ME_SMOOTH;
- }
-
- mf->edcode = 0;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ int gridSize = ccgSubSurf_getGridSize(ss);
+ int edgeSize = ccgSubSurf_getEdgeSize(ss);
+ int gridSideEdges = gridSize - 1;
+ int gridFaces = gridSideEdges * gridSideEdges;
+ int i;
+ CCGFace *f;
+ /*int numVerts;*/
+ int offset;
+ int grid;
+ int x, y;
+ /*int lastface = ccgSubSurf_getNumFaces(ss) - 1;*/ /*UNUSED*/
+ DMFlagMat *faceFlags = ccgdm->faceFlags;
+
+ memset(mf, 0, sizeof(*mf));
+ if (faceNum >= ccgdm->dm.numTessFaceData)
+ return;
+
+ i = ccgdm->reverseFaceMap[faceNum];
+
+ f = ccgdm->faceMap[i].face;
+ /*numVerts = ccgSubSurf_getFaceNumVerts(f);*/ /*UNUSED*/
+
+ offset = faceNum - ccgdm->faceMap[i].startFace;
+ grid = offset / gridFaces;
+ offset %= gridFaces;
+ y = offset / gridSideEdges;
+ x = offset % gridSideEdges;
+
+ mf->v1 = getFaceIndex(ss, f, grid, x + 0, y + 0, edgeSize, gridSize);
+ mf->v2 = getFaceIndex(ss, f, grid, x + 0, y + 1, edgeSize, gridSize);
+ mf->v3 = getFaceIndex(ss, f, grid, x + 1, y + 1, edgeSize, gridSize);
+ mf->v4 = getFaceIndex(ss, f, grid, x + 1, y + 0, edgeSize, gridSize);
+
+ if (faceFlags) {
+ mf->flag = faceFlags[i].flag;
+ mf->mat_nr = faceFlags[i].mat_nr;
+ }
+ else {
+ mf->flag = ME_SMOOTH;
+ }
+
+ mf->edcode = 0;
}
/* Translate GridHidden into the ME_HIDE flag for MVerts. Assumes
* vertices are in the order output by ccgDM_copyFinalVertArray. */
-void subsurf_copy_grid_hidden(DerivedMesh *dm, const MPoly *mpoly,
- MVert *mvert, const MDisps *mdisps)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- CCGSubSurf *ss = ccgdm->ss;
- int level = ccgSubSurf_getSubdivisionLevels(ss);
- int gridSize = ccgSubSurf_getGridSize(ss);
- int edgeSize = ccgSubSurf_getEdgeSize(ss);
- int totface = ccgSubSurf_getNumFaces(ss);
- int i, j, x, y;
-
- for (i = 0; i < totface; i++) {
- CCGFace *f = ccgdm->faceMap[i].face;
-
- for (j = 0; j < mpoly[i].totloop; j++) {
- const MDisps *md = &mdisps[mpoly[i].loopstart + j];
- int hidden_gridsize = BKE_ccg_gridsize(md->level);
- int factor = BKE_ccg_factor(level, md->level);
- BLI_bitmap *hidden = md->hidden;
-
- if (!hidden)
- continue;
-
- for (y = 0; y < gridSize; y++) {
- for (x = 0; x < gridSize; x++) {
- int vndx, offset;
-
- vndx = getFaceIndex(ss, f, j, x, y, edgeSize, gridSize);
- offset = (y * factor) * hidden_gridsize + (x * factor);
- if (BLI_BITMAP_TEST(hidden, offset))
- mvert[vndx].flag |= ME_HIDE;
- }
- }
- }
- }
+void subsurf_copy_grid_hidden(DerivedMesh *dm,
+ const MPoly *mpoly,
+ MVert *mvert,
+ const MDisps *mdisps)
+{
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ int level = ccgSubSurf_getSubdivisionLevels(ss);
+ int gridSize = ccgSubSurf_getGridSize(ss);
+ int edgeSize = ccgSubSurf_getEdgeSize(ss);
+ int totface = ccgSubSurf_getNumFaces(ss);
+ int i, j, x, y;
+
+ for (i = 0; i < totface; i++) {
+ CCGFace *f = ccgdm->faceMap[i].face;
+
+ for (j = 0; j < mpoly[i].totloop; j++) {
+ const MDisps *md = &mdisps[mpoly[i].loopstart + j];
+ int hidden_gridsize = BKE_ccg_gridsize(md->level);
+ int factor = BKE_ccg_factor(level, md->level);
+ BLI_bitmap *hidden = md->hidden;
+
+ if (!hidden)
+ continue;
+
+ for (y = 0; y < gridSize; y++) {
+ for (x = 0; x < gridSize; x++) {
+ int vndx, offset;
+
+ vndx = getFaceIndex(ss, f, j, x, y, edgeSize, gridSize);
+ offset = (y * factor) * hidden_gridsize + (x * factor);
+ if (BLI_BITMAP_TEST(hidden, offset))
+ mvert[vndx].flag |= ME_HIDE;
+ }
+ }
+ }
+ }
}
/* Translate GridPaintMask into vertex paint masks. Assumes vertices
* are in the order output by ccgDM_copyFinalVertArray. */
-void subsurf_copy_grid_paint_mask(DerivedMesh *dm, const MPoly *mpoly,
+void subsurf_copy_grid_paint_mask(DerivedMesh *dm,
+ const MPoly *mpoly,
float *paint_mask,
const GridPaintMask *grid_paint_mask)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- CCGSubSurf *ss = ccgdm->ss;
- int level = ccgSubSurf_getSubdivisionLevels(ss);
- int gridSize = ccgSubSurf_getGridSize(ss);
- int edgeSize = ccgSubSurf_getEdgeSize(ss);
- int totface = ccgSubSurf_getNumFaces(ss);
- int i, j, x, y, factor, gpm_gridsize;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ int level = ccgSubSurf_getSubdivisionLevels(ss);
+ int gridSize = ccgSubSurf_getGridSize(ss);
+ int edgeSize = ccgSubSurf_getEdgeSize(ss);
+ int totface = ccgSubSurf_getNumFaces(ss);
+ int i, j, x, y, factor, gpm_gridsize;
- for (i = 0; i < totface; i++) {
- CCGFace *f = ccgdm->faceMap[i].face;
- const MPoly *p = &mpoly[i];
+ for (i = 0; i < totface; i++) {
+ CCGFace *f = ccgdm->faceMap[i].face;
+ const MPoly *p = &mpoly[i];
- for (j = 0; j < p->totloop; j++) {
- const GridPaintMask *gpm = &grid_paint_mask[p->loopstart + j];
- if (!gpm->data)
- continue;
+ for (j = 0; j < p->totloop; j++) {
+ const GridPaintMask *gpm = &grid_paint_mask[p->loopstart + j];
+ if (!gpm->data)
+ continue;
- factor = BKE_ccg_factor(level, gpm->level);
- gpm_gridsize = BKE_ccg_gridsize(gpm->level);
+ factor = BKE_ccg_factor(level, gpm->level);
+ gpm_gridsize = BKE_ccg_gridsize(gpm->level);
- for (y = 0; y < gridSize; y++) {
- for (x = 0; x < gridSize; x++) {
- int vndx, offset;
+ for (y = 0; y < gridSize; y++) {
+ for (x = 0; x < gridSize; x++) {
+ int vndx, offset;
- vndx = getFaceIndex(ss, f, j, x, y, edgeSize, gridSize);
- offset = y * factor * gpm_gridsize + x * factor;
- paint_mask[vndx] = gpm->data[offset];
- }
- }
- }
- }
+ vndx = getFaceIndex(ss, f, j, x, y, edgeSize, gridSize);
+ offset = y * factor * gpm_gridsize + x * factor;
+ paint_mask[vndx] = gpm->data[offset];
+ }
+ }
+ }
+ }
}
/* utility function */
BLI_INLINE void ccgDM_to_MVert(MVert *mv, const CCGKey *key, CCGElem *elem)
{
- copy_v3_v3(mv->co, CCG_elem_co(key, elem));
- normal_float_to_short_v3(mv->no, CCG_elem_no(key, elem));
- mv->flag = mv->bweight = 0;
+ copy_v3_v3(mv->co, CCG_elem_co(key, elem));
+ normal_float_to_short_v3(mv->no, CCG_elem_no(key, elem));
+ mv->flag = mv->bweight = 0;
}
static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGElem *vd;
- CCGKey key;
- int index;
- int totvert, totedge, totface;
- int gridSize = ccgSubSurf_getGridSize(ss);
- int edgeSize = ccgSubSurf_getEdgeSize(ss);
- unsigned int i = 0;
-
- CCG_key_top_level(&key, ss);
-
- totface = ccgSubSurf_getNumFaces(ss);
- for (index = 0; index < totface; index++) {
- CCGFace *f = ccgdm->faceMap[index].face;
- int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
-
- vd = ccgSubSurf_getFaceCenterData(f);
- ccgDM_to_MVert(&mvert[i++], &key, vd);
-
- for (S = 0; S < numVerts; S++) {
- for (x = 1; x < gridSize - 1; x++) {
- vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
- ccgDM_to_MVert(&mvert[i++], &key, vd);
- }
- }
-
- for (S = 0; S < numVerts; S++) {
- for (y = 1; y < gridSize - 1; y++) {
- for (x = 1; x < gridSize - 1; x++) {
- vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y);
- ccgDM_to_MVert(&mvert[i++], &key, vd);
- }
- }
- }
- }
-
- totedge = ccgSubSurf_getNumEdges(ss);
- for (index = 0; index < totedge; index++) {
- CCGEdge *e = ccgdm->edgeMap[index].edge;
- int x;
-
- for (x = 1; x < edgeSize - 1; x++) {
- /* This gives errors with -debug-fpe
- * the normals don't seem to be unit length.
- * this is most likely caused by edges with no
- * faces which are now zerod out, see comment in:
- * ccgSubSurf__calcVertNormals(), - campbell */
- vd = ccgSubSurf_getEdgeData(ss, e, x);
- ccgDM_to_MVert(&mvert[i++], &key, vd);
- }
- }
-
- totvert = ccgSubSurf_getNumVerts(ss);
- for (index = 0; index < totvert; index++) {
- CCGVert *v = ccgdm->vertMap[index].vert;
-
- vd = ccgSubSurf_getVertData(ss, v);
- ccgDM_to_MVert(&mvert[i++], &key, vd);
- }
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ CCGElem *vd;
+ CCGKey key;
+ int index;
+ int totvert, totedge, totface;
+ int gridSize = ccgSubSurf_getGridSize(ss);
+ int edgeSize = ccgSubSurf_getEdgeSize(ss);
+ unsigned int i = 0;
+
+ CCG_key_top_level(&key, ss);
+
+ totface = ccgSubSurf_getNumFaces(ss);
+ for (index = 0; index < totface; index++) {
+ CCGFace *f = ccgdm->faceMap[index].face;
+ int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
+
+ vd = ccgSubSurf_getFaceCenterData(f);
+ ccgDM_to_MVert(&mvert[i++], &key, vd);
+
+ for (S = 0; S < numVerts; S++) {
+ for (x = 1; x < gridSize - 1; x++) {
+ vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
+ ccgDM_to_MVert(&mvert[i++], &key, vd);
+ }
+ }
+
+ for (S = 0; S < numVerts; S++) {
+ for (y = 1; y < gridSize - 1; y++) {
+ for (x = 1; x < gridSize - 1; x++) {
+ vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y);
+ ccgDM_to_MVert(&mvert[i++], &key, vd);
+ }
+ }
+ }
+ }
+
+ totedge = ccgSubSurf_getNumEdges(ss);
+ for (index = 0; index < totedge; index++) {
+ CCGEdge *e = ccgdm->edgeMap[index].edge;
+ int x;
+
+ for (x = 1; x < edgeSize - 1; x++) {
+ /* This gives errors with -debug-fpe
+ * the normals don't seem to be unit length.
+ * this is most likely caused by edges with no
+ * faces which are now zerod out, see comment in:
+ * ccgSubSurf__calcVertNormals(), - campbell */
+ vd = ccgSubSurf_getEdgeData(ss, e, x);
+ ccgDM_to_MVert(&mvert[i++], &key, vd);
+ }
+ }
+
+ totvert = ccgSubSurf_getNumVerts(ss);
+ for (index = 0; index < totvert; index++) {
+ CCGVert *v = ccgdm->vertMap[index].vert;
+
+ vd = ccgSubSurf_getVertData(ss, v);
+ ccgDM_to_MVert(&mvert[i++], &key, vd);
+ }
}
-
/* utility function */
BLI_INLINE void ccgDM_to_MEdge(MEdge *med, const int v1, const int v2, const short flag)
{
- med->v1 = v1;
- med->v2 = v2;
- med->crease = med->bweight = 0;
- med->flag = flag;
+ med->v1 = v1;
+ med->v2 = v2;
+ med->crease = med->bweight = 0;
+ med->flag = flag;
}
static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- int index;
- int totedge, totface;
- int gridSize = ccgSubSurf_getGridSize(ss);
- int edgeSize = ccgSubSurf_getEdgeSize(ss);
- unsigned int i = 0;
- short *edgeFlags = ccgdm->edgeFlags;
- const short ed_interior_flag = ccgdm->drawInteriorEdges ? (ME_EDGEDRAW | ME_EDGERENDER) : 0;
-
- totface = ccgSubSurf_getNumFaces(ss);
- for (index = 0; index < totface; index++) {
- CCGFace *f = ccgdm->faceMap[index].face;
- int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
-
- for (S = 0; S < numVerts; S++) {
- for (x = 0; x < gridSize - 1; x++) {
- ccgDM_to_MEdge(&medge[i++],
- getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize),
- getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize),
- ed_interior_flag);
- }
-
- for (x = 1; x < gridSize - 1; x++) {
- for (y = 0; y < gridSize - 1; y++) {
- ccgDM_to_MEdge(&medge[i++],
- getFaceIndex(ss, f, S, x, y, edgeSize, gridSize),
- getFaceIndex(ss, f, S, x, y + 1, edgeSize, gridSize),
- ed_interior_flag);
- ccgDM_to_MEdge(&medge[i++],
- getFaceIndex(ss, f, S, y, x, edgeSize, gridSize),
- getFaceIndex(ss, f, S, y + 1, x, edgeSize, gridSize),
- ed_interior_flag);
- }
- }
- }
- }
-
- totedge = ccgSubSurf_getNumEdges(ss);
- for (index = 0; index < totedge; index++) {
- CCGEdge *e = ccgdm->edgeMap[index].edge;
- short ed_flag = 0;
- int x;
- int edgeIdx = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(e));
-
- if (!ccgSubSurf_getEdgeNumFaces(e)) {
- ed_flag |= ME_LOOSEEDGE;
- }
-
- if (edgeFlags) {
- if (edgeIdx != -1) {
- ed_flag |= ((edgeFlags[index] & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER);
- }
- }
- else {
- ed_flag |= ME_EDGEDRAW | ME_EDGERENDER;
- }
-
- for (x = 0; x < edgeSize - 1; x++) {
- ccgDM_to_MEdge(&medge[i++],
- getEdgeIndex(ss, e, x, edgeSize),
- getEdgeIndex(ss, e, x + 1, edgeSize),
- ed_flag);
- }
- }
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ int index;
+ int totedge, totface;
+ int gridSize = ccgSubSurf_getGridSize(ss);
+ int edgeSize = ccgSubSurf_getEdgeSize(ss);
+ unsigned int i = 0;
+ short *edgeFlags = ccgdm->edgeFlags;
+ const short ed_interior_flag = ccgdm->drawInteriorEdges ? (ME_EDGEDRAW | ME_EDGERENDER) : 0;
+
+ totface = ccgSubSurf_getNumFaces(ss);
+ for (index = 0; index < totface; index++) {
+ CCGFace *f = ccgdm->faceMap[index].face;
+ int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
+
+ for (S = 0; S < numVerts; S++) {
+ for (x = 0; x < gridSize - 1; x++) {
+ ccgDM_to_MEdge(&medge[i++],
+ getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize),
+ getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize),
+ ed_interior_flag);
+ }
+
+ for (x = 1; x < gridSize - 1; x++) {
+ for (y = 0; y < gridSize - 1; y++) {
+ ccgDM_to_MEdge(&medge[i++],
+ getFaceIndex(ss, f, S, x, y, edgeSize, gridSize),
+ getFaceIndex(ss, f, S, x, y + 1, edgeSize, gridSize),
+ ed_interior_flag);
+ ccgDM_to_MEdge(&medge[i++],
+ getFaceIndex(ss, f, S, y, x, edgeSize, gridSize),
+ getFaceIndex(ss, f, S, y + 1, x, edgeSize, gridSize),
+ ed_interior_flag);
+ }
+ }
+ }
+ }
+
+ totedge = ccgSubSurf_getNumEdges(ss);
+ for (index = 0; index < totedge; index++) {
+ CCGEdge *e = ccgdm->edgeMap[index].edge;
+ short ed_flag = 0;
+ int x;
+ int edgeIdx = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(e));
+
+ if (!ccgSubSurf_getEdgeNumFaces(e)) {
+ ed_flag |= ME_LOOSEEDGE;
+ }
+
+ if (edgeFlags) {
+ if (edgeIdx != -1) {
+ ed_flag |= ((edgeFlags[index] & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER);
+ }
+ }
+ else {
+ ed_flag |= ME_EDGEDRAW | ME_EDGERENDER;
+ }
+
+ for (x = 0; x < edgeSize - 1; x++) {
+ ccgDM_to_MEdge(&medge[i++],
+ getEdgeIndex(ss, e, x, edgeSize),
+ getEdgeIndex(ss, e, x + 1, edgeSize),
+ ed_flag);
+ }
+ }
}
static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- int index;
- int totface;
- int gridSize = ccgSubSurf_getGridSize(ss);
- int edgeSize = ccgSubSurf_getEdgeSize(ss);
- int i = 0;
- DMFlagMat *faceFlags = ccgdm->faceFlags;
-
- totface = dm->getNumTessFaces(dm);
- for (index = 0; index < totface; index++) {
- CCGFace *f = ccgdm->faceMap[index].face;
- int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
- /* keep types in sync with MFace, avoid many conversions */
- char flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH;
- short mat_nr = (faceFlags) ? faceFlags[index].mat_nr : 0;
-
- for (S = 0; S < numVerts; S++) {
- for (y = 0; y < gridSize - 1; y++) {
- for (x = 0; x < gridSize - 1; x++) {
- MFace *mf = &mface[i];
- mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
- edgeSize, gridSize);
- mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
- edgeSize, gridSize);
- mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
- edgeSize, gridSize);
- mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
- edgeSize, gridSize);
- mf->mat_nr = mat_nr;
- mf->flag = flag;
- mf->edcode = 0;
-
- i++;
- }
- }
- }
- }
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ int index;
+ int totface;
+ int gridSize = ccgSubSurf_getGridSize(ss);
+ int edgeSize = ccgSubSurf_getEdgeSize(ss);
+ int i = 0;
+ DMFlagMat *faceFlags = ccgdm->faceFlags;
+
+ totface = dm->getNumTessFaces(dm);
+ for (index = 0; index < totface; index++) {
+ CCGFace *f = ccgdm->faceMap[index].face;
+ int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
+ /* keep types in sync with MFace, avoid many conversions */
+ char flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH;
+ short mat_nr = (faceFlags) ? faceFlags[index].mat_nr : 0;
+
+ for (S = 0; S < numVerts; S++) {
+ for (y = 0; y < gridSize - 1; y++) {
+ for (x = 0; x < gridSize - 1; x++) {
+ MFace *mf = &mface[i];
+ mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0, edgeSize, gridSize);
+ mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1, edgeSize, gridSize);
+ mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1, edgeSize, gridSize);
+ mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0, edgeSize, gridSize);
+ mf->mat_nr = mat_nr;
+ mf->flag = flag;
+ mf->edcode = 0;
+
+ i++;
+ }
+ }
+ }
+ }
}
typedef struct CopyFinalLoopArrayData {
- CCGDerivedMesh *ccgdm;
- MLoop *mloop;
- int grid_size;
- int *grid_offset;
- int edge_size;
- size_t mloop_index;
+ CCGDerivedMesh *ccgdm;
+ MLoop *mloop;
+ int grid_size;
+ int *grid_offset;
+ int edge_size;
+ size_t mloop_index;
} CopyFinalLoopArrayData;
-static void copyFinalLoopArray_task_cb(
- void *__restrict userdata,
- const int iter,
- const ParallelRangeTLS *__restrict UNUSED(tls))
-{
- CopyFinalLoopArrayData *data = userdata;
- CCGDerivedMesh *ccgdm = data->ccgdm;
- CCGSubSurf *ss = ccgdm->ss;
- const int grid_size = data->grid_size;
- const int edge_size = data->edge_size;
- CCGFace *f = ccgdm->faceMap[iter].face;
- const int num_verts = ccgSubSurf_getFaceNumVerts(f);
- const int grid_index = data->grid_offset[iter];
- const size_t loop_index = 4 * (size_t)grid_index * (grid_size - 1) * (grid_size - 1);
- MLoop *ml = &data->mloop[loop_index];
- for (int S = 0; S < num_verts; S++) {
- for (int y = 0; y < grid_size - 1; y++) {
- for (int x = 0; x < grid_size - 1; x++) {
-
- uint v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
- edge_size, grid_size);
- uint v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
- edge_size, grid_size);
- uint v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
- edge_size, grid_size);
- uint v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
- edge_size, grid_size);
-
- ml->v = v1;
- ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v1, v2));
- ml++;
-
- ml->v = v2;
- ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v2, v3));
- ml++;
-
- ml->v = v3;
- ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v3, v4));
- ml++;
-
- ml->v = v4;
- ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v4, v1));
- ml++;
- }
- }
- }
+static void copyFinalLoopArray_task_cb(void *__restrict userdata,
+ const int iter,
+ const ParallelRangeTLS *__restrict UNUSED(tls))
+{
+ CopyFinalLoopArrayData *data = userdata;
+ CCGDerivedMesh *ccgdm = data->ccgdm;
+ CCGSubSurf *ss = ccgdm->ss;
+ const int grid_size = data->grid_size;
+ const int edge_size = data->edge_size;
+ CCGFace *f = ccgdm->faceMap[iter].face;
+ const int num_verts = ccgSubSurf_getFaceNumVerts(f);
+ const int grid_index = data->grid_offset[iter];
+ const size_t loop_index = 4 * (size_t)grid_index * (grid_size - 1) * (grid_size - 1);
+ MLoop *ml = &data->mloop[loop_index];
+ for (int S = 0; S < num_verts; S++) {
+ for (int y = 0; y < grid_size - 1; y++) {
+ for (int x = 0; x < grid_size - 1; x++) {
+
+ uint v1 = getFaceIndex(ss, f, S, x + 0, y + 0, edge_size, grid_size);
+ uint v2 = getFaceIndex(ss, f, S, x + 0, y + 1, edge_size, grid_size);
+ uint v3 = getFaceIndex(ss, f, S, x + 1, y + 1, edge_size, grid_size);
+ uint v4 = getFaceIndex(ss, f, S, x + 1, y + 0, edge_size, grid_size);
+
+ ml->v = v1;
+ ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v1, v2));
+ ml++;
+
+ ml->v = v2;
+ ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v2, v3));
+ ml++;
+
+ ml->v = v3;
+ ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v3, v4));
+ ml++;
+
+ ml->v = v4;
+ ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v4, v1));
+ ml++;
+ }
+ }
+ }
}
static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
- if (!ccgdm->ehash) {
- BLI_mutex_lock(&ccgdm->loops_cache_lock);
- if (!ccgdm->ehash) {
- MEdge *medge;
- EdgeHash *ehash;
+ if (!ccgdm->ehash) {
+ BLI_mutex_lock(&ccgdm->loops_cache_lock);
+ if (!ccgdm->ehash) {
+ MEdge *medge;
+ EdgeHash *ehash;
- ehash = BLI_edgehash_new_ex(__func__, ccgdm->dm.numEdgeData);
- medge = ccgdm->dm.getEdgeArray((DerivedMesh *)ccgdm);
+ ehash = BLI_edgehash_new_ex(__func__, ccgdm->dm.numEdgeData);
+ medge = ccgdm->dm.getEdgeArray((DerivedMesh *)ccgdm);
- for (int i = 0; i < ccgdm->dm.numEdgeData; i++) {
- BLI_edgehash_insert(ehash, medge[i].v1, medge[i].v2, POINTER_FROM_INT(i));
- }
+ for (int i = 0; i < ccgdm->dm.numEdgeData; i++) {
+ BLI_edgehash_insert(ehash, medge[i].v1, medge[i].v2, POINTER_FROM_INT(i));
+ }
- atomic_cas_ptr((void **)&ccgdm->ehash, ccgdm->ehash, ehash);
- }
- BLI_mutex_unlock(&ccgdm->loops_cache_lock);
- }
+ atomic_cas_ptr((void **)&ccgdm->ehash, ccgdm->ehash, ehash);
+ }
+ BLI_mutex_unlock(&ccgdm->loops_cache_lock);
+ }
- CopyFinalLoopArrayData data;
- data.ccgdm = ccgdm;
- data.mloop = mloop;
- data.grid_size = ccgSubSurf_getGridSize(ss);
- data.grid_offset = dm->getGridOffset(dm);
- data.edge_size = ccgSubSurf_getEdgeSize(ss);
+ CopyFinalLoopArrayData data;
+ data.ccgdm = ccgdm;
+ data.mloop = mloop;
+ data.grid_size = ccgSubSurf_getGridSize(ss);
+ data.grid_offset = dm->getGridOffset(dm);
+ data.edge_size = ccgSubSurf_getEdgeSize(ss);
- /* NOTE: For a dense subdivision we've got enough work for each face and
- * hence can dedicate whole thread to single face. For less dense
- * subdivision we handle multiple faces per thread.
- */
- data.mloop_index = data.grid_size >= 5 ? 1 : 8;
+ /* NOTE: For a dense subdivision we've got enough work for each face and
+ * hence can dedicate whole thread to single face. For less dense
+ * subdivision we handle multiple faces per thread.
+ */
+ data.mloop_index = data.grid_size >= 5 ? 1 : 8;
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.min_iter_per_thread = 1;
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.min_iter_per_thread = 1;
- BLI_task_parallel_range(0, ccgSubSurf_getNumFaces(ss),
- &data,
- copyFinalLoopArray_task_cb,
- &settings);
+ BLI_task_parallel_range(
+ 0, ccgSubSurf_getNumFaces(ss), &data, copyFinalLoopArray_task_cb, &settings);
}
static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *mpoly)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- int index;
- int totface;
- int gridSize = ccgSubSurf_getGridSize(ss);
- /* int edgeSize = ccgSubSurf_getEdgeSize(ss); */ /* UNUSED */
- int i = 0, k = 0;
- DMFlagMat *faceFlags = ccgdm->faceFlags;
-
- totface = ccgSubSurf_getNumFaces(ss);
- for (index = 0; index < totface; index++) {
- CCGFace *f = ccgdm->faceMap[index].face;
- int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
- int flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH;
- int mat_nr = (faceFlags) ? faceFlags[index].mat_nr : 0;
-
- for (S = 0; S < numVerts; S++) {
- for (y = 0; y < gridSize - 1; y++) {
- for (x = 0; x < gridSize - 1; x++) {
- MPoly *mp = &mpoly[i];
-
- mp->mat_nr = mat_nr;
- mp->flag = flag;
- mp->loopstart = k;
- mp->totloop = 4;
-
- k += 4;
- i++;
- }
- }
- }
- }
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ int index;
+ int totface;
+ int gridSize = ccgSubSurf_getGridSize(ss);
+ /* int edgeSize = ccgSubSurf_getEdgeSize(ss); */ /* UNUSED */
+ int i = 0, k = 0;
+ DMFlagMat *faceFlags = ccgdm->faceFlags;
+
+ totface = ccgSubSurf_getNumFaces(ss);
+ for (index = 0; index < totface; index++) {
+ CCGFace *f = ccgdm->faceMap[index].face;
+ int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
+ int flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH;
+ int mat_nr = (faceFlags) ? faceFlags[index].mat_nr : 0;
+
+ for (S = 0; S < numVerts; S++) {
+ for (y = 0; y < gridSize - 1; y++) {
+ for (x = 0; x < gridSize - 1; x++) {
+ MPoly *mp = &mpoly[i];
+
+ mp->mat_nr = mat_nr;
+ mp->flag = flag;
+ mp->loopstart = k;
+ mp->totloop = 4;
+
+ k += 4;
+ i++;
+ }
+ }
+ }
+ }
}
static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3])
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- int edgeSize = ccgSubSurf_getEdgeSize(ss);
- int gridSize = ccgSubSurf_getGridSize(ss);
- int i;
- CCGVertIterator vi;
- CCGEdgeIterator ei;
- CCGFaceIterator fi;
- CCGFace **faceMap2;
- CCGEdge **edgeMap2;
- CCGVert **vertMap2;
- int index, totvert, totedge, totface;
-
- totvert = ccgSubSurf_getNumVerts(ss);
- vertMap2 = MEM_mallocN(totvert * sizeof(*vertMap2), "vertmap");
- for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
- CCGVert *v = ccgVertIterator_getCurrent(&vi);
-
- vertMap2[POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v))] = v;
- }
-
- totedge = ccgSubSurf_getNumEdges(ss);
- edgeMap2 = MEM_mallocN(totedge * sizeof(*edgeMap2), "edgemap");
- for (ccgSubSurf_initEdgeIterator(ss, &ei), i = 0; !ccgEdgeIterator_isStopped(&ei); i++, ccgEdgeIterator_next(&ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
-
- edgeMap2[POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(e))] = e;
- }
-
- totface = ccgSubSurf_getNumFaces(ss);
- faceMap2 = MEM_mallocN(totface * sizeof(*faceMap2), "facemap");
- for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(&fi);
-
- faceMap2[POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f))] = f;
- }
-
- i = 0;
- for (index = 0; index < totface; index++) {
- CCGFace *f = faceMap2[index];
- int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
-
- copy_v3_v3(cos[i++], ccgSubSurf_getFaceCenterData(f));
-
- for (S = 0; S < numVerts; S++) {
- for (x = 1; x < gridSize - 1; x++) {
- copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
- }
- }
-
- for (S = 0; S < numVerts; S++) {
- for (y = 1; y < gridSize - 1; y++) {
- for (x = 1; x < gridSize - 1; x++) {
- copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
- }
- }
- }
- }
-
- for (index = 0; index < totedge; index++) {
- CCGEdge *e = edgeMap2[index];
- int x;
-
- for (x = 1; x < edgeSize - 1; x++) {
- copy_v3_v3(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
- }
- }
-
- for (index = 0; index < totvert; index++) {
- CCGVert *v = vertMap2[index];
- copy_v3_v3(cos[i++], ccgSubSurf_getVertData(ss, v));
- }
-
- MEM_freeN(vertMap2);
- MEM_freeN(edgeMap2);
- MEM_freeN(faceMap2);
-}
-
-static void ccgDM_foreachMappedVert(
- DerivedMesh *dm,
- void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
- void *userData,
- DMForeachFlag flag)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGVertIterator vi;
- CCGKey key;
- CCG_key_top_level(&key, ccgdm->ss);
-
- for (ccgSubSurf_initVertIterator(ccgdm->ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
- CCGVert *v = ccgVertIterator_getCurrent(&vi);
- const int index = ccgDM_getVertMapIndex(ccgdm->ss, v);
-
- if (index != -1) {
- CCGElem *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
- const float *no = (flag & DM_FOREACH_USE_NORMAL) ? CCG_elem_no(&key, vd) : NULL;
- func(userData, index, CCG_elem_co(&key, vd), no, NULL);
- }
- }
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ int edgeSize = ccgSubSurf_getEdgeSize(ss);
+ int gridSize = ccgSubSurf_getGridSize(ss);
+ int i;
+ CCGVertIterator vi;
+ CCGEdgeIterator ei;
+ CCGFaceIterator fi;
+ CCGFace **faceMap2;
+ CCGEdge **edgeMap2;
+ CCGVert **vertMap2;
+ int index, totvert, totedge, totface;
+
+ totvert = ccgSubSurf_getNumVerts(ss);
+ vertMap2 = MEM_mallocN(totvert * sizeof(*vertMap2), "vertmap");
+ for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi);
+ ccgVertIterator_next(&vi)) {
+ CCGVert *v = ccgVertIterator_getCurrent(&vi);
+
+ vertMap2[POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v))] = v;
+ }
+
+ totedge = ccgSubSurf_getNumEdges(ss);
+ edgeMap2 = MEM_mallocN(totedge * sizeof(*edgeMap2), "edgemap");
+ for (ccgSubSurf_initEdgeIterator(ss, &ei), i = 0; !ccgEdgeIterator_isStopped(&ei);
+ i++, ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
+
+ edgeMap2[POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(e))] = e;
+ }
+
+ totface = ccgSubSurf_getNumFaces(ss);
+ faceMap2 = MEM_mallocN(totface * sizeof(*faceMap2), "facemap");
+ for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi);
+ ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
+
+ faceMap2[POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f))] = f;
+ }
+
+ i = 0;
+ for (index = 0; index < totface; index++) {
+ CCGFace *f = faceMap2[index];
+ int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
+
+ copy_v3_v3(cos[i++], ccgSubSurf_getFaceCenterData(f));
+
+ for (S = 0; S < numVerts; S++) {
+ for (x = 1; x < gridSize - 1; x++) {
+ copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
+ }
+ }
+
+ for (S = 0; S < numVerts; S++) {
+ for (y = 1; y < gridSize - 1; y++) {
+ for (x = 1; x < gridSize - 1; x++) {
+ copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
+ }
+ }
+ }
+ }
+
+ for (index = 0; index < totedge; index++) {
+ CCGEdge *e = edgeMap2[index];
+ int x;
+
+ for (x = 1; x < edgeSize - 1; x++) {
+ copy_v3_v3(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
+ }
+ }
+
+ for (index = 0; index < totvert; index++) {
+ CCGVert *v = vertMap2[index];
+ copy_v3_v3(cos[i++], ccgSubSurf_getVertData(ss, v));
+ }
+
+ MEM_freeN(vertMap2);
+ MEM_freeN(edgeMap2);
+ MEM_freeN(faceMap2);
+}
+
+static void ccgDM_foreachMappedVert(DerivedMesh *dm,
+ void (*func)(void *userData,
+ int index,
+ const float co[3],
+ const float no_f[3],
+ const short no_s[3]),
+ void *userData,
+ DMForeachFlag flag)
+{
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGVertIterator vi;
+ CCGKey key;
+ CCG_key_top_level(&key, ccgdm->ss);
+
+ for (ccgSubSurf_initVertIterator(ccgdm->ss, &vi); !ccgVertIterator_isStopped(&vi);
+ ccgVertIterator_next(&vi)) {
+ CCGVert *v = ccgVertIterator_getCurrent(&vi);
+ const int index = ccgDM_getVertMapIndex(ccgdm->ss, v);
+
+ if (index != -1) {
+ CCGElem *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
+ const float *no = (flag & DM_FOREACH_USE_NORMAL) ? CCG_elem_no(&key, vd) : NULL;
+ func(userData, index, CCG_elem_co(&key, vd), no, NULL);
+ }
+ }
}
static void ccgDM_foreachMappedEdge(
- DerivedMesh *dm,
- void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
- void *userData)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGEdgeIterator ei;
- CCGKey key;
- int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
-
- CCG_key_top_level(&key, ss);
-
- for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
- const int index = ccgDM_getEdgeMapIndex(ss, e);
-
- if (index != -1) {
- CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
- for (i = 0; i < edgeSize - 1; i++) {
- func(userData, index, CCG_elem_offset_co(&key, edgeData, i), CCG_elem_offset_co(&key, edgeData, i + 1));
- }
- }
- }
-}
-
-static void ccgDM_foreachMappedLoop(
- DerivedMesh *dm,
- void (*func)(void *userData, int vertex_index, int face_index, const float co[3], const float no[3]),
- void *userData,
- DMForeachFlag flag)
-{
- /* We can't use dm->getLoopDataLayout(dm) here, we want to always access dm->loopData, EditDerivedBMesh would
- * return loop data from bmesh itself. */
- const float (*lnors)[3] = (flag & DM_FOREACH_USE_NORMAL) ? DM_get_loop_data_layer(dm, CD_NORMAL) : NULL;
-
- MVert *mv = dm->getVertArray(dm);
- MLoop *ml = dm->getLoopArray(dm);
- MPoly *mp = dm->getPolyArray(dm);
- const int *v_index = dm->getVertDataArray(dm, CD_ORIGINDEX);
- const int *f_index = dm->getPolyDataArray(dm, CD_ORIGINDEX);
- int p_idx, i;
-
- for (p_idx = 0; p_idx < dm->numPolyData; ++p_idx, ++mp) {
- for (i = 0; i < mp->totloop; ++i, ++ml) {
- const int v_idx = v_index ? v_index[ml->v] : ml->v;
- const int f_idx = f_index ? f_index[p_idx] : p_idx;
- const float *no = lnors ? *lnors++ : NULL;
- if (!ELEM(ORIGINDEX_NONE, v_idx, f_idx)) {
- func(userData, v_idx, f_idx, mv[ml->v].co, no);
- }
- }
- }
+ DerivedMesh *dm,
+ void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
+ void *userData)
+{
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ CCGEdgeIterator ei;
+ CCGKey key;
+ int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
+
+ CCG_key_top_level(&key, ss);
+
+ for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei);
+ ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
+ const int index = ccgDM_getEdgeMapIndex(ss, e);
+
+ if (index != -1) {
+ CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
+ for (i = 0; i < edgeSize - 1; i++) {
+ func(userData,
+ index,
+ CCG_elem_offset_co(&key, edgeData, i),
+ CCG_elem_offset_co(&key, edgeData, i + 1));
+ }
+ }
+ }
+}
+
+static void ccgDM_foreachMappedLoop(DerivedMesh *dm,
+ void (*func)(void *userData,
+ int vertex_index,
+ int face_index,
+ const float co[3],
+ const float no[3]),
+ void *userData,
+ DMForeachFlag flag)
+{
+ /* We can't use dm->getLoopDataLayout(dm) here, we want to always access dm->loopData, EditDerivedBMesh would
+ * return loop data from bmesh itself. */
+ const float(*lnors)[3] = (flag & DM_FOREACH_USE_NORMAL) ? DM_get_loop_data_layer(dm, CD_NORMAL) :
+ NULL;
+
+ MVert *mv = dm->getVertArray(dm);
+ MLoop *ml = dm->getLoopArray(dm);
+ MPoly *mp = dm->getPolyArray(dm);
+ const int *v_index = dm->getVertDataArray(dm, CD_ORIGINDEX);
+ const int *f_index = dm->getPolyDataArray(dm, CD_ORIGINDEX);
+ int p_idx, i;
+
+ for (p_idx = 0; p_idx < dm->numPolyData; ++p_idx, ++mp) {
+ for (i = 0; i < mp->totloop; ++i, ++ml) {
+ const int v_idx = v_index ? v_index[ml->v] : ml->v;
+ const int f_idx = f_index ? f_index[p_idx] : p_idx;
+ const float *no = lnors ? *lnors++ : NULL;
+ if (!ELEM(ORIGINDEX_NONE, v_idx, f_idx)) {
+ func(userData, v_idx, f_idx, mv[ml->v].co, no);
+ }
+ }
+ }
}
static void UNUSED_FUNCTION(ccgdm_pbvh_update)(CCGDerivedMesh *ccgdm)
{
- if (ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) {
- CCGFace **faces;
- int totface;
+ if (ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) {
+ CCGFace **faces;
+ int totface;
- BKE_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void ***)&faces, &totface);
- if (totface) {
- ccgSubSurf_updateFromFaces(ccgdm->ss, 0, faces, totface);
- ccgSubSurf_updateNormals(ccgdm->ss, faces, totface);
- MEM_freeN(faces);
- }
- }
+ BKE_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void ***)&faces, &totface);
+ if (totface) {
+ ccgSubSurf_updateFromFaces(ccgdm->ss, 0, faces, totface);
+ ccgSubSurf_updateNormals(ccgdm->ss, faces, totface);
+ MEM_freeN(faces);
+ }
+ }
}
static void ccgDM_foreachMappedFaceCenter(
- DerivedMesh *dm,
- void (*func)(void *userData, int index, const float co[3], const float no[3]),
- void *userData,
- DMForeachFlag flag)
+ DerivedMesh *dm,
+ void (*func)(void *userData, int index, const float co[3], const float no[3]),
+ void *userData,
+ DMForeachFlag flag)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGKey key;
- CCGFaceIterator fi;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ CCGKey key;
+ CCGFaceIterator fi;
- CCG_key_top_level(&key, ss);
+ CCG_key_top_level(&key, ss);
- for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(&fi);
- const int index = ccgDM_getFaceMapIndex(ss, f);
+ for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi);
+ ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
+ const int index = ccgDM_getFaceMapIndex(ss, f);
- if (index != -1) {
- /* Face center data normal isn't updated atm. */
- CCGElem *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
- const float *no = (flag & DM_FOREACH_USE_NORMAL) ? CCG_elem_no(&key, vd) : NULL;
- func(userData, index, CCG_elem_co(&key, vd), no);
- }
- }
+ if (index != -1) {
+ /* Face center data normal isn't updated atm. */
+ CCGElem *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
+ const float *no = (flag & DM_FOREACH_USE_NORMAL) ? CCG_elem_no(&key, vd) : NULL;
+ func(userData, index, CCG_elem_co(&key, vd), no);
+ }
+ }
}
static void ccgDM_release(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
-
- if (DM_release(dm)) {
- /* Before freeing, need to update the displacement map */
- if (ccgdm->multires.modified_flags) {
- /* Check that mmd still exists */
- if (!ccgdm->multires.local_mmd &&
- BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0)
- {
- ccgdm->multires.mmd = NULL;
- }
-
- if (ccgdm->multires.mmd) {
- if (ccgdm->multires.modified_flags & MULTIRES_COORDS_MODIFIED)
- multires_modifier_update_mdisps(dm, NULL);
- if (ccgdm->multires.modified_flags & MULTIRES_HIDDEN_MODIFIED)
- multires_modifier_update_hidden(dm);
- }
- }
-
- if (ccgdm->ehash)
- BLI_edgehash_free(ccgdm->ehash, NULL);
-
- if (ccgdm->reverseFaceMap) MEM_freeN(ccgdm->reverseFaceMap);
- if (ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces);
- if (ccgdm->gridData) MEM_freeN(ccgdm->gridData);
- if (ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset);
- if (ccgdm->gridFlagMats) MEM_freeN(ccgdm->gridFlagMats);
- if (ccgdm->gridHidden) {
- /* Using dm->getNumGrids(dm) accesses freed memory */
- uint numGrids = ccgdm->numGrid;
- for (uint i = 0; i < numGrids; i++) {
- if (ccgdm->gridHidden[i]) {
- MEM_freeN(ccgdm->gridHidden[i]);
- }
- }
- MEM_freeN(ccgdm->gridHidden);
- }
- if (ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss);
- if (ccgdm->pmap) MEM_freeN(ccgdm->pmap);
- if (ccgdm->pmap_mem) MEM_freeN(ccgdm->pmap_mem);
- MEM_freeN(ccgdm->edgeFlags);
- MEM_freeN(ccgdm->faceFlags);
- if (ccgdm->useGpuBackend == false) {
- MEM_freeN(ccgdm->vertMap);
- MEM_freeN(ccgdm->edgeMap);
- MEM_freeN(ccgdm->faceMap);
- }
-
- BLI_mutex_end(&ccgdm->loops_cache_lock);
- BLI_rw_mutex_end(&ccgdm->origindex_cache_rwlock);
-
- MEM_freeN(ccgdm);
- }
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+
+ if (DM_release(dm)) {
+ /* Before freeing, need to update the displacement map */
+ if (ccgdm->multires.modified_flags) {
+ /* Check that mmd still exists */
+ if (!ccgdm->multires.local_mmd &&
+ BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0) {
+ ccgdm->multires.mmd = NULL;
+ }
+
+ if (ccgdm->multires.mmd) {
+ if (ccgdm->multires.modified_flags & MULTIRES_COORDS_MODIFIED)
+ multires_modifier_update_mdisps(dm, NULL);
+ if (ccgdm->multires.modified_flags & MULTIRES_HIDDEN_MODIFIED)
+ multires_modifier_update_hidden(dm);
+ }
+ }
+
+ if (ccgdm->ehash)
+ BLI_edgehash_free(ccgdm->ehash, NULL);
+
+ if (ccgdm->reverseFaceMap)
+ MEM_freeN(ccgdm->reverseFaceMap);
+ if (ccgdm->gridFaces)
+ MEM_freeN(ccgdm->gridFaces);
+ if (ccgdm->gridData)
+ MEM_freeN(ccgdm->gridData);
+ if (ccgdm->gridOffset)
+ MEM_freeN(ccgdm->gridOffset);
+ if (ccgdm->gridFlagMats)
+ MEM_freeN(ccgdm->gridFlagMats);
+ if (ccgdm->gridHidden) {
+ /* Using dm->getNumGrids(dm) accesses freed memory */
+ uint numGrids = ccgdm->numGrid;
+ for (uint i = 0; i < numGrids; i++) {
+ if (ccgdm->gridHidden[i]) {
+ MEM_freeN(ccgdm->gridHidden[i]);
+ }
+ }
+ MEM_freeN(ccgdm->gridHidden);
+ }
+ if (ccgdm->freeSS)
+ ccgSubSurf_free(ccgdm->ss);
+ if (ccgdm->pmap)
+ MEM_freeN(ccgdm->pmap);
+ if (ccgdm->pmap_mem)
+ MEM_freeN(ccgdm->pmap_mem);
+ MEM_freeN(ccgdm->edgeFlags);
+ MEM_freeN(ccgdm->faceFlags);
+ if (ccgdm->useGpuBackend == false) {
+ MEM_freeN(ccgdm->vertMap);
+ MEM_freeN(ccgdm->edgeMap);
+ MEM_freeN(ccgdm->faceMap);
+ }
+
+ BLI_mutex_end(&ccgdm->loops_cache_lock);
+ BLI_rw_mutex_end(&ccgdm->origindex_cache_rwlock);
+
+ MEM_freeN(ccgdm);
+ }
}
static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
{
- if (type == CD_ORIGINDEX) {
- /* create origindex on demand to save memory */
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- CCGSubSurf *ss = ccgdm->ss;
- int *origindex;
- int a, index, totnone, totorig;
+ if (type == CD_ORIGINDEX) {
+ /* create origindex on demand to save memory */
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ int *origindex;
+ int a, index, totnone, totorig;
- /* Avoid re-creation if the layer exists already */
- BLI_rw_mutex_lock(&ccgdm->origindex_cache_rwlock, THREAD_LOCK_READ);
- origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
- BLI_rw_mutex_unlock(&ccgdm->origindex_cache_rwlock);
- if (origindex) {
- return origindex;
- }
+ /* Avoid re-creation if the layer exists already */
+ BLI_rw_mutex_lock(&ccgdm->origindex_cache_rwlock, THREAD_LOCK_READ);
+ origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
+ BLI_rw_mutex_unlock(&ccgdm->origindex_cache_rwlock);
+ if (origindex) {
+ return origindex;
+ }
- BLI_rw_mutex_lock(&ccgdm->origindex_cache_rwlock, THREAD_LOCK_WRITE);
- DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
- origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
+ BLI_rw_mutex_lock(&ccgdm->origindex_cache_rwlock, THREAD_LOCK_WRITE);
+ DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
+ origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
- totorig = ccgSubSurf_getNumVerts(ss);
- totnone = dm->numVertData - totorig;
+ totorig = ccgSubSurf_getNumVerts(ss);
+ totnone = dm->numVertData - totorig;
- /* original vertices are at the end */
- for (a = 0; a < totnone; a++)
- origindex[a] = ORIGINDEX_NONE;
+ /* original vertices are at the end */
+ for (a = 0; a < totnone; a++)
+ origindex[a] = ORIGINDEX_NONE;
- for (index = 0; index < totorig; index++, a++) {
- CCGVert *v = ccgdm->vertMap[index].vert;
- origindex[a] = ccgDM_getVertMapIndex(ccgdm->ss, v);
- }
- BLI_rw_mutex_unlock(&ccgdm->origindex_cache_rwlock);
+ for (index = 0; index < totorig; index++, a++) {
+ CCGVert *v = ccgdm->vertMap[index].vert;
+ origindex[a] = ccgDM_getVertMapIndex(ccgdm->ss, v);
+ }
+ BLI_rw_mutex_unlock(&ccgdm->origindex_cache_rwlock);
- return origindex;
- }
+ return origindex;
+ }
- return DM_get_vert_data_layer(dm, type);
+ return DM_get_vert_data_layer(dm, type);
}
static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
{
- if (type == CD_ORIGINDEX) {
- /* create origindex on demand to save memory */
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- CCGSubSurf *ss = ccgdm->ss;
- int *origindex;
- int a, i, index, totnone, totorig, totedge;
- int edgeSize = ccgSubSurf_getEdgeSize(ss);
+ if (type == CD_ORIGINDEX) {
+ /* create origindex on demand to save memory */
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ int *origindex;
+ int a, i, index, totnone, totorig, totedge;
+ int edgeSize = ccgSubSurf_getEdgeSize(ss);
- /* Avoid re-creation if the layer exists already */
- origindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
- if (origindex) {
- return origindex;
- }
+ /* Avoid re-creation if the layer exists already */
+ origindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
+ if (origindex) {
+ return origindex;
+ }
- DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
- origindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
+ DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
+ origindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
- totedge = ccgSubSurf_getNumEdges(ss);
- totorig = totedge * (edgeSize - 1);
- totnone = dm->numEdgeData - totorig;
+ totedge = ccgSubSurf_getNumEdges(ss);
+ totorig = totedge * (edgeSize - 1);
+ totnone = dm->numEdgeData - totorig;
- /* original edges are at the end */
- for (a = 0; a < totnone; a++)
- origindex[a] = ORIGINDEX_NONE;
+ /* original edges are at the end */
+ for (a = 0; a < totnone; a++)
+ origindex[a] = ORIGINDEX_NONE;
- for (index = 0; index < totedge; index++) {
- CCGEdge *e = ccgdm->edgeMap[index].edge;
- int mapIndex = ccgDM_getEdgeMapIndex(ss, e);
+ for (index = 0; index < totedge; index++) {
+ CCGEdge *e = ccgdm->edgeMap[index].edge;
+ int mapIndex = ccgDM_getEdgeMapIndex(ss, e);
- for (i = 0; i < edgeSize - 1; i++, a++)
- origindex[a] = mapIndex;
- }
+ for (i = 0; i < edgeSize - 1; i++, a++)
+ origindex[a] = mapIndex;
+ }
- return origindex;
- }
+ return origindex;
+ }
- return DM_get_edge_data_layer(dm, type);
+ return DM_get_edge_data_layer(dm, type);
}
static void *ccgDM_get_tessface_data_layer(DerivedMesh *dm, int type)
{
- if (type == CD_ORIGINDEX) {
- /* create origindex on demand to save memory */
- int *origindex;
+ if (type == CD_ORIGINDEX) {
+ /* create origindex on demand to save memory */
+ int *origindex;
- /* Avoid re-creation if the layer exists already */
- origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
- if (origindex) {
- return origindex;
- }
+ /* Avoid re-creation if the layer exists already */
+ origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
+ if (origindex) {
+ return origindex;
+ }
- DM_add_tessface_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
- origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
+ DM_add_tessface_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
+ origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
- /* silly loop counting up */
- range_vn_i(origindex, dm->getNumTessFaces(dm), 0);
+ /* silly loop counting up */
+ range_vn_i(origindex, dm->getNumTessFaces(dm), 0);
- return origindex;
- }
+ return origindex;
+ }
- if (type == CD_TESSLOOPNORMAL) {
- /* Create tessloopnormal on demand to save memory. */
- /* Note that since tessellated face corners are the same a loops in CCGDM, and since all faces have four
- * loops/corners, we can simplify the code here by converting tessloopnormals from 'short (*)[4][3]'
- * to 'short (*)[3]'.
- */
- short (*tlnors)[3];
+ if (type == CD_TESSLOOPNORMAL) {
+ /* Create tessloopnormal on demand to save memory. */
+ /* Note that since tessellated face corners are the same a loops in CCGDM, and since all faces have four
+ * loops/corners, we can simplify the code here by converting tessloopnormals from 'short (*)[4][3]'
+ * to 'short (*)[3]'.
+ */
+ short(*tlnors)[3];
- /* Avoid re-creation if the layer exists already */
- tlnors = DM_get_tessface_data_layer(dm, CD_TESSLOOPNORMAL);
- if (!tlnors) {
- float (*lnors)[3];
- short (*tlnors_it)[3];
- const int numLoops = ccgDM_getNumLoops(dm);
- int i;
+ /* Avoid re-creation if the layer exists already */
+ tlnors = DM_get_tessface_data_layer(dm, CD_TESSLOOPNORMAL);
+ if (!tlnors) {
+ float(*lnors)[3];
+ short(*tlnors_it)[3];
+ const int numLoops = ccgDM_getNumLoops(dm);
+ int i;
- lnors = dm->getLoopDataArray(dm, CD_NORMAL);
- if (!lnors) {
- return NULL;
- }
+ lnors = dm->getLoopDataArray(dm, CD_NORMAL);
+ if (!lnors) {
+ return NULL;
+ }
- DM_add_tessface_layer(dm, CD_TESSLOOPNORMAL, CD_CALLOC, NULL);
- tlnors = tlnors_it = (short (*)[3])DM_get_tessface_data_layer(dm, CD_TESSLOOPNORMAL);
+ DM_add_tessface_layer(dm, CD_TESSLOOPNORMAL, CD_CALLOC, NULL);
+ tlnors = tlnors_it = (short(*)[3])DM_get_tessface_data_layer(dm, CD_TESSLOOPNORMAL);
- /* With ccgdm, we have a simple one to one mapping between loops and tessellated face corners. */
- for (i = 0; i < numLoops; ++i, ++tlnors_it, ++lnors) {
- normal_float_to_short_v3(*tlnors_it, *lnors);
- }
- }
+ /* With ccgdm, we have a simple one to one mapping between loops and tessellated face corners. */
+ for (i = 0; i < numLoops; ++i, ++tlnors_it, ++lnors) {
+ normal_float_to_short_v3(*tlnors_it, *lnors);
+ }
+ }
- return tlnors;
- }
+ return tlnors;
+ }
- return DM_get_tessface_data_layer(dm, type);
+ return DM_get_tessface_data_layer(dm, type);
}
static void *ccgDM_get_poly_data_layer(DerivedMesh *dm, int type)
{
- if (type == CD_ORIGINDEX) {
- /* create origindex on demand to save memory */
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- CCGSubSurf *ss = ccgdm->ss;
- int *origindex;
- int a, i, index, totface;
- int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
+ if (type == CD_ORIGINDEX) {
+ /* create origindex on demand to save memory */
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ int *origindex;
+ int a, i, index, totface;
+ int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
- /* Avoid re-creation if the layer exists already */
- origindex = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
- if (origindex) {
- return origindex;
- }
+ /* Avoid re-creation if the layer exists already */
+ origindex = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
+ if (origindex) {
+ return origindex;
+ }
- DM_add_poly_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
- origindex = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
+ DM_add_poly_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
+ origindex = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
- totface = ccgSubSurf_getNumFaces(ss);
+ totface = ccgSubSurf_getNumFaces(ss);
- for (a = 0, index = 0; index < totface; index++) {
- CCGFace *f = ccgdm->faceMap[index].face;
- int numVerts = ccgSubSurf_getFaceNumVerts(f);
- int mapIndex = ccgDM_getFaceMapIndex(ss, f);
+ for (a = 0, index = 0; index < totface; index++) {
+ CCGFace *f = ccgdm->faceMap[index].face;
+ int numVerts = ccgSubSurf_getFaceNumVerts(f);
+ int mapIndex = ccgDM_getFaceMapIndex(ss, f);
- for (i = 0; i < gridFaces * gridFaces * numVerts; i++, a++)
- origindex[a] = mapIndex;
- }
+ for (i = 0; i < gridFaces * gridFaces * numVerts; i++, a++)
+ origindex[a] = mapIndex;
+ }
- return origindex;
- }
+ return origindex;
+ }
- return DM_get_poly_data_layer(dm, type);
+ return DM_get_poly_data_layer(dm, type);
}
static void *ccgDM_get_vert_data(DerivedMesh *dm, int index, int type)
{
- if (type == CD_ORIGINDEX) {
- /* ensure creation of CD_ORIGINDEX layer */
- ccgDM_get_vert_data_layer(dm, type);
- }
+ if (type == CD_ORIGINDEX) {
+ /* ensure creation of CD_ORIGINDEX layer */
+ ccgDM_get_vert_data_layer(dm, type);
+ }
- return DM_get_vert_data(dm, index, type);
+ return DM_get_vert_data(dm, index, type);
}
static void *ccgDM_get_edge_data(DerivedMesh *dm, int index, int type)
{
- if (type == CD_ORIGINDEX) {
- /* ensure creation of CD_ORIGINDEX layer */
- ccgDM_get_edge_data_layer(dm, type);
- }
+ if (type == CD_ORIGINDEX) {
+ /* ensure creation of CD_ORIGINDEX layer */
+ ccgDM_get_edge_data_layer(dm, type);
+ }
- return DM_get_edge_data(dm, index, type);
+ return DM_get_edge_data(dm, index, type);
}
static void *ccgDM_get_tessface_data(DerivedMesh *dm, int index, int type)
{
- if (ELEM(type, CD_ORIGINDEX, CD_TESSLOOPNORMAL)) {
- /* ensure creation of CD_ORIGINDEX/CD_TESSLOOPNORMAL layers */
- ccgDM_get_tessface_data_layer(dm, type);
- }
+ if (ELEM(type, CD_ORIGINDEX, CD_TESSLOOPNORMAL)) {
+ /* ensure creation of CD_ORIGINDEX/CD_TESSLOOPNORMAL layers */
+ ccgDM_get_tessface_data_layer(dm, type);
+ }
- return DM_get_tessface_data(dm, index, type);
+ return DM_get_tessface_data(dm, index, type);
}
static void *ccgDM_get_poly_data(DerivedMesh *dm, int index, int type)
{
- if (type == CD_ORIGINDEX) {
- /* ensure creation of CD_ORIGINDEX layer */
- ccgDM_get_tessface_data_layer(dm, type);
- }
+ if (type == CD_ORIGINDEX) {
+ /* ensure creation of CD_ORIGINDEX layer */
+ ccgDM_get_tessface_data_layer(dm, type);
+ }
- return DM_get_poly_data(dm, index, type);
+ return DM_get_poly_data(dm, index, type);
}
static int ccgDM_getNumGrids(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- int index, numFaces, numGrids;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ int index, numFaces, numGrids;
- numFaces = ccgSubSurf_getNumFaces(ccgdm->ss);
- numGrids = 0;
+ numFaces = ccgSubSurf_getNumFaces(ccgdm->ss);
+ numGrids = 0;
- for (index = 0; index < numFaces; index++) {
- CCGFace *f = ccgdm->faceMap[index].face;
- numGrids += ccgSubSurf_getFaceNumVerts(f);
- }
+ for (index = 0; index < numFaces; index++) {
+ CCGFace *f = ccgdm->faceMap[index].face;
+ numGrids += ccgSubSurf_getFaceNumVerts(f);
+ }
- return numGrids;
+ return numGrids;
}
static int ccgDM_getGridSize(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- return ccgSubSurf_getGridSize(ccgdm->ss);
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ return ccgSubSurf_getGridSize(ccgdm->ss);
}
static void ccgdm_create_grids(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGElem **gridData;
- DMFlagMat *gridFlagMats;
- CCGFace **gridFaces;
- int *gridOffset;
- int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ CCGElem **gridData;
+ DMFlagMat *gridFlagMats;
+ CCGFace **gridFaces;
+ int *gridOffset;
+ int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
- if (ccgdm->gridData)
- return;
+ if (ccgdm->gridData)
+ return;
- numGrids = ccgDM_getNumGrids(dm);
- numFaces = ccgSubSurf_getNumFaces(ss);
- /*gridSize = ccgDM_getGridSize(dm);*/ /*UNUSED*/
+ numGrids = ccgDM_getNumGrids(dm);
+ numFaces = ccgSubSurf_getNumFaces(ss);
+ /*gridSize = ccgDM_getGridSize(dm);*/ /*UNUSED*/
- /* compute offset into grid array for each face */
- gridOffset = MEM_mallocN(sizeof(int) * numFaces, "ccgdm.gridOffset");
+ /* compute offset into grid array for each face */
+ gridOffset = MEM_mallocN(sizeof(int) * numFaces, "ccgdm.gridOffset");
- for (gIndex = 0, index = 0; index < numFaces; index++) {
- CCGFace *f = ccgdm->faceMap[index].face;
- int numVerts = ccgSubSurf_getFaceNumVerts(f);
+ for (gIndex = 0, index = 0; index < numFaces; index++) {
+ CCGFace *f = ccgdm->faceMap[index].face;
+ int numVerts = ccgSubSurf_getFaceNumVerts(f);
- gridOffset[index] = gIndex;
- gIndex += numVerts;
- }
+ gridOffset[index] = gIndex;
+ gIndex += numVerts;
+ }
- /* compute grid data */
- gridData = MEM_mallocN(sizeof(CCGElem *) * numGrids, "ccgdm.gridData");
- gridFaces = MEM_mallocN(sizeof(CCGFace *) * numGrids, "ccgdm.gridFaces");
- gridFlagMats = MEM_mallocN(sizeof(DMFlagMat) * numGrids, "ccgdm.gridFlagMats");
+ /* compute grid data */
+ gridData = MEM_mallocN(sizeof(CCGElem *) * numGrids, "ccgdm.gridData");
+ gridFaces = MEM_mallocN(sizeof(CCGFace *) * numGrids, "ccgdm.gridFaces");
+ gridFlagMats = MEM_mallocN(sizeof(DMFlagMat) * numGrids, "ccgdm.gridFlagMats");
- ccgdm->gridHidden = MEM_callocN(sizeof(*ccgdm->gridHidden) * numGrids, "ccgdm.gridHidden");
+ ccgdm->gridHidden = MEM_callocN(sizeof(*ccgdm->gridHidden) * numGrids, "ccgdm.gridHidden");
- for (gIndex = 0, index = 0; index < numFaces; index++) {
- CCGFace *f = ccgdm->faceMap[index].face;
- int numVerts = ccgSubSurf_getFaceNumVerts(f);
+ for (gIndex = 0, index = 0; index < numFaces; index++) {
+ CCGFace *f = ccgdm->faceMap[index].face;
+ int numVerts = ccgSubSurf_getFaceNumVerts(f);
- for (S = 0; S < numVerts; S++, gIndex++) {
- gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
- gridFaces[gIndex] = f;
- gridFlagMats[gIndex] = ccgdm->faceFlags[index];
- }
- }
+ for (S = 0; S < numVerts; S++, gIndex++) {
+ gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
+ gridFaces[gIndex] = f;
+ gridFlagMats[gIndex] = ccgdm->faceFlags[index];
+ }
+ }
- ccgdm->gridData = gridData;
- ccgdm->gridFaces = gridFaces;
- ccgdm->gridOffset = gridOffset;
- ccgdm->gridFlagMats = gridFlagMats;
- ccgdm->numGrid = numGrids;
+ ccgdm->gridData = gridData;
+ ccgdm->gridFaces = gridFaces;
+ ccgdm->gridOffset = gridOffset;
+ ccgdm->gridFlagMats = gridFlagMats;
+ ccgdm->numGrid = numGrids;
}
static CCGElem **ccgDM_getGridData(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- ccgdm_create_grids(dm);
- return ccgdm->gridData;
+ ccgdm_create_grids(dm);
+ return ccgdm->gridData;
}
static int *ccgDM_getGridOffset(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- ccgdm_create_grids(dm);
- return ccgdm->gridOffset;
+ ccgdm_create_grids(dm);
+ return ccgdm->gridOffset;
}
static void ccgDM_getGridKey(DerivedMesh *dm, CCGKey *key)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- CCG_key_top_level(key, ccgdm->ss);
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCG_key_top_level(key, ccgdm->ss);
}
static DMFlagMat *ccgDM_getGridFlagMats(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- ccgdm_create_grids(dm);
- return ccgdm->gridFlagMats;
+ ccgdm_create_grids(dm);
+ return ccgdm->gridFlagMats;
}
static BLI_bitmap **ccgDM_getGridHidden(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- ccgdm_create_grids(dm);
- return ccgdm->gridHidden;
+ ccgdm_create_grids(dm);
+ return ccgdm->gridHidden;
}
static const MeshElemMap *ccgDM_getPolyMap(Object *ob, DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- if (!ccgdm->multires.mmd && !ccgdm->pmap && ob->type == OB_MESH) {
- Mesh *me = ob->data;
+ if (!ccgdm->multires.mmd && !ccgdm->pmap && ob->type == OB_MESH) {
+ Mesh *me = ob->data;
- BKE_mesh_vert_poly_map_create(&ccgdm->pmap, &ccgdm->pmap_mem,
- me->mpoly, me->mloop,
- me->totvert, me->totpoly, me->totloop);
- }
+ BKE_mesh_vert_poly_map_create(&ccgdm->pmap,
+ &ccgdm->pmap_mem,
+ me->mpoly,
+ me->mloop,
+ me->totvert,
+ me->totpoly,
+ me->totloop);
+ }
- return ccgdm->pmap;
+ return ccgdm->pmap;
}
static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
{
- MultiresModifierData *mmd = ccgdm->multires.mmd;
+ MultiresModifierData *mmd = ccgdm->multires.mmd;
- /* both of multires and subsurf modifiers are CCG, but
- * grids should only be used when sculpting on multires */
- if (!mmd)
- return 0;
+ /* both of multires and subsurf modifiers are CCG, but
+ * grids should only be used when sculpting on multires */
+ if (!mmd)
+ return 0;
- return 1;
+ return 1;
}
static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- CCGKey key;
- int numGrids;
-
- CCG_key_top_level(&key, ccgdm->ss);
-
- if (!ob) {
- ccgdm->pbvh = NULL;
- return NULL;
- }
-
- if (!ob->sculpt)
- return NULL;
-
- bool grid_pbvh = ccgDM_use_grid_pbvh(ccgdm);
- if ((ob->mode & OB_MODE_SCULPT) == 0) {
- /* In vwpaint, we may use a grid_pbvh for multires/subsurf, under certain conditions.
- * More complex cases break 'history' trail back to original vertices, in that case we fall back to
- * deformed cage only (i.e. original deformed mesh). */
- VirtualModifierData virtualModifierData;
- ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
-
- grid_pbvh = true;
- bool has_one_ccg_modifier = false;
- for (; md; md = md->next) {
- /* We can only accept to use this ccgdm if:
- * - it's the only active ccgdm in the stack.
- * - there is no topology-modifying modifier in the stack.
- * Otherwise, there is no way to map back to original geometry from grid-generated PBVH.
- */
- const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
-
- if (!modifier_isEnabled(NULL, md, eModifierMode_Realtime)) {
- continue;
- }
- if (ELEM(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_NonGeometrical)) {
- continue;
- }
-
- if (ELEM(md->type, eModifierType_Subsurf, eModifierType_Multires)) {
- if (has_one_ccg_modifier) {
- /* We only allow a single active ccg modifier in the stack. */
- grid_pbvh = false;
- break;
- }
- has_one_ccg_modifier = true;
- continue;
- }
-
- /* Any other non-deforming modifier makes it impossible to use grid pbvh. */
- grid_pbvh = false;
- break;
- }
- }
-
- if (ob->sculpt->pbvh) {
- /* Note that we have to clean up exisitng pbvh instead of updating it in case it does not match current
- * grid_pbvh status. */
- const PBVHType pbvh_type = BKE_pbvh_type(ob->sculpt->pbvh);
- if (grid_pbvh) {
- if (pbvh_type == PBVH_GRIDS) {
- /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
- * but this can be freed on ccgdm release, this updates the pointers
- * when the ccgdm gets remade, the assumption is that the topology
- * does not change. */
- ccgdm_create_grids(dm);
- BKE_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, (void **)ccgdm->gridFaces,
- ccgdm->gridFlagMats, ccgdm->gridHidden);
- }
- else {
- BKE_pbvh_free(ob->sculpt->pbvh);
- ob->sculpt->pbvh = NULL;
- }
- }
- else if (pbvh_type == PBVH_GRIDS) {
- BKE_pbvh_free(ob->sculpt->pbvh);
- ob->sculpt->pbvh = NULL;
- }
-
- ccgdm->pbvh = ob->sculpt->pbvh;
- }
-
- if (ccgdm->pbvh) {
- return ccgdm->pbvh;
- }
-
- /* No pbvh exists yet, we need to create one. only in case of multires
- * we build a pbvh over the modified mesh, in other cases the base mesh
- * is being sculpted, so we build a pbvh from that. */
- /* Note: vwpaint tries to always build a pbvh over the modified mesh. */
- if (grid_pbvh) {
- ccgdm_create_grids(dm);
-
- numGrids = ccgDM_getNumGrids(dm);
-
- ob->sculpt->pbvh = ccgdm->pbvh = BKE_pbvh_new();
- BKE_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData,
- numGrids, &key, (void **) ccgdm->gridFaces, ccgdm->gridFlagMats, ccgdm->gridHidden);
- }
- else if (ob->type == OB_MESH) {
- Mesh *me = BKE_object_get_original_mesh(ob);
- const int looptris_num = poly_to_tri_count(me->totpoly, me->totloop);
- MLoopTri *looptri;
-
- looptri = MEM_mallocN(sizeof(*looptri) * looptris_num, __func__);
-
- BKE_mesh_recalc_looptri(
- me->mloop, me->mpoly,
- me->mvert,
- me->totloop, me->totpoly,
- looptri);
-
- ob->sculpt->pbvh = ccgdm->pbvh = BKE_pbvh_new();
- BKE_pbvh_build_mesh(ccgdm->pbvh, me->mpoly, me->mloop, me->mvert, me->totvert, &me->vdata,
- looptri, looptris_num);
-
- if (ob->sculpt->modifiers_active && ob->derivedDeform != NULL) {
- DerivedMesh *deformdm = ob->derivedDeform;
- float (*vertCos)[3];
- int totvert;
-
- totvert = deformdm->getNumVerts(deformdm);
- vertCos = MEM_malloc_arrayN(totvert, sizeof(float[3]), "ccgDM_getPBVH vertCos");
- deformdm->getVertCos(deformdm, vertCos);
- BKE_pbvh_apply_vertCos(ccgdm->pbvh, vertCos, totvert);
- MEM_freeN(vertCos);
- }
- }
-
- if (ccgdm->pbvh != NULL) {
- pbvh_show_diffuse_color_set(ccgdm->pbvh, ob->sculpt->show_diffuse_color);
- pbvh_show_mask_set(ccgdm->pbvh, ob->sculpt->show_mask);
- }
-
- return ccgdm->pbvh;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGKey key;
+ int numGrids;
+
+ CCG_key_top_level(&key, ccgdm->ss);
+
+ if (!ob) {
+ ccgdm->pbvh = NULL;
+ return NULL;
+ }
+
+ if (!ob->sculpt)
+ return NULL;
+
+ bool grid_pbvh = ccgDM_use_grid_pbvh(ccgdm);
+ if ((ob->mode & OB_MODE_SCULPT) == 0) {
+ /* In vwpaint, we may use a grid_pbvh for multires/subsurf, under certain conditions.
+ * More complex cases break 'history' trail back to original vertices, in that case we fall back to
+ * deformed cage only (i.e. original deformed mesh). */
+ VirtualModifierData virtualModifierData;
+ ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
+
+ grid_pbvh = true;
+ bool has_one_ccg_modifier = false;
+ for (; md; md = md->next) {
+ /* We can only accept to use this ccgdm if:
+ * - it's the only active ccgdm in the stack.
+ * - there is no topology-modifying modifier in the stack.
+ * Otherwise, there is no way to map back to original geometry from grid-generated PBVH.
+ */
+ const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+
+ if (!modifier_isEnabled(NULL, md, eModifierMode_Realtime)) {
+ continue;
+ }
+ if (ELEM(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_NonGeometrical)) {
+ continue;
+ }
+
+ if (ELEM(md->type, eModifierType_Subsurf, eModifierType_Multires)) {
+ if (has_one_ccg_modifier) {
+ /* We only allow a single active ccg modifier in the stack. */
+ grid_pbvh = false;
+ break;
+ }
+ has_one_ccg_modifier = true;
+ continue;
+ }
+
+ /* Any other non-deforming modifier makes it impossible to use grid pbvh. */
+ grid_pbvh = false;
+ break;
+ }
+ }
+
+ if (ob->sculpt->pbvh) {
+ /* Note that we have to clean up exisitng pbvh instead of updating it in case it does not match current
+ * grid_pbvh status. */
+ const PBVHType pbvh_type = BKE_pbvh_type(ob->sculpt->pbvh);
+ if (grid_pbvh) {
+ if (pbvh_type == PBVH_GRIDS) {
+ /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
+ * but this can be freed on ccgdm release, this updates the pointers
+ * when the ccgdm gets remade, the assumption is that the topology
+ * does not change. */
+ ccgdm_create_grids(dm);
+ BKE_pbvh_grids_update(ob->sculpt->pbvh,
+ ccgdm->gridData,
+ (void **)ccgdm->gridFaces,
+ ccgdm->gridFlagMats,
+ ccgdm->gridHidden);
+ }
+ else {
+ BKE_pbvh_free(ob->sculpt->pbvh);
+ ob->sculpt->pbvh = NULL;
+ }
+ }
+ else if (pbvh_type == PBVH_GRIDS) {
+ BKE_pbvh_free(ob->sculpt->pbvh);
+ ob->sculpt->pbvh = NULL;
+ }
+
+ ccgdm->pbvh = ob->sculpt->pbvh;
+ }
+
+ if (ccgdm->pbvh) {
+ return ccgdm->pbvh;
+ }
+
+ /* No pbvh exists yet, we need to create one. only in case of multires
+ * we build a pbvh over the modified mesh, in other cases the base mesh
+ * is being sculpted, so we build a pbvh from that. */
+ /* Note: vwpaint tries to always build a pbvh over the modified mesh. */
+ if (grid_pbvh) {
+ ccgdm_create_grids(dm);
+
+ numGrids = ccgDM_getNumGrids(dm);
+
+ ob->sculpt->pbvh = ccgdm->pbvh = BKE_pbvh_new();
+ BKE_pbvh_build_grids(ccgdm->pbvh,
+ ccgdm->gridData,
+ numGrids,
+ &key,
+ (void **)ccgdm->gridFaces,
+ ccgdm->gridFlagMats,
+ ccgdm->gridHidden);
+ }
+ else if (ob->type == OB_MESH) {
+ Mesh *me = BKE_object_get_original_mesh(ob);
+ const int looptris_num = poly_to_tri_count(me->totpoly, me->totloop);
+ MLoopTri *looptri;
+
+ looptri = MEM_mallocN(sizeof(*looptri) * looptris_num, __func__);
+
+ BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri);
+
+ ob->sculpt->pbvh = ccgdm->pbvh = BKE_pbvh_new();
+ BKE_pbvh_build_mesh(ccgdm->pbvh,
+ me->mpoly,
+ me->mloop,
+ me->mvert,
+ me->totvert,
+ &me->vdata,
+ looptri,
+ looptris_num);
+
+ if (ob->sculpt->modifiers_active && ob->derivedDeform != NULL) {
+ DerivedMesh *deformdm = ob->derivedDeform;
+ float(*vertCos)[3];
+ int totvert;
+
+ totvert = deformdm->getNumVerts(deformdm);
+ vertCos = MEM_malloc_arrayN(totvert, sizeof(float[3]), "ccgDM_getPBVH vertCos");
+ deformdm->getVertCos(deformdm, vertCos);
+ BKE_pbvh_apply_vertCos(ccgdm->pbvh, vertCos, totvert);
+ MEM_freeN(vertCos);
+ }
+ }
+
+ if (ccgdm->pbvh != NULL) {
+ pbvh_show_diffuse_color_set(ccgdm->pbvh, ob->sculpt->show_diffuse_color);
+ pbvh_show_mask_set(ccgdm->pbvh, ob->sculpt->show_mask);
+ }
+
+ return ccgdm->pbvh;
}
static void ccgDM_recalcTessellation(DerivedMesh *UNUSED(dm))
{
- /* Nothing to do: CCG handles creating its own tessfaces */
+ /* Nothing to do: CCG handles creating its own tessfaces */
}
/* WARNING! *MUST* be called in an 'loops_cache_rwlock' protected thread context! */
static void ccgDM_recalcLoopTri(DerivedMesh *dm)
{
- MLoopTri *mlooptri = dm->looptris.array;
- const int tottri = dm->numPolyData * 2;
- int i, poly_index;
+ MLoopTri *mlooptri = dm->looptris.array;
+ const int tottri = dm->numPolyData * 2;
+ int i, poly_index;
- DM_ensure_looptri_data(dm);
- mlooptri = dm->looptris.array_wip;
+ DM_ensure_looptri_data(dm);
+ mlooptri = dm->looptris.array_wip;
- BLI_assert(tottri == 0 || mlooptri != NULL);
- BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
- BLI_assert(tottri == dm->looptris.num);
+ BLI_assert(tottri == 0 || mlooptri != NULL);
+ BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
+ BLI_assert(tottri == dm->looptris.num);
- for (i = 0, poly_index = 0; i < tottri; i += 2, poly_index += 1) {
- MLoopTri *lt;
- lt = &mlooptri[i];
- /* quad is (0, 3, 2, 1) */
- lt->tri[0] = (poly_index * 4) + 0;
- lt->tri[1] = (poly_index * 4) + 2;
- lt->tri[2] = (poly_index * 4) + 3;
- lt->poly = poly_index;
+ for (i = 0, poly_index = 0; i < tottri; i += 2, poly_index += 1) {
+ MLoopTri *lt;
+ lt = &mlooptri[i];
+ /* quad is (0, 3, 2, 1) */
+ lt->tri[0] = (poly_index * 4) + 0;
+ lt->tri[1] = (poly_index * 4) + 2;
+ lt->tri[2] = (poly_index * 4) + 3;
+ lt->poly = poly_index;
- lt = &mlooptri[i + 1];
- lt->tri[0] = (poly_index * 4) + 0;
- lt->tri[1] = (poly_index * 4) + 1;
- lt->tri[2] = (poly_index * 4) + 2;
- lt->poly = poly_index;
- }
+ lt = &mlooptri[i + 1];
+ lt->tri[0] = (poly_index * 4) + 0;
+ lt->tri[1] = (poly_index * 4) + 1;
+ lt->tri[2] = (poly_index * 4) + 2;
+ lt->poly = poly_index;
+ }
- BLI_assert(dm->looptris.array == NULL);
- atomic_cas_ptr((void **)&dm->looptris.array, dm->looptris.array, dm->looptris.array_wip);
- dm->looptris.array_wip = NULL;
+ BLI_assert(dm->looptris.array == NULL);
+ atomic_cas_ptr((void **)&dm->looptris.array, dm->looptris.array, dm->looptris.array_wip);
+ dm->looptris.array_wip = NULL;
}
static void ccgDM_calcNormals(DerivedMesh *dm)
{
- /* Nothing to do: CCG calculates normals during drawing */
- dm->dirty &= ~DM_DIRTY_NORMALS;
+ /* Nothing to do: CCG calculates normals during drawing */
+ dm->dirty &= ~DM_DIRTY_NORMALS;
}
static void set_default_ccgdm_callbacks(CCGDerivedMesh *ccgdm)
{
- ccgdm->dm.getMinMax = ccgDM_getMinMax;
- ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
- ccgdm->dm.getNumEdges = ccgDM_getNumEdges;
- ccgdm->dm.getNumLoops = ccgDM_getNumLoops;
- /* reuse of ccgDM_getNumTessFaces is intentional here: subsurf polys are just created from tessfaces */
- ccgdm->dm.getNumPolys = ccgDM_getNumPolys;
- ccgdm->dm.getNumTessFaces = ccgDM_getNumTessFaces;
-
- ccgdm->dm.getVert = ccgDM_getFinalVert;
- ccgdm->dm.getEdge = ccgDM_getFinalEdge;
- ccgdm->dm.getTessFace = ccgDM_getFinalFace;
-
- ccgdm->dm.getVertCo = ccgDM_getFinalVertCo;
- ccgdm->dm.getVertNo = ccgDM_getFinalVertNo;
-
- ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
- ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
- ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray;
- ccgdm->dm.copyLoopArray = ccgDM_copyFinalLoopArray;
- ccgdm->dm.copyPolyArray = ccgDM_copyFinalPolyArray;
-
- ccgdm->dm.getVertData = ccgDM_get_vert_data;
- ccgdm->dm.getEdgeData = ccgDM_get_edge_data;
- ccgdm->dm.getTessFaceData = ccgDM_get_tessface_data;
- ccgdm->dm.getPolyData = ccgDM_get_poly_data;
- ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;
- ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer;
- ccgdm->dm.getTessFaceDataArray = ccgDM_get_tessface_data_layer;
- ccgdm->dm.getPolyDataArray = ccgDM_get_poly_data_layer;
- ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
- ccgdm->dm.getGridSize = ccgDM_getGridSize;
- ccgdm->dm.getGridData = ccgDM_getGridData;
- ccgdm->dm.getGridOffset = ccgDM_getGridOffset;
- ccgdm->dm.getGridKey = ccgDM_getGridKey;
- ccgdm->dm.getGridFlagMats = ccgDM_getGridFlagMats;
- ccgdm->dm.getGridHidden = ccgDM_getGridHidden;
- ccgdm->dm.getPolyMap = ccgDM_getPolyMap;
- ccgdm->dm.getPBVH = ccgDM_getPBVH;
-
- ccgdm->dm.calcNormals = ccgDM_calcNormals;
- ccgdm->dm.calcLoopNormals = CDDM_calc_loop_normals;
- ccgdm->dm.calcLoopNormalsSpaceArray = CDDM_calc_loop_normals_spacearr;
- ccgdm->dm.calcLoopTangents = DM_calc_loop_tangents;
- ccgdm->dm.recalcTessellation = ccgDM_recalcTessellation;
- ccgdm->dm.recalcLoopTri = ccgDM_recalcLoopTri;
-
- ccgdm->dm.getVertCos = ccgdm_getVertCos;
- ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert;
- ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge;
- ccgdm->dm.foreachMappedLoop = ccgDM_foreachMappedLoop;
- ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter;
-
- ccgdm->dm.release = ccgDM_release;
-}
-
-static void create_ccgdm_maps(CCGDerivedMesh *ccgdm,
- CCGSubSurf *ss)
-{
- CCGVertIterator vi;
- CCGEdgeIterator ei;
- CCGFaceIterator fi;
- int totvert, totedge, totface;
-
- totvert = ccgSubSurf_getNumVerts(ss);
- ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
- for (ccgSubSurf_initVertIterator(ss, &vi);
- !ccgVertIterator_isStopped(&vi);
- ccgVertIterator_next(&vi))
- {
- CCGVert *v = ccgVertIterator_getCurrent(&vi);
-
- ccgdm->vertMap[POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v))].vert = v;
- }
-
- totedge = ccgSubSurf_getNumEdges(ss);
- ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
- for (ccgSubSurf_initEdgeIterator(ss, &ei);
- !ccgEdgeIterator_isStopped(&ei);
- ccgEdgeIterator_next(&ei))
- {
- CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
-
- ccgdm->edgeMap[POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
- }
-
- totface = ccgSubSurf_getNumFaces(ss);
- ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
- for (ccgSubSurf_initFaceIterator(ss, &fi);
- !ccgFaceIterator_isStopped(&fi);
- ccgFaceIterator_next(&fi))
- {
- CCGFace *f = ccgFaceIterator_getCurrent(&fi);
-
- ccgdm->faceMap[POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f))].face = f;
- }
+ ccgdm->dm.getMinMax = ccgDM_getMinMax;
+ ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
+ ccgdm->dm.getNumEdges = ccgDM_getNumEdges;
+ ccgdm->dm.getNumLoops = ccgDM_getNumLoops;
+ /* reuse of ccgDM_getNumTessFaces is intentional here: subsurf polys are just created from tessfaces */
+ ccgdm->dm.getNumPolys = ccgDM_getNumPolys;
+ ccgdm->dm.getNumTessFaces = ccgDM_getNumTessFaces;
+
+ ccgdm->dm.getVert = ccgDM_getFinalVert;
+ ccgdm->dm.getEdge = ccgDM_getFinalEdge;
+ ccgdm->dm.getTessFace = ccgDM_getFinalFace;
+
+ ccgdm->dm.getVertCo = ccgDM_getFinalVertCo;
+ ccgdm->dm.getVertNo = ccgDM_getFinalVertNo;
+
+ ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
+ ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
+ ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray;
+ ccgdm->dm.copyLoopArray = ccgDM_copyFinalLoopArray;
+ ccgdm->dm.copyPolyArray = ccgDM_copyFinalPolyArray;
+
+ ccgdm->dm.getVertData = ccgDM_get_vert_data;
+ ccgdm->dm.getEdgeData = ccgDM_get_edge_data;
+ ccgdm->dm.getTessFaceData = ccgDM_get_tessface_data;
+ ccgdm->dm.getPolyData = ccgDM_get_poly_data;
+ ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;
+ ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer;
+ ccgdm->dm.getTessFaceDataArray = ccgDM_get_tessface_data_layer;
+ ccgdm->dm.getPolyDataArray = ccgDM_get_poly_data_layer;
+ ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
+ ccgdm->dm.getGridSize = ccgDM_getGridSize;
+ ccgdm->dm.getGridData = ccgDM_getGridData;
+ ccgdm->dm.getGridOffset = ccgDM_getGridOffset;
+ ccgdm->dm.getGridKey = ccgDM_getGridKey;
+ ccgdm->dm.getGridFlagMats = ccgDM_getGridFlagMats;
+ ccgdm->dm.getGridHidden = ccgDM_getGridHidden;
+ ccgdm->dm.getPolyMap = ccgDM_getPolyMap;
+ ccgdm->dm.getPBVH = ccgDM_getPBVH;
+
+ ccgdm->dm.calcNormals = ccgDM_calcNormals;
+ ccgdm->dm.calcLoopNormals = CDDM_calc_loop_normals;
+ ccgdm->dm.calcLoopNormalsSpaceArray = CDDM_calc_loop_normals_spacearr;
+ ccgdm->dm.calcLoopTangents = DM_calc_loop_tangents;
+ ccgdm->dm.recalcTessellation = ccgDM_recalcTessellation;
+ ccgdm->dm.recalcLoopTri = ccgDM_recalcLoopTri;
+
+ ccgdm->dm.getVertCos = ccgdm_getVertCos;
+ ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert;
+ ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge;
+ ccgdm->dm.foreachMappedLoop = ccgDM_foreachMappedLoop;
+ ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter;
+
+ ccgdm->dm.release = ccgDM_release;
+}
+
+static void create_ccgdm_maps(CCGDerivedMesh *ccgdm, CCGSubSurf *ss)
+{
+ CCGVertIterator vi;
+ CCGEdgeIterator ei;
+ CCGFaceIterator fi;
+ int totvert, totedge, totface;
+
+ totvert = ccgSubSurf_getNumVerts(ss);
+ ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
+ for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi);
+ ccgVertIterator_next(&vi)) {
+ CCGVert *v = ccgVertIterator_getCurrent(&vi);
+
+ ccgdm->vertMap[POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v))].vert = v;
+ }
+
+ totedge = ccgSubSurf_getNumEdges(ss);
+ ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
+ for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei);
+ ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
+
+ ccgdm->edgeMap[POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
+ }
+
+ totface = ccgSubSurf_getNumFaces(ss);
+ ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
+ for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi);
+ ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
+
+ ccgdm->faceMap[POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f))].face = f;
+ }
}
/* Fill in all geometry arrays making it possible to access any
@@ -2463,383 +2483,373 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
DerivedMesh *dm,
bool useSubsurfUv)
{
- const int totvert = ccgSubSurf_getNumVerts(ss);
- const int totedge = ccgSubSurf_getNumEdges(ss);
- const int totface = ccgSubSurf_getNumFaces(ss);
- int index;
- int i;
- int vertNum = 0, edgeNum = 0, faceNum = 0;
- int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex, *base_polyOrigIndex, *edgeOrigIndex;
- short *edgeFlags = ccgdm->edgeFlags;
- DMFlagMat *faceFlags = ccgdm->faceFlags;
- int *polyidx = NULL;
+ const int totvert = ccgSubSurf_getNumVerts(ss);
+ const int totedge = ccgSubSurf_getNumEdges(ss);
+ const int totface = ccgSubSurf_getNumFaces(ss);
+ int index;
+ int i;
+ int vertNum = 0, edgeNum = 0, faceNum = 0;
+ int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex, *base_polyOrigIndex, *edgeOrigIndex;
+ short *edgeFlags = ccgdm->edgeFlags;
+ DMFlagMat *faceFlags = ccgdm->faceFlags;
+ int *polyidx = NULL;
#ifndef USE_DYNSIZE
- int *loopidx = NULL, *vertidx = NULL;
- BLI_array_declare(loopidx);
- BLI_array_declare(vertidx);
+ int *loopidx = NULL, *vertidx = NULL;
+ BLI_array_declare(loopidx);
+ BLI_array_declare(vertidx);
#endif
- int loopindex, loopindex2;
- int edgeSize;
- int gridSize;
- int gridFaces, gridCuts;
- int gridSideEdges;
- int gridInternalEdges;
- WeightTable wtable = {NULL};
- MEdge *medge = NULL;
- MPoly *mpoly = NULL;
- bool has_edge_cd;
-
- edgeSize = ccgSubSurf_getEdgeSize(ss);
- gridSize = ccgSubSurf_getGridSize(ss);
- gridFaces = gridSize - 1;
- gridCuts = gridSize - 2;
- /*gridInternalVerts = gridSideVerts * gridSideVerts; - as yet, unused */
- gridSideEdges = gridSize - 1;
- gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
-
- /* mvert = dm->getVertArray(dm); */ /* UNUSED */
- medge = dm->getEdgeArray(dm);
- /* mface = dm->getTessFaceArray(dm); */ /* UNUSED */
-
- mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
- base_polyOrigIndex = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
-
- vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX);
- edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX);
-
- faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX);
- polyOrigIndex = DM_get_poly_data_layer(&ccgdm->dm, CD_ORIGINDEX);
-
- has_edge_cd = ((ccgdm->dm.edgeData.totlayer - (edgeOrigIndex ? 1 : 0)) != 0);
-
- loopindex = loopindex2 = 0; /* current loop index */
- for (index = 0; index < totface; index++) {
- CCGFace *f = ccgdm->faceMap[index].face;
- int numVerts = ccgSubSurf_getFaceNumVerts(f);
- int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
- int origIndex = POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f));
- int g2_wid = gridCuts + 2;
- float *w, *w2;
- int s, x, y;
+ int loopindex, loopindex2;
+ int edgeSize;
+ int gridSize;
+ int gridFaces, gridCuts;
+ int gridSideEdges;
+ int gridInternalEdges;
+ WeightTable wtable = {NULL};
+ MEdge *medge = NULL;
+ MPoly *mpoly = NULL;
+ bool has_edge_cd;
+
+ edgeSize = ccgSubSurf_getEdgeSize(ss);
+ gridSize = ccgSubSurf_getGridSize(ss);
+ gridFaces = gridSize - 1;
+ gridCuts = gridSize - 2;
+ /*gridInternalVerts = gridSideVerts * gridSideVerts; - as yet, unused */
+ gridSideEdges = gridSize - 1;
+ gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
+
+ /* mvert = dm->getVertArray(dm); */ /* UNUSED */
+ medge = dm->getEdgeArray(dm);
+ /* mface = dm->getTessFaceArray(dm); */ /* UNUSED */
+
+ mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
+ base_polyOrigIndex = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
+
+ vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX);
+ edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX);
+
+ faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX);
+ polyOrigIndex = DM_get_poly_data_layer(&ccgdm->dm, CD_ORIGINDEX);
+
+ has_edge_cd = ((ccgdm->dm.edgeData.totlayer - (edgeOrigIndex ? 1 : 0)) != 0);
+
+ loopindex = loopindex2 = 0; /* current loop index */
+ for (index = 0; index < totface; index++) {
+ CCGFace *f = ccgdm->faceMap[index].face;
+ int numVerts = ccgSubSurf_getFaceNumVerts(f);
+ int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
+ int origIndex = POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f));
+ int g2_wid = gridCuts + 2;
+ float *w, *w2;
+ int s, x, y;
#ifdef USE_DYNSIZE
- int loopidx[numVerts], vertidx[numVerts];
+ int loopidx[numVerts], vertidx[numVerts];
#endif
- w = get_ss_weights(&wtable, gridCuts, numVerts);
+ w = get_ss_weights(&wtable, gridCuts, numVerts);
- ccgdm->faceMap[index].startVert = vertNum;
- ccgdm->faceMap[index].startEdge = edgeNum;
- ccgdm->faceMap[index].startFace = faceNum;
+ ccgdm->faceMap[index].startVert = vertNum;
+ ccgdm->faceMap[index].startEdge = edgeNum;
+ ccgdm->faceMap[index].startFace = faceNum;
- faceFlags->flag = mpoly ? mpoly[origIndex].flag : 0;
- faceFlags->mat_nr = mpoly ? mpoly[origIndex].mat_nr : 0;
- faceFlags++;
+ faceFlags->flag = mpoly ? mpoly[origIndex].flag : 0;
+ faceFlags->mat_nr = mpoly ? mpoly[origIndex].mat_nr : 0;
+ faceFlags++;
- /* set the face base vert */
- *((int *)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
+ /* set the face base vert */
+ *((int *)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
#ifndef USE_DYNSIZE
- BLI_array_clear(loopidx);
- BLI_array_grow_items(loopidx, numVerts);
+ BLI_array_clear(loopidx);
+ BLI_array_grow_items(loopidx, numVerts);
#endif
- for (s = 0; s < numVerts; s++) {
- loopidx[s] = loopindex++;
- }
+ for (s = 0; s < numVerts; s++) {
+ loopidx[s] = loopindex++;
+ }
#ifndef USE_DYNSIZE
- BLI_array_clear(vertidx);
- BLI_array_grow_items(vertidx, numVerts);
+ BLI_array_clear(vertidx);
+ BLI_array_grow_items(vertidx, numVerts);
#endif
- for (s = 0; s < numVerts; s++) {
- CCGVert *v = ccgSubSurf_getFaceVert(f, s);
- vertidx[s] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
- }
-
- /*I think this is for interpolating the center vert?*/
- w2 = w; // + numVerts*(g2_wid-1) * (g2_wid-1); //numVerts*((g2_wid-1) * g2_wid+g2_wid-1);
- DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
- numVerts, vertNum);
- if (vertOrigIndex) {
- *vertOrigIndex = ORIGINDEX_NONE;
- vertOrigIndex++;
- }
-
- vertNum++;
-
- /*interpolate per-vert data*/
- for (s = 0; s < numVerts; s++) {
- for (x = 1; x < gridFaces; x++) {
- w2 = w + s * numVerts * g2_wid * g2_wid + x * numVerts;
- DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
- numVerts, vertNum);
-
- if (vertOrigIndex) {
- *vertOrigIndex = ORIGINDEX_NONE;
- vertOrigIndex++;
- }
-
- vertNum++;
- }
- }
-
- /*interpolate per-vert data*/
- for (s = 0; s < numVerts; s++) {
- for (y = 1; y < gridFaces; y++) {
- for (x = 1; x < gridFaces; x++) {
- w2 = w + s * numVerts * g2_wid * g2_wid + (y * g2_wid + x) * numVerts;
- DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
- numVerts, vertNum);
-
- if (vertOrigIndex) {
- *vertOrigIndex = ORIGINDEX_NONE;
- vertOrigIndex++;
- }
-
- vertNum++;
- }
- }
- }
-
- if (edgeOrigIndex) {
- for (i = 0; i < numFinalEdges; ++i) {
- edgeOrigIndex[edgeNum + i] = ORIGINDEX_NONE;
- }
- }
-
- for (s = 0; s < numVerts; s++) {
- /*interpolate per-face data*/
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
- w2 = w + s * numVerts * g2_wid * g2_wid + (y * g2_wid + x) * numVerts;
- CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
- loopidx, w2, NULL, numVerts, loopindex2);
- loopindex2++;
-
- w2 = w + s * numVerts * g2_wid * g2_wid + ((y + 1) * g2_wid + (x)) * numVerts;
- CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
- loopidx, w2, NULL, numVerts, loopindex2);
- loopindex2++;
-
- w2 = w + s * numVerts * g2_wid * g2_wid + ((y + 1) * g2_wid + (x + 1)) * numVerts;
- CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
- loopidx, w2, NULL, numVerts, loopindex2);
- loopindex2++;
-
- w2 = w + s * numVerts * g2_wid * g2_wid + ((y) * g2_wid + (x + 1)) * numVerts;
- CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
- loopidx, w2, NULL, numVerts, loopindex2);
- loopindex2++;
-
- /*copy over poly data, e.g. mtexpoly*/
- CustomData_copy_data(&dm->polyData, &ccgdm->dm.polyData, origIndex, faceNum, 1);
-
- /*set original index data*/
- if (faceOrigIndex) {
- /* reference the index in 'polyOrigIndex' */
- *faceOrigIndex = faceNum;
- faceOrigIndex++;
- }
- if (polyOrigIndex) {
- *polyOrigIndex = base_polyOrigIndex ? base_polyOrigIndex[origIndex] : origIndex;
- polyOrigIndex++;
- }
-
- ccgdm->reverseFaceMap[faceNum] = index;
-
- /* This is a simple one to one mapping, here... */
- if (polyidx) {
- polyidx[faceNum] = faceNum;
- }
-
- faceNum++;
- }
- }
- }
-
- edgeNum += numFinalEdges;
- }
-
- for (index = 0; index < totedge; ++index) {
- CCGEdge *e = ccgdm->edgeMap[index].edge;
- int numFinalEdges = edgeSize - 1;
- int mapIndex = ccgDM_getEdgeMapIndex(ss, e);
- int x;
- int vertIdx[2];
- int edgeIdx = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(e));
-
- CCGVert *v;
- v = ccgSubSurf_getEdgeVert0(e);
- vertIdx[0] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
- v = ccgSubSurf_getEdgeVert1(e);
- vertIdx[1] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
-
- ccgdm->edgeMap[index].startVert = vertNum;
- ccgdm->edgeMap[index].startEdge = edgeNum;
-
- if (edgeIdx >= 0 && edgeFlags)
- edgeFlags[edgeIdx] = medge[edgeIdx].flag;
-
- /* set the edge base vert */
- *((int *)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum;
-
- for (x = 1; x < edgeSize - 1; x++) {
- float w[2];
- w[1] = (float) x / (edgeSize - 1);
- w[0] = 1 - w[1];
- DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum);
- if (vertOrigIndex) {
- *vertOrigIndex = ORIGINDEX_NONE;
- vertOrigIndex++;
- }
- vertNum++;
- }
-
- if (has_edge_cd) {
- BLI_assert(edgeIdx >= 0 && edgeIdx < dm->getNumEdges(dm));
- for (i = 0; i < numFinalEdges; ++i) {
- CustomData_copy_data(&dm->edgeData, &ccgdm->dm.edgeData, edgeIdx, edgeNum + i, 1);
- }
- }
-
- if (edgeOrigIndex) {
- for (i = 0; i < numFinalEdges; ++i) {
- edgeOrigIndex[edgeNum + i] = mapIndex;
- }
- }
-
- edgeNum += numFinalEdges;
- }
-
- if (useSubsurfUv) {
- CustomData *ldata = &ccgdm->dm.loopData;
- CustomData *dmldata = &dm->loopData;
- int numlayer = CustomData_number_of_layers(ldata, CD_MLOOPUV);
- int dmnumlayer = CustomData_number_of_layers(dmldata, CD_MLOOPUV);
-
- for (i = 0; i < numlayer && i < dmnumlayer; i++)
- set_subsurf_uv(ss, dm, &ccgdm->dm, i);
- }
-
- for (index = 0; index < totvert; ++index) {
- CCGVert *v = ccgdm->vertMap[index].vert;
- int mapIndex = ccgDM_getVertMapIndex(ccgdm->ss, v);
- int vertIdx;
-
- vertIdx = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
-
- ccgdm->vertMap[index].startVert = vertNum;
-
- /* set the vert base vert */
- *((int *) ccgSubSurf_getVertUserData(ss, v)) = vertNum;
-
- DM_copy_vert_data(dm, &ccgdm->dm, vertIdx, vertNum, 1);
-
- if (vertOrigIndex) {
- *vertOrigIndex = mapIndex;
- vertOrigIndex++;
- }
- vertNum++;
- }
+ for (s = 0; s < numVerts; s++) {
+ CCGVert *v = ccgSubSurf_getFaceVert(f, s);
+ vertidx[s] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
+ }
+
+ /*I think this is for interpolating the center vert?*/
+ w2 = w; // + numVerts*(g2_wid-1) * (g2_wid-1); //numVerts*((g2_wid-1) * g2_wid+g2_wid-1);
+ DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum);
+ if (vertOrigIndex) {
+ *vertOrigIndex = ORIGINDEX_NONE;
+ vertOrigIndex++;
+ }
+
+ vertNum++;
+
+ /*interpolate per-vert data*/
+ for (s = 0; s < numVerts; s++) {
+ for (x = 1; x < gridFaces; x++) {
+ w2 = w + s * numVerts * g2_wid * g2_wid + x * numVerts;
+ DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum);
+
+ if (vertOrigIndex) {
+ *vertOrigIndex = ORIGINDEX_NONE;
+ vertOrigIndex++;
+ }
+
+ vertNum++;
+ }
+ }
+
+ /*interpolate per-vert data*/
+ for (s = 0; s < numVerts; s++) {
+ for (y = 1; y < gridFaces; y++) {
+ for (x = 1; x < gridFaces; x++) {
+ w2 = w + s * numVerts * g2_wid * g2_wid + (y * g2_wid + x) * numVerts;
+ DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum);
+
+ if (vertOrigIndex) {
+ *vertOrigIndex = ORIGINDEX_NONE;
+ vertOrigIndex++;
+ }
+
+ vertNum++;
+ }
+ }
+ }
+
+ if (edgeOrigIndex) {
+ for (i = 0; i < numFinalEdges; ++i) {
+ edgeOrigIndex[edgeNum + i] = ORIGINDEX_NONE;
+ }
+ }
+
+ for (s = 0; s < numVerts; s++) {
+ /*interpolate per-face data*/
+ for (y = 0; y < gridFaces; y++) {
+ for (x = 0; x < gridFaces; x++) {
+ w2 = w + s * numVerts * g2_wid * g2_wid + (y * g2_wid + x) * numVerts;
+ CustomData_interp(
+ &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2);
+ loopindex2++;
+
+ w2 = w + s * numVerts * g2_wid * g2_wid + ((y + 1) * g2_wid + (x)) * numVerts;
+ CustomData_interp(
+ &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2);
+ loopindex2++;
+
+ w2 = w + s * numVerts * g2_wid * g2_wid + ((y + 1) * g2_wid + (x + 1)) * numVerts;
+ CustomData_interp(
+ &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2);
+ loopindex2++;
+
+ w2 = w + s * numVerts * g2_wid * g2_wid + ((y)*g2_wid + (x + 1)) * numVerts;
+ CustomData_interp(
+ &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2);
+ loopindex2++;
+
+ /*copy over poly data, e.g. mtexpoly*/
+ CustomData_copy_data(&dm->polyData, &ccgdm->dm.polyData, origIndex, faceNum, 1);
+
+ /*set original index data*/
+ if (faceOrigIndex) {
+ /* reference the index in 'polyOrigIndex' */
+ *faceOrigIndex = faceNum;
+ faceOrigIndex++;
+ }
+ if (polyOrigIndex) {
+ *polyOrigIndex = base_polyOrigIndex ? base_polyOrigIndex[origIndex] : origIndex;
+ polyOrigIndex++;
+ }
+
+ ccgdm->reverseFaceMap[faceNum] = index;
+
+ /* This is a simple one to one mapping, here... */
+ if (polyidx) {
+ polyidx[faceNum] = faceNum;
+ }
+
+ faceNum++;
+ }
+ }
+ }
+
+ edgeNum += numFinalEdges;
+ }
+
+ for (index = 0; index < totedge; ++index) {
+ CCGEdge *e = ccgdm->edgeMap[index].edge;
+ int numFinalEdges = edgeSize - 1;
+ int mapIndex = ccgDM_getEdgeMapIndex(ss, e);
+ int x;
+ int vertIdx[2];
+ int edgeIdx = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(e));
+
+ CCGVert *v;
+ v = ccgSubSurf_getEdgeVert0(e);
+ vertIdx[0] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
+ v = ccgSubSurf_getEdgeVert1(e);
+ vertIdx[1] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
+
+ ccgdm->edgeMap[index].startVert = vertNum;
+ ccgdm->edgeMap[index].startEdge = edgeNum;
+
+ if (edgeIdx >= 0 && edgeFlags)
+ edgeFlags[edgeIdx] = medge[edgeIdx].flag;
+
+ /* set the edge base vert */
+ *((int *)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum;
+
+ for (x = 1; x < edgeSize - 1; x++) {
+ float w[2];
+ w[1] = (float)x / (edgeSize - 1);
+ w[0] = 1 - w[1];
+ DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum);
+ if (vertOrigIndex) {
+ *vertOrigIndex = ORIGINDEX_NONE;
+ vertOrigIndex++;
+ }
+ vertNum++;
+ }
+
+ if (has_edge_cd) {
+ BLI_assert(edgeIdx >= 0 && edgeIdx < dm->getNumEdges(dm));
+ for (i = 0; i < numFinalEdges; ++i) {
+ CustomData_copy_data(&dm->edgeData, &ccgdm->dm.edgeData, edgeIdx, edgeNum + i, 1);
+ }
+ }
+
+ if (edgeOrigIndex) {
+ for (i = 0; i < numFinalEdges; ++i) {
+ edgeOrigIndex[edgeNum + i] = mapIndex;
+ }
+ }
+
+ edgeNum += numFinalEdges;
+ }
+
+ if (useSubsurfUv) {
+ CustomData *ldata = &ccgdm->dm.loopData;
+ CustomData *dmldata = &dm->loopData;
+ int numlayer = CustomData_number_of_layers(ldata, CD_MLOOPUV);
+ int dmnumlayer = CustomData_number_of_layers(dmldata, CD_MLOOPUV);
+
+ for (i = 0; i < numlayer && i < dmnumlayer; i++)
+ set_subsurf_uv(ss, dm, &ccgdm->dm, i);
+ }
+
+ for (index = 0; index < totvert; ++index) {
+ CCGVert *v = ccgdm->vertMap[index].vert;
+ int mapIndex = ccgDM_getVertMapIndex(ccgdm->ss, v);
+ int vertIdx;
+
+ vertIdx = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
+
+ ccgdm->vertMap[index].startVert = vertNum;
+
+ /* set the vert base vert */
+ *((int *)ccgSubSurf_getVertUserData(ss, v)) = vertNum;
+
+ DM_copy_vert_data(dm, &ccgdm->dm, vertIdx, vertNum, 1);
+
+ if (vertOrigIndex) {
+ *vertOrigIndex = mapIndex;
+ vertOrigIndex++;
+ }
+ vertNum++;
+ }
#ifndef USE_DYNSIZE
- BLI_array_free(vertidx);
- BLI_array_free(loopidx);
+ BLI_array_free(vertidx);
+ BLI_array_free(loopidx);
#endif
- free_ss_weights(&wtable);
-
- BLI_assert(vertNum == ccgSubSurf_getNumFinalVerts(ss));
- BLI_assert(edgeNum == ccgSubSurf_getNumFinalEdges(ss));
- BLI_assert(loopindex2 == ccgSubSurf_getNumFinalFaces(ss) * 4);
- BLI_assert(faceNum == ccgSubSurf_getNumFinalFaces(ss));
+ free_ss_weights(&wtable);
+ BLI_assert(vertNum == ccgSubSurf_getNumFinalVerts(ss));
+ BLI_assert(edgeNum == ccgSubSurf_getNumFinalEdges(ss));
+ BLI_assert(loopindex2 == ccgSubSurf_getNumFinalFaces(ss) * 4);
+ BLI_assert(faceNum == ccgSubSurf_getNumFinalFaces(ss));
}
/* Fill in only geometry arrays needed for the GPU tessellation. */
static void set_ccgdm_gpu_geometry(CCGDerivedMesh *ccgdm, DerivedMesh *dm)
{
- const int totface = dm->getNumPolys(dm);
- MPoly *mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
- int index;
- DMFlagMat *faceFlags = ccgdm->faceFlags;
+ const int totface = dm->getNumPolys(dm);
+ MPoly *mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
+ int index;
+ DMFlagMat *faceFlags = ccgdm->faceFlags;
- for (index = 0; index < totface; index++) {
- faceFlags->flag = mpoly ? mpoly[index].flag : 0;
- faceFlags->mat_nr = mpoly ? mpoly[index].mat_nr : 0;
- faceFlags++;
- }
+ for (index = 0; index < totface; index++) {
+ faceFlags->flag = mpoly ? mpoly[index].flag : 0;
+ faceFlags->mat_nr = mpoly ? mpoly[index].mat_nr : 0;
+ faceFlags++;
+ }
- /* TODO(sergey): Fill in edge flags. */
+ /* TODO(sergey): Fill in edge flags. */
}
-static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
- int drawInteriorEdges,
- int useSubsurfUv,
- DerivedMesh *dm,
- bool use_gpu_backend)
+static CCGDerivedMesh *getCCGDerivedMesh(
+ CCGSubSurf *ss, int drawInteriorEdges, int useSubsurfUv, DerivedMesh *dm, bool use_gpu_backend)
{
#ifdef WITH_OPENSUBDIV
- const int totedge = dm->getNumEdges(dm);
- const int totface = dm->getNumPolys(dm);
+ const int totedge = dm->getNumEdges(dm);
+ const int totface = dm->getNumPolys(dm);
#else
- const int totedge = ccgSubSurf_getNumEdges(ss);
- const int totface = ccgSubSurf_getNumFaces(ss);
+ const int totedge = ccgSubSurf_getNumEdges(ss);
+ const int totface = ccgSubSurf_getNumFaces(ss);
#endif
- CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
-
- if (use_gpu_backend == false) {
- BLI_assert(totedge == ccgSubSurf_getNumEdges(ss));
- BLI_assert(totface == ccgSubSurf_getNumFaces(ss));
- DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
- ccgSubSurf_getNumFinalVerts(ss),
- ccgSubSurf_getNumFinalEdges(ss),
- 0,
- ccgSubSurf_getNumFinalFaces(ss) * 4,
- ccgSubSurf_getNumFinalFaces(ss));
-
- CustomData_free_layer_active(&ccgdm->dm.polyData, CD_NORMAL,
- ccgdm->dm.numPolyData);
-
- ccgdm->reverseFaceMap =
- MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinalFaces(ss),
- "reverseFaceMap");
-
- create_ccgdm_maps(ccgdm, ss);
- }
- else {
- DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
- 0, 0, 0, 0, dm->getNumPolys(dm));
- CustomData_copy_data(&dm->polyData,
- &ccgdm->dm.polyData,
- 0, 0, dm->getNumPolys(dm));
- }
-
- set_default_ccgdm_callbacks(ccgdm);
-
- ccgdm->ss = ss;
- ccgdm->drawInteriorEdges = drawInteriorEdges;
- ccgdm->useSubsurfUv = useSubsurfUv;
- ccgdm->useGpuBackend = use_gpu_backend;
-
- /* CDDM hack. */
- ccgdm->edgeFlags = MEM_callocN(sizeof(short) * totedge, "edgeFlags");
- ccgdm->faceFlags = MEM_callocN(sizeof(DMFlagMat) * totface, "faceFlags");
-
- if (use_gpu_backend == false) {
- set_ccgdm_all_geometry(ccgdm, ss, dm, useSubsurfUv != 0);
- }
- else {
- set_ccgdm_gpu_geometry(ccgdm, dm);
- }
-
- ccgdm->dm.numVertData = ccgSubSurf_getNumFinalVerts(ss);
- ccgdm->dm.numEdgeData = ccgSubSurf_getNumFinalEdges(ss);
- ccgdm->dm.numPolyData = ccgSubSurf_getNumFinalFaces(ss);
- ccgdm->dm.numLoopData = ccgdm->dm.numPolyData * 4;
- ccgdm->dm.numTessFaceData = 0;
-
- BLI_mutex_init(&ccgdm->loops_cache_lock);
- BLI_rw_mutex_init(&ccgdm->origindex_cache_rwlock);
-
- return ccgdm;
+ CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
+
+ if (use_gpu_backend == false) {
+ BLI_assert(totedge == ccgSubSurf_getNumEdges(ss));
+ BLI_assert(totface == ccgSubSurf_getNumFaces(ss));
+ DM_from_template(&ccgdm->dm,
+ dm,
+ DM_TYPE_CCGDM,
+ ccgSubSurf_getNumFinalVerts(ss),
+ ccgSubSurf_getNumFinalEdges(ss),
+ 0,
+ ccgSubSurf_getNumFinalFaces(ss) * 4,
+ ccgSubSurf_getNumFinalFaces(ss));
+
+ CustomData_free_layer_active(&ccgdm->dm.polyData, CD_NORMAL, ccgdm->dm.numPolyData);
+
+ ccgdm->reverseFaceMap = MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinalFaces(ss),
+ "reverseFaceMap");
+
+ create_ccgdm_maps(ccgdm, ss);
+ }
+ else {
+ DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM, 0, 0, 0, 0, dm->getNumPolys(dm));
+ CustomData_copy_data(&dm->polyData, &ccgdm->dm.polyData, 0, 0, dm->getNumPolys(dm));
+ }
+
+ set_default_ccgdm_callbacks(ccgdm);
+
+ ccgdm->ss = ss;
+ ccgdm->drawInteriorEdges = drawInteriorEdges;
+ ccgdm->useSubsurfUv = useSubsurfUv;
+ ccgdm->useGpuBackend = use_gpu_backend;
+
+ /* CDDM hack. */
+ ccgdm->edgeFlags = MEM_callocN(sizeof(short) * totedge, "edgeFlags");
+ ccgdm->faceFlags = MEM_callocN(sizeof(DMFlagMat) * totface, "faceFlags");
+
+ if (use_gpu_backend == false) {
+ set_ccgdm_all_geometry(ccgdm, ss, dm, useSubsurfUv != 0);
+ }
+ else {
+ set_ccgdm_gpu_geometry(ccgdm, dm);
+ }
+
+ ccgdm->dm.numVertData = ccgSubSurf_getNumFinalVerts(ss);
+ ccgdm->dm.numEdgeData = ccgSubSurf_getNumFinalEdges(ss);
+ ccgdm->dm.numPolyData = ccgSubSurf_getNumFinalFaces(ss);
+ ccgdm->dm.numLoopData = ccgdm->dm.numPolyData * 4;
+ ccgdm->dm.numTessFaceData = 0;
+
+ BLI_mutex_init(&ccgdm->loops_cache_lock);
+ BLI_rw_mutex_init(&ccgdm->origindex_cache_rwlock);
+
+ return ccgdm;
}
/***/
@@ -2847,231 +2857,225 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
static bool subsurf_use_gpu_backend(SubsurfFlags flags)
{
#ifdef WITH_OPENSUBDIV
- /* Use GPU backend if it's a last modifier in the stack
- * and user chose to use any of the OSD compute devices,
- * but also check if GPU has all needed features.
- */
- return
- (flags & SUBSURF_USE_GPU_BACKEND) != 0 &&
- (U.opensubdiv_compute_type != USER_OPENSUBDIV_COMPUTE_NONE);
+ /* Use GPU backend if it's a last modifier in the stack
+ * and user chose to use any of the OSD compute devices,
+ * but also check if GPU has all needed features.
+ */
+ return (flags & SUBSURF_USE_GPU_BACKEND) != 0 &&
+ (U.opensubdiv_compute_type != USER_OPENSUBDIV_COMPUTE_NONE);
#else
- (void)flags;
- return false;
+ (void)flags;
+ return false;
#endif
}
-struct DerivedMesh *subsurf_make_derived_from_derived(
- struct DerivedMesh *dm,
- struct SubsurfModifierData *smd,
- struct Scene *scene,
- float (*vertCos)[3],
- SubsurfFlags flags)
-{
- const int useSimple = (smd->subdivType == ME_SIMPLE_SUBSURF) ? CCG_SIMPLE_SUBDIV : 0;
- const CCGFlags useAging = (smd->flags & eSubsurfModifierFlag_DebugIncr) ? CCG_USE_AGING : 0;
- const int useSubsurfUv = (smd->uv_smooth != SUBSURF_UV_SMOOTH_NONE);
- const int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
- const bool use_gpu_backend = subsurf_use_gpu_backend(flags);
- const bool ignore_simplify = (flags & SUBSURF_IGNORE_SIMPLIFY);
- CCGDerivedMesh *result;
-
- /* note: editmode calculation can only run once per
- * modifier stack evaluation (uses freed cache) [#36299] */
- if (flags & SUBSURF_FOR_EDIT_MODE) {
- int levels = (scene != NULL && !ignore_simplify)
- ? get_render_subsurf_level(&scene->r, smd->levels, false)
- : smd->levels;
-
- /* TODO(sergey): Same as emCache below. */
- if ((flags & SUBSURF_IN_EDIT_MODE) && smd->mCache) {
- ccgSubSurf_free(smd->mCache);
- smd->mCache = NULL;
- }
-
- smd->emCache = _getSubSurf(smd->emCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS);
+struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm,
+ struct SubsurfModifierData *smd,
+ struct Scene *scene,
+ float (*vertCos)[3],
+ SubsurfFlags flags)
+{
+ const int useSimple = (smd->subdivType == ME_SIMPLE_SUBSURF) ? CCG_SIMPLE_SUBDIV : 0;
+ const CCGFlags useAging = (smd->flags & eSubsurfModifierFlag_DebugIncr) ? CCG_USE_AGING : 0;
+ const int useSubsurfUv = (smd->uv_smooth != SUBSURF_UV_SMOOTH_NONE);
+ const int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
+ const bool use_gpu_backend = subsurf_use_gpu_backend(flags);
+ const bool ignore_simplify = (flags & SUBSURF_IGNORE_SIMPLIFY);
+ CCGDerivedMesh *result;
+
+ /* note: editmode calculation can only run once per
+ * modifier stack evaluation (uses freed cache) [#36299] */
+ if (flags & SUBSURF_FOR_EDIT_MODE) {
+ int levels = (scene != NULL && !ignore_simplify) ?
+ get_render_subsurf_level(&scene->r, smd->levels, false) :
+ smd->levels;
+
+ /* TODO(sergey): Same as emCache below. */
+ if ((flags & SUBSURF_IN_EDIT_MODE) && smd->mCache) {
+ ccgSubSurf_free(smd->mCache);
+ smd->mCache = NULL;
+ }
+
+ smd->emCache = _getSubSurf(smd->emCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS);
#ifdef WITH_OPENSUBDIV
- ccgSubSurf_setSkipGrids(smd->emCache, use_gpu_backend);
+ ccgSubSurf_setSkipGrids(smd->emCache, use_gpu_backend);
#endif
- ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple, useSubsurfUv);
- result = getCCGDerivedMesh(smd->emCache,
- drawInteriorEdges,
- useSubsurfUv, dm, use_gpu_backend);
- }
- else if (flags & SUBSURF_USE_RENDER_PARAMS) {
- /* Do not use cache in render mode. */
- CCGSubSurf *ss;
- int levels = (scene != NULL && !ignore_simplify)
- ? get_render_subsurf_level(&scene->r, smd->renderLevels, true)
- : smd->renderLevels;
-
- if (levels == 0)
- return dm;
-
- ss = _getSubSurf(NULL, levels, 3, useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS);
-
- ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
-
- result = getCCGDerivedMesh(ss,
- drawInteriorEdges, useSubsurfUv, dm, false);
-
- result->freeSS = 1;
- }
- else {
- int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental);
- int levels = (scene != NULL && !ignore_simplify)
- ? get_render_subsurf_level(&scene->r, smd->levels, false)
- : smd->levels;
- CCGSubSurf *ss;
-
- /* It is quite possible there is a much better place to do this. It
- * depends a bit on how rigorously we expect this function to never
- * be called in editmode. In semi-theory we could share a single
- * cache, but the handles used inside and outside editmode are not
- * the same so we would need some way of converting them. Its probably
- * not worth the effort. But then why am I even writing this long
- * comment that no one will read? Hmmm. - zr
- *
- * Addendum: we can't really ensure that this is never called in edit
- * mode, so now we have a parameter to verify it. - brecht
- */
- if (!(flags & SUBSURF_IN_EDIT_MODE) && smd->emCache) {
- ccgSubSurf_free(smd->emCache);
- smd->emCache = NULL;
- }
-
- if (useIncremental && (flags & SUBSURF_IS_FINAL_CALC)) {
- smd->mCache = ss = _getSubSurf(smd->mCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS);
-
- ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
-
- result = getCCGDerivedMesh(smd->mCache,
- drawInteriorEdges,
- useSubsurfUv, dm, false);
- }
- else {
- CCGFlags ccg_flags = useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS;
- CCGSubSurf *prevSS = NULL;
-
- if (smd->mCache && (flags & SUBSURF_IS_FINAL_CALC)) {
+ ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple, useSubsurfUv);
+ result = getCCGDerivedMesh(smd->emCache, drawInteriorEdges, useSubsurfUv, dm, use_gpu_backend);
+ }
+ else if (flags & SUBSURF_USE_RENDER_PARAMS) {
+ /* Do not use cache in render mode. */
+ CCGSubSurf *ss;
+ int levels = (scene != NULL && !ignore_simplify) ?
+ get_render_subsurf_level(&scene->r, smd->renderLevels, true) :
+ smd->renderLevels;
+
+ if (levels == 0)
+ return dm;
+
+ ss = _getSubSurf(NULL, levels, 3, useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS);
+
+ ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
+
+ result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm, false);
+
+ result->freeSS = 1;
+ }
+ else {
+ int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental);
+ int levels = (scene != NULL && !ignore_simplify) ?
+ get_render_subsurf_level(&scene->r, smd->levels, false) :
+ smd->levels;
+ CCGSubSurf *ss;
+
+ /* It is quite possible there is a much better place to do this. It
+ * depends a bit on how rigorously we expect this function to never
+ * be called in editmode. In semi-theory we could share a single
+ * cache, but the handles used inside and outside editmode are not
+ * the same so we would need some way of converting them. Its probably
+ * not worth the effort. But then why am I even writing this long
+ * comment that no one will read? Hmmm. - zr
+ *
+ * Addendum: we can't really ensure that this is never called in edit
+ * mode, so now we have a parameter to verify it. - brecht
+ */
+ if (!(flags & SUBSURF_IN_EDIT_MODE) && smd->emCache) {
+ ccgSubSurf_free(smd->emCache);
+ smd->emCache = NULL;
+ }
+
+ if (useIncremental && (flags & SUBSURF_IS_FINAL_CALC)) {
+ smd->mCache = ss = _getSubSurf(
+ smd->mCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS);
+
+ ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
+
+ result = getCCGDerivedMesh(smd->mCache, drawInteriorEdges, useSubsurfUv, dm, false);
+ }
+ else {
+ CCGFlags ccg_flags = useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS;
+ CCGSubSurf *prevSS = NULL;
+
+ if (smd->mCache && (flags & SUBSURF_IS_FINAL_CALC)) {
#ifdef WITH_OPENSUBDIV
- /* With OpenSubdiv enabled we always tries to re-use previous
- * subsurf structure in order to save computation time since
- * re-creation is rather a complicated business.
- *
- * TODO(sergey): There was a good eason why final calculation
- * used to free entirely cached subsurf structure. reason of
- * this is to be investigated still to be sure we don't have
- * regressions here.
- */
- if (use_gpu_backend) {
- prevSS = smd->mCache;
- }
- else
+ /* With OpenSubdiv enabled we always tries to re-use previous
+ * subsurf structure in order to save computation time since
+ * re-creation is rather a complicated business.
+ *
+ * TODO(sergey): There was a good eason why final calculation
+ * used to free entirely cached subsurf structure. reason of
+ * this is to be investigated still to be sure we don't have
+ * regressions here.
+ */
+ if (use_gpu_backend) {
+ prevSS = smd->mCache;
+ }
+ else
#endif
- {
- ccgSubSurf_free(smd->mCache);
- smd->mCache = NULL;
- }
- }
-
+ {
+ ccgSubSurf_free(smd->mCache);
+ smd->mCache = NULL;
+ }
+ }
- if (flags & SUBSURF_ALLOC_PAINT_MASK)
- ccg_flags |= CCG_ALLOC_MASK;
+ if (flags & SUBSURF_ALLOC_PAINT_MASK)
+ ccg_flags |= CCG_ALLOC_MASK;
- ss = _getSubSurf(prevSS, levels, 3, ccg_flags);
+ ss = _getSubSurf(prevSS, levels, 3, ccg_flags);
#ifdef WITH_OPENSUBDIV
- ccgSubSurf_setSkipGrids(ss, use_gpu_backend);
+ ccgSubSurf_setSkipGrids(ss, use_gpu_backend);
#endif
- ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
+ ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
- result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm, use_gpu_backend);
+ result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm, use_gpu_backend);
- if (flags & SUBSURF_IS_FINAL_CALC)
- smd->mCache = ss;
- else
- result->freeSS = 1;
+ if (flags & SUBSURF_IS_FINAL_CALC)
+ smd->mCache = ss;
+ else
+ result->freeSS = 1;
- if (flags & SUBSURF_ALLOC_PAINT_MASK)
- ccgSubSurf_setNumLayers(ss, 4);
- }
- }
+ if (flags & SUBSURF_ALLOC_PAINT_MASK)
+ ccgSubSurf_setNumLayers(ss, 4);
+ }
+ }
- return (DerivedMesh *)result;
+ return (DerivedMesh *)result;
}
void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3])
{
- /* Finds the subsurf limit positions for the verts in a mesh
- * and puts them in an array of floats. Please note that the
- * calculated vert positions is incorrect for the verts
- * on the boundary of the mesh.
- */
- CCGSubSurf *ss = _getSubSurf(NULL, 1, 3, CCG_USE_ARENA);
- float edge_sum[3], face_sum[3];
- CCGVertIterator vi;
- DerivedMesh *dm = CDDM_from_mesh(me);
-
- ss_sync_from_derivedmesh(ss, dm, NULL, 0, 0);
-
- for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
- CCGVert *v = ccgVertIterator_getCurrent(&vi);
- int idx = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
- int N = ccgSubSurf_getVertNumEdges(v);
- int numFaces = ccgSubSurf_getVertNumFaces(v);
- float *co;
- int i;
-
- zero_v3(edge_sum);
- zero_v3(face_sum);
-
- for (i = 0; i < N; i++) {
- CCGEdge *e = ccgSubSurf_getVertEdge(v, i);
- add_v3_v3v3(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
- }
- for (i = 0; i < numFaces; i++) {
- CCGFace *f = ccgSubSurf_getVertFace(v, i);
- add_v3_v3(face_sum, ccgSubSurf_getFaceCenterData(f));
- }
-
- /* ad-hoc correction for boundary vertices, to at least avoid them
- * moving completely out of place (brecht) */
- if (numFaces && numFaces != N)
- mul_v3_fl(face_sum, (float)N / (float)numFaces);
-
- co = ccgSubSurf_getVertData(ss, v);
- r_positions[idx][0] = (co[0] * N * N + edge_sum[0] * 4 + face_sum[0]) / (N * (N + 5));
- r_positions[idx][1] = (co[1] * N * N + edge_sum[1] * 4 + face_sum[1]) / (N * (N + 5));
- r_positions[idx][2] = (co[2] * N * N + edge_sum[2] * 4 + face_sum[2]) / (N * (N + 5));
- }
-
- ccgSubSurf_free(ss);
-
- dm->release(dm);
+ /* Finds the subsurf limit positions for the verts in a mesh
+ * and puts them in an array of floats. Please note that the
+ * calculated vert positions is incorrect for the verts
+ * on the boundary of the mesh.
+ */
+ CCGSubSurf *ss = _getSubSurf(NULL, 1, 3, CCG_USE_ARENA);
+ float edge_sum[3], face_sum[3];
+ CCGVertIterator vi;
+ DerivedMesh *dm = CDDM_from_mesh(me);
+
+ ss_sync_from_derivedmesh(ss, dm, NULL, 0, 0);
+
+ for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi);
+ ccgVertIterator_next(&vi)) {
+ CCGVert *v = ccgVertIterator_getCurrent(&vi);
+ int idx = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
+ int N = ccgSubSurf_getVertNumEdges(v);
+ int numFaces = ccgSubSurf_getVertNumFaces(v);
+ float *co;
+ int i;
+
+ zero_v3(edge_sum);
+ zero_v3(face_sum);
+
+ for (i = 0; i < N; i++) {
+ CCGEdge *e = ccgSubSurf_getVertEdge(v, i);
+ add_v3_v3v3(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
+ }
+ for (i = 0; i < numFaces; i++) {
+ CCGFace *f = ccgSubSurf_getVertFace(v, i);
+ add_v3_v3(face_sum, ccgSubSurf_getFaceCenterData(f));
+ }
+
+ /* ad-hoc correction for boundary vertices, to at least avoid them
+ * moving completely out of place (brecht) */
+ if (numFaces && numFaces != N)
+ mul_v3_fl(face_sum, (float)N / (float)numFaces);
+
+ co = ccgSubSurf_getVertData(ss, v);
+ r_positions[idx][0] = (co[0] * N * N + edge_sum[0] * 4 + face_sum[0]) / (N * (N + 5));
+ r_positions[idx][1] = (co[1] * N * N + edge_sum[1] * 4 + face_sum[1]) / (N * (N + 5));
+ r_positions[idx][2] = (co[2] * N * N + edge_sum[2] * 4 + face_sum[2]) / (N * (N + 5));
+ }
+
+ ccgSubSurf_free(ss);
+
+ dm->release(dm);
}
bool subsurf_has_edges(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- return true;
- }
+ if (ccgdm->useGpuBackend) {
+ return true;
+ }
#else
- (void)ccgdm;
+ (void)ccgdm;
#endif
- return dm->getNumEdges(dm) != 0;
+ return dm->getNumEdges(dm) != 0;
}
bool subsurf_has_faces(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- return true;
- }
+ if (ccgdm->useGpuBackend) {
+ return true;
+ }
#else
- (void)ccgdm;
+ (void)ccgdm;
#endif
- return dm->getNumPolys(dm) != 0;
+ return dm->getNumPolys(dm) != 0;
}