Add mask support to CCGSubSurf and multires.
* Add new CCG function ccgSubSurf_setAllocMask(). Similar to to ccgSubSurf_setCalcVertexNormals(), it sets whether the CCG elements have a mask layer and what that layer's offset is. Unlike normals however, it doesn't change any behavior during CCG calculation; it's there only to give CCGKey information on the mask. * Add a new flag to _getSubSurf(), CCG_ALLOC_MASK. If set, space for an extra layer is allocated, but the number of CCG layers is not set to include it. This is done because GridPaintMasks are absolute, rather than being relative to the subdivided output (as MDisp displacements are), so we skip subdividing paint masks here. * Add a new flag to subsurf_make_derived_from_derived(), SUBSURF_ALLOC_PAINT_MASK. This controls whether CCG_ALLOC_MASK is set for _getSubSurf(). Related, masks are never loaded in during ss_sync_from_derivedmesh(). After subdivision is finished, if the alloc mask flag is set, the number of CCG layers is increase to 4 with ccgSubSurf_setNumLayers(). * Add a new flag to multires_make_from_derived(), MULTIRES_ALLOC_PAINT_MASK. Not all multires functions need paint mask data (e.g. multiresModifier_base_apply.) This flag is always set in MOD_multires.c so that subdividing a mesh with a mask updates properly even when not in sculpt mode. * Update multiresModifier_disp_run() to apply, calculate, and add mask elements. It's almost the same as the existing operations with xyz coordinates, but treats masks as absolute rather than displacements relative to subdivided values. * Update multires_customdata_delete to free CD_GRID_PAINT_MASK in addition to CD_MDISPS. * Update multires_del_higher() to call the new function multires_grid_paint_mask_downsample(), which allocates a lower-resolution paint mask grid and copies values over from the high-resolution grid.
This commit is contained in:
@@ -44,7 +44,7 @@ struct MultiresModifierData;
|
||||
struct Object;
|
||||
struct Scene;
|
||||
|
||||
/* Delete mesh mdisps */
|
||||
/* Delete mesh mdisps and grid paint masks */
|
||||
void multires_customdata_delete(struct Mesh *me);
|
||||
|
||||
void multires_mark_as_modified(struct Object *ob, enum MultiresModifiedFlags flags);
|
||||
@@ -62,6 +62,7 @@ void multiresModifier_set_levels_from_disps(struct MultiresModifierData *mmd, st
|
||||
typedef enum {
|
||||
MULTIRES_USE_LOCAL_MMD = 1,
|
||||
MULTIRES_USE_RENDER_PARAMS = 2,
|
||||
MULTIRES_ALLOC_PAINT_MASK = 4
|
||||
} MultiresFlags;
|
||||
|
||||
struct DerivedMesh *multires_make_derived_from_derived(struct DerivedMesh *dm,
|
||||
|
||||
@@ -59,7 +59,8 @@ typedef enum {
|
||||
SUBSURF_USE_RENDER_PARAMS = 1,
|
||||
SUBSURF_IS_FINAL_CALC = 2,
|
||||
SUBSURF_FOR_EDIT_MODE = 4,
|
||||
SUBSURF_IN_EDIT_MODE = 8
|
||||
SUBSURF_IN_EDIT_MODE = 8,
|
||||
SUBSURF_ALLOC_PAINT_MASK = 16
|
||||
} SubsurfFlags;
|
||||
|
||||
struct DerivedMesh *subsurf_make_derived_from_derived(
|
||||
|
||||
@@ -387,6 +387,10 @@ struct CCGSubSurf {
|
||||
int calcVertNormals;
|
||||
int normalDataOffset;
|
||||
|
||||
/* data for paint masks */
|
||||
int allocMask;
|
||||
int maskDataOffset;
|
||||
|
||||
/* data for age'ing (to debug sync) */
|
||||
int currentAge;
|
||||
int useAgeCounts;
|
||||
@@ -852,6 +856,8 @@ CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *a
|
||||
ss->calcVertNormals = 0;
|
||||
ss->normalDataOffset = 0;
|
||||
|
||||
ss->allocMask = 0;
|
||||
|
||||
ss->q = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
|
||||
ss->r = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
|
||||
|
||||
@@ -996,6 +1002,12 @@ CCGError ccgSubSurf_setCalcVertexNormals(CCGSubSurf *ss, int useVertNormals, int
|
||||
return eCCGError_None;
|
||||
}
|
||||
|
||||
void ccgSubSurf_setAllocMask(CCGSubSurf *ss, int allocMask, int maskOffset)
|
||||
{
|
||||
ss->allocMask = allocMask;
|
||||
ss->maskDataOffset = maskOffset;
|
||||
}
|
||||
|
||||
void ccgSubSurf_setNumLayers(CCGSubSurf *ss, int numLayers)
|
||||
{
|
||||
ss->meshIFC.numLayers = numLayers;
|
||||
@@ -3123,6 +3135,12 @@ void CCG_key(CCGKey *key, const CCGSubSurf *ss, int level)
|
||||
key->grid_size = ccgSubSurf_getGridLevelSize(ss, level);
|
||||
key->grid_area = key->grid_size * key->grid_size;
|
||||
key->grid_bytes = key->elem_size * key->grid_area;
|
||||
|
||||
key->has_mask = ss->allocMask;
|
||||
if (key->has_mask)
|
||||
key->mask_offset = ss->maskDataOffset;
|
||||
else
|
||||
key->mask_offset = -1;
|
||||
}
|
||||
|
||||
void CCG_key_top_level(CCGKey *key, const CCGSubSurf *ss)
|
||||
|
||||
@@ -76,6 +76,7 @@ void ccgSubSurf_getUseAgeCounts (CCGSubSurf *ss, int *useAgeCounts_r, int *ve
|
||||
CCGError ccgSubSurf_setUseAgeCounts (CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset);
|
||||
|
||||
CCGError ccgSubSurf_setCalcVertexNormals (CCGSubSurf *ss, int useVertNormals, int normalDataOffset);
|
||||
void ccgSubSurf_setAllocMask (CCGSubSurf *ss, int allocMask, int maskOffset);
|
||||
|
||||
void ccgSubSurf_setNumLayers (CCGSubSurf *ss, int numLayers);
|
||||
|
||||
|
||||
@@ -90,12 +90,17 @@ void multires_customdata_delete(Mesh *me)
|
||||
CustomData_external_remove(&em->bm->ldata, &me->id,
|
||||
CD_MDISPS, 0);
|
||||
BM_data_layer_free(em->bm, &em->bm->ldata, CD_MDISPS);
|
||||
|
||||
BM_data_layer_free(em->bm, &em->bm->ldata, CD_GRID_PAINT_MASK);
|
||||
}
|
||||
else {
|
||||
CustomData_external_remove(&me->ldata, &me->id,
|
||||
CD_MDISPS, me->totloop);
|
||||
CustomData_free_layer_active(&me->ldata, CD_MDISPS,
|
||||
me->totloop);
|
||||
me->totloop);
|
||||
|
||||
CustomData_free_layer_active(&me->ldata, CD_GRID_PAINT_MASK,
|
||||
me->totloop);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -594,15 +599,40 @@ static void multires_copy_dm_grid(CCGElem *gridA, CCGElem *gridB, CCGKey *keyA,
|
||||
}
|
||||
}
|
||||
|
||||
/* Reallocate gpm->data at a lower resolution and copy values over
|
||||
from the original high-resolution data */
|
||||
static void multires_grid_paint_mask_downsample(GridPaintMask *gpm, int level)
|
||||
{
|
||||
if (level < gpm->level) {
|
||||
int gridsize = ccg_gridsize(level);
|
||||
float *data = MEM_callocN(sizeof(float) * gridsize * gridsize,
|
||||
"multires_grid_paint_mask_downsample");
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < gridsize; y++) {
|
||||
for (x = 0; x < gridsize; x++) {
|
||||
data[y * gridsize + x] =
|
||||
paint_grid_paint_mask(gpm, level, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN(gpm->data);
|
||||
gpm->data = data;
|
||||
gpm->level = level;
|
||||
}
|
||||
}
|
||||
|
||||
static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
|
||||
{
|
||||
Mesh *me = (Mesh *)ob->data;
|
||||
int levels = mmd->totlvl - lvl;
|
||||
MDisps *mdisps;
|
||||
GridPaintMask *gpm;
|
||||
|
||||
multires_set_tot_mdisps(me, mmd->totlvl);
|
||||
CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
|
||||
mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
|
||||
gpm = CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK);
|
||||
|
||||
multires_force_update(ob);
|
||||
|
||||
@@ -615,7 +645,8 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
|
||||
|
||||
for (i = 0; i < me->totpoly; ++i) {
|
||||
for (j = 0; j < me->mpoly[i].totloop; j++) {
|
||||
MDisps *mdisp = &mdisps[me->mpoly[i].loopstart + j];
|
||||
int g = me->mpoly[i].loopstart + j;
|
||||
MDisps *mdisp = &mdisps[g];
|
||||
float (*disps)[3], (*ndisps)[3], (*hdisps)[3];
|
||||
int totdisp = multires_grid_tot[lvl];
|
||||
|
||||
@@ -641,6 +672,8 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
|
||||
mdisp->disps = disps;
|
||||
mdisp->totdisp = totdisp;
|
||||
mdisp->level = lvl;
|
||||
|
||||
multires_grid_paint_mask_downsample(&gpm[g], lvl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -673,9 +706,10 @@ void multiresModifier_del_levels(MultiresModifierData *mmd, Object *ob, int dire
|
||||
multires_set_tot_level(ob, mmd, lvl);
|
||||
}
|
||||
|
||||
static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int totlvl, int simple)
|
||||
static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int totlvl, int simple, int alloc_paint_mask)
|
||||
{
|
||||
MultiresModifierData mmd = {{NULL}};
|
||||
MultiresFlags flags = MULTIRES_USE_LOCAL_MMD;
|
||||
|
||||
mmd.lvl = lvl;
|
||||
mmd.sculptlvl = lvl;
|
||||
@@ -683,10 +717,13 @@ static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lv
|
||||
mmd.totlvl = totlvl;
|
||||
mmd.simple = simple;
|
||||
|
||||
return multires_make_derived_from_derived(dm, &mmd, ob, MULTIRES_USE_LOCAL_MMD);
|
||||
if (alloc_paint_mask)
|
||||
flags |= MULTIRES_ALLOC_PAINT_MASK;
|
||||
|
||||
return multires_make_derived_from_derived(dm, &mmd, ob, flags);
|
||||
}
|
||||
|
||||
static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int simple, int optimal, int plain_uv)
|
||||
static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int simple, int optimal, int plain_uv, int alloc_paint_mask)
|
||||
{
|
||||
SubsurfModifierData smd = {{NULL}};
|
||||
SubsurfFlags flags = 0;
|
||||
@@ -701,6 +738,10 @@ static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl
|
||||
|
||||
if (ob->mode & OB_MODE_EDIT)
|
||||
flags |= SUBSURF_IN_EDIT_MODE;
|
||||
|
||||
if (alloc_paint_mask)
|
||||
flags |= SUBSURF_ALLOC_PAINT_MASK;
|
||||
|
||||
return subsurf_make_derived_from_derived(dm, &smd, NULL, flags);
|
||||
}
|
||||
|
||||
@@ -737,7 +778,7 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob)
|
||||
/* generate highest level with displacements */
|
||||
cddm = CDDM_from_mesh(me, NULL);
|
||||
DM_set_only_copy(cddm, CD_MASK_BAREMESH);
|
||||
dispdm = multires_dm_create_local(ob, cddm, totlvl, totlvl, 0);
|
||||
dispdm = multires_dm_create_local(ob, cddm, totlvl, totlvl, 0, 0);
|
||||
cddm->release(cddm);
|
||||
|
||||
/* copy the new locations of the base verts into the mesh */
|
||||
@@ -827,7 +868,7 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob)
|
||||
/* subdivide the mesh to highest level without displacements */
|
||||
cddm = CDDM_from_mesh(me, NULL);
|
||||
DM_set_only_copy(cddm, CD_MASK_BAREMESH);
|
||||
origdm = subsurf_dm_create_local(ob, cddm, totlvl, 0, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
|
||||
origdm = subsurf_dm_create_local(ob, cddm, totlvl, 0, 0, mmd->flags & eMultiresModifierFlag_PlainUv, 0);
|
||||
cddm->release(cddm);
|
||||
|
||||
/* calc disps */
|
||||
@@ -863,10 +904,11 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl
|
||||
/* create subsurf DM from original mesh at high level */
|
||||
cddm = CDDM_from_mesh(me, NULL);
|
||||
DM_set_only_copy(cddm, CD_MASK_BAREMESH);
|
||||
highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
|
||||
highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE);
|
||||
ss = ((CCGDerivedMesh*)highdm)->ss;
|
||||
|
||||
/* create multires DM from original mesh at low level */
|
||||
lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple);
|
||||
lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple, TRUE);
|
||||
cddm->release(cddm);
|
||||
|
||||
/* copy subsurf grids and replace them with low displaced grids */
|
||||
@@ -892,7 +934,6 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl
|
||||
lowdm->release(lowdm);
|
||||
|
||||
/* subsurf higher levels again with displaced data */
|
||||
ss = ((CCGDerivedMesh *)highdm)->ss;
|
||||
ccgSubSurf_updateFromFaces(ss, lvl, NULL, 0);
|
||||
ccgSubSurf_updateLevels(ss, lvl, NULL, 0);
|
||||
|
||||
@@ -952,6 +993,7 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm
|
||||
CCGKey key;
|
||||
MPoly *mpoly = me->mpoly;
|
||||
MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
|
||||
GridPaintMask *grid_paint_mask = NULL;
|
||||
int *gridOffset;
|
||||
int i, k, /*numGrids, */ gridSize, dGridSize, dSkip;
|
||||
int totloop, totpoly;
|
||||
@@ -985,6 +1027,10 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm
|
||||
dGridSize = multires_side_tot[totlvl];
|
||||
dSkip = (dGridSize - 1) / (gridSize - 1);
|
||||
|
||||
/* multires paint masks */
|
||||
if (key.has_mask)
|
||||
grid_paint_mask = CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK);
|
||||
|
||||
k = 0; /*current loop/mdisp index within the mloop array*/
|
||||
|
||||
#pragma omp parallel for private(i) if (totloop*gridSize*gridSize >= CCG_OMP_LIMIT)
|
||||
@@ -994,6 +1040,7 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm
|
||||
int S, x, y, gIndex = gridOffset[i];
|
||||
|
||||
for (S = 0; S < numVerts; ++S, ++gIndex, ++k) {
|
||||
GridPaintMask *gpm = grid_paint_mask ? &grid_paint_mask[gIndex] : NULL;
|
||||
MDisps *mdisp = &mdisps[mpoly[i].loopstart + S];
|
||||
CCGElem *grid = gridData[gIndex];
|
||||
CCGElem *subgrid = subGridData[gIndex];
|
||||
@@ -1008,13 +1055,22 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm
|
||||
|
||||
dispgrid = mdisp->disps;
|
||||
|
||||
/* if needed, reallocate multires paint mask */
|
||||
if (gpm && op == CALC_DISPLACEMENTS) {
|
||||
if (gpm->level < key.level) {
|
||||
gpm->level = key.level;
|
||||
MEM_freeN(gpm->data);
|
||||
gpm->data = MEM_callocN(sizeof(float) * key.grid_area, "gpm.data");
|
||||
}
|
||||
}
|
||||
|
||||
for (y = 0; y < gridSize; y++) {
|
||||
for (x = 0; x < gridSize; x++) {
|
||||
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];
|
||||
float *data = dispgrid[dGridSize*y*dSkip + x*dSkip];
|
||||
float mat[3][3], tx[3], ty[3], disp[3], d[3], mask;
|
||||
|
||||
/* construct tangent space matrix */
|
||||
grid_tangent(&key, x, y, 0, subGridData[gIndex], tx);
|
||||
@@ -1051,11 +1107,31 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm
|
||||
add_v3_v3(data, d);
|
||||
break;
|
||||
}
|
||||
|
||||
if (gpm) {
|
||||
switch (op) {
|
||||
case APPLY_DISPLACEMENTS:
|
||||
/* Copy mask from gpm to DM */
|
||||
*CCG_grid_elem_mask(&key, grid, x, y) =
|
||||
paint_grid_paint_mask(gpm, key.level, x, y);
|
||||
break;
|
||||
case CALC_DISPLACEMENTS:
|
||||
/* Copy mask from DM to gpm */
|
||||
mask = *CCG_grid_elem_mask(&key, grid, x, y);
|
||||
gpm->data[y * gridSize + x] = CLAMPIS(mask, 0, 1);
|
||||
break;
|
||||
case ADD_DISPLACEMENTS:
|
||||
/* Add mask displacement to gpm */
|
||||
gpm->data[y * gridSize + x] +=
|
||||
*CCG_grid_elem_mask(&key, grid, x, y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (op == APPLY_DISPLACEMENTS) {
|
||||
ccgSubSurf_stitchFaces(ccgdm->ss, 0, NULL, 0);
|
||||
ccgSubSurf_updateNormals(ccgdm->ss, NULL, 0);
|
||||
@@ -1094,10 +1170,11 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm)
|
||||
else cddm = CDDM_from_mesh(me, NULL);
|
||||
DM_set_only_copy(cddm, CD_MASK_BAREMESH);
|
||||
|
||||
highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
|
||||
highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE);
|
||||
ss = ((CCGDerivedMesh*)highdm)->ss;
|
||||
|
||||
/* create multires DM from original mesh and displacements */
|
||||
lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple);
|
||||
lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple, TRUE);
|
||||
cddm->release(cddm);
|
||||
|
||||
/* gather grid data */
|
||||
@@ -1122,7 +1199,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm)
|
||||
|
||||
/* write difference of subsurf and displaced low level into high subsurf */
|
||||
for (j = 0; j < lowGridSize*lowGridSize; ++j) {
|
||||
sub_v3_v3v3(CCG_elem_offset_co(&lowGridKey, diffGrid, j),
|
||||
sub_v4_v4v4(CCG_elem_offset_co(&lowGridKey, diffGrid, j),
|
||||
CCG_elem_offset_co(&lowGridKey, gridData[i], j),
|
||||
CCG_elem_offset_co(&lowGridKey, lowGridData[i], j));
|
||||
}
|
||||
@@ -1135,7 +1212,6 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm)
|
||||
lowdm->release(lowdm);
|
||||
|
||||
/* subsurf higher levels again with difference of coordinates */
|
||||
ss = ((CCGDerivedMesh *)highdm)->ss;
|
||||
ccgSubSurf_updateFromFaces(ss, lvl, NULL, 0);
|
||||
ccgSubSurf_updateLevels(ss, lvl, NULL, 0);
|
||||
|
||||
@@ -1155,7 +1231,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm)
|
||||
else cddm = CDDM_from_mesh(me, NULL);
|
||||
DM_set_only_copy(cddm, CD_MASK_BAREMESH);
|
||||
|
||||
subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
|
||||
subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE);
|
||||
cddm->release(cddm);
|
||||
|
||||
multiresModifier_disp_run(dm, me, NULL, CALC_DISPLACEMENTS, subdm->getGridData(subdm), mmd->totlvl);
|
||||
@@ -1218,10 +1294,10 @@ void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to)
|
||||
}
|
||||
|
||||
totlvl = mmd->totlvl;
|
||||
ccgdm = multires_dm_create_local(ob, dm, totlvl, totlvl, mmd->simple);
|
||||
ccgdm = multires_dm_create_local(ob, dm, totlvl, totlvl, mmd->simple, FALSE);
|
||||
|
||||
subsurf = subsurf_dm_create_local(ob, dm, totlvl,
|
||||
mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges, mmd->flags & eMultiresModifierFlag_PlainUv);
|
||||
mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges, mmd->flags & eMultiresModifierFlag_PlainUv, 0);
|
||||
|
||||
numGrids = subsurf->getNumGrids(subsurf);
|
||||
gridSize = subsurf->getGridSize(subsurf);
|
||||
@@ -1362,8 +1438,9 @@ DerivedMesh *multires_make_derived_from_derived(DerivedMesh *dm,
|
||||
return dm;
|
||||
|
||||
result = subsurf_dm_create_local(ob, dm, lvl,
|
||||
mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges,
|
||||
mmd->flags & eMultiresModifierFlag_PlainUv);
|
||||
mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges,
|
||||
mmd->flags & eMultiresModifierFlag_PlainUv,
|
||||
flags & MULTIRES_ALLOC_PAINT_MASK);
|
||||
|
||||
if (!(flags & MULTIRES_USE_LOCAL_MMD)) {
|
||||
ccgdm = (CCGDerivedMesh *)result;
|
||||
@@ -2101,7 +2178,7 @@ static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3])
|
||||
MEM_freeN(vertCos);
|
||||
|
||||
/* scaled ccgDM for tangent space of object with applied scale */
|
||||
dm = subsurf_dm_create_local(ob, cddm, high_mmd.totlvl, high_mmd.simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
|
||||
dm = subsurf_dm_create_local(ob, cddm, high_mmd.totlvl, high_mmd.simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, 0);
|
||||
cddm->release(cddm);
|
||||
|
||||
/*numGrids = dm->getNumGrids(dm);*/ /*UNUSED*/
|
||||
|
||||
@@ -111,7 +111,9 @@ static void arena_release(CCGAllocatorHDL a)
|
||||
typedef enum {
|
||||
CCG_USE_AGING = 1,
|
||||
CCG_USE_ARENA = 2,
|
||||
CCG_CALC_NORMALS = 4
|
||||
CCG_CALC_NORMALS = 4,
|
||||
/* add an extra four bytes for a mask layer */
|
||||
CCG_ALLOC_MASK = 8
|
||||
} CCGFlags;
|
||||
|
||||
static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels,
|
||||
@@ -152,6 +154,8 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels,
|
||||
normalOffset += sizeof(float) * numLayers;
|
||||
if(flags & CCG_CALC_NORMALS)
|
||||
ifc.vertDataSize += sizeof(float) * 3;
|
||||
if(flags & CCG_ALLOC_MASK)
|
||||
ifc.vertDataSize += sizeof(float);
|
||||
|
||||
if (useArena) {
|
||||
CCGAllocatorIFC allocatorIFC;
|
||||
@@ -172,6 +176,12 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels,
|
||||
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
|
||||
@@ -3496,12 +3506,17 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
|
||||
useSubsurfUv, dm);
|
||||
}
|
||||
else {
|
||||
CCGFlags ccg_flags = CCG_USE_ARENA | CCG_CALC_NORMALS;
|
||||
|
||||
if (smd->mCache && (flags & SUBSURF_IS_FINAL_CALC)) {
|
||||
ccgSubSurf_free(smd->mCache);
|
||||
smd->mCache = NULL;
|
||||
}
|
||||
|
||||
ss = _getSubSurf(NULL, levels, 3, CCG_USE_ARENA | CCG_CALC_NORMALS);
|
||||
if (flags & SUBSURF_ALLOC_PAINT_MASK)
|
||||
ccg_flags |= CCG_ALLOC_MASK;
|
||||
|
||||
ss = _getSubSurf(NULL, levels, 3, ccg_flags);
|
||||
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
|
||||
|
||||
result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
|
||||
@@ -3510,6 +3525,9 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
|
||||
smd->mCache = ss;
|
||||
else
|
||||
result->freeSS = 1;
|
||||
|
||||
if (flags & SUBSURF_ALLOC_PAINT_MASK)
|
||||
ccgSubSurf_setNumLayers(ss, 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm,
|
||||
}
|
||||
}
|
||||
|
||||
flags = MULTIRES_ALLOC_PAINT_MASK;
|
||||
if (useRenderParams)
|
||||
flags |= MULTIRES_USE_RENDER_PARAMS;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user