diff options
author | Joseph Eagar <joeedh@gmail.com> | 2011-03-29 09:48:18 +0400 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2011-03-29 09:48:18 +0400 |
commit | 7d43a48993c056419f144b0395781af731b06e6f (patch) | |
tree | d4aabca1f70ca8ad5199e2b723581b5ed2dd4e19 /source/blender/blenkernel/intern | |
parent | 3875461a3349722fcb7c31e444a9c76c02ae314d (diff) |
=bmesh=
Multires interpolation is considerably better
now, though it still has a problem with occasionally
producing little random tangent spikes. Still, it's
far better then it was.
Also fixed a bug in dissolve faces.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 12 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/editderivedbmesh.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifiers_bmesh.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/multires.c | 184 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 3 |
9 files changed, 181 insertions, 37 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 015574f4e68..1a4fc77c7a4 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -754,7 +754,7 @@ static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, BMEditMesh *em, int lay float (*orco)[3]; int free; - if(em) dm= CDDM_from_BMEditMesh(em, me); + if(em) dm= CDDM_from_BMEditMesh(em, me, 0); else dm= CDDM_from_mesh(me, ob); orco= get_orco_coords_dm(ob, em, layer, &free); @@ -1379,7 +1379,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D } } else { - dm = CDDM_from_BMEditMesh(em, ob->data); + dm = CDDM_from_BMEditMesh(em, ob->data, 0); if(deformedVerts) { CDDM_apply_vert_coords(dm, deformedVerts); diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index f17e72f2530..8c22ea02ce6 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1832,7 +1832,7 @@ static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata, } } -DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *me) +DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *me, int use_mdisps) { DerivedMesh *dm = CDDM_new(em->bm->totvert, em->bm->totedge, em->tottri, em->bm->totloop, em->bm->totface); @@ -1851,6 +1851,7 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *me) int numTex = CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY); int i, j, *index, add_orig; int has_crease, has_edge_bweight, has_vert_bweight; + int flag; has_edge_bweight = CustomData_has_layer(&em->bm->edata, CD_BWEIGHT); has_vert_bweight = CustomData_has_layer(&em->bm->vdata, CD_BWEIGHT); @@ -1861,13 +1862,14 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *me) /*don't add origindex layer if one already exists*/ add_orig = !CustomData_has_layer(&em->bm->pdata, CD_ORIGINDEX); - CustomData_merge(&em->bm->vdata, &dm->vertData, CD_MASK_DERIVEDMESH, + flag = use_mdisps ? CD_MASK_DERIVEDMESH|CD_MASK_MDISPS : CD_MASK_DERIVEDMESH; + CustomData_merge(&em->bm->vdata, &dm->vertData, flag, CD_CALLOC, dm->numVertData); - CustomData_merge(&em->bm->edata, &dm->edgeData, CD_MASK_DERIVEDMESH, + CustomData_merge(&em->bm->edata, &dm->edgeData, flag, CD_CALLOC, dm->numEdgeData); - CustomData_merge(&em->bm->ldata, &dm->loopData, CD_MASK_DERIVEDMESH, + CustomData_merge(&em->bm->ldata, &dm->loopData, flag, CD_CALLOC, dm->numLoopData); - CustomData_merge(&em->bm->pdata, &dm->polyData, CD_MASK_DERIVEDMESH, + CustomData_merge(&em->bm->pdata, &dm->polyData, flag, CD_CALLOC, dm->numPolyData); /*add tesselation mface layers*/ diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 36d19b53ed2..2527831319e 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -444,7 +444,7 @@ static void contarget_get_mesh_mat (Scene *scene, Object *ob, const char *substr /* get DerivedMesh */ if (em) { /* target is in editmode, so get a special derived mesh */ - dm = CDDM_from_BMEditMesh(em, ob->data); + dm = CDDM_from_BMEditMesh(em, ob->data, 0); freeDM= 1; } else { diff --git a/source/blender/blenkernel/intern/editderivedbmesh.c b/source/blender/blenkernel/intern/editderivedbmesh.c index 3f45a0069d9..62d38506eef 100644 --- a/source/blender/blenkernel/intern/editderivedbmesh.c +++ b/source/blender/blenkernel/intern/editderivedbmesh.c @@ -298,10 +298,10 @@ void BMEdit_Free(BMEditMesh *em) if (em->edge_index) MEM_freeN(em->edge_index); if (em->face_index) MEM_freeN(em->face_index); - BM_Free_Mesh(em->bm); + if (em->bm) + BM_Free_Mesh(em->bm); } - /* ok, basic design: diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index b7c300ffe22..bbf9dc87e42 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -567,7 +567,7 @@ BMesh *BKE_mesh_to_bmesh(Mesh *me, Object *ob) BMesh *bm; int allocsize[4] = {512,512,2048,512}; - bm = BM_Make_Mesh(allocsize); + bm = BM_Make_Mesh(ob, allocsize); BMO_CallOpf(bm, "mesh_to_bmesh mesh=%p object=%p", me, ob); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 7439a47a746..631e5fe2cb3 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -301,7 +301,8 @@ int modifier_isEnabled(struct Scene *scene, ModifierData *md, int required_mode) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); - md->scene= scene; + if (scene) + md->scene= scene; if((md->mode & required_mode) != required_mode) return 0; if(mti->isDisabled && mti->isDisabled(md, required_mode == eModifierMode_Render)) return 0; diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index 8b437635b2a..63784fb00bf 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -106,7 +106,7 @@ /*converts a cddm to a BMEditMesh. if existing is non-NULL, the new geometry will be put in there.*/ -BMEditMesh *CDDM_To_BMesh(DerivedMesh *dm, BMEditMesh *existing) +BMEditMesh *CDDM_To_BMesh(Object *ob, DerivedMesh *dm, BMEditMesh *existing) { int allocsize[4] = {512, 512, 2048, 512}; BMesh *bm, bmold; /*bmold is for storing old customdata layout*/ @@ -125,7 +125,7 @@ BMEditMesh *CDDM_To_BMesh(DerivedMesh *dm, BMEditMesh *existing) int i, j, k, totvert, totedge, totface; if (em) bm = em->bm; - else bm = BM_Make_Mesh(allocsize); + else bm = BM_Make_Mesh(ob, allocsize); bmold = *bm; diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index f3a4e3c3913..47106a50543 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -63,7 +63,7 @@ static const int multires_grid_tot[] = {0, 4, 9, 25, 81, 289, 1089, 4225, 16641, static const int multires_side_tot[] = {0, 2, 3, 5, 9, 17, 33, 65, 129, 257, 513, 1025, 2049, 4097}; static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert); -static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int add, DMGridData **oldGridData, int totlvl); +static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, int invert, int add, DMGridData **oldGridData, int totlvl); DerivedMesh *get_multires_dm(Scene *scene, MultiresModifierData *mmd, Object *ob) { @@ -126,6 +126,9 @@ MultiresModifierData *get_multires_modifier(Scene *scene, Object *ob, int use_fi static int multires_get_level(Object *ob, MultiresModifierData *mmd, int render) { + if (!ob || !mmd) + return 0; + if(render) return (mmd->modifier.scene)? get_render_subsurf_level(&mmd->modifier.scene->r, mmd->renderlvl): mmd->renderlvl; else if(ob->mode == OB_MODE_SCULPT) @@ -314,12 +317,12 @@ static void multires_set_tot_mdisps(Mesh *me, int lvl) } } -static void multires_reallocate_mdisps(Mesh *me, MDisps *mdisps, int lvl) +static void multires_reallocate_mdisps(int totloop, MDisps *mdisps, int lvl) { int i; /* reallocate displacements to be filled in */ - for(i = 0; i < me->totloop; ++i) { + for(i = 0; i < totloop; ++i) { int totdisp = multires_grid_tot[lvl]; float (*disps)[3] = BLI_cellalloc_calloc(sizeof(float) * 3 * totdisp, "multires disps"); @@ -331,6 +334,7 @@ static void multires_reallocate_mdisps(Mesh *me, MDisps *mdisps, int lvl) } } + static void column_vectors_to_mat3(float mat[][3], float v1[3], float v2[3], float v3[3]) { copy_v3_v3(mat[0], v1); @@ -395,11 +399,11 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl) MLoop *ml = me->mloop; int nsize = multires_side_tot[lvl]; int hsize = multires_side_tot[mmd->totlvl]; - int i, j, k=0; + int i, j; for(i = 0; i < me->totpoly; ++i) { - for (j=0; j<me->mpoly[i].totloop; j++, k++) { - MDisps *mdisp= &mdisps[k]; + for (j=0; j<me->mpoly[i].totloop; j++) { + MDisps *mdisp= &mdisps[me->mpoly[i].loopstart+j]; float (*disps)[3], (*ndisps)[3], (*hdisps)[3]; int totdisp = multires_grid_tot[lvl]; @@ -435,10 +439,10 @@ void multiresModifier_del_levels(MultiresModifierData *mmd, Object *ob, int dire int lvl = multires_get_level(ob, mmd, 0); int levels = mmd->totlvl - lvl; MDisps *mdisps; - + multires_set_tot_mdisps(me, mmd->totlvl); CustomData_external_read(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface); - mdisps= CustomData_get_layer(&me->fdata, CD_MDISPS); + mdisps= CustomData_get_layer(&me->ldata, CD_MDISPS); multires_force_update(ob); @@ -449,7 +453,7 @@ 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) +DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int totlvl, int simple) { MultiresModifierData mmd= {{NULL}}; @@ -592,7 +596,7 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob) cddm->release(cddm); /* calc disps */ - multiresModifier_disp_run(dispdm, me, 1, 0, origdm->getGridData(origdm), totlvl); + multiresModifier_disp_run(dispdm, me, NULL, 1, 0, origdm->getGridData(origdm), totlvl); origdm->release(origdm); dispdm->release(dispdm); @@ -656,10 +660,10 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl ccgSubSurf_updateLevels(ss, lvl, NULL, 0); /* reallocate displacements */ - multires_reallocate_mdisps(me, mdisps, totlvl); + multires_reallocate_mdisps(me->totloop, mdisps, totlvl); /* compute displacements */ - multiresModifier_disp_run(highdm, me, 1, 0, subGridData, totlvl); + multiresModifier_disp_run(highdm, me, NULL, 1, 0, subGridData, totlvl); /* free */ highdm->release(highdm); @@ -669,7 +673,7 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl } else { /* only reallocate, nothing to upsample */ - multires_reallocate_mdisps(me, mdisps, totlvl); + multires_reallocate_mdisps(me->totloop, mdisps, totlvl); } multires_set_tot_level(ob, mmd, totlvl); @@ -704,7 +708,7 @@ void grid_tangent(int gridSize, int index, int x, int y, int axis, DMGridData ** } } -static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int add, DMGridData **oldGridData, int totlvl) +static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, int invert, int add, DMGridData **oldGridData, int totlvl) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*)dm; DMGridData **gridData, **subGridData; @@ -712,7 +716,19 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS); int *gridOffset; int i, k, /*numGrids,*/ gridSize, dGridSize, dSkip; - + int totloop, totpoly; + + /*this happens in the dm made by bmesh_set_mdisps_space*/ + if (dm2 && CustomData_has_layer(&dm2->loopData, CD_MDISPS)) { + mpoly = CustomData_get_layer(&dm2->polyData, CD_MPOLY); + mdisps = CustomData_get_layer(&dm2->loopData, CD_MDISPS); + totloop = dm2->numLoopData; + totpoly = dm2->numPolyData; + } else { + totloop = me->totloop; + totpoly = me->totpoly; + } + if(!mdisps) { if(invert) mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS, CD_DEFAULT, NULL, me->totloop); @@ -731,9 +747,9 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int k = 0; /*current loop/mdisp index within the mloop array*/ - #pragma omp parallel for private(i) if(me->totloop*gridSize*gridSize >= CCG_OMP_LIMIT) + #pragma omp parallel for private(i) if(totloop*gridSize*gridSize >= CCG_OMP_LIMIT) - for(i = 0; i < me->totpoly; ++i) { + for(i = 0; i < totpoly; ++i) { const int numVerts = mpoly[i].totloop; int S, x, y, gIndex = gridOffset[i]; @@ -747,7 +763,7 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int if(!mdisp->disps) #pragma omp critical { - multires_reallocate_mdisps(me, mdisps, totlvl); + multires_reallocate_mdisps(totloop, mdisps, totlvl); } dispgrid = mdisp->disps; @@ -872,7 +888,7 @@ static void multiresModifier_update(DerivedMesh *dm) ccgSubSurf_updateLevels(ss, lvl, NULL, 0); /* add to displacements */ - multiresModifier_disp_run(highdm, me, 1, 1, subGridData, mmd->totlvl); + multiresModifier_disp_run(highdm, me, NULL, 1, 1, subGridData, mmd->totlvl); /* free */ highdm->release(highdm); @@ -890,13 +906,134 @@ static void multiresModifier_update(DerivedMesh *dm) subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0); cddm->release(cddm); - multiresModifier_disp_run(dm, me, 1, 0, subdm->getGridData(subdm), mmd->totlvl); + multiresModifier_disp_run(dm, me, NULL, 1, 0, subdm->getGridData(subdm), mmd->totlvl); subdm->release(subdm); } } } + +void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to) +{ + CCGDerivedMesh *ccgdm, *subsurf=NULL; + DMGridData **gridData, **subGridData=NULL; + MPoly *mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY); + MDisps *mdisps; + MultiresModifierData *mmd = get_multires_modifier(NULL, ob, 1); + int *gridOffset, totlvl; + int i, k, numGrids, gridSize, dGridSize, dSkip; + + if (!mmd) + return; + + mdisps = CustomData_get_layer(&dm->loopData, CD_MDISPS); + + if(!mdisps) { + goto cleanup; + } + + totlvl = mmd->totlvl; + ccgdm = (CCGDerivedMesh*)multires_dm_create_local(ob, dm, totlvl, totlvl, mmd->simple); + + subsurf = subsurf_dm_create_local(ob, dm, totlvl, + mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges); + + numGrids = subsurf->dm.getNumGrids(subsurf); + gridSize = subsurf->dm.getGridSize(subsurf); + gridData = subsurf->dm.getGridData(subsurf); + + subGridData = MEM_callocN(sizeof(DMGridData*)*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); + } + + /*numGrids = ccgdm->dm->getNumGrids((DerivedMesh*)ccgdm);*/ /*UNUSED*/ + gridSize = ccgdm->dm.getGridSize((DerivedMesh*)ccgdm); + gridData = ccgdm->dm.getGridData((DerivedMesh*)ccgdm); + gridOffset = ccgdm->dm.getGridOffset((DerivedMesh*)ccgdm); + + dGridSize = multires_side_tot[totlvl]; + dSkip = (dGridSize-1)/(gridSize-1); + + k = 0; /*current loop/mdisp index within the mloop array*/ + + //#pragma omp parallel for private(i) if(dm->numLoopData*gridSize*gridSize >= CCG_OMP_LIMIT) + + for(i = 0; i < dm->numPolyData; ++i) { + const int numVerts = mpoly[i].totloop; + int S, x, y, gIndex = gridOffset[i]; + + for(S = 0; S < numVerts; ++S, ++gIndex, ++k) { + MDisps *mdisp = &mdisps[mpoly[i].loopstart+S]; + DMGridData *grid = gridData[gIndex]; + DMGridData *subgrid = subGridData[gIndex]; + float (*dispgrid)[3] = NULL; + + /* when adding new faces in edit mode, need to allocate disps */ + if(!mdisp->disps) { + mdisp->totdisp = gridSize*gridSize; + mdisp->disps = BLI_cellalloc_calloc(sizeof(float)*3*mdisp->totdisp, "disp in multires_set_space"); + } + + dispgrid = mdisp->disps; + + 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 mat[3][3], tx[3], ty[3], dco[3]; + + /* construct tangent space matrix */ + grid_tangent(gridSize, gIndex, x, y, 0, subGridData, tx); + normalize_v3(tx); + + grid_tangent(gridSize, gIndex, x, y, 1, subGridData, ty); + normalize_v3(ty); + column_vectors_to_mat3(mat, tx, ty, no); + + /* convert to absolute coordinates in space */ + if (from == MULTIRES_SPACE_TANGENT) { + mul_v3_m3v3(dco, mat, data); + add_v3_v3(dco, co); + } else if (from == MULTIRES_SPACE_OBJECT) { + add_v3_v3v3(dco, co, data); + } else if (from == MULTIRES_SPACE_ABSOLUTE) { + copy_v3_v3(dco, data); + } + + column_vectors_to_mat3(mat, tx, ty, no); + + /*now, convert to desired displacement type*/ + if (to == MULTIRES_SPACE_TANGENT) { + invert_m3(mat); + + sub_v3_v3(dco, co); + mul_v3_m3v3(data, mat, dco); + } else if (to == MULTIRES_SPACE_OBJECT) { + sub_v3_v3(dco, co); + mul_v3_m3v3(data, mat, dco); + } else if (to == MULTIRES_SPACE_ABSOLUTE) { + copy_v3_v3(data, dco); + } + } + } + } + } + +cleanup: + if (subsurf) { + subsurf->dm.needsFree = 1; + subsurf->dm.release(subsurf); + } + + ccgdm->dm.needsFree = 1; + ccgdm->dm.release((DerivedMesh*)ccgdm); +} + void multires_stitch_grids(Object *ob) { /* utility for smooth brush */ @@ -959,7 +1096,7 @@ DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, int loca CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop); /*run displacement*/ - multiresModifier_disp_run(result, ob->data, 0, 0, subGridData, mmd->totlvl); + multiresModifier_disp_run(result, ob->data, dm, 0, 0, subGridData, mmd->totlvl); for(i = 0; i < numGrids; i++) MEM_freeN(subGridData[i]); @@ -978,7 +1115,10 @@ void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, const int st_max = st - 1; float urat, vrat, uopp; float d[4][3], d2[2][3]; - + + if (!disps) + return; + if(u < 0) u = 0; else if(u >= st) diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index c92b5686df3..ffea719264b 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -498,7 +498,8 @@ void free_ss_weights(WeightTable *wtable) MEM_freeN(wtable->weight_table[i].w); } - MEM_freeN(wtable->weight_table); + if (wtable->weight_table) + MEM_freeN(wtable->weight_table); } static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh, |