diff options
author | Joseph Eagar <joeedh@gmail.com> | 2009-08-31 01:30:07 +0400 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2009-08-31 01:30:07 +0400 |
commit | 8823761534ce735e4d0787bfa659a18cd9ad4ccc (patch) | |
tree | e3f2f7a388c14e6c4dd2096ff8d0a5b8481e9632 /source/blender | |
parent | 8408a72d16c2010b88242bbbbe410f0fae7aaca0 (diff) |
vpaint works with the new face structures, yay, though it probably still has issues, needs more testing. also hopefully fixed subsurf crash everyone but me was getting, what I found should have caused crashes even for me, no idea why it did not. also got face flags to work with subsurf, and partially got materials, though theres still a problem there.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_customdata.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_tessmesh.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 133 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/editderivedbmesh.c | 20 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 212 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 22 | ||||
-rw-r--r-- | source/blender/bmesh/operators/mesh_conv.c | 2 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_vertex.c | 342 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_meshdata_types.h | 10 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_mesh.c | 17 |
11 files changed, 525 insertions, 248 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index f11d7824db6..17513b1b7c3 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -226,7 +226,6 @@ void *CustomData_get_layer(const struct CustomData *data, int type); void *CustomData_get_layer_n(const struct CustomData *data, int type, int n); void *CustomData_get_layer_named(const struct CustomData *data, int type, char *name); - int CustomData_get_layer_index(const struct CustomData *data, int type); int CustomData_get_named_layer_index(const struct CustomData *data, int type, char *name); int CustomData_get_active_layer_index(const struct CustomData *data, int type); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 5a672ddc5b2..f41bc451b65 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -57,11 +57,24 @@ struct EditMesh *BKE_mesh_get_editmesh(struct Mesh *me); void BKE_mesh_end_editmesh(struct Mesh *me, struct EditMesh *em); struct BMesh *BKE_mesh_to_bmesh(struct Mesh *me); +/* + this function recreates a tesselation. + returns number of tesselation faces. + */ +int mesh_recalcTesselation(struct CustomData *fdata, struct CustomData *ldata, + struct CustomData *pdata, struct MVert *mvert, int totface, + int totloop, int totpoly); + void unlink_mesh(struct Mesh *me); void free_mesh(struct Mesh *me); struct Mesh *add_mesh(char *name); struct Mesh *copy_mesh(struct Mesh *me); void mesh_update_customdata_pointers(struct Mesh *me); + +/*this ensures grouped customdata (e.g. mtexpoly and mloopuv and mtface, or + mloopcol and mcol) have the same relative active/render/clone/mask indices.*/ +void mesh_update_linked_customdata(struct Mesh *me); + void make_local_tface(struct Mesh *me); void make_local_mesh(struct Mesh *me); void boundbox_mesh(struct Mesh *me, float *loc, float *size); diff --git a/source/blender/blenkernel/BKE_tessmesh.h b/source/blender/blenkernel/BKE_tessmesh.h index e448f904841..b01cd3c2e89 100644 --- a/source/blender/blenkernel/BKE_tessmesh.h +++ b/source/blender/blenkernel/BKE_tessmesh.h @@ -54,3 +54,4 @@ void BMEdit_RecalcTesselation(BMEditMesh *tm); BMEditMesh *BMEdit_Create(BMesh *bm); BMEditMesh *BMEdit_Copy(BMEditMesh *tm); void BMEdit_Free(BMEditMesh *em); +void BMEdit_UpdateLinkedCustomData(BMEditMesh *em); diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 707b350111d..d1df02a4606 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -819,141 +819,14 @@ static void cdDM_foreachMappedFaceCenter( } -void cddm_loops_to_corners(CustomData *fdata, CustomData *ldata, - CustomData *pdata, int lindex[3], int findex, - int polyindex, int numTex, int numCol) -{ - MTFace *texface; - MTexPoly *texpoly; - MCol *mcol; - MLoopCol *mloopcol; - MLoopUV *mloopuv; - int i, j; - - for(i=0; i < numTex; i++){ - texface = CustomData_get_n(fdata, CD_MTFACE, findex, i); - texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, polyindex, i); - - texface->tpage = texpoly->tpage; - texface->flag = texpoly->flag; - texface->transp = texpoly->transp; - texface->mode = texpoly->mode; - texface->tile = texpoly->tile; - texface->unwrap = texpoly->unwrap; - - for (j=0; j<3; j++) { - mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, lindex[j], i); - texface->uv[j][0] = mloopuv->uv[0]; - texface->uv[j][1] = mloopuv->uv[1]; - } - } - - for(i=0; i < numCol; i++){ - mcol = CustomData_get_n(fdata, CD_MCOL, findex, i); - - for (j=0; j<3; j++) { - mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, lindex[j], i); - mcol[j].r = mloopcol->r; - mcol[j].g = mloopcol->g; - mcol[j].b = mloopcol->b; - mcol[j].a = mloopcol->a; - } - } -} - static void cdDM_recalcTesselation(DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh*)dm; - MPoly *mp; - MLoop *ml; - MFace *mf = NULL; - V_DECLARE(mf); - EditVert *v, *lastv, *firstv; - EditFace *f; - V_DECLARE(origIndex); - int i, j, k, lindex[3], *origIndex = NULL, *polyorigIndex; - int numTex, numCol; - - numTex = CustomData_number_of_layers(&dm->loopData, CD_MLOOPUV); - numCol = CustomData_number_of_layers(&dm->loopData, CD_MLOOPCOL); - - k = 0; - mp = cddm->mpoly; - polyorigIndex = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX); - for (i=0; i<dm->numPolyData; i++, mp++) { - ml = cddm->mloop + mp->loopstart; - firstv = NULL; - lastv = NULL; - for (j=0; j<mp->totloop; j++, ml++) { - v = BLI_addfillvert(cddm->mvert[ml->v].co); - if (polyorigIndex) - v->tmp.l = polyorigIndex[i]; - else - v->tmp.l = i; - - v->keyindex = mp->loopstart + j; - - if (lastv) - BLI_addfilledge(lastv, v); - - if (!firstv) - firstv = v; - lastv = v; - } - BLI_addfilledge(lastv, firstv); - - BLI_edgefill(0, 0); - for (f=fillfacebase.first; f; f=f->next) { - V_GROW(mf); - V_GROW(origIndex); - - /*these are loop indices, they'll be transformed - into vert indices later.*/ - mf[k].v1 = f->v1->keyindex; - mf[k].v2 = f->v2->keyindex; - mf[k].v3 = f->v3->keyindex; - origIndex[k] = f->v1->tmp.l; - - k++; - } - - BLI_end_edgefill(); - } - memset(&dm->faceData, 0, sizeof(CustomData)); - dm->numFaceData = k; + dm->numFaceData = mesh_recalcTesselation(&dm->faceData, &dm->loopData, + &dm->polyData, cddm->mvert, dm->numFaceData, dm->numLoopData, dm->numPolyData); - CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, mf, dm->numFaceData); - CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_ASSIGN, origIndex, dm->numFaceData); - CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, dm->numFaceData); - - /*set convienence pointer*/ - cddm->mface = mf; - - for (i=0; i<dm->numFaceData; i++, mf++) { - lindex[0] = mf->v1; - lindex[1] = mf->v2; - lindex[2] = mf->v3; - - /*ensure winding is correct*/ - if (mf->v1 > mf->v2) { - SWAP(int, mf->v1, mf->v2); - } - if (mf->v2 > mf->v3) { - SWAP(int, mf->v2, mf->v3); - } - if (mf->v1 > mf->v2) { - SWAP(int, mf->v1, mf->v2); - } - - /*transform loop indices to vert indices*/ - mf->v1 = cddm->mloop[mf->v1].v; - mf->v2 = cddm->mloop[mf->v2].v; - mf->v3 = cddm->mloop[mf->v3].v; - - cddm_loops_to_corners(&dm->faceData, &dm->loopData, &dm->polyData, - lindex, i, origIndex[i], numTex, numCol); - } + cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE); } static void cdDM_release(DerivedMesh *dm) diff --git a/source/blender/blenkernel/intern/editderivedbmesh.c b/source/blender/blenkernel/intern/editderivedbmesh.c index a17d16ce754..d6f31847ca5 100644 --- a/source/blender/blenkernel/intern/editderivedbmesh.c +++ b/source/blender/blenkernel/intern/editderivedbmesh.c @@ -213,6 +213,26 @@ void BMEdit_RecalcTesselation(BMEditMesh *tm) } } +void BMEdit_UpdateLinkedCustomData(BMEditMesh *em) +{ + BMesh *bm = em->bm; + int act; + + if (CustomData_has_layer(&bm->pdata, CD_MTEXPOLY)) { + act = CustomData_get_active_layer(&bm->pdata, CD_MTEXPOLY); + CustomData_set_layer_active(&bm->ldata, CD_MLOOPUV, act); + + act = CustomData_get_render_layer(&bm->pdata, CD_MTEXPOLY); + CustomData_set_layer_render(&bm->ldata, CD_MLOOPUV, act); + + act = CustomData_get_clone_layer(&bm->pdata, CD_MTEXPOLY); + CustomData_set_layer_clone(&bm->ldata, CD_MLOOPUV, act); + + act = CustomData_get_mask_layer(&bm->pdata, CD_MTEXPOLY); + CustomData_set_layer_mask(&bm->ldata, CD_MLOOPUV, act); + } +} + /*does not free the BMEditMesh struct itself*/ void BMEdit_Free(BMEditMesh *em) { diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index e74066cf52c..51cb8d903b0 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -86,9 +86,72 @@ void BKE_mesh_end_editmesh(Mesh *me, EditMesh *em) BMEdit_RecalcTesselation(me->edit_btmesh); } +static void mesh_ensure_tesselation_customdata(Mesh *me) +{ + int tottex, totcol; + + tottex = CustomData_number_of_layers(&me->fdata, CD_MTFACE); + totcol = CustomData_number_of_layers(&me->fdata, CD_MCOL); + + if (tottex != CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY) || + totcol != CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL)) + { + CustomData_free(&me->fdata, me->totface); + memset(&me->fdata, 0, sizeof(&me->fdata)); + + CustomData_from_bmeshpoly(&me->fdata, &me->pdata, &me->ldata, me->totface); + printf("Warning! Tesselation uvs or vcol data got out of sync, had to reset!\n"); + } +} + +/*this ensures grouped customdata (e.g. mtexpoly and mloopuv and mtface, or + mloopcol and mcol) have the same relative active/render/clone/mask indices.*/ +void mesh_update_linked_customdata(Mesh *me) +{ + int act; + + if (me->edit_btmesh) + BMEdit_UpdateLinkedCustomData(me->edit_btmesh); + + mesh_ensure_tesselation_customdata(me); + + if (CustomData_has_layer(&me->pdata, CD_MTEXPOLY)) { + act = CustomData_get_active_layer(&me->pdata, CD_MTEXPOLY); + CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, act); + CustomData_set_layer_active(&me->fdata, CD_MTFACE, act); + + act = CustomData_get_render_layer(&me->pdata, CD_MTEXPOLY); + CustomData_set_layer_render(&me->ldata, CD_MLOOPUV, act); + CustomData_set_layer_render(&me->fdata, CD_MTFACE, act); + + act = CustomData_get_clone_layer(&me->pdata, CD_MTEXPOLY); + CustomData_set_layer_clone(&me->ldata, CD_MLOOPUV, act); + CustomData_set_layer_clone(&me->fdata, CD_MTFACE, act); + + act = CustomData_get_mask_layer(&me->pdata, CD_MTEXPOLY); + CustomData_set_layer_mask(&me->ldata, CD_MLOOPUV, act); + CustomData_set_layer_mask(&me->fdata, CD_MTFACE, act); + } + + if (CustomData_has_layer(&me->ldata, CD_MLOOPCOL)) { + act = CustomData_get_active_layer(&me->ldata, CD_MLOOPCOL); + CustomData_set_layer_active(&me->fdata, CD_MCOL, act); + + act = CustomData_get_render_layer(&me->ldata, CD_MLOOPCOL); + CustomData_set_layer_render(&me->fdata, CD_MCOL, act); + + act = CustomData_get_clone_layer(&me->ldata, CD_MLOOPCOL); + CustomData_set_layer_clone(&me->fdata, CD_MCOL, act); + + act = CustomData_get_mask_layer(&me->ldata, CD_MLOOPCOL); + CustomData_set_layer_mask(&me->fdata, CD_MCOL, act); + } +} void mesh_update_customdata_pointers(Mesh *me) { + mesh_update_linked_customdata(me); + me->mvert = CustomData_get_layer(&me->vdata, CD_MVERT); me->dvert = CustomData_get_layer(&me->vdata, CD_MDEFORMVERT); me->msticky = CustomData_get_layer(&me->vdata, CD_MSTICKY); @@ -1336,3 +1399,152 @@ void mesh_pmv_off(Object *ob, Mesh *me) me->pv= NULL; } } + +static void mesh_loops_to_corners(CustomData *fdata, CustomData *ldata, + CustomData *pdata, int lindex[3], int findex, + int polyindex, int numTex, int numCol) +{ + MTFace *texface; + MTexPoly *texpoly; + MCol *mcol; + MLoopCol *mloopcol; + MLoopUV *mloopuv; + int i, j; + + for(i=0; i < numTex; i++){ + texface = CustomData_get_n(fdata, CD_MTFACE, findex, i); + texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, polyindex, i); + + texface->tpage = texpoly->tpage; + texface->flag = texpoly->flag; + texface->transp = texpoly->transp; + texface->mode = texpoly->mode; + texface->tile = texpoly->tile; + texface->unwrap = texpoly->unwrap; + + for (j=0; j<3; j++) { + mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, lindex[j], i); + texface->uv[j][0] = mloopuv->uv[0]; + texface->uv[j][1] = mloopuv->uv[1]; + } + } + + for(i=0; i < numCol; i++){ + mcol = CustomData_get_n(fdata, CD_MCOL, findex, i); + + for (j=0; j<3; j++) { + mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, lindex[j], i); + mcol[j].r = mloopcol->r; + mcol[j].g = mloopcol->g; + mcol[j].b = mloopcol->b; + mcol[j].a = mloopcol->a; + } + } +} + +/*this function recreates a tesselation. + + returns number of tesselation faces.*/ +int mesh_recalcTesselation(CustomData *fdata, + CustomData *ldata, CustomData *pdata, + MVert *mvert, int totface, int totloop, + int totpoly) +{ + MPoly *mp, *mpoly; + MLoop *ml, *mloop; + MFace *mf = NULL, *mface; + V_DECLARE(mf); + EditVert *v, *lastv, *firstv; + EditFace *f; + V_DECLARE(origIndex); + int i, j, k, lindex[3], *origIndex = NULL, *polyorigIndex; + int numTex, numCol; + + mpoly = CustomData_get_layer(pdata, CD_MPOLY); + mloop = CustomData_get_layer(ldata, CD_MLOOP); + + numTex = CustomData_number_of_layers(ldata, CD_MLOOPUV); + numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL); + + k = 0; + mp = mpoly; + polyorigIndex = CustomData_get_layer(pdata, CD_ORIGINDEX); + for (i=0; i<totpoly; i++, mp++) { + ml = mloop + mp->loopstart; + firstv = NULL; + lastv = NULL; + for (j=0; j<mp->totloop; j++, ml++) { + v = BLI_addfillvert(mvert[ml->v].co); + if (polyorigIndex) + v->tmp.l = polyorigIndex[i]; + else + v->tmp.l = i; + + v->keyindex = mp->loopstart + j; + + if (lastv) + BLI_addfilledge(lastv, v); + + if (!firstv) + firstv = v; + lastv = v; + } + BLI_addfilledge(lastv, firstv); + + BLI_edgefill(0, 0); + for (f=fillfacebase.first; f; f=f->next) { + V_GROW(mf); + V_GROW(origIndex); + + /*these are loop indices, they'll be transformed + into vert indices later.*/ + mf[k].v1 = f->v1->keyindex; + mf[k].v2 = f->v2->keyindex; + mf[k].v3 = f->v3->keyindex; + origIndex[k] = f->v1->tmp.l; + + k++; + } + + BLI_end_edgefill(); + } + + CustomData_free(fdata, totface); + memset(fdata, 0, sizeof(CustomData)); + totface = k; + + CustomData_add_layer(fdata, CD_MFACE, CD_ASSIGN, mf, totface); + CustomData_add_layer(fdata, CD_ORIGINDEX, CD_ASSIGN, origIndex, totface); + CustomData_from_bmeshpoly(fdata, pdata, ldata, totface); + + mface = mf; + for (i=0; i<totface; i++, mf++) { + /*ensure winding is correct*/ + if (mf->v1 > mf->v2) { + SWAP(int, mf->v1, mf->v2); + } + if (mf->v2 > mf->v3) { + SWAP(int, mf->v2, mf->v3); + } + if (mf->v1 > mf->v2) { + SWAP(int, mf->v1, mf->v2); + } + + lindex[0] = mf->v1; + lindex[1] = mf->v2; + lindex[2] = mf->v3; + + /*transform loop indices to vert indices*/ + mf->v1 = mloop[mf->v1].v; + mf->v2 = mloop[mf->v2].v; + mf->v3 = mloop[mf->v3].v; + + mf->flag = mpoly[origIndex[i]].flag; + mf->mat_nr = mpoly[origIndex[i]].mat_nr; + + mesh_loops_to_corners(fdata, ldata, pdata, + lindex, i, origIndex[i], numTex, numCol); + } + + return totface; +} diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index e182fe4bc51..f21d4f658ab 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -1298,8 +1298,11 @@ static void cgdm_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf) mf->v3 = getFaceIndex(ss, f, grid, x+1, y+1, edgeSize, gridSize); mf->v4 = getFaceIndex(ss, f, grid, x+1, y+0, edgeSize, gridSize); - if(faceFlags) mf->flag = faceFlags[i*4]; - else mf->flag = ME_SMOOTH; + if(faceFlags) { + mf->flag = faceFlags[i*4]; + mf->mat_nr = faceFlags[i*4+1]; + } else + mf->flag = ME_SMOOTH; } static void cgdm_copyFinalVertArray(DerivedMesh *dm, MVert *mvert) @@ -1593,6 +1596,8 @@ DMFaceIter *cgdm_newFaceIter(DerivedMesh *dm) fiter->liter.lindex = -1; fiter->head.step(fiter); + + return fiter; } static void cgdm_copyFinalFaceArray(DerivedMesh *dm, MFace *mface) @@ -2586,6 +2591,7 @@ void ccg_loops_to_corners(CustomData *fdata, CustomData *ldata, } } +/*this function requires dm to be a CDDM*/ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, int drawInteriorEdges, int useSubsurfUv, @@ -2619,6 +2625,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, MCol *mcol; MEdge *medge = NULL; MFace *mface = NULL; + MPoly *mpoly = NULL; DM_from_template(&cgdm->dm, dm, CCS_getNumFinalVerts(ss), CCS_getNumFinalEdges(ss), @@ -2733,6 +2740,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, medge = dm->getEdgeArray(dm); mface = dm->getTessFaceArray(dm); + /*CDDM hack*/ + mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY); + vertOrigIndex = DM_get_vert_data_layer(&cgdm->dm, CD_ORIGINDEX); /*edgeOrigIndex = DM_get_edge_data_layer(&cgdm->dm, CD_ORIGINDEX);*/ faceOrigIndex = DM_get_tessface_data_layer(&cgdm->dm, CD_ORIGINDEX); @@ -2850,7 +2860,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, /*copy over poly data, e.g. mtexpoly*/ CustomData_copy_data(&dm->polyData, &cgdm->dm.polyData, origIndex, faceNum, 1); - //CustomData_interp(&dm->polyData, &cgdm->dm.polyData, &origIndex, &one, NULL, 1, faceNum); /*generate tesselated face data used for drawing*/ ccg_loops_to_corners(&cgdm->dm.faceData, &cgdm->dm.loopData, @@ -2861,6 +2870,13 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, } } + polyFlags[0] = mpoly[origIndex].flag; + polyFlags[1] = mpoly[origIndex].mat_nr; + faceFlags[0] = polyFlags[0]; + faceFlags[1] = polyFlags[1]; + + faceFlags += 4; + polyFlags += 4; edgeNum += numFinalEdges; } diff --git a/source/blender/bmesh/operators/mesh_conv.c b/source/blender/bmesh/operators/mesh_conv.c index ab23427112a..31eb2914427 100644 --- a/source/blender/bmesh/operators/mesh_conv.c +++ b/source/blender/bmesh/operators/mesh_conv.c @@ -266,8 +266,6 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, mloop, me->totloop); CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, mpoly, me->totpoly); - mesh_update_customdata_pointers(me); - i = 0; BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) { VECCOPY(mvert->co, v->co); diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index ee3d9e5baa1..7a78bebbdcd 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -43,6 +43,7 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" +#include "BLI_memarena.h" #include "MTC_matrixops.h" #include "DNA_action_types.h" @@ -205,6 +206,58 @@ static unsigned int vpaint_get_current_col(VPaint *vp) void do_shared_vertexcol(Mesh *me) { + MLoop *ml = me->mloop; + MLoopCol *lcol = me->mloopcol; + MTexPoly *mtp = me->mtpoly; + MPoly *mp = me->mpoly; + float (*scol)[5]; + int i; + + /* if no mloopcol: do not do */ + /* if mtexpoly: only the involved faces, otherwise all */ + + if(me->mloopcol==0 || me->totvert==0 || me->totface==0) return; + + scol = MEM_callocN(sizeof(float)*me->totvert*5, "scol"); + + for (i=0; i<me->totloop; i++, ml++, lcol++) { + if (i >= mp->loopstart + mp->totloop) { + mp++; + if (mtp) mtp++; + } + + if (mtp && !(mtp->mode & TF_SHAREDCOL)) + continue; + + scol[ml->v][0] += lcol->r; + scol[ml->v][1] += lcol->g; + scol[ml->v][2] += lcol->b; + scol[ml->v][3] += lcol->a; + scol[ml->v][4] += 1.0; + } + + for (i=0; i<me->totvert; i++) { + if (!scol[i][4]) continue; + + scol[i][0] /= scol[i][4]; + scol[i][1] /= scol[i][4]; + scol[i][2] /= scol[i][4]; + scol[i][3] /= scol[i][4]; + } + + ml = me->mloop; + lcol = me->mloopcol; + for (i=0; i<me->totloop; i++, ml++, lcol++) { + if (!scol[4]) continue; + + lcol->r = scol[ml->v][0]; + lcol->g = scol[ml->v][1]; + lcol->b = scol[ml->v][2]; + lcol->a = scol[ml->v][3]; + } + + MEM_freeN(scol); +#if 0 /* if no mcol: do not do */ /* if tface: only the involved faces, otherwise all */ MFace *mface; @@ -267,6 +320,7 @@ void do_shared_vertexcol(Mesh *me) } MEM_freeN(scolmain); +#endif } void make_vertexcol(Scene *scene, int shade) /* single ob */ @@ -287,19 +341,22 @@ void make_vertexcol(Scene *scene, int shade) /* single ob */ /* copies from shadedisplist to mcol */ if(!me->mcol) { CustomData_add_layer(&me->fdata, CD_MCOL, CD_CALLOC, NULL, me->totface); + CustomData_add_layer(&me->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, me->totloop); mesh_update_customdata_pointers(me); } + /* if(shade) shadeMeshMCol(scene, ob, me); else memset(me->mcol, 255, 4*sizeof(MCol)*me->totface); - + */ + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); } -static void copy_vpaint_prev(VPaint *vp, unsigned int *mcol, int tot) +static void copy_vpaint_prev(VPaint *vp, unsigned int *lcol, int tot) { if(vp->vpaint_prev) { MEM_freeN(vp->vpaint_prev); @@ -307,10 +364,10 @@ static void copy_vpaint_prev(VPaint *vp, unsigned int *mcol, int tot) } vp->tot= tot; - if(mcol==NULL || tot==0) return; + if(lcol==NULL || tot==0) return; - vp->vpaint_prev= MEM_mallocN(4*sizeof(int)*tot, "vpaint_prev"); - memcpy(vp->vpaint_prev, mcol, 4*sizeof(int)*tot); + vp->vpaint_prev= MEM_mallocN(sizeof(int)*tot, "vpaint_prev"); + memcpy(vp->vpaint_prev, lcol, sizeof(int)*tot); } @@ -334,9 +391,11 @@ void clear_vpaint(Scene *scene, int selected) { Mesh *me; MFace *mf; + MPoly *mp; + MLoopCol *lcol; Object *ob; unsigned int paintcol, *mcol; - int i; + int i, j; ob= OBACT; me= get_mesh(ob); @@ -357,6 +416,18 @@ void clear_vpaint(Scene *scene, int selected) mcol[3] = paintcol; } } + + mp = me->mpoly; + lcol = me->mloopcol; + for (i=0; i<me->totpoly; i++, mp++) { + if (!(!selected || mp->flag & ME_FACE_SEL)) + continue; + + lcol = me->mloopcol + mp->loopstart; + for (j=0; j<mp->totloop; j++, lcol++) { + *(int*)lcol = paintcol; + } + } DAG_object_flush_update(scene, ob, OB_RECALC_DATA); } @@ -851,13 +922,14 @@ static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float /* else */ /* sets wp->weight to the closest weight value to vertex */ /* note: we cant sample frontbuf, weight colors are interpolated too unpredictable */ +#if 0 void sample_wpaint(Scene *scene, ARegion *ar, View3D *v3d, int mode) { ViewContext vc; ToolSettings *ts= scene->toolsettings; Object *ob= OBACT; Mesh *me= get_mesh(ob); - int index; + int index, i; short mval[2], sco[2]; if (!me) return; @@ -865,13 +937,13 @@ void sample_wpaint(Scene *scene, ARegion *ar, View3D *v3d, int mode) // getmouseco_areawin(mval); index= view3d_sample_backbuf(&vc, mval[0], mval[1]); - if(index && index<=me->totface) { - MFace *mface; - - mface= ((MFace *)me->mface) + index-1; + if(index && index<=me->totpoly) { + MPoly *mpoly; + mpoly= ((MPoly *)me->mpoly) + index-1; if(mode==1) { /* sampe which groups are in here */ MDeformVert *dv; + MLoop *ml; int a, totgroup; totgroup= BLI_countlist(&ob->defbase); @@ -879,28 +951,14 @@ void sample_wpaint(Scene *scene, ARegion *ar, View3D *v3d, int mode) int totmenu=0; int *groups=MEM_callocN(totgroup*sizeof(int), "groups"); - dv= me->dvert+mface->v1; - for(a=0; a<dv->totweight; a++) { - if (dv->dw[a].def_nr<totgroup) - groups[dv->dw[a].def_nr]= 1; - } - dv= me->dvert+mface->v2; - for(a=0; a<dv->totweight; a++) { - if (dv->dw[a].def_nr<totgroup) - groups[dv->dw[a].def_nr]= 1; - } - dv= me->dvert+mface->v3; - for(a=0; a<dv->totweight; a++) { + ml = me->mloop+mpoly->loopstart; + for (i=0; i<mpoly->totloop; i++, ml++) { + dv = me->dvert+ml->v; if (dv->dw[a].def_nr<totgroup) groups[dv->dw[a].def_nr]= 1; + } - if(mface->v4) { - dv= me->dvert+mface->v4; - for(a=0; a<dv->totweight; a++) { - if (dv->dw[a].def_nr<totgroup) - groups[dv->dw[a].def_nr]= 1; - } - } + for(a=0; a<totgroup; a++) if(groups[a]) totmenu++; @@ -934,52 +992,32 @@ void sample_wpaint(Scene *scene, ARegion *ar, View3D *v3d, int mode) else { DerivedMesh *dm; MDeformWeight *dw; - float w1, w2, w3, w4, co[3], fac; + MLoop *ml; + float w, co[3], fmin = 10000000.0f; + int loopi = mpoly->loopstart; dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); if(dm->getVertCo==NULL) { //notice("Not supported yet"); } else { - /* calc 3 or 4 corner weights */ - dm->getVertCo(dm, mface->v1, co); - project_short_noclip(ar, co, sco); - w1= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1])); - - dm->getVertCo(dm, mface->v2, co); - project_short_noclip(ar, co, sco); - w2= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1])); - - dm->getVertCo(dm, mface->v3, co); - project_short_noclip(ar, co, sco); - w3= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1])); - - if(mface->v4) { - dm->getVertCo(dm, mface->v4, co); + /* find minimum distance */ + ml = me->mloop + mpoly->loopstart; + for (i=0; i<mpoly->totloop; i++, ml++) { + dm->getVertCo(dm, ml->v, co); project_short_noclip(ar, co, sco); - w4= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1])); - } - else w4= 1.0e10; - - fac= MIN4(w1, w2, w3, w4); - if(w1==fac) { - dw= get_defweight(me->dvert+mface->v1, ob->actdef-1); - if(dw) ts->vgroup_weight= dw->weight; else ts->vgroup_weight= 0.0f; - } - else if(w2==fac) { - dw= get_defweight(me->dvert+mface->v2, ob->actdef-1); - if(dw) ts->vgroup_weight= dw->weight; else ts->vgroup_weight= 0.0f; - } - else if(w3==fac) { - dw= get_defweight(me->dvert+mface->v3, ob->actdef-1); - if(dw) ts->vgroup_weight= dw->weight; else ts->vgroup_weight= 0.0f; - } - else if(w4==fac) { - if(mface->v4) { - dw= get_defweight(me->dvert+mface->v4, ob->actdef-1); - if(dw) ts->vgroup_weight= dw->weight; else ts->vgroup_weight= 0.0f; + + w= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1])); + + if (w < fmin) { + fmin = w; + loopi = i + mpoly->loopstart; } } + + ml = me->mloop + loopi; + dw= get_defweight(me->dvert+ml->v, ob->actdef-1); + if(dw) ts->vgroup_weight= dw->weight; else ts->vgroup_weight= 0.0f; } dm->release(dm); } @@ -987,6 +1025,7 @@ void sample_wpaint(Scene *scene, ARegion *ar, View3D *v3d, int mode) } } +#endif static void do_weight_paint_vertex(VPaint *wp, Object *ob, int index, int alpha, float paintweight, int vgroup_mirror) { @@ -1541,7 +1580,7 @@ static int set_vpaint(bContext *C, wmOperator *op) /* toggle */ return OPERATOR_FINISHED; } - if(me && me->mcol==NULL) make_vertexcol(scene, 0); + if(me && me->mloopcol==NULL) make_vertexcol(scene, 0); /* toggle: end vpaint */ if(ob->mode & OB_MODE_VERTEX_PAINT) { @@ -1610,14 +1649,59 @@ For future: */ +typedef struct polyfacemap_e { + struct polyfacemap_e *next, *prev; + int facenr; +} polyfacemap_e; + struct VPaintData { ViewContext vc; unsigned int paintcol; int *indexar; float *vertexcosnos; float vpimat[3][3]; + + /*mpoly -> mface mapping*/ + MemArena *arena; + ListBase *polyfacemap; + }; +static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me) +{ + MFace *mf; + polyfacemap_e *e; + int *origIndex; + int i; + + vd->arena = BLI_memarena_new(1<<13); + BLI_memarena_use_calloc(vd->arena); + + vd->polyfacemap = BLI_memarena_alloc(vd->arena, sizeof(ListBase)*me->totpoly); + + /*we can't assume mfaces have a correct origindex layer that indices to mpolys. + so instead we have to regenerate the tesselation faces altogether.*/ + me->totface = mesh_recalcTesselation(&me->fdata, &me->ldata, &me->pdata, + me->mvert, me->totface, me->totloop, me->totpoly); + + mesh_update_customdata_pointers(me); + origIndex = CustomData_get_layer(&me->fdata, CD_ORIGINDEX); + mf = me->mface; + + if (!origIndex) + return; + + for (i=0; i<me->totface; i++, mf++, origIndex++) { + if (*origIndex == ORIGINDEX_NONE) + continue; + + e = BLI_memarena_alloc(vd->arena, sizeof(polyfacemap_e)); + e->facenr = i; + + BLI_addtail(&vd->polyfacemap[*origIndex], e); + } +} + static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, wmEvent *event) { ToolSettings *ts= CTX_data_tool_settings(C); @@ -1630,10 +1714,13 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, wmEvent /* context checks could be a poll() */ me= get_mesh(ob); - if(me==NULL || me->totface==0) return OPERATOR_PASS_THROUGH; + if(me==NULL || me->totface==0) + return OPERATOR_PASS_THROUGH; - if(me->mcol==NULL) make_vertexcol(CTX_data_scene(C), 0); - if(me->mcol==NULL) return OPERATOR_CANCELLED; + if(me->mloopcol==NULL) + make_vertexcol(CTX_data_scene(C), 0); + if(me->mloopcol==NULL) + return OPERATOR_CANCELLED; /* make mode data storage */ vpd= MEM_callocN(sizeof(struct VPaintData), "VPaintData"); @@ -1643,9 +1730,10 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, wmEvent vpd->vertexcosnos= mesh_get_mapped_verts_nors(vpd->vc.scene, ob); vpd->indexar= get_indexarray(); vpd->paintcol= vpaint_get_current_col(vp); + vpaint_build_poly_facemap(vpd, me); /* for filtering */ - copy_vpaint_prev(vp, (unsigned int *)me->mcol, me->totface); + copy_vpaint_prev(vp, (unsigned int *)me->mloopcol, me->totloop); /* some old cruft to sort out later */ Mat4MulMat4(mat, ob->obmat, vpd->vc.rv3d->viewmat); @@ -1663,6 +1751,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P Brush *brush = paint_brush(&vp->paint); ViewContext *vc= &vpd->vc; Object *ob= vc->obact; + polyfacemap_e *e; Mesh *me= ob->data; float mat[4][4]; int *indexar= vpd->indexar; @@ -1697,9 +1786,9 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P if(vp->flag & VP_COLINDEX) { for(index=0; index<totindex; index++) { if(indexar[index] && indexar[index]<=me->totface) { - MFace *mface= ((MFace *)me->mface) + (indexar[index]-1); + MPoly *mpoly= ((MPoly *)me->mpoly) + (indexar[index]-1); - if(mface->mat_nr!=ob->actcol-1) { + if(mpoly->mat_nr!=ob->actcol-1) { indexar[index]= 0; } } @@ -1708,9 +1797,9 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P if((G.f & G_FACESELECT) && me->mface) { for(index=0; index<totindex; index++) { if(indexar[index] && indexar[index]<=me->totface) { - MFace *mface= ((MFace *)me->mface) + (indexar[index]-1); + MPoly *mpoly= ((MPoly *)me->mpoly) + (indexar[index]-1); - if((mface->flag & ME_FACE_SEL)==0) + if((mpoly->flag & ME_FACE_SEL)==0) indexar[index]= 0; } } @@ -1719,39 +1808,85 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P for(index=0; index<totindex; index++) { if(indexar[index] && indexar[index]<=me->totface) { - MFace *mface= ((MFace *)me->mface) + (indexar[index]-1); - unsigned int *mcol= ( (unsigned int *)me->mcol) + 4*(indexar[index]-1); - unsigned int *mcolorig= ( (unsigned int *)vp->vpaint_prev) + 4*(indexar[index]-1); - int alpha; + MPoly *mpoly= ((MPoly *)me->mpoly) + (indexar[index]-1); + MFace *mf; + MCol *mc; + MLoop *ml; + MLoopCol *mlc; + unsigned int *lcol = ((unsigned int*)me->mloopcol) + mpoly->loopstart; + unsigned int *lcolorig = ((unsigned int*)vp->vpaint_prev) + mpoly->loopstart; + int i, j, alpha; if(vp->mode==VP_BLUR) { - unsigned int fcol1= mcol_blend( mcol[0], mcol[1], 128); - if(mface->v4) { - unsigned int fcol2= mcol_blend( mcol[2], mcol[3], 128); - vpd->paintcol= mcol_blend( fcol1, fcol2, 128); - } - else { - vpd->paintcol= mcol_blend( mcol[2], fcol1, 170); + unsigned int blend[5] = {0}; + char *col; + + for (j=0; j<mpoly->totloop; j += 2) { + col = (char*)(lcol + j); + blend[0] += col[0]; + blend[1] += col[1]; + blend[2] += col[2]; + blend[3] += col[3]; } - + + blend[0] /= mpoly->totloop; + blend[1] /= mpoly->totloop; + blend[2] /= mpoly->totloop; + blend[3] /= mpoly->totloop; + col = (char*)(blend + 4); + col[0] = blend[0]; + col[1] = blend[1]; + col[2] = blend[2]; + col[3] = blend[3]; + + vpd->paintcol = *((unsigned int*)col); } - - alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v1, mval); - if(alpha) vpaint_blend(vp, mcol, mcolorig, vpd->paintcol, alpha); - - alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v2, mval); - if(alpha) vpaint_blend(vp, mcol+1, mcolorig+1, vpd->paintcol, alpha); - - alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v3, mval); - if(alpha) vpaint_blend(vp, mcol+2, mcolorig+2, vpd->paintcol, alpha); - - if(mface->v4) { - alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v4, mval); - if(alpha) vpaint_blend(vp, mcol+3, mcolorig+3, vpd->paintcol, alpha); + + ml = me->mloop + mpoly->loopstart; + for (i=0; i<mpoly->totloop; i++, ml++) { + alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*ml->v, mval); + if(alpha) vpaint_blend(vp, lcol+i, lcolorig+i, vpd->paintcol, alpha); } + +#ifdef CPYCOL +#if 0 + #undef CPYCOL + #endif + #define CPYCOL(c, l) (c)->a = (l)->a, (c)->r = (l)->r, (c)->g = (l)->g, (c)->b = (l)->b + + /*update vertex colors for tesselations. this code + isn't strictly necassary, since CDDM regenerates + the tesselations when it creates a CDDM from + a Mesh. this also makes it hard to test that this + code is working correctly. + + if it turns out having cddm constantly recalculating + the tesselation is a problem, we can always turn on + this code and add an exception where cddm doesn't + redo the tesselation if it's in vpaint mode.*/ + for (e=vpd->polyfacemap[(indexar[index]-1)].first; e; e=e->next) { + mf = me->mface + e->facenr; + mc = me->mcol + e->facenr*4; + + ml = me->mloop + mpoly->loopstart; + mlc = me->mloopcol + mpoly->loopstart; + for (j=0; j<mpoly->totloop; j++, ml++, mlc++) { + if (ml->v == mf->v1) + CPYCOL(mc, mlc); + else if (ml->v == mf->v2) + CPYCOL(mc+4, mlc); + else if (ml->v == mf->v3) + CPYCOL(mc+8, mlc); + else if (mf->v4 && ml->v == mf->v4) + CPYCOL(mc+12, mlc); + + } + } + #undef CPYCOL +#endif } } - + MTC_Mat4SwapMat4(vc->rv3d->persmat, mat); do_shared_vertexcol(me); @@ -1772,7 +1907,8 @@ static void vpaint_stroke_done(bContext *C, struct PaintStroke *stroke) /* frees prev buffer */ copy_vpaint_prev(ts->vpaint, NULL, 0); - + BLI_memarena_free(vpd->arena); + MEM_freeN(vpd); } diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index f54aee1dfc0..27cd63fd7db 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -35,6 +35,7 @@ struct Bone; struct Image; +/*tesselation face, see MLoop/MPoly for the real face data*/ typedef struct MFace { unsigned int v1, v2, v3, v4; short mat_nr; @@ -65,7 +66,8 @@ typedef struct MVert { char flag, bweight, pad[2]; } MVert; -/* at the moment alpha is abused for vertex painting +/* tesselation vertex color data. + * at the moment alpha is abused for vertex painting * and not used for transperency, note that red and blue are swapped */ typedef struct MCol { char a, r, g, b; @@ -103,10 +105,11 @@ typedef struct MLoopUV{ #define MLOOPUV_VERTSEL 2 #define MLOOPUV_PINNED 4 +/* at the moment alpha is abused for vertex painting + * and not used for transperency, note that red and blue are swapped */ typedef struct MLoopCol{ char a, r, g, b; - int pad; /*waste!*/ -}MLoopCol; +} MLoopCol; typedef struct MSticky { float co[2]; @@ -117,6 +120,7 @@ typedef struct MSelect { int type; } MSelect; +/*tesselation uv face data*/ typedef struct MTFace { float uv[4][2]; struct Image *tpage; diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 914291a259b..5f47b3d1d95 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -337,10 +337,10 @@ static void rna_Mesh_active_uv_texture_index_set(PointerRNA *ptr, int value) static void rna_Mesh_active_uv_texture_index_range(PointerRNA *ptr, int *min, int *max) { Mesh *me= (Mesh*)ptr->data; - CustomData *fdata= rna_mesh_pdata(me); + CustomData *pdata= rna_mesh_pdata(me); *min= 0; - *max= CustomData_number_of_layers(fdata, CD_MTEXPOLY)-1; + *max= CustomData_number_of_layers(pdata, CD_MTEXPOLY)-1; *max= MAX2(0, *max); } @@ -481,17 +481,22 @@ static PointerRNA rna_Mesh_active_vertex_color_get(PointerRNA *ptr) static void rna_Mesh_active_vertex_color_set(PointerRNA *ptr, PointerRNA value) { Mesh *me= (Mesh*)ptr->data; - CustomData *ldata= rna_mesh_ldata(me); + CustomData *ldata= rna_mesh_ldata(me), *fdata; CustomDataLayer *cdl; - int a; + int a, b, c; + b = 0; for(cdl=ldata->layers, a=0; a<ldata->totlayer; cdl++, a++) { + if (cdl->type == CD_MLOOPCOL) + b++; + if(value.data == cdl) { CustomData_set_layer_active_index(ldata, CD_MLOOPCOL, a); - mesh_update_customdata_pointers(me); - return; + break; } } + + mesh_update_customdata_pointers(me); } static int rna_Mesh_active_vertex_color_index_get(PointerRNA *ptr) |