From f751d0f6ae7de155343e24e36965956bd7a061e3 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Thu, 10 May 2012 20:33:09 +0000 Subject: [PATCH] Replace hardcoded DMGridData structure with CCGElem/CCGKey. * Changes to DerivedMesh interface: DMGridData has been removed, getGridData() now returns an array of CCGElem pointers. Also added getGridKey() to initialize a CCGKey (implemented only by CCGDerivedMesh.) * PBVH: added BLI_pbvh_get_grid_key(). * A lot of code is affected, but mainly is just replacing DMGridData.co, DMGridData.no, and sizeof(DMGridData) with the CCG_*_elem functions, removing the reliance on grid elements of exactly six floats. --- source/blender/blenkernel/BKE_DerivedMesh.h | 10 +- source/blender/blenkernel/BKE_subsurf.h | 5 +- source/blender/blenkernel/intern/multires.c | 182 +++++---- .../blender/blenkernel/intern/subsurf_ccg.c | 352 ++++++++++-------- source/blender/blenlib/BLI_pbvh.h | 25 +- source/blender/blenlib/intern/pbvh.c | 55 +-- source/blender/editors/object/object_bake.c | 31 +- .../blender/editors/sculpt_paint/paint_hide.c | 27 +- source/blender/editors/sculpt_paint/sculpt.c | 21 +- .../editors/sculpt_paint/sculpt_undo.c | 9 +- source/blender/gpu/GPU_buffers.h | 13 +- source/blender/gpu/intern/gpu_buffers.c | 105 +++--- 12 files changed, 477 insertions(+), 358 deletions(-) diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index a15192f156a..595a1e884d7 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -74,6 +74,8 @@ #include "BKE_customdata.h" #include "BKE_bvhutils.h" +struct CCGElem; +struct CCGKey; struct MVert; struct MEdge; struct MFace; @@ -102,11 +104,6 @@ struct PBVH; * Also, the mface origindex layer indexes mpolys, not mfaces. */ -typedef struct DMGridData { - float co[3]; - float no[3]; -} DMGridData; - typedef struct DMGridAdjacency { int index[4]; int rotation[4]; @@ -250,9 +247,10 @@ struct DerivedMesh { /* optional grid access for subsurf */ int (*getNumGrids)(DerivedMesh *dm); int (*getGridSize)(DerivedMesh *dm); - DMGridData **(*getGridData)(DerivedMesh *dm); + struct CCGElem **(*getGridData)(DerivedMesh *dm); DMGridAdjacency *(*getGridAdjacency)(DerivedMesh *dm); int *(*getGridOffset)(DerivedMesh *dm); + void (*getGridKey)(DerivedMesh *dm, struct CCGKey *key); DMFlagMat *(*getGridFlagMats)(DerivedMesh *dm); unsigned int **(*getGridHidden)(DerivedMesh *dm); diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h index 400056c527c..c4d23a327d7 100644 --- a/source/blender/blenkernel/BKE_subsurf.h +++ b/source/blender/blenkernel/BKE_subsurf.h @@ -34,9 +34,9 @@ /* struct DerivedMesh is used directly */ #include "BKE_DerivedMesh.h" +struct CCGElem; struct DMFlagMat; struct DMGridAdjacency; -struct DMGridData; struct DerivedMesh; struct MeshElemMap; struct Mesh; @@ -51,7 +51,6 @@ struct CCGSubsurf; struct CCGVert; struct EdgeHash; struct PBVH; -struct DMGridData; struct DMGridAdjacency; /**************************** External *****************************/ @@ -115,7 +114,7 @@ typedef struct CCGDerivedMesh { struct MeshElemMap *pmap; int *pmap_mem; - struct DMGridData **gridData; + struct CCGElem **gridData; struct DMGridAdjacency *gridAdjacency; int *gridOffset; struct CCGFace **gridFaces; diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 37407ce7342..73705ab3752 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -46,6 +46,7 @@ #include "BLI_pbvh.h" #include "BLI_utildefines.h" +#include "BKE_ccg.h" #include "BKE_cdderivedmesh.h" #include "BKE_mesh.h" #include "BKE_modifier.h" @@ -75,7 +76,7 @@ typedef enum { } DispOp; static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert); -static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, DMGridData **oldGridData, int totlvl); +static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, CCGElem **oldGridData, int totlvl); /** Customdata **/ @@ -569,23 +570,27 @@ static void multires_copy_grid(float (*gridA)[3], float (*gridB)[3], int sizeA, } } -static void multires_copy_dm_grid(DMGridData *gridA, DMGridData *gridB, int sizeA, int sizeB) +static void multires_copy_dm_grid(CCGElem *gridA, CCGElem *gridB, CCGKey *keyA, CCGKey *keyB) { int x, y, j, skip; - if (sizeA > sizeB) { - skip = (sizeA - 1) / (sizeB - 1); + if (keyA->grid_size > keyB->grid_size) { + skip = (keyA->grid_size - 1) / (keyB->grid_size - 1); - for (j = 0, y = 0; y < sizeB; y++) - for (x = 0; x < sizeB; x++, j++) - copy_v3_v3(gridA[y * skip * sizeA + x * skip].co, gridB[j].co); + for (j = 0, y = 0; y < keyB->grid_size; y++) + for (x = 0; x < keyB->grid_size; x++, j++) + memcpy(CCG_elem_offset_co(keyA, gridA, y * skip * keyA->grid_size + x * skip), + CCG_elem_offset_co(keyB, gridB, j), + sizeof(float) * keyA->num_layers); } else { - skip = (sizeB - 1) / (sizeA - 1); + skip = (keyB->grid_size - 1) / (keyA->grid_size - 1); - for (j = 0, y = 0; y < sizeA; y++) - for (x = 0; x < sizeA; x++, j++) - copy_v3_v3(gridA[j].co, gridB[y * skip * sizeB + x * skip].co); + for (j = 0, y = 0; y < keyA->grid_size; y++) + for (x = 0; x < keyA->grid_size; x++, j++) + memcpy(CCG_elem_offset_co(keyA, gridA, j), + CCG_elem_offset_co(keyB, gridB, y * skip * keyB->grid_size + x*skip), + sizeof(float) * keyA->num_layers); } } @@ -850,9 +855,10 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl if (mdisps->disps && !updateblock && totlvl > 1) { /* upsample */ DerivedMesh *lowdm, *cddm, *highdm; - DMGridData **highGridData, **lowGridData, **subGridData; + CCGElem **highGridData, **lowGridData, **subGridData; + CCGKey highGridKey, lowGridKey; CCGSubSurf *ss; - int i, numGrids, highGridSize, lowGridSize; + int i, numGrids, highGridSize; /* create subsurf DM from original mesh at high level */ cddm = CDDM_from_mesh(me, NULL); @@ -867,18 +873,19 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl numGrids = highdm->getNumGrids(highdm); highGridSize = highdm->getGridSize(highdm); highGridData = highdm->getGridData(highdm); - lowGridSize = lowdm->getGridSize(lowdm); + highdm->getGridKey(highdm, &highGridKey); lowGridData = lowdm->getGridData(lowdm); + lowdm->getGridKey(lowdm, &lowGridKey); subGridData = MEM_callocN(sizeof(float *) * numGrids, "subGridData*"); for (i = 0; i < numGrids; ++i) { /* backup subsurf grids */ - subGridData[i] = MEM_callocN(sizeof(DMGridData) * highGridSize * highGridSize, "subGridData"); - memcpy(subGridData[i], highGridData[i], sizeof(DMGridData) * highGridSize * highGridSize); + subGridData[i] = MEM_callocN(highGridKey.elem_size * highGridSize * highGridSize, "subGridData"); + memcpy(subGridData[i], highGridData[i], highGridKey.elem_size*highGridSize * highGridSize); /* overwrite with current displaced grids */ - multires_copy_dm_grid(highGridData[i], lowGridData[i], highGridSize, lowGridSize); + multires_copy_dm_grid(highGridData[i], lowGridData[i], &highGridKey, &lowGridKey); } /* low lower level dm no longer needed at this point */ @@ -914,34 +921,35 @@ void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int updat multires_subdivide(mmd, ob, mmd->totlvl + 1, updateblock, simple); } -void grid_tangent(int gridSize, int index, int x, int y, int axis, DMGridData **gridData, float t[3]) +void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *grid, float t[3]) { if (axis == 0) { - if (x == gridSize - 1) { - if (y == gridSize - 1) - sub_v3_v3v3(t, gridData[index][x + gridSize * (y - 1)].co, gridData[index][x - 1 + gridSize * (y - 1)].co); + if (x == key->grid_size - 1) { + if (y == key->grid_size - 1) + sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x, y - 1), CCG_grid_elem_co(key, grid, x - 1, y - 1)); else - sub_v3_v3v3(t, gridData[index][x + gridSize * y].co, gridData[index][x - 1 + gridSize * y].co); + sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x, y), CCG_grid_elem_co(key, grid, x - 1, y)); } else - sub_v3_v3v3(t, gridData[index][x + 1 + gridSize * y].co, gridData[index][x + gridSize * y].co); + sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x + 1, y), CCG_grid_elem_co(key, grid, x, y)); } else if (axis == 1) { - if (y == gridSize - 1) { - if (x == gridSize - 1) - sub_v3_v3v3(t, gridData[index][x - 1 + gridSize * y].co, gridData[index][x - 1 + gridSize * (y - 1)].co); + if (y == key->grid_size - 1) { + if (x == key->grid_size - 1) + sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x - 1, y), CCG_grid_elem_co(key, grid, x - 1, (y - 1))); else - sub_v3_v3v3(t, gridData[index][x + gridSize * y].co, gridData[index][x + gridSize * (y - 1)].co); + sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x, y), CCG_grid_elem_co(key, grid, x, (y - 1))); } else - sub_v3_v3v3(t, gridData[index][x + gridSize * (y + 1)].co, gridData[index][x + gridSize * y].co); + sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x, (y + 1)), CCG_grid_elem_co(key, grid, x, y)); } } -static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, DMGridData **oldGridData, int totlvl) +static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, CCGElem **oldGridData, int totlvl) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; - DMGridData **gridData, **subGridData; + CCGElem **gridData, **subGridData; + CCGKey key; MPoly *mpoly = me->mpoly; MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS); int *gridOffset; @@ -971,7 +979,8 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm gridSize = dm->getGridSize(dm); gridData = dm->getGridData(dm); gridOffset = dm->getGridOffset(dm); - subGridData = (oldGridData) ? oldGridData : gridData; + dm->getGridKey(dm, &key); + subGridData = (oldGridData) ? oldGridData: gridData; dGridSize = multires_side_tot[totlvl]; dSkip = (dGridSize - 1) / (gridSize - 1); @@ -986,8 +995,8 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm for (S = 0; S < numVerts; ++S, ++gIndex, ++k) { MDisps *mdisp = &mdisps[mpoly[i].loopstart + S]; - DMGridData *grid = gridData[gIndex]; - DMGridData *subgrid = subGridData[gIndex]; + CCGElem *grid = gridData[gIndex]; + CCGElem *subgrid = subGridData[gIndex]; float (*dispgrid)[3] = NULL; /* when adding new faces in edit mode, need to allocate disps */ @@ -1001,17 +1010,17 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm for (y = 0; y < gridSize; y++) { for (x = 0; x < gridSize; x++) { - float *co = grid[x + y * gridSize].co; - float *sco = subgrid[x + y * gridSize].co; - float *no = subgrid[x + y * gridSize].no; + float *co = CCG_grid_elem_co(&key, grid, x, y); + float *sco = CCG_grid_elem_co(&key, subgrid, x, y); + float *no = CCG_grid_elem_no(&key, subgrid, x, y); float *data = dispgrid[dGridSize * y * dSkip + x * dSkip]; float mat[3][3], tx[3], ty[3], disp[3], d[3]; /* construct tangent space matrix */ - grid_tangent(gridSize, gIndex, x, y, 0, subGridData, tx); + grid_tangent(&key, x, y, 0, subGridData[gIndex], tx); normalize_v3(tx); - grid_tangent(gridSize, gIndex, x, y, 1, subGridData, ty); + grid_tangent(&key, x, y, 1, subGridData[gIndex], ty); normalize_v3(ty); //mul_v3_fl(tx, 1.0f/(gridSize-1)); @@ -1075,7 +1084,8 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm) if (lvl < totlvl) { Mesh *me = ob->data; DerivedMesh *lowdm, *cddm, *highdm; - DMGridData **highGridData, **lowGridData, **subGridData, **gridData, *diffGrid; + CCGElem **highGridData, **lowGridData, **subGridData, **gridData, *diffGrid; + CCGKey highGridKey, lowGridKey; CCGSubSurf *ss; int i, j, numGrids, highGridSize, lowGridSize; @@ -1094,23 +1104,30 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm) numGrids = highdm->getNumGrids(highdm); highGridSize = highdm->getGridSize(highdm); highGridData = highdm->getGridData(highdm); + highdm->getGridKey(highdm, &highGridKey); lowGridSize = lowdm->getGridSize(lowdm); lowGridData = lowdm->getGridData(lowdm); + lowdm->getGridKey(lowdm, &lowGridKey); gridData = dm->getGridData(dm); - subGridData = MEM_callocN(sizeof(DMGridData *) * numGrids, "subGridData*"); - diffGrid = MEM_callocN(sizeof(DMGridData) * lowGridSize * lowGridSize, "diff"); + BLI_assert(highGridKey.elem_size == lowGridKey.elem_size); + + subGridData = MEM_callocN(sizeof(CCGElem*)*numGrids, "subGridData*"); + diffGrid = MEM_callocN(lowGridKey.elem_size*lowGridSize*lowGridSize, "diff"); for (i = 0; i < numGrids; ++i) { /* backup subsurf grids */ - subGridData[i] = MEM_callocN(sizeof(DMGridData) * highGridSize * highGridSize, "subGridData"); - memcpy(subGridData[i], highGridData[i], sizeof(DMGridData) * highGridSize * highGridSize); + subGridData[i] = MEM_callocN(highGridKey.elem_size*highGridSize*highGridSize, "subGridData"); + memcpy(subGridData[i], highGridData[i], highGridKey.elem_size*highGridSize*highGridSize); /* write difference of subsurf and displaced low level into high subsurf */ - for (j = 0; j < lowGridSize * lowGridSize; ++j) - sub_v3_v3v3(diffGrid[j].co, gridData[i][j].co, lowGridData[i][j].co); + for (j = 0; j < lowGridSize*lowGridSize; ++j) { + sub_v3_v3v3(CCG_elem_offset_co(&lowGridKey, diffGrid, j), + CCG_elem_offset_co(&lowGridKey, gridData[i], j), + CCG_elem_offset_co(&lowGridKey, lowGridData[i], j)); + } - multires_copy_dm_grid(highGridData[i], diffGrid, highGridSize, lowGridSize); + multires_copy_dm_grid(highGridData[i], diffGrid, &highGridKey, &lowGridKey); } /* lower level dm no longer needed at this point */ @@ -1183,7 +1200,8 @@ void multires_modifier_update_hidden(DerivedMesh *dm) void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to) { DerivedMesh *ccgdm = NULL, *subsurf = NULL; - DMGridData **gridData, **subGridData = NULL; + CCGElem **gridData, **subGridData = NULL; + CCGKey key; MPoly *mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY); MDisps *mdisps; MultiresModifierData *mmd = get_multires_modifier(NULL, ob, 1); @@ -1208,12 +1226,13 @@ void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to) numGrids = subsurf->getNumGrids(subsurf); gridSize = subsurf->getGridSize(subsurf); gridData = subsurf->getGridData(subsurf); + subsurf->getGridKey(subsurf, &key); - subGridData = MEM_callocN(sizeof(DMGridData *) * numGrids, "subGridData*"); + subGridData = MEM_callocN(sizeof(CCGElem*)*numGrids, "subGridData*"); for (i = 0; i < numGrids; i++) { - subGridData[i] = MEM_callocN(sizeof(DMGridData) * gridSize * gridSize, "subGridData"); - memcpy(subGridData[i], gridData[i], sizeof(DMGridData) * gridSize * gridSize); + subGridData[i] = MEM_callocN(key.elem_size*gridSize*gridSize, "subGridData"); + memcpy(subGridData[i], gridData[i], key.elem_size*gridSize*gridSize); } /*numGrids = ccgdm->dm->getNumGrids((DerivedMesh*)ccgdm);*/ /*UNUSED*/ @@ -1234,8 +1253,8 @@ void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to) for (S = 0; S < numVerts; ++S, ++gIndex, ++k) { MDisps *mdisp = &mdisps[mpoly[i].loopstart + S]; - /* DMGridData *grid = gridData[gIndex]; */ /* UNUSED */ - DMGridData *subgrid = subGridData[gIndex]; + /* CCGElem *grid = gridData[gIndex]; */ /* UNUSED */ + CCGElem *subgrid = subGridData[gIndex]; float (*dispgrid)[3] = NULL; /* when adding new faces in edit mode, need to allocate disps */ @@ -1249,16 +1268,16 @@ void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to) for (y = 0; y < gridSize; y++) { for (x = 0; x < gridSize; x++) { - float *data = dispgrid[dGridSize * y * dSkip + x * dSkip]; - float *no = subgrid[x + y * gridSize].no; - float *co = subgrid[x + y * gridSize].co; + float *data = dispgrid[dGridSize*y*dSkip + x*dSkip]; + float *no = CCG_grid_elem_no(&key, subgrid, x, y); + float *co = CCG_grid_elem_co(&key, subgrid, x, y); float mat[3][3], tx[3], ty[3], dco[3]; /* construct tangent space matrix */ - grid_tangent(gridSize, gIndex, x, y, 0, subGridData, tx); + grid_tangent(&key, x, y, 0, subGridData[gIndex], tx); normalize_v3(tx); - grid_tangent(gridSize, gIndex, x, y, 1, subGridData, ty); + grid_tangent(&key, x, y, 1, subGridData[gIndex], ty); normalize_v3(ty); column_vectors_to_mat3(mat, tx, ty, no); @@ -1334,7 +1353,8 @@ DerivedMesh *multires_make_derived_from_derived(DerivedMesh *dm, Mesh *me = ob->data; DerivedMesh *result; CCGDerivedMesh *ccgdm = NULL; - DMGridData **gridData, **subGridData; + CCGElem **gridData, **subGridData; + CCGKey key; int lvl = multires_get_level(ob, mmd, (flags & MULTIRES_USE_RENDER_PARAMS)); int i, gridSize, numGrids; @@ -1359,12 +1379,13 @@ DerivedMesh *multires_make_derived_from_derived(DerivedMesh *dm, numGrids = result->getNumGrids(result); gridSize = result->getGridSize(result); gridData = result->getGridData(result); + result->getGridKey(result, &key); - subGridData = MEM_callocN(sizeof(DMGridData *) * numGrids, "subGridData*"); + subGridData = MEM_callocN(sizeof(CCGElem*)*numGrids, "subGridData*"); for (i = 0; i < numGrids; i++) { - subGridData[i] = MEM_callocN(sizeof(DMGridData) * gridSize * gridSize, "subGridData"); - memcpy(subGridData[i], gridData[i], sizeof(DMGridData) * gridSize * gridSize); + subGridData[i] = MEM_callocN(key.elem_size*gridSize*gridSize, "subGridData"); + memcpy(subGridData[i], gridData[i], key.elem_size*gridSize*gridSize); } multires_set_tot_mdisps(me, mmd->totlvl); @@ -1679,26 +1700,29 @@ static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; - DMGridData *vd; + CCGElem *vd; + CCGKey key; int index; int totvert, totedge, totface; int gridSize = ccgSubSurf_getGridSize(ss); int edgeSize = ccgSubSurf_getEdgeSize(ss); int i = 0; + dm->getGridKey(dm, &key); + 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); - copy_v3_v3(vd->co, mvert[i].co); + copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co); i++; for (S = 0; S < numVerts; S++) { for (x = 1; x < gridSize - 1; x++, i++) { vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x); - copy_v3_v3(vd->co, mvert[i].co); + copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co); } } @@ -1706,7 +1730,7 @@ static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert) for (y = 1; y < gridSize - 1; y++) { for (x = 1; x < gridSize - 1; x++, i++) { vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y); - copy_v3_v3(vd->co, mvert[i].co); + copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co); } } } @@ -1719,7 +1743,7 @@ static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert) for (x = 1; x < edgeSize - 1; x++, i++) { vd = ccgSubSurf_getEdgeData(ss, e, x); - copy_v3_v3(vd->co, mvert[i].co); + copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co); } } @@ -1728,7 +1752,7 @@ static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert) CCGVert *v = ccgdm->vertMap[index].vert; vd = ccgSubSurf_getVertData(ss, v); - copy_v3_v3(vd->co, mvert[i].co); + copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co); i++; } @@ -2041,8 +2065,9 @@ static void multires_sync_levels(Scene *scene, Object *ob, Object *to_ob) static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3]) { DerivedMesh *dm = NULL, *cddm = NULL, *subdm = NULL; - DMGridData **gridData, **subGridData; - Mesh *me = (Mesh *)ob->data; + CCGElem **gridData, **subGridData; + CCGKey key; + Mesh *me = (Mesh*)ob->data; MPoly *mpoly = me->mpoly; /* MLoop *mloop = me->mloop; */ /* UNUSED */ MDisps *mdisps; @@ -2079,10 +2104,11 @@ static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3]) dm = subsurf_dm_create_local(ob, cddm, high_mmd.totlvl, high_mmd.simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv); cddm->release(cddm); - /*numGrids= dm->getNumGrids(dm);*/ /*UNUSED*/ + /*numGrids = dm->getNumGrids(dm);*/ /*UNUSED*/ gridSize = dm->getGridSize(dm); gridData = dm->getGridData(dm); gridOffset = dm->getGridOffset(dm); + dm->getGridKey(dm, &key); subGridData = subdm->getGridData(subdm); dGridSize = multires_side_tot[high_mmd.totlvl]; @@ -2095,23 +2121,23 @@ static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3]) int S, x, y, gIndex = gridOffset[i]; for (S = 0; S < numVerts; ++S, ++gIndex, mdisp++) { - DMGridData *grid = gridData[gIndex]; - DMGridData *subgrid = subGridData[gIndex]; + CCGElem *grid = gridData[gIndex]; + CCGElem *subgrid = subGridData[gIndex]; float (*dispgrid)[3] = mdisp->disps; for (y = 0; y < gridSize; y++) { for (x = 0; x < gridSize; x++) { - float *co = grid[x + y * gridSize].co; - float *sco = subgrid[x + y * gridSize].co; - float *no = grid[x + y * gridSize].no; - float *data = dispgrid[dGridSize * y * dSkip + x * dSkip]; + float *co = CCG_grid_elem_co(&key, grid, x, y); + float *sco = CCG_grid_elem_co(&key, subgrid, x, y); + float *no = CCG_grid_elem_no(&key, grid, x, y); + float *data = dispgrid[dGridSize*y*dSkip + x*dSkip]; float mat[3][3], tx[3], ty[3], disp[3]; /* construct tangent space matrix */ - grid_tangent(gridSize, gIndex, x, y, 0, gridData, tx); + grid_tangent(&key, x, y, 0, gridData[gIndex], tx); normalize_v3(tx); - grid_tangent(gridSize, gIndex, x, y, 1, gridData, ty); + grid_tangent(&key, x, y, 1, gridData[gIndex], ty); normalize_v3(ty); column_vectors_to_mat3(mat, tx, ty, no); diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index e4fcd002822..732e7fe108a 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -52,6 +52,7 @@ #include "BLI_memarena.h" #include "BLI_pbvh.h" +#include "BKE_ccg.h" #include "BKE_cdderivedmesh.h" #include "BKE_global.h" #include "BKE_mesh.h" @@ -639,6 +640,16 @@ static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f) 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]; +} + static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; @@ -646,9 +657,12 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss); CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); + CCGKey key; int i, edgeSize = ccgSubSurf_getEdgeSize(ss); int gridSize = ccgSubSurf_getGridSize(ss); + CCG_key_top_level(&key, ss); + if (!ccgSubSurf_getNumVerts(ss)) min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0; @@ -656,15 +670,15 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) CCGVert *v = ccgVertIterator_getCurrent(vi); float *co = ccgSubSurf_getVertData(ss, v); - DO_MINMAX(co, min_r, max_r); + minmax_v3_v3v3(co, min_r, max_r); } for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); - DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); + CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); - for (i = 0; i < edgeSize; i++) - DO_MINMAX(edgeData[i].co, min_r, max_r); + for (i=0; i < edgeSize; i++) + minmax_v3_v3v3(CCG_elem_offset_co(&key, edgeData, i), min_r, max_r); } for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { @@ -672,11 +686,11 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); for (S = 0; S < numVerts; S++) { - DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); + CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); for (y = 0; y < gridSize; y++) for (x = 0; x < gridSize; x++) - DO_MINMAX(faceGridData[y * gridSize + x].co, min_r, max_r); + minmax_v3_v3v3(CCG_grid_elem_co(&key, faceGridData, x, y), min_r, max_r); } } @@ -718,9 +732,11 @@ static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; - DMGridData *vd; + 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)) { @@ -752,16 +768,16 @@ static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv) offset = vertNum - ccgdm->faceMap[i].startVert; if (offset < 1) { vd = ccgSubSurf_getFaceCenterData(f); - copy_v3_v3(mv->co, vd->co); - normal_float_to_short_v3(mv->no, vd->no); + 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, vd->co); - normal_float_to_short_v3(mv->no, vd->no); + 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; @@ -770,8 +786,8 @@ static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv) y = offset / gridSideVerts + 1; x = offset % gridSideVerts + 1; vd = ccgSubSurf_getFaceGridData(ss, f, grid, x, y); - copy_v3_v3(mv->co, vd->co); - normal_float_to_short_v3(mv->no, vd->no); + 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)) { @@ -789,8 +805,8 @@ static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv) x = vertNum - ccgdm->edgeMap[i].startVert + 1; vd = ccgSubSurf_getEdgeData(ss, e, x); - copy_v3_v3(mv->co, vd->co); - normal_float_to_short_v3(mv->no, vd->no); + 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 */ @@ -799,8 +815,8 @@ static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv) v = ccgdm->vertMap[i].vert; vd = ccgSubSurf_getVertData(ss, v); - copy_v3_v3(mv->co, vd->co); - normal_float_to_short_v3(mv->no, vd->no); + copy_v3_v3(mv->co, CCG_elem_co(&key, vd)); + normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd)); } } @@ -1025,28 +1041,31 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; - DMGridData *vd; + CCGElem *vd; + CCGKey key; int index; int totvert, totedge, totface; int gridSize = ccgSubSurf_getGridSize(ss); int edgeSize = ccgSubSurf_getEdgeSize(ss); 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); - copy_v3_v3(mvert[i].co, vd->co); - normal_float_to_short_v3(mvert[i].no, vd->no); + copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd)); + normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key, vd)); i++; for (S = 0; S < numVerts; S++) { for (x = 1; x < gridSize - 1; x++, i++) { vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x); - copy_v3_v3(mvert[i].co, vd->co); - normal_float_to_short_v3(mvert[i].no, vd->no); + copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd)); + normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key, vd)); } } @@ -1054,8 +1073,8 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert) for (y = 1; y < gridSize - 1; y++) { for (x = 1; x < gridSize - 1; x++, i++) { vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y); - copy_v3_v3(mvert[i].co, vd->co); - normal_float_to_short_v3(mvert[i].no, vd->no); + copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd)); + normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key, vd)); } } } @@ -1068,13 +1087,13 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert) for (x = 1; x < edgeSize - 1; x++, i++) { vd = ccgSubSurf_getEdgeData(ss, e, x); - copy_v3_v3(mvert[i].co, vd->co); + copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd)); /* 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 */ - normal_float_to_short_v3(mvert[i].no, vd->no); + normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key, vd)); } } @@ -1083,8 +1102,8 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert) CCGVert *v = ccgdm->vertMap[index].vert; vd = ccgSubSurf_getVertData(ss, v); - copy_v3_v3(mvert[i].co, vd->co); - normal_float_to_short_v3(mvert[i].no, vd->no); + copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd)); + normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key, vd)); i++; } } @@ -1406,14 +1425,16 @@ static void ccgDM_foreachMappedVert( { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss); + CCGKey key; + CCG_key_top_level(&key, ccgdm->ss); for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { CCGVert *v = ccgVertIterator_getCurrent(vi); - DMGridData *vd = ccgSubSurf_getVertData(ccgdm->ss, v); + CCGElem *vd = ccgSubSurf_getVertData(ccgdm->ss, v); int index = ccgDM_getVertMapIndex(ccgdm->ss, v); if (index != -1) - func(userData, index, vd->co, vd->no, NULL); + func(userData, index, CCG_elem_co(&key, vd), CCG_elem_no(&key, vd), NULL); } ccgVertIterator_free(vi); @@ -1427,16 +1448,19 @@ static void ccgDM_foreachMappedEdge( CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); + CCGKey key; int i, edgeSize = ccgSubSurf_getEdgeSize(ss); + CCG_key_top_level(&key, ss); + for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); - DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); + CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); int index = ccgDM_getEdgeMapIndex(ss, e); if (index != -1) { for (i = 0; i < edgeSize - 1; i++) - func(userData, index, edgeData[i].co, edgeData[i + 1].co); + func(userData, index, CCG_elem_offset_co(&key, edgeData, i), CCG_elem_offset_co(&key, edgeData, i + 1)); } } @@ -1508,18 +1532,20 @@ static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdge { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; + CCGKey key; int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss); int totedge = ccgSubSurf_getNumEdges(ss); int gridSize = ccgSubSurf_getGridSize(ss); int useAging; + CCG_key_top_level(&key, ss); ccgdm_pbvh_update(ccgdm); ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); for (j = 0; j < totedge; j++) { CCGEdge *e = ccgdm->edgeMap[j].edge; - DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); + CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(e)) continue; @@ -1534,8 +1560,8 @@ static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdge glBegin(GL_LINE_STRIP); for (i = 0; i < edgeSize - 1; i++) { - glVertex3fv(edgeData[i].co); - glVertex3fv(edgeData[i + 1].co); + glVertex3fv(CCG_elem_offset_co(&key, edgeData, i)); + glVertex3fv(CCG_elem_offset_co(&key, edgeData, i + 1)); } glEnd(); } @@ -1552,22 +1578,22 @@ static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdge int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); for (S = 0; S < numVerts; S++) { - DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); + CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); glBegin(GL_LINE_STRIP); for (x = 0; x < gridSize; x++) - glVertex3fv(faceGridData[x].co); + glVertex3fv(CCG_elem_offset_co(&key, faceGridData, x)); glEnd(); for (y = 1; y < gridSize - 1; y++) { glBegin(GL_LINE_STRIP); for (x = 0; x < gridSize; x++) - glVertex3fv(faceGridData[y * gridSize + x].co); + glVertex3fv(CCG_grid_elem_co(&key, faceGridData, x, y)); glEnd(); } for (x = 1; x < gridSize - 1; x++) { glBegin(GL_LINE_STRIP); for (y = 0; y < gridSize; y++) - glVertex3fv(faceGridData[y * gridSize + x].co); + glVertex3fv(CCG_grid_elem_co(&key, faceGridData, x, y)); glEnd(); } } @@ -1579,18 +1605,21 @@ static void ccgDM_drawLooseEdges(DerivedMesh *dm) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; + CCGKey key; int totedge = ccgSubSurf_getNumEdges(ss); int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss); + CCG_key_top_level(&key, ss); + for (j = 0; j < totedge; j++) { CCGEdge *e = ccgdm->edgeMap[j].edge; - DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); + CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); if (!ccgSubSurf_getEdgeNumFaces(e)) { glBegin(GL_LINE_STRIP); for (i = 0; i < edgeSize - 1; i++) { - glVertex3fv(edgeData[i].co); - glVertex3fv(edgeData[i + 1].co); + glVertex3fv(CCG_elem_offset_co(&key, edgeData, i)); + glVertex3fv(CCG_elem_offset_co(&key, edgeData, i + 1)); } glEnd(); } @@ -1616,12 +1645,14 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; + CCGKey key; int gridSize = ccgSubSurf_getGridSize(ss); DMFlagMat *faceFlags = ccgdm->faceFlags; int step = (fast) ? gridSize - 1 : 1; int i, totface = ccgSubSurf_getNumFaces(ss); int drawcurrent = 0, matnr = -1, shademodel = -1; + CCG_key_top_level(&key, ss); ccgdm_pbvh_update(ccgdm); if (ccgdm->pbvh && ccgdm->multires.mmd && !fast) { @@ -1661,19 +1692,19 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes) continue; for (S = 0; S < numVerts; S++) { - DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); + CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); if (shademodel == GL_SMOOTH) { for (y = 0; y < gridSize - 1; y += step) { glBegin(GL_QUAD_STRIP); for (x = 0; x < gridSize; x += step) { - DMGridData *a = &faceGridData[(y + 0) * gridSize + x]; - DMGridData *b = &faceGridData[(y + step) * gridSize + x]; + CCGElem *a = CCG_grid_elem(&key, faceGridData, x, y + 0); + CCGElem *b = CCG_grid_elem(&key, faceGridData, x, y + step); - glNormal3fv(a->no); - glVertex3fv(a->co); - glNormal3fv(b->no); - glVertex3fv(b->co); + glNormal3fv(CCG_elem_no(&key, a)); + glVertex3fv(CCG_elem_co(&key, a)); + glNormal3fv(CCG_elem_no(&key, b)); + glVertex3fv(CCG_elem_co(&key, b)); } glEnd(); } @@ -1682,10 +1713,10 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes) glBegin(GL_QUADS); for (y = 0; y < gridSize - 1; y += step) { for (x = 0; x < gridSize - 1; x += step) { - float *a = faceGridData[(y + 0) * gridSize + x].co; - float *b = faceGridData[(y + 0) * gridSize + x + step].co; - float *c = faceGridData[(y + step) * gridSize + x + step].co; - float *d = faceGridData[(y + step) * gridSize + x].co; + float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0); + float *b = CCG_grid_elem_co(&key, faceGridData, x + step, y + 0); + float *c = CCG_grid_elem_co(&key, faceGridData, x + step, y + step); + float *d = CCG_grid_elem_co(&key, faceGridData, x, y + step); ccgDM_glNormalFast(a, b, c, d); @@ -1709,6 +1740,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; + CCGKey key; GPUVertexAttribs gattribs; DMVertexAttribs attribs = {{{NULL}}}; /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */ @@ -1718,6 +1750,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, DMFlagMat *faceFlags = ccgdm->faceFlags; int a, b, i, doDraw, numVerts, matnr, new_matnr, totface; + CCG_key_top_level(&key, ss); ccgdm_pbvh_update(ccgdm); doDraw = 0; @@ -1775,40 +1808,40 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, continue; } - glShadeModel(drawSmooth ? GL_SMOOTH : GL_FLAT); + glShadeModel(drawSmooth ? GL_SMOOTH: GL_FLAT); for (S = 0; S < numVerts; S++) { - DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - DMGridData *vda, *vdb; + CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); + CCGElem *vda, *vdb; if (drawSmooth) { for (y = 0; y < gridFaces; y++) { glBegin(GL_QUAD_STRIP); for (x = 0; x < gridFaces; x++) { - vda = &faceGridData[(y + 0) * gridSize + x]; - vdb = &faceGridData[(y + 1) * gridSize + x]; + vda = CCG_grid_elem(&key, faceGridData, x, y + 0); + vdb = CCG_grid_elem(&key, faceGridData, x, y + 1); PASSATTRIB(0, 0, 0); - glNormal3fv(vda->no); - glVertex3fv(vda->co); + glNormal3fv(CCG_elem_no(&key, vda)); + glVertex3fv(CCG_elem_co(&key, vda)); PASSATTRIB(0, 1, 1); - glNormal3fv(vdb->no); - glVertex3fv(vdb->co); + glNormal3fv(CCG_elem_no(&key, vdb)); + glVertex3fv(CCG_elem_co(&key, vdb)); if (x != gridFaces - 1) a++; } - vda = &faceGridData[(y + 0) * gridSize + x]; - vdb = &faceGridData[(y + 1) * gridSize + x]; + vda = CCG_grid_elem(&key, faceGridData, x, y + 0); + vdb = CCG_grid_elem(&key, faceGridData, x, y + 1); PASSATTRIB(0, 0, 3); - glNormal3fv(vda->no); - glVertex3fv(vda->co); + glNormal3fv(CCG_elem_no(&key, vda)); + glVertex3fv(CCG_elem_co(&key, vda)); PASSATTRIB(0, 1, 2); - glNormal3fv(vdb->no); - glVertex3fv(vdb->co); + glNormal3fv(CCG_elem_no(&key, vdb)); + glVertex3fv(CCG_elem_co(&key, vdb)); glEnd(); @@ -1819,10 +1852,10 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, glBegin(GL_QUADS); for (y = 0; y < gridFaces; y++) { for (x = 0; x < gridFaces; x++) { - float *aco = faceGridData[(y + 0) * gridSize + x].co; - float *bco = faceGridData[(y + 0) * gridSize + x + 1].co; - float *cco = faceGridData[(y + 1) * gridSize + x + 1].co; - float *dco = faceGridData[(y + 1) * gridSize + x].co; + float *aco = CCG_grid_elem_co(&key, faceGridData, x, y); + float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y); + float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); + float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1); ccgDM_glNormalFast(aco, bco, cco, dco); @@ -1856,6 +1889,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void * { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; + CCGKey key; GPUVertexAttribs gattribs; DMVertexAttribs attribs = {{{NULL}}}; int gridSize = ccgSubSurf_getGridSize(ss); @@ -1864,6 +1898,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void * DMFlagMat *faceFlags = ccgdm->faceFlags; int a, b, i, numVerts, matnr, new_matnr, totface; + CCG_key_top_level(&key, ss); ccgdm_pbvh_update(ccgdm); matnr = -1; @@ -1927,40 +1962,40 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void * } /* draw face*/ - glShadeModel(drawSmooth ? GL_SMOOTH : GL_FLAT); + glShadeModel(drawSmooth ? GL_SMOOTH: GL_FLAT); for (S = 0; S < numVerts; S++) { - DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - DMGridData *vda, *vdb; + CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); + CCGElem *vda, *vdb; if (drawSmooth) { for (y = 0; y < gridFaces; y++) { glBegin(GL_QUAD_STRIP); for (x = 0; x < gridFaces; x++) { - vda = &faceGridData[(y + 0) * gridSize + x]; - vdb = &faceGridData[(y + 1) * gridSize + x]; + vda = CCG_grid_elem(&key, faceGridData, x, y); + vdb = CCG_grid_elem(&key, faceGridData, x, y + 1); PASSATTRIB(0, 0, 0); - glNormal3fv(vda->no); - glVertex3fv(vda->co); + glNormal3fv(CCG_elem_no(&key, vda)); + glVertex3fv(CCG_elem_co(&key, vda)); PASSATTRIB(0, 1, 1); - glNormal3fv(vdb->no); - glVertex3fv(vdb->co); + glNormal3fv(CCG_elem_no(&key, vdb)); + glVertex3fv(CCG_elem_co(&key, vdb)); if (x != gridFaces - 1) a++; } - vda = &faceGridData[(y + 0) * gridSize + x]; - vdb = &faceGridData[(y + 1) * gridSize + x]; + vda = CCG_grid_elem(&key, faceGridData, x, y + 0); + vdb = CCG_grid_elem(&key, faceGridData, x, y + 1); PASSATTRIB(0, 0, 3); - glNormal3fv(vda->no); - glVertex3fv(vda->co); + glNormal3fv(CCG_elem_no(&key, vda)); + glVertex3fv(CCG_elem_co(&key, vda)); PASSATTRIB(0, 1, 2); - glNormal3fv(vdb->no); - glVertex3fv(vdb->co); + glNormal3fv(CCG_elem_no(&key, vdb)); + glVertex3fv(CCG_elem_co(&key, vdb)); glEnd(); @@ -1969,12 +2004,12 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void * } else { glBegin(GL_QUADS); - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - float *aco = faceGridData[(y + 0) * gridSize + x].co; - float *bco = faceGridData[(y + 0) * gridSize + x + 1].co; - float *cco = faceGridData[(y + 1) * gridSize + x + 1].co; - float *dco = faceGridData[(y + 1) * gridSize + x].co; + for (y=0; y < gridFaces; y++) { + for (x=0; x < gridFaces; x++) { + float *aco = CCG_grid_elem_co(&key, faceGridData, x, y + 0); + float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0); + float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); + float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1); ccgDM_glNormalFast(aco, bco, cco, dco); @@ -2006,6 +2041,7 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; + CCGKey key; MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL); MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); DMFlagMat *faceFlags = ccgdm->faceFlags; @@ -2015,6 +2051,7 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, (void) compareDrawOptions; + CCG_key_top_level(&key, ss); ccgdm_pbvh_update(ccgdm); if (!mcol) @@ -2063,26 +2100,26 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, } for (S = 0; S < numVerts; S++) { - DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - DMGridData *a, *b; + CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); + CCGElem *a, *b; if (drawSmooth) { glShadeModel(GL_SMOOTH); for (y = 0; y < gridFaces; y++) { glBegin(GL_QUAD_STRIP); - for (x = 0; x < gridFaces; x++) { - a = &faceGridData[(y + 0) * gridSize + x]; - b = &faceGridData[(y + 1) * gridSize + x]; + for (x=0; xuv[0]); if (cp) glColor3ub(cp[3], cp[2], cp[1]); - glNormal3fv(a->no); - glVertex3fv(a->co); + glNormal3fv(CCG_elem_no(&key, a)); + glVertex3fv(CCG_elem_co(&key, a)); if (tf) glTexCoord2fv(tf->uv[1]); if (cp) glColor3ub(cp[7], cp[6], cp[5]); - glNormal3fv(b->no); - glVertex3fv(b->co); + glNormal3fv(CCG_elem_no(&key, b)); + glVertex3fv(CCG_elem_co(&key, b)); if (x != gridFaces - 1) { if (tf) tf++; @@ -2090,18 +2127,18 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, } } - a = &faceGridData[(y + 0) * gridSize + x]; - b = &faceGridData[(y + 1) * gridSize + x]; + a = CCG_grid_elem(&key, faceGridData, x, y + 0); + b = CCG_grid_elem(&key, faceGridData, x, y + 1); if (tf) glTexCoord2fv(tf->uv[3]); if (cp) glColor3ub(cp[15], cp[14], cp[13]); - glNormal3fv(a->no); - glVertex3fv(a->co); + glNormal3fv(CCG_elem_no(&key, a)); + glVertex3fv(CCG_elem_co(&key, a)); if (tf) glTexCoord2fv(tf->uv[2]); if (cp) glColor3ub(cp[11], cp[10], cp[9]); - glNormal3fv(b->no); - glVertex3fv(b->co); + glNormal3fv(CCG_elem_no(&key, b)); + glVertex3fv(CCG_elem_co(&key, b)); if (tf) tf++; if (cp) cp += 16; @@ -2114,10 +2151,10 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, glBegin(GL_QUADS); for (y = 0; y < gridFaces; y++) { for (x = 0; x < gridFaces; x++) { - float *a_co = faceGridData[(y + 0) * gridSize + x].co; - float *b_co = faceGridData[(y + 0) * gridSize + x + 1].co; - float *c_co = faceGridData[(y + 1) * gridSize + x + 1].co; - float *d_co = faceGridData[(y + 1) * gridSize + x].co; + float *a_co = CCG_grid_elem_co(&key, faceGridData, x, y + 0); + float *b_co = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0); + float *c_co = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); + float *d_co = CCG_grid_elem_co(&key, faceGridData, x, y + 1); ccgDM_glNormalFast(a_co, b_co, c_co, d_co); @@ -2205,12 +2242,15 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; + CCGKey key; MCol *mcol = NULL; int i, gridSize = ccgSubSurf_getGridSize(ss); DMFlagMat *faceFlags = ccgdm->faceFlags; int useColors = flag & DM_DRAW_USE_COLORS; int gridFaces = gridSize - 1, totface; + CCG_key_top_level(&key, ss); + /* currently unused -- each original face is handled separately */ (void)compareDrawOptions; @@ -2257,37 +2297,37 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, * normals are already used to change shading */ glShadeModel(GL_SMOOTH); - for (S = 0; S < numVerts; S++) { - DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); + for (S=0; Sno); - glVertex3fv(a->co); + glNormal3fv(CCG_elem_no(&key, a)); + glVertex3fv(CCG_elem_co(&key, a)); if (cp) glColor3ub(cp[7], cp[6], cp[5]); - glNormal3fv(b->no); - glVertex3fv(b->co); + glNormal3fv(CCG_elem_no(&key, b)); + glVertex3fv(CCG_elem_co(&key, b)); if (x != gridFaces - 1) { if (cp) cp += 16; } } - a = &faceGridData[(y + 0) * gridSize + x]; - b = &faceGridData[(y + 1) * gridSize + x]; + a = CCG_grid_elem(&key, faceGridData, x, y + 0); + b = CCG_grid_elem(&key, faceGridData, x, y + 1); if (cp) glColor3ub(cp[15], cp[14], cp[13]); - glNormal3fv(a->no); - glVertex3fv(a->co); + glNormal3fv(CCG_elem_no(&key, a)); + glVertex3fv(CCG_elem_co(&key, a)); if (cp) glColor3ub(cp[11], cp[10], cp[9]); - glNormal3fv(b->no); - glVertex3fv(b->co); + glNormal3fv(CCG_elem_no(&key, b)); + glVertex3fv(CCG_elem_co(&key, b)); if (cp) cp += 16; @@ -2298,10 +2338,10 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, glBegin(GL_QUADS); for (y = 0; y < gridFaces; y++) { for (x = 0; x < gridFaces; x++) { - float *a = faceGridData[(y + 0) * gridSize + x].co; - float *b = faceGridData[(y + 0) * gridSize + x + 1].co; - float *c = faceGridData[(y + 1) * gridSize + x + 1].co; - float *d = faceGridData[(y + 1) * gridSize + x].co; + float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0); + float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0); + float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); + float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1); ccgDM_glNormalFast(a, b, c, d); @@ -2334,13 +2374,15 @@ static void ccgDM_drawMappedEdges(DerivedMesh *dm, CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); + CCGKey key; int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss); + CCG_key_top_level(&key, ss); ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); - DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); + CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); int index = ccgDM_getEdgeMapIndex(ss, e); glBegin(GL_LINE_STRIP); @@ -2351,8 +2393,8 @@ static void ccgDM_drawMappedEdges(DerivedMesh *dm, } for (i = 0; i < edgeSize - 1; i++) { - glVertex3fv(edgeData[i].co); - glVertex3fv(edgeData[i + 1].co); + glVertex3fv(CCG_elem_offset_co(&key, edgeData, i)); + glVertex3fv(CCG_elem_offset_co(&key, edgeData, i + 1)); } } glEnd(); @@ -2368,14 +2410,16 @@ static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; + CCGKey key; CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss); + CCG_key_top_level(&key, ss); ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); - DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); + CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); int index = ccgDM_getEdgeMapIndex(ss, e); glBegin(GL_LINE_STRIP); @@ -2388,7 +2432,7 @@ static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, glColor3ub(0, ageCol > 0 ? ageCol : 0, 0); } - glVertex3fv(edgeData[i].co); + glVertex3fv(CCG_elem_offset_co(&key, edgeData, i)); } } glEnd(); @@ -2404,17 +2448,20 @@ static void ccgDM_foreachMappedFaceCenter( { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; + CCGKey key; CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); + CCG_key_top_level(&key, ss); + for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { CCGFace *f = ccgFaceIterator_getCurrent(fi); int index = ccgDM_getFaceMapIndex(ss, f); if (index != -1) { - /* Face center data normal isn't updated atm. */ - DMGridData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0); + /* Face center data normal isn't updated atm. */ + CCGElem *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0); - func(userData, index, vd->co, vd->no); + func(userData, index, CCG_elem_co(&key, vd), CCG_elem_no(&key, vd)); } } @@ -2727,7 +2774,7 @@ static void ccgdm_create_grids(DerivedMesh *dm) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; CCGSubSurf *ss = ccgdm->ss; - DMGridData **gridData; + CCGElem **gridData; DMGridAdjacency *gridAdjacency, *adj; DMFlagMat *gridFlagMats; CCGFace **gridFaces; @@ -2753,7 +2800,7 @@ static void ccgdm_create_grids(DerivedMesh *dm) } /* compute grid data */ - gridData = MEM_mallocN(sizeof(DMGridData *) * numGrids, "ccgdm.gridData"); + gridData = MEM_mallocN(sizeof(CCGElem *) * numGrids, "ccgdm.gridData"); gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency) * numGrids, "ccgdm.gridAdjacency"); gridFaces = MEM_mallocN(sizeof(CCGFace *) * numGrids, "ccgdm.gridFaces"); gridFlagMats = MEM_mallocN(sizeof(DMFlagMat) * numGrids, "ccgdm.gridFlagMats"); @@ -2792,7 +2839,7 @@ static void ccgdm_create_grids(DerivedMesh *dm) ccgdm->gridFlagMats = gridFlagMats; } -static DMGridData **ccgDM_getGridData(DerivedMesh *dm) +static CCGElem **ccgDM_getGridData(DerivedMesh *dm) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; @@ -2816,6 +2863,12 @@ static int *ccgDM_getGridOffset(DerivedMesh *dm) return ccgdm->gridOffset; } +static void ccgDM_getGridKey(DerivedMesh *dm, CCGKey *key) +{ + CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; + CCG_key_top_level(key, ccgdm->ss); +} + static DMFlagMat *ccgDM_getGridFlagMats(DerivedMesh *dm) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; @@ -2862,7 +2915,10 @@ static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm) static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; - int gridSize, numGrids, grid_pbvh; + CCGKey key; + int numGrids, grid_pbvh; + + CCG_key_top_level(&key, ccgdm->ss); if (!ob) { ccgdm->pbvh = NULL; @@ -2896,16 +2952,15 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) if (grid_pbvh) { ccgdm_create_grids(dm); - gridSize = ccgDM_getGridSize(dm); numGrids = ccgDM_getNumGrids(dm); ob->sculpt->pbvh = ccgdm->pbvh = BLI_pbvh_new(); BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, - numGrids, gridSize, (void **)ccgdm->gridFaces, ccgdm->gridFlagMats, ccgdm->gridHidden); + numGrids, &key, (void **) ccgdm->gridFaces, ccgdm->gridFlagMats, ccgdm->gridHidden); } - else if (ob->type == OB_MESH) { - Mesh *me = ob->data; - ob->sculpt->pbvh = ccgdm->pbvh = BLI_pbvh_new(); + else if(ob->type == OB_MESH) { + Mesh *me= ob->data; + ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new(); BLI_assert(!(me->mface == NULL && me->mpoly != NULL)); /* BMESH ONLY complain if mpoly is valid but not mface */ BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert, me->totface, me->totvert); @@ -3022,6 +3077,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, ccgdm->dm.getGridData = ccgDM_getGridData; ccgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency; 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; diff --git a/source/blender/blenlib/BLI_pbvh.h b/source/blender/blenlib/BLI_pbvh.h index e6578390ea6..b69579128ba 100644 --- a/source/blender/blenlib/BLI_pbvh.h +++ b/source/blender/blenlib/BLI_pbvh.h @@ -28,9 +28,10 @@ #include "BLI_bitmap.h" +struct CCGElem; +struct CCGKey; struct DMFlagMat; struct DMGridAdjacency; -struct DMGridData; struct ListBase; struct MFace; struct MVert; @@ -57,9 +58,9 @@ typedef void (*BLI_pbvh_HitOccludedCallback)(PBVHNode *node, void *data, float* PBVH *BLI_pbvh_new(void); void BLI_pbvh_build_mesh(PBVH *bvh, struct MFace *faces, struct MVert *verts, int totface, int totvert); -void BLI_pbvh_build_grids(PBVH *bvh, struct DMGridData **grids, +void BLI_pbvh_build_grids(PBVH *bvh, struct CCGElem **grid_elems, struct DMGridAdjacency *gridadj, int totgrid, - int gridsize, void **gridfaces, struct DMFlagMat *flagmats, + struct CCGKey *key, void **gridfaces, struct DMFlagMat *flagmats, unsigned int **grid_hidden); void BLI_pbvh_free(PBVH *bvh); @@ -102,6 +103,9 @@ PBVHType BLI_pbvh_type(const PBVH *bvh); /* multires hidden data, only valid for type == PBVH_GRIDS */ unsigned int **BLI_pbvh_grid_hidden(const PBVH *bvh); +/* multires level, only valid for type == PBVH_GRIDS */ +void BLI_pbvh_get_grid_key(const PBVH *pbvh, struct CCGKey *key); + /* Node Access */ typedef enum { @@ -123,7 +127,7 @@ void BLI_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden); void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int *totgrid, int *maxgrid, int *gridsize, - struct DMGridData ***griddata, struct DMGridAdjacency **gridadj); + struct CCGElem ***grid_elems, struct DMGridAdjacency **gridadj); void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, int *uniquevert, int *totvert); void BLI_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node, @@ -144,7 +148,7 @@ int BLI_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data); void BLI_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]); void BLI_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3]); void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface); -void BLI_pbvh_grids_update(PBVH *bvh, struct DMGridData **grids, +void BLI_pbvh_grids_update(PBVH *bvh, struct CCGElem **grid_elems, struct DMGridAdjacency *gridadj, void **gridfaces); /* vertex deformer */ @@ -174,8 +178,9 @@ typedef struct PBVHVertexIter { int i; /* grid */ - struct DMGridData **grids; - struct DMGridData *grid; + struct CCGElem **grids; + struct CCGElem *grid; + struct CCGKey *key; BLI_bitmap *grid_hidden, gh; int *grid_indices; int totgrid; @@ -220,9 +225,9 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, for(vi.gy=0; vi.gyco; \ - vi.fno= vi.grid->no; \ - vi.grid++; \ + vi.co= CCG_elem_co(vi.key, vi.grid); \ + vi.fno= CCG_elem_no(vi.key, vi.grid); \ + vi.grid= CCG_elem_next(vi.key, vi.grid); \ if(vi.gh) { \ if(BLI_BITMAP_GET(vi.gh, vi.gy * vi.gridsize + vi.gx)) \ continue; \ diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenlib/intern/pbvh.c index 4ad350c7786..1e87b44784e 100644 --- a/source/blender/blenlib/intern/pbvh.c +++ b/source/blender/blenlib/intern/pbvh.c @@ -34,6 +34,7 @@ #include "BLI_ghash.h" #include "BLI_pbvh.h" +#include "BKE_ccg.h" #include "BKE_DerivedMesh.h" #include "BKE_mesh.h" /* for BKE_mesh_calc_normals */ #include "BKE_global.h" /* for BKE_mesh_calc_normals */ @@ -137,12 +138,12 @@ struct PBVH { MFace *faces; /* Grid Data */ - DMGridData **grids; + CCGKey gridkey; + CCGElem **grids; DMGridAdjacency *gridadj; void **gridfaces; const DMFlagMat *grid_flag_mats; int totgrid; - int gridsize; BLI_bitmap *grid_hidden; /* Only used during BVH build and update, @@ -447,7 +448,7 @@ static void build_grids_leaf_node(PBVH *bvh, PBVHNode *node) if (!G.background) { node->draw_buffers = GPU_build_grid_buffers(node->prim_indices, - node->totprim, bvh->grid_hidden, bvh->gridsize); + node->totprim, bvh->grid_hidden, bvh->gridkey.grid_size); } node->flag |= PBVH_UpdateDrawBuffers; } @@ -642,11 +643,12 @@ void BLI_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int totface, int } /* Do a full rebuild with on Grids data structure */ -void BLI_pbvh_build_grids(PBVH *bvh, DMGridData **grids, DMGridAdjacency *gridadj, - int totgrid, int gridsize, void **gridfaces, DMFlagMat *flagmats, BLI_bitmap *grid_hidden) +void BLI_pbvh_build_grids(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj, + int totgrid, CCGKey *key, void **gridfaces, DMFlagMat *flagmats, BLI_bitmap *grid_hidden) { BBC *prim_bbc = NULL; BB cb; + int gridsize = key->grid_size; int i, j; bvh->type = PBVH_GRIDS; @@ -655,7 +657,7 @@ void BLI_pbvh_build_grids(PBVH *bvh, DMGridData **grids, DMGridAdjacency *gridad bvh->gridfaces= gridfaces; bvh->grid_flag_mats= flagmats; bvh->totgrid= totgrid; - bvh->gridsize= gridsize; + bvh->gridkey = *key; bvh->grid_hidden= grid_hidden; bvh->leaf_limit = MAX2(LEAF_LIMIT/((gridsize-1)*(gridsize-1)), 1); @@ -665,13 +667,13 @@ void BLI_pbvh_build_grids(PBVH *bvh, DMGridData **grids, DMGridAdjacency *gridad prim_bbc = MEM_mallocN(sizeof(BBC) * totgrid, "prim_bbc"); for (i = 0; i < totgrid; ++i) { - DMGridData *grid= grids[i]; + CCGElem *grid= grids[i]; BBC *bbc = prim_bbc + i; BB_reset((BB*)bbc); for (j = 0; j < gridsize*gridsize; ++j) - BB_expand((BB*)bbc, grid[j].co); + BB_expand((BB*)bbc, CCG_elem_offset_co(key, grid, j)); BBC_update_centroid(bbc); @@ -1137,7 +1139,7 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode) if (bvh->grids) { node->draw_buffers = GPU_build_grid_buffers(node->prim_indices, - node->totprim, bvh->grid_hidden, bvh->gridsize); + node->totprim, bvh->grid_hidden, bvh->gridkey.grid_size); } else { node->draw_buffers = @@ -1158,7 +1160,7 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode) bvh->grid_flag_mats, node->prim_indices, node->totprim, - bvh->gridsize); + &bvh->gridkey); break; case PBVH_FACES: GPU_update_mesh_buffers(node->draw_buffers, @@ -1315,6 +1317,12 @@ BLI_bitmap *BLI_pbvh_grid_hidden(const PBVH *bvh) return bvh->grid_hidden; } +void BLI_pbvh_get_grid_key(const PBVH *bvh, CCGKey *key) +{ + BLI_assert(bvh->type == PBVH_GRIDS); + *key = bvh->gridkey; +} + /***************************** Node Access ***********************************/ void BLI_pbvh_node_mark_update(PBVHNode *node) @@ -1349,7 +1357,7 @@ void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, int *uniquevert, int *to switch (bvh->type) { case PBVH_GRIDS: - tot= node->totprim*bvh->gridsize*bvh->gridsize; + tot= node->totprim * bvh->gridkey.grid_area; if (totvert) *totvert= tot; if (uniquevert) *uniquevert= tot; break; @@ -1360,14 +1368,14 @@ void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, int *uniquevert, int *to } } -void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int *totgrid, int *maxgrid, int *gridsize, DMGridData ***griddata, DMGridAdjacency **gridadj) +void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int *totgrid, int *maxgrid, int *gridsize, CCGElem ***griddata, DMGridAdjacency **gridadj) { switch (bvh->type) { case PBVH_GRIDS: if (grid_indices) *grid_indices= node->prim_indices; if (totgrid) *totgrid= node->totprim; if (maxgrid) *maxgrid= bvh->totgrid; - if (gridsize) *gridsize= bvh->gridsize; + if (gridsize) *gridsize= bvh->gridkey.grid_size; if (griddata) *griddata= bvh->grids; if (gridadj) *gridadj= bvh->gridadj; break; @@ -1541,10 +1549,10 @@ int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], break; case PBVH_GRIDS: totgrid= node->totprim; - gridsize= bvh->gridsize; + gridsize= bvh->gridkey.grid_size; for (i = 0; i < totgrid; ++i) { - DMGridData *grid= bvh->grids[node->prim_indices[i]]; + CCGElem *grid= bvh->grids[node->prim_indices[i]]; if (!grid) continue; @@ -1568,11 +1576,11 @@ int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], } else { hit |= ray_face_intersection(ray_start, ray_normal, - grid[y*gridsize + x].co, - grid[y*gridsize + x+1].co, - grid[(y+1)*gridsize + x+1].co, - grid[(y+1)*gridsize + x].co, - dist); + CCG_grid_elem_co(&bvh->gridkey, grid, x, y), + CCG_grid_elem_co(&bvh->gridkey, grid, x+1, y), + CCG_grid_elem_co(&bvh->gridkey, grid, x+1, y+1), + CCG_grid_elem_co(&bvh->gridkey, grid, x, y+1), + dist); } } } @@ -1690,7 +1698,7 @@ void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3], } } -void BLI_pbvh_grids_update(PBVH *bvh, DMGridData **grids, DMGridAdjacency *gridadj, void **gridfaces) +void BLI_pbvh_grids_update(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj, void **gridfaces) { bvh->grids= grids; bvh->gridadj= gridadj; @@ -1777,7 +1785,7 @@ PBVHProxyNode* BLI_pbvh_node_add_proxy(PBVH* bvh, PBVHNode* node) node->proxies= MEM_mallocN(sizeof(PBVHProxyNode), "PBVHNodeProxy"); if (bvh->grids) - totverts = node->totprim*bvh->gridsize*bvh->gridsize; + totverts = node->totprim*bvh->gridkey.grid_area; else totverts = node->uniq_verts; @@ -1845,7 +1853,7 @@ void BLI_pbvh_gather_proxies(PBVH* pbvh, PBVHNode*** r_array, int* r_tot) void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mode) { - struct DMGridData **grids; + struct CCGElem **grids; struct MVert *verts; int *grid_indices, *vert_indices; int totgrid, gridsize, uniq_verts, totvert; @@ -1858,6 +1866,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, BLI_pbvh_node_get_grids(bvh, node, &grid_indices, &totgrid, NULL, &gridsize, &grids, NULL); BLI_pbvh_node_num_verts(bvh, node, &uniq_verts, &totvert); BLI_pbvh_node_get_verts(bvh, node, &vert_indices, &verts); + vi->key = &bvh->gridkey; vi->grids= grids; vi->grid_indices= grid_indices; diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 91acb18dfda..c6155b54aec 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -49,6 +49,7 @@ #include "BLI_math_geom.h" #include "BKE_blender.h" +#include "BKE_ccg.h" #include "BKE_screen.h" #include "BKE_context.h" #include "BKE_global.h" @@ -475,32 +476,32 @@ static void interp_barycentric_tri_data(float data[3][3], float u, float v, floa /* mode = 0: interpolate normals, * mode = 1: interpolate coord */ -static void interp_bilinear_grid(DMGridData *grid, int grid_size, float crn_x, float crn_y, int mode, float res[3]) +static void interp_bilinear_grid(CCGKey *key, CCGElem *grid, float crn_x, float crn_y, int mode, float res[3]) { int x0, x1, y0, y1; float u, v; float data[4][3]; x0 = (int) crn_x; - x1 = x0 >= (grid_size - 1) ? (grid_size - 1) : (x0 + 1); + x1 = x0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (x0 + 1); y0 = (int) crn_y; - y1 = y0 >= (grid_size - 1) ? (grid_size - 1) : (y0 + 1); + y1 = y0 >= (key->grid_size - 1 ) ? (key->grid_size - 1) : (y0 + 1); u = crn_x - x0; v = crn_y - y0; if (mode == 0) { - copy_v3_v3(data[0], grid[y0 * grid_size + x0].no); - copy_v3_v3(data[1], grid[y0 * grid_size + x1].no); - copy_v3_v3(data[2], grid[y1 * grid_size + x1].no); - copy_v3_v3(data[3], grid[y1 * grid_size + x0].no); + copy_v3_v3(data[0], CCG_grid_elem_no(key, grid, x0, y0)); + copy_v3_v3(data[1], CCG_grid_elem_no(key, grid, x1, y0)); + copy_v3_v3(data[2], CCG_grid_elem_no(key, grid, x1, y1)); + copy_v3_v3(data[3], CCG_grid_elem_no(key, grid, x0, y1)); } else { - copy_v3_v3(data[0], grid[y0 * grid_size + x0].co); - copy_v3_v3(data[1], grid[y0 * grid_size + x1].co); - copy_v3_v3(data[2], grid[y1 * grid_size + x1].co); - copy_v3_v3(data[3], grid[y1 * grid_size + x0].co); + copy_v3_v3(data[0], CCG_grid_elem_co(key, grid, x0, y0)); + copy_v3_v3(data[1], CCG_grid_elem_co(key, grid, x1, y0)); + copy_v3_v3(data[2], CCG_grid_elem_co(key, grid, x1, y1)); + copy_v3_v3(data[3], CCG_grid_elem_co(key, grid, x0, y1)); } interp_bilinear_quad_data(data, u, v, res); @@ -509,7 +510,8 @@ static void interp_bilinear_grid(DMGridData *grid, int grid_size, float crn_x, f static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm, const int *origindex, const int lvl, const int face_index, const float u, const float v, float co[3], float n[3]) { MFace mface; - DMGridData **grid_data; + CCGElem **grid_data; + CCGKey key; float crn_x, crn_y; int grid_size, S, face_side; int *grid_offset, g_index; @@ -519,6 +521,7 @@ static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm, const int *orig grid_size = hidm->getGridSize(hidm); grid_data = hidm->getGridData(hidm); grid_offset = hidm->getGridOffset(hidm); + hidm->getGridKey(hidm, &key); face_side = (grid_size << 1) - 1; @@ -546,10 +549,10 @@ static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm, const int *orig CLAMP(crn_y, 0.0f, grid_size); if (n != NULL) - interp_bilinear_grid(grid_data[g_index + S], grid_size, crn_x, crn_y, 0, n); + interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 0, n); if (co != NULL) - interp_bilinear_grid(grid_data[g_index + S], grid_size, crn_x, crn_y, 1, co); + interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 1, co); } /* mode = 0: interpolate normals, diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index a3c74b33f9e..ca70a81055c 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -45,6 +45,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "BKE_ccg.h" #include "BKE_context.h" #include "BKE_DerivedMesh.h" #include "BKE_mesh.h" @@ -141,16 +142,18 @@ static void partialvis_update_grids(Object *ob, PartialVisArea area, float planes[4][4]) { - DMGridData **grids; + CCGElem **grids; + CCGKey key; BLI_bitmap *grid_hidden; int any_visible = 0; - int *grid_indices, gridsize, totgrid, any_changed, i; + int *grid_indices, totgrid, any_changed, i; /* get PBVH data */ BLI_pbvh_node_get_grids(pbvh, node, - &grid_indices, &totgrid, NULL, &gridsize, - &grids, NULL); + &grid_indices, &totgrid, NULL, NULL, + &grids, NULL); grid_hidden = BLI_pbvh_grid_hidden(pbvh); + BLI_pbvh_get_grid_key(pbvh, &key); sculpt_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN); @@ -164,8 +167,8 @@ static void partialvis_update_grids(Object *ob, switch (action) { case PARTIALVIS_HIDE: /* create grid flags data */ - gh = grid_hidden[g] = BLI_BITMAP_NEW(gridsize * gridsize, - "partialvis_update_grids"); + gh = grid_hidden[g] = BLI_BITMAP_NEW(key.grid_area, + "partialvis_update_grids"); break; case PARTIALVIS_SHOW: /* entire grid is visible, nothing to show */ @@ -182,21 +185,21 @@ static void partialvis_update_grids(Object *ob, continue; } - for (y = 0; y < gridsize; y++) { - for (x = 0; x < gridsize; x++) { - const float *co = grids[g][y * gridsize + x].co; + for (y = 0; y < key.grid_size; y++) { + for (x = 0; x < key.grid_size; x++) { + const float *co = CCG_grid_elem_co(&key, grids[g], x, y); /* skip grid element if not in the effected area */ if (is_effected(area, planes, co)) { /* set or clear the hide flag */ - BLI_BITMAP_MODIFY(gh, y * gridsize + x, - action == PARTIALVIS_HIDE); + BLI_BITMAP_MODIFY(gh, y * key.grid_size + x, + action == PARTIALVIS_HIDE); any_changed = 1; } /* keep track of whether any elements are still hidden */ - if (BLI_BITMAP_GET(gh, y * gridsize + x)) + if (BLI_BITMAP_GET(gh, y * key.grid_size + x)) any_hidden = 1; else any_visible = 1; diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 3edda91e4e4..77f9a444153 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -52,6 +52,7 @@ #include "DNA_brush_types.h" #include "BKE_brush.h" +#include "BKE_ccg.h" #include "BKE_cdderivedmesh.h" #include "BKE_context.h" #include "BKE_depsgraph.h" @@ -1049,7 +1050,8 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no { Brush *brush = paint_brush(&sd->paint); SculptBrushTest test; - DMGridData **griddata, *data; + CCGElem **griddata, *data; + CCGKey key; DMGridAdjacency *gridadj, *adj; float (*tmpgrid)[3], (*tmprow)[3]; int v1, v2, v3, v4; @@ -1060,7 +1062,8 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no CLAMP(bstrength, 0.0f, 1.0f); BLI_pbvh_node_get_grids(ss->pbvh, node, &grid_indices, &totgrid, - NULL, &gridsize, &griddata, &gridadj); + NULL, &gridsize, &griddata, &gridadj); + BLI_pbvh_get_grid_key(ss->pbvh, &key); #pragma omp critical { @@ -1078,7 +1081,9 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no float tmp[3]; v1 = y * gridsize; - add_v3_v3v3(tmprow[0], data[v1].co, data[v1 + gridsize].co); + add_v3_v3v3(tmprow[0], + CCG_elem_offset_co(&key, data, v1), + CCG_elem_offset_co(&key, data, v1 + gridsize)); for (x = 0; x < gridsize - 1; x++) { v1 = x + y * gridsize; @@ -1086,7 +1091,9 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no v3 = v1 + gridsize; v4 = v3 + 1; - add_v3_v3v3(tmprow[x + 1], data[v2].co, data[v4].co); + add_v3_v3v3(tmprow[x + 1], + CCG_elem_offset_co(&key, data, v2), + CCG_elem_offset_co(&key, data, v4)); add_v3_v3v3(tmp, tmprow[x + 1], tmprow[x]); add_v3_v3(tmpgrid[v1], tmp); @@ -1115,9 +1122,9 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no if (y == gridsize - 1 && adj->index[1] == -1) continue; - index = x + y * gridsize; - co = data[index].co; - fno = data[index].no; + index = x + y*gridsize; + co = CCG_elem_offset_co(&key, data, index); + fno = CCG_elem_offset_no(&key, data, index); if (sculpt_brush_test(&test, co)) { const float fade = bstrength * tex_strength(ss, brush, co, test.dist, diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 801bfabc748..ea5c173e410 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -47,6 +47,7 @@ #include "DNA_scene_types.h" #include "DNA_mesh_types.h" +#include "BKE_ccg.h" #include "BKE_cdderivedmesh.h" #include "BKE_context.h" #include "BKE_depsgraph.h" @@ -157,19 +158,21 @@ static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNo } else if (unode->maxgrid && dm->getGridData) { /* multires restore */ - DMGridData **grids, *grid; + CCGElem **grids, *grid; + CCGKey key; float (*co)[3]; int gridsize; grids = dm->getGridData(dm); gridsize = dm->getGridSize(dm); + dm->getGridKey(dm, &key); co = unode->co; for (j = 0; j < unode->totgrid; j++) { grid = grids[unode->grids[j]]; - for (i = 0; i < gridsize * gridsize; i++, co++) - swap_v3_v3(grid[i].co, co[0]); + for (i = 0; i < gridsize*gridsize; i++, co++) + swap_v3_v3(CCG_elem_offset_co(&key, grid, i), co[0]); } } diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index cee9039e3f9..e074b2b65a6 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -39,12 +39,11 @@ #define DEBUG_VBO(X) #endif -struct DerivedMesh; -struct DMFlagMat; -struct DMGridData; +struct CCGElem; +struct CCGKey; struct CustomData; -struct GHash; -struct DMGridData; +struct DMFlagMat; +struct DerivedMesh; struct GPUVertPointLink; typedef struct GPUBuffer { @@ -169,9 +168,9 @@ void GPU_update_mesh_buffers(GPU_Buffers *buffers, struct MVert *mvert, GPU_Buffers *GPU_build_grid_buffers(int *grid_indices, int totgrid, unsigned int **grid_hidden, int gridsize); -void GPU_update_grid_buffers(GPU_Buffers *buffers, struct DMGridData **grids, +void GPU_update_grid_buffers(GPU_Buffers *buffers, struct CCGElem **grids, const struct DMFlagMat *grid_flag_mats, - int *grid_indices, int totgrid, int gridsize); + int *grid_indices, int totgrid, const struct CCGKey *key); void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial); diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 1885b5fc979..fa350b62ebf 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -46,6 +46,7 @@ #include "DNA_meshdata_types.h" +#include "BKE_ccg.h" #include "BKE_DerivedMesh.h" #include "BKE_paint.h" #include "BKE_subsurf.h" @@ -1280,12 +1281,12 @@ struct GPU_Buffers { int totface; /* grid pointers */ - DMGridData **grids; + CCGKey gridkey; + CCGElem **grids; const DMFlagMat *grid_flag_mats; const BLI_bitmap *grid_hidden; int *grid_indices; int totgrid; - int gridsize; int has_hidden; unsigned int tot_tri, tot_quad; @@ -1402,13 +1403,14 @@ GPU_Buffers *GPU_build_mesh_buffers(int (*face_vert_indices)[4], return buffers; } -void GPU_update_grid_buffers(GPU_Buffers *buffers, DMGridData **grids, - const DMFlagMat *grid_flag_mats, int *grid_indices, int totgrid, int gridsize) +void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids, + const DMFlagMat *grid_flag_mats, int *grid_indices, + int totgrid, const CCGKey *key) { - DMGridData *vert_data; + CCGElem *vert_data; int i, j, k, totvert; - totvert= gridsize*gridsize*totgrid; + totvert= key->grid_area * totgrid; /* Build VBO */ if (buffers->vert_buf) { @@ -1416,33 +1418,33 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, DMGridData **grids, glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf); glBufferDataARB(GL_ARRAY_BUFFER_ARB, - sizeof(DMGridData) * totvert, + key->elem_size * totvert, NULL, GL_STATIC_DRAW_ARB); vert_data = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); if (vert_data) { for (i = 0; i < totgrid; ++i) { - DMGridData *grid= grids[grid_indices[i]]; - memcpy(vert_data, grid, sizeof(DMGridData)*gridsize*gridsize); + CCGElem *grid= grids[grid_indices[i]]; + memcpy(vert_data, grid, key->elem_size * key->grid_area); if (!smooth) { /* for flat shading, recalc normals and set the last vertex of * each quad in the index buffer to have the flat normal as * that is what opengl will use */ - for (j = 0; j < gridsize-1; ++j) { - for (k = 0; k < gridsize-1; ++k) { + for (j = 0; j < key->grid_size - 1; j++) { + for (k = 0; k < key->grid_size - 1; k++) { float fno[3]; normal_quad_v3(fno, - grid[(j+1)*gridsize + k].co, - grid[(j+1)*gridsize + k+1].co, - grid[j*gridsize + k+1].co, - grid[j*gridsize + k].co); + CCG_grid_elem_co(key, grid, k, j+1), + CCG_grid_elem_co(key, grid, k+1, j+1), + CCG_grid_elem_co(key, grid, k+1, j), + CCG_grid_elem_co(key, grid, k, j)); - copy_v3_v3(vert_data[(j+1)*gridsize + (k+1)].no, fno); + copy_v3_v3(CCG_grid_elem_no(key, vert_data, k+1, j+1), fno); } } } - vert_data += gridsize*gridsize; + vert_data = CCG_elem_offset(key, vert_data, key->grid_area); } glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); } @@ -1456,8 +1458,8 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, DMGridData **grids, buffers->grids = grids; buffers->grid_indices = grid_indices; buffers->totgrid = totgrid; - buffers->gridsize = gridsize; buffers->grid_flag_mats = grid_flag_mats; + buffers->gridkey = *key; //printf("node updated %p\n", buffers); } @@ -1600,7 +1602,6 @@ GPU_Buffers *GPU_build_grid_buffers(int *grid_indices, int totgrid, buffers = MEM_callocN(sizeof(GPU_Buffers), "GPU_Buffers"); buffers->grid_hidden = grid_hidden; - buffers->gridsize = gridsize; buffers->totgrid = totgrid; /* Count the number of quads */ @@ -1685,11 +1686,12 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers, int smooth) static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth) { - int i, j, x, y, gridsize = buffers->gridsize; + const CCGKey *key = &buffers->gridkey; + int i, j, x, y, gridsize = buffers->gridkey.grid_size; for (i = 0; i < buffers->totgrid; ++i) { int g = buffers->grid_indices[i]; - const DMGridData *grid = buffers->grids[g]; + CCGElem *grid = buffers->grids[g]; BLI_bitmap gh = buffers->grid_hidden[g]; /* TODO: could use strips with hiding as well */ @@ -1699,11 +1701,11 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth) for (y = 0; y < gridsize-1; y++) { for (x = 0; x < gridsize-1; x++) { - const DMGridData *e[4] = { - &grid[y*gridsize + x], - &grid[(y+1)*gridsize + x], - &grid[(y+1)*gridsize + x+1], - &grid[y*gridsize + x+1] + CCGElem *e[4] = { + CCG_grid_elem(key, grid, x+1, y+1), + CCG_grid_elem(key, grid, x+1, y), + CCG_grid_elem(key, grid, x, y), + CCG_grid_elem(key, grid, x, y+1) }; /* skip face if any of its corners are hidden */ @@ -1712,17 +1714,21 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth) if (smooth) { for (j = 0; j < 4; j++) { - glNormal3fv(e[j]->no); - glVertex3fv(e[j]->co); + glNormal3fv(CCG_elem_no(key, e[j])); + glVertex3fv(CCG_elem_co(key, e[j])); } } else { float fno[3]; - normal_quad_v3(fno, e[0]->co, e[1]->co, e[2]->co, e[3]->co); + normal_quad_v3(fno, + CCG_elem_co(key, e[0]), + CCG_elem_co(key, e[1]), + CCG_elem_co(key, e[2]), + CCG_elem_co(key, e[3])); glNormal3fv(fno); for (j = 0; j < 4; j++) - glVertex3fv(e[j]->co); + glVertex3fv(CCG_elem_co(key, e[j])); } } } @@ -1733,13 +1739,13 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth) for (y = 0; y < gridsize-1; y++) { glBegin(GL_QUAD_STRIP); for (x = 0; x < gridsize; x++) { - const DMGridData *a = &grid[y*gridsize + x]; - const DMGridData *b = &grid[(y+1)*gridsize + x]; + CCGElem *a = CCG_grid_elem(key, grid, x, y); + CCGElem *b = CCG_grid_elem(key, grid, x, y+1); - glNormal3fv(a->no); - glVertex3fv(a->co); - glNormal3fv(b->no); - glVertex3fv(b->co); + glNormal3fv(CCG_elem_no(key, a)); + glVertex3fv(CCG_elem_co(key, a)); + glNormal3fv(CCG_elem_no(key, b)); + glVertex3fv(CCG_elem_co(key, b)); } glEnd(); } @@ -1748,19 +1754,24 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth) for (y = 0; y < gridsize-1; y++) { glBegin(GL_QUAD_STRIP); for (x = 0; x < gridsize; x++) { - const DMGridData *a = &grid[y*gridsize + x]; - const DMGridData *b = &grid[(y+1)*gridsize + x]; + CCGElem *a = CCG_grid_elem(key, grid, x, y); + CCGElem *b = CCG_grid_elem(key, grid, x, y+1); if (x > 0) { - const DMGridData *c = &grid[y*gridsize + x-1]; - const DMGridData *d = &grid[(y+1)*gridsize + x-1]; + CCGElem *c = CCG_grid_elem(key, grid, x-1, y); + CCGElem *d = CCG_grid_elem(key, grid, x-1, y+1); + float fno[3]; - normal_quad_v3(fno, d->co, b->co, a->co, c->co); + normal_quad_v3(fno, + CCG_elem_co(key, d), + CCG_elem_co(key, b), + CCG_elem_co(key, a), + CCG_elem_co(key, c)); glNormal3fv(fno); } - glVertex3fv(a->co); - glVertex3fv(b->co); + glVertex3fv(CCG_elem_co(key, a)); + glVertex3fv(CCG_elem_co(key, b)); } glEnd(); } @@ -1797,15 +1808,15 @@ void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial) glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf); if (buffers->tot_quad) { - unsigned offset = 0; + char *offset = 0; int i, last = buffers->has_hidden ? 1 : buffers->totgrid; for (i = 0; i < last; i++) { - glVertexPointer(3, GL_FLOAT, sizeof(DMGridData), offset + (char*)offsetof(DMGridData, co)); - glNormalPointer(GL_FLOAT, sizeof(DMGridData), offset + (char*)offsetof(DMGridData, no)); + glVertexPointer(3, GL_FLOAT, buffers->gridkey.elem_size, offset); + glNormalPointer(GL_FLOAT, buffers->gridkey.elem_size, offset + buffers->gridkey.normal_offset); glDrawElements(GL_QUADS, buffers->tot_quad * 4, buffers->index_type, 0); - offset += buffers->gridsize * buffers->gridsize * sizeof(DMGridData); + offset += buffers->gridkey.grid_area * buffers->gridkey.elem_size; } } else {