From 7d43a48993c056419f144b0395781af731b06e6f Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Tue, 29 Mar 2011 05:48:18 +0000 Subject: =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. --- source/blender/blenkernel/BKE_cdderivedmesh.h | 4 +- source/blender/blenkernel/BKE_multires.h | 8 + source/blender/blenkernel/intern/DerivedMesh.c | 4 +- source/blender/blenkernel/intern/cdderivedmesh.c | 12 +- source/blender/blenkernel/intern/constraint.c | 2 +- .../blender/blenkernel/intern/editderivedbmesh.c | 4 +- source/blender/blenkernel/intern/mesh.c | 2 +- source/blender/blenkernel/intern/modifier.c | 3 +- source/blender/blenkernel/intern/modifiers_bmesh.c | 4 +- source/blender/blenkernel/intern/multires.c | 184 ++++++++++++-- source/blender/blenkernel/intern/subsurf_ccg.c | 3 +- source/blender/blenlib/BLI_utildefines.h | 3 +- source/blender/bmesh/bmesh.h | 4 +- source/blender/bmesh/bmesh_class.h | 2 + source/blender/bmesh/bmesh_operator_api.h | 5 +- source/blender/bmesh/intern/bmesh_construct.c | 2 +- source/blender/bmesh/intern/bmesh_interp.c | 268 +++++++++++++++------ source/blender/bmesh/intern/bmesh_mesh.c | 80 +++++- source/blender/bmesh/intern/bmesh_mods.c | 3 +- source/blender/bmesh/intern/bmesh_opdefines.c | 67 ++---- source/blender/bmesh/intern/bmesh_operators.c | 4 +- source/blender/bmesh/intern/bmesh_polygon.c | 1 + source/blender/bmesh/intern/bmesh_private.h | 2 +- source/blender/bmesh/operators/bmesh_dupeops.c | 31 --- source/blender/editors/mesh/bmesh_tools.c | 2 +- source/blender/editors/mesh/bmeshutils.c | 16 +- source/blender/modifiers/intern/MOD_armature.c | 4 +- source/blender/modifiers/intern/MOD_array.c | 4 +- source/blender/modifiers/intern/MOD_curve.c | 2 +- source/blender/modifiers/intern/MOD_hook.c | 2 +- source/blender/modifiers/intern/MOD_lattice.c | 2 +- source/blender/modifiers/intern/MOD_util.c | 2 +- 32 files changed, 526 insertions(+), 210 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h index 1d99d9c388b..dd3a1005bae 100644 --- a/source/blender/blenkernel/BKE_cdderivedmesh.h +++ b/source/blender/blenkernel/BKE_cdderivedmesh.h @@ -62,7 +62,7 @@ struct DerivedMesh *CDDM_from_mesh(struct Mesh *mesh, struct Object *ob); struct DerivedMesh *CDDM_from_editmesh(struct EditMesh *em, struct Mesh *me); /* creates a CDDerivedMesh from the given BMEditMesh */ -DerivedMesh *CDDM_from_BMEditMesh(struct BMEditMesh *em, struct Mesh *me); +DerivedMesh *CDDM_from_BMEditMesh(struct BMEditMesh *em, struct Mesh *me, int use_mdisps); /* merge verts */ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, int *vtargetmap); @@ -74,7 +74,7 @@ struct DerivedMesh *CDDM_from_curve(struct Object *ob); /* useful for OrcoDM creation for curves with constructive modifiers */ DerivedMesh *CDDM_from_curve_customDB(struct Object *ob, struct ListBase *dispbase); -struct BMEditMesh *CDDM_To_BMesh(DerivedMesh *dm, struct BMEditMesh *existing); +struct BMEditMesh *CDDM_To_BMesh(struct Object *ob, struct DerivedMesh *dm, struct BMEditMesh *existing); /* Copies the given DerivedMesh with verts, faces & edges stored as diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index ea34ff4aa07..25b56a371e7 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -73,6 +73,14 @@ int multiresModifier_reshapeFromDeformMod(struct Scene *scene, struct MultiresMo void multires_stitch_grids(struct Object *); +/*switch mdisp data in dm between tangent and object space*/ +enum { + MULTIRES_SPACE_TANGENT, + MULTIRES_SPACE_OBJECT, + MULTIRES_SPACE_ABSOLUTE, +}; +void multires_set_space(struct DerivedMesh *dm, struct Object *ob, int from, int to); + /* Related to the old multires */ void multires_free(struct Multires *mr); void multires_load_old(struct Object *ob, struct Mesh *me); 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; jmpoly[i].totloop; j++, k++) { - MDisps *mdisp= &mdisps[k]; + for (j=0; jmpoly[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, diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index b2129a6ab76..6bf19010980 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -112,7 +112,8 @@ #define VECADD(v1,v2,v3) {*(v1)= *(v2) + *(v3); *(v1+1)= *(v2+1) + *(v3+1); *(v1+2)= *(v2+2) + *(v3+2);} #define VECSUB(v1,v2,v3) {*(v1)= *(v2) - *(v3); *(v1+1)= *(v2+1) - *(v3+1); *(v1+2)= *(v2+2) - *(v3+2);} -#define VECSUB2D(v1,v2,v3) {*(v1)= *(v2) - *(v3); *(v1+1)= *(v2+1) - *(v3+1);} +#define VECSUB2D(v1,v2,v3, fac) {*(v1)= *(v2) - *(v3); *(v1+1)= *(v2+1) - *(v3+1);} +#define VECINTERP(v1,v2,v3, fac) {*(v1) = *(v2) + (*(v3)-*(v2))*(fac); *(v1+1) = *(v2+1) + (*(v3+1)-*(v2+1))*(fac); *(v1+2) = *(v2+2) + (*(v3+2)-*(v2+2))*(fac);} #define VECADDFAC(v1,v2,v3,fac) {*(v1)= *(v2) + *(v3)*(fac); *(v1+1)= *(v2+1) + *(v3+1)*(fac); *(v1+2)= *(v2+2) + *(v3+2)*(fac);} #define VECSUBFAC(v1,v2,v3,fac) {*(v1)= *(v2) - *(v3)*(fac); *(v1+1)= *(v2+1) - *(v3+1)*(fac); *(v1+2)= *(v2+2) - *(v3+2)*(fac);} #define QUATADDFAC(v1,v2,v3,fac) {*(v1)= *(v2) + *(v3)*(fac); *(v1+1)= *(v2+1) + *(v3+1)*(fac); *(v1+2)= *(v2+2) + *(v3+2)*(fac); *(v1+3)= *(v2+3) + *(v3+3)*(fac);} diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index 97741854f71..edfdd6676ae 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -119,7 +119,9 @@ struct EditMesh; void bmesh_error ( void ); /*Mesh Level Ops */ -struct BMesh *BM_Make_Mesh ( int allocsize[4] ); + +/*ob is needed by multires*/ +struct BMesh *BM_Make_Mesh (struct Object *ob, int allocsize[4] ); BMesh *BM_Copy_Mesh ( BMesh *bmold ); void BM_Free_Mesh ( struct BMesh *bm ); diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index 65c4bddd999..d63d37c1cb2 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -19,6 +19,7 @@ struct BMLayerType; struct BMSubClassLayer; struct BMFlagLayer; struct BLI_mempool; +struct Object; /* UPDATE: ok, this hasn't been all that useful. Need to rip this out and just go with original @@ -253,6 +254,7 @@ typedef struct BMesh { BMFace *act_face; ListBase errorstack; + struct Object *ob; /*owner object*/ } BMesh; BMFace *BM_Copy_Face(BMesh *bm, BMFace *f, int copyedges, int copyverts); diff --git a/source/blender/bmesh/bmesh_operator_api.h b/source/blender/bmesh/bmesh_operator_api.h index 9c76bedb5c4..e3075e9a6a6 100644 --- a/source/blender/bmesh/bmesh_operator_api.h +++ b/source/blender/bmesh/bmesh_operator_api.h @@ -113,9 +113,12 @@ typedef struct BMOpDefine { const char *name; slottype slottypes[BMOP_MAX_SLOTS]; void (*exec)(BMesh *bm, BMOperator *op); - int flag; /*doesn't do anything right now*/ + int flag; } BMOpDefine; +/*BMOpDefine->flag*/ +#define BMOP_UNTAN_MULTIRES 1 /*switch from multires tangent space to absolute coordinates*/ + /*------------- Operator API --------------*/ /*data types that use pointers (arrays, etc) should never diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index a41fc6f7e22..9a838577920 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -478,7 +478,7 @@ BMesh *BM_Copy_Mesh(BMesh *bmold) int i, j; /*allocate a bmesh*/ - bm = BM_Make_Mesh(allocsize); + bm = BM_Make_Mesh(bmold->ob, allocsize); CustomData_copy(&bmold->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0); CustomData_copy(&bmold->edata, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0); diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index 9e1d1fc6176..3f66cce1c74 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -272,7 +272,8 @@ int isect_ray_tri_threshold_v3_uvw(float p1[3], float d[3], float _v0[3], float float du = 0, dv = 0; float v0[3], v1[3], v2[3], c[3]; - /*expand triange a bit*/ + /*expand triangle a bit*/ +#if 1 cent_tri_v3(c, _v0, _v1, _v2); sub_v3_v3v3(v0, _v0, c); sub_v3_v3v3(v1, _v1, c); @@ -283,6 +284,11 @@ int isect_ray_tri_threshold_v3_uvw(float p1[3], float d[3], float _v0[3], float add_v3_v3(v0, c); add_v3_v3(v1, c); add_v3_v3(v2, c); +#else + copy_v3_v3(v0, _v0); + copy_v3_v3(v1, _v1); + copy_v3_v3(v2, _v2); +#endif sub_v3_v3v3(e1, v1, v0); sub_v3_v3v3(e2, v2, v0); @@ -329,20 +335,154 @@ int isect_ray_tri_threshold_v3_uvw(float p1[3], float d[3], float _v0[3], float return 1; } +/* find closest point to p on line through l1,l2 and return lambda, + * where (0 <= lambda <= 1) when cp is in the line segement l1,l2 + */ +static double closest_to_line_v3_d(double cp[3], const double p[3], const double l1[3], const double l2[3]) +{ + double h[3],u[3],lambda; + VECSUB(u, l2, l1); + VECSUB(h, p, l1); + lambda =INPR(u,h)/INPR(u,u); + cp[0] = l1[0] + u[0] * lambda; + cp[1] = l1[1] + u[1] * lambda; + cp[2] = l1[2] + u[2] * lambda; + return lambda; +} + +/* point closest to v1 on line v2-v3 in 3D */ +static void closest_to_line_segment_v3_d(double *closest, double v1[3], double v2[3], double v3[3]) +{ + double lambda, cp[3]; + + lambda= closest_to_line_v3_d(cp,v1, v2, v3); + + if(lambda <= 0.0) { + VECCOPY(closest, v2); + } else if(lambda >= 1.0) { + VECCOPY(closest, v3); + } else { + VECCOPY(closest, cp); + } +} + +static double len_v3v3_d(const double a[3], const double b[3]) +{ + double d[3]; + + VECSUB(d, b, a); + return sqrt(INPR(d, d)); +} + +/*funnily enough, I think this is identical to face_to_crn_interp, heh*/ +double quad_coord(double aa[3], double bb[3], double cc[3], double dd[3], int a1, int a2) +{ + double x, y, z, f1, f2; + + x = aa[a1]*cc[a2]-cc[a1]*aa[a2]; + y = aa[a1]*dd[a2]+bb[a1]*cc[a2]-cc[a1]*bb[a2]-dd[a1]*aa[a2]; + z = bb[a1]*dd[a2]-dd[a1]*bb[a2]; + + + if (fabs(2*(x-y+z)) > DBL_EPSILON*1000.0) { + f1 = (sqrt(y*y-4.0*x*z) - y + 2.0*z) / (2.0*(x-y+z)); + f2 = (-sqrt(y*y-4.0*x*z) - y + 2.0*z) / (2.0*(x-y+z)); + } else f1 = -1; + + if (isnan(f1) || f1 == -1.0) { + int i, tot=200; + double d, lastd=-1.0; + + //return -1.0f; +#if 0 + double co[3], p[3] = {0.0, 0.0, 0.0}; + closest_to_line_segment_v3_d(co, p, aa, bb); + + return len_v3v3_d(bb, co) / len_v3v3_d(aa, bb); +#endif +#if 1 + f1 = 1.0; + f2 = 0.0; + for (i=0; i 0.0000001 || f1 < -FLT_EPSILON*1000 || f1 >= 1.0+FLT_EPSILON*100) + return -1.0; + + CLAMP(f1, 0.0, 1.0+DBL_EPSILON); + return 1.0 - f1; +#endif + } + + f1 = MIN2(fabs(f1), fabs(f2)); + CLAMP(f1, 0.0, 1.0+DBL_EPSILON); + + return f1; +} + +void quad_co(float *x, float *y, float v1[3], float v2[3], float v3[3], float v4[3], float p[3], float n[3]) +{ + float projverts[4][3]; + double dverts[4][3]; + int i; + + sub_v3_v3v3(projverts[0], v1, p); + sub_v3_v3v3(projverts[1], v2, p); + sub_v3_v3v3(projverts[2], v3, p); + sub_v3_v3v3(projverts[3], v4, p); + + /*rotate*/ + poly_rotate_plane(n, projverts, 4); + + /*flatten*/ + for (i=0; i<4; i++) projverts[i][2] = 0.0f; + + VECCOPY(dverts[0], projverts[0]); + VECCOPY(dverts[1], projverts[1]); + VECCOPY(dverts[2], projverts[2]); + VECCOPY(dverts[3], projverts[3]); + + *y = quad_coord(dverts[1], dverts[0], dverts[2], dverts[3], 0, 1); + *x = quad_coord(dverts[2], dverts[1], dverts[3], dverts[0], 0, 1); +} + /*tl is loop to project onto, sl is loop whose internal displacement, co, is being projected. x and y are location in loop's mdisps grid of co.*/ -static int mdisp_in_mdispquad(BMLoop *l, BMLoop *tl, float p[3], float *x, float *y, int res) +static int mdisp_in_mdispquad(BMesh *bm, BMLoop *l, BMLoop *tl, float p[3], float *x, float *y, int res) { float v1[3], v2[3], c[3], co[3], v3[3], v4[3], e1[3], e2[3]; float w[4], dir[3], uv[4] = {0.0f, 0.0f, 0.0f, 0.0f}, hit[3]; - float lm, eps = FLT_EPSILON*80; + float x2, y2, lm, eps = FLT_EPSILON*20; int ret=0; + if (len_v3(l->f->no) < FLT_EPSILON*50) + BM_Face_UpdateNormal(bm, l->f); + + if (len_v3(tl->f->no) < FLT_EPSILON*50) + BM_Face_UpdateNormal(bm, tl->f); + compute_mdisp_quad(tl, v1, v2, v3, v4, e1, e2); - copy_v3_v3(dir, l->f->no); + copy_v3_v3(dir, tl->f->no); copy_v3_v3(co, dir); - mul_v3_fl(co, -0.000001); + mul_v3_fl(co, -0.001); add_v3_v3(co, p); /*four tests, two per triangle, once again normal, once along -normal*/ @@ -356,13 +496,17 @@ static int mdisp_in_mdispquad(BMLoop *l, BMLoop *tl, float p[3], float *x, float ret = ret || isect_ray_tri_threshold_v3_uvw(co, dir, v1, v3, v4, &lm, uv, eps); } - if (!ret || isnan(lm) || (uv[0]+uv[1]+uv[2]+uv[3]) < 1.0-FLT_EPSILON*10) + if (!ret) + return 0; + + if (isnan(lm)) return 0; mul_v3_fl(dir, lm); add_v3_v3v3(hit, co, dir); /*expand quad a bit*/ +#if 1 cent_quad_v3(c, v1, v2, v3, v4); sub_v3_v3(v1, c); sub_v3_v3(v2, c); @@ -371,34 +515,30 @@ static int mdisp_in_mdispquad(BMLoop *l, BMLoop *tl, float p[3], float *x, float mul_v3_fl(v3, 1.0+eps); mul_v3_fl(v4, 1.0+eps); add_v3_v3(v1, c); add_v3_v3(v2, c); add_v3_v3(v3, c); add_v3_v3(v4, c); +#endif - interp_weights_face_v3(uv, v1, v2, v3, v4, hit); - - *x = ((1.0+FLT_EPSILON)*uv[2] + (1.0+FLT_EPSILON)*uv[3])*(float)(res-1); - *y = ((1.0+FLT_EPSILON)*uv[1] + (1.0+FLT_EPSILON)*uv[2])*(float)(res-1); + quad_co(x, y, v1, v2, v3, v4, hit, tl->f->no); - return 1; -} + if (isnan(*x) || isnan(*y) || *x == -1.0f || *y == -1.0f) { + interp_weights_face_v3(uv, v1, v2, v3, v4, hit); + + x2 = ((1.0+FLT_EPSILON)*uv[2] + (1.0+FLT_EPSILON)*uv[3]); + y2 = ((1.0+FLT_EPSILON)*uv[1] + (1.0+FLT_EPSILON)*uv[2]); -void undo_tangent(MDisps *md, int res, int x, int y, int redo) -{ -#if 0 - float co[3], tx[3], ty[3], mat[3][3]; + if (*x == -1.0f || isnan(*x)) + *x = x2; + if (*y == -1.0f || isnan(*y)) + *y = y2; + } - /* construct tangent space matrix */ - grid_tangent(res, 0, x, y, 0, md->disps, tx); - normalize_v3(tx); - - grid_tangent(res, 0, x, y, 1, md->disps, ty); - normalize_v3(ty); + *x *= res-1-FLT_EPSILON*100; + *y *= res-1-FLT_EPSILON*100; - column_vectors_to_mat3(mat, tx, ty, no); - if (redo) - invert_m3(mat); + if (fabs(*x-x2) > 1.5 || fabs(*y-y2) > 1.5) { + x2 = 1; + } - mul_v3_m3v3(co, mat, md->disps[y*res+x]); - copy_v3_v3(md->disps[y*res+x], co); -#endif + return 1; } static void bmesh_loop_interp_mdisps(BMesh *bm, BMLoop *target, BMFace *source) @@ -425,22 +565,30 @@ static void bmesh_loop_interp_mdisps(BMesh *bm, BMLoop *target, BMFace *source) return; } - res = (int)(sqrt(mdisps->totdisp)+0.5f); + res = (int)sqrt(mdisps->totdisp); d = 1.0f/(float)(res-1); for (x=0.0f, ix=0; ixldata, target->head.data, CD_MDISPS); md2 = CustomData_bmesh_get(&bm->ldata, l2->head.data, CD_MDISPS); - if (mdisp_in_mdispquad(target, l2, co, &x2, &y2, res)) { - int i1, j1; - float tx[3], mat[3][3], ty[3]; - + if (mdisp_in_mdispquad(bm, target, l2, co, &x2, &y2, res)) { ix2 = (int)x2; iy2 = (int)y2; - for (i1=ix2-1; i1= res) continue; - if (j1 < 0 || j1 >= res) continue; - - undo_tangent(md2, res, i1, j1, 0); - } - } - old_mdisps_bilinear(md1->disps[iy*res+ix], md2->disps, res, x2, y2); - - for (i1=ix2-1; i1= res) continue; - if (j1 < 0 || j1 >= res) continue; - - undo_tangent(md2, res, i1, j1, 1); - } - } - } l2 = l2->next; } while (l2 != bm_firstfaceloop(source)); @@ -491,7 +617,7 @@ void BM_multires_smooth_bounds(BMesh *bm, BMFace *f) BMLoop *l; BMIter liter; - return;//XXX + //return;//XXX if (!CustomData_has_layer(&bm->ldata, CD_MDISPS)) return; @@ -507,23 +633,27 @@ void BM_multires_smooth_bounds(BMesh *bm, BMFace *f) /***** mdisps is a grid of displacements, ordered thus: - v1/center -- v4/next -> x - | | - | | - v2/prev ---- v3/cur - | - V - - y + v4/next + | + | v1/cent-mid2 ---> x + | | | + | | | + v2/prev--mid1--v3/cur + | + V + y *****/ sides = sqrt(mdp->totdisp); for (y=0; ydisps[y*sides + sides-1], mdl->disps[y*sides]); - mul_v3_fl(co, 0.5); - - copy_v3_v3(mdp->disps[y*sides + sides-1], co); - copy_v3_v3(mdl->disps[y*sides], co); + //add_v3_v3v3(co, mdp->disps[y*sides + sides-1], mdl->disps[y*sides]); + //mul_v3_fl(co, 0.5); + copy_v3_v3(co, mdn->disps[y*sides]); + copy_v3_v3(mdn->disps[y*sides], mdl->disps[y]); + copy_v3_v3(mdl->disps[y], co); + + //copy_v3_v3(mdp->disps[y*sides + sides-1], co); + //copy_v3_v3(mdl->disps[y*sides], co); } } } diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 26a3761b98e..1493b456ce6 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -33,10 +33,23 @@ */ #include "MEM_guardedalloc.h" + #include "DNA_listBase.h" +#include "DNA_object_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_mesh_types.h" + #include "BLI_blenlib.h" #include "BLI_math.h" +#include "BLI_utildefines.h" +#include "BLI_cellalloc.h" + #include "BKE_utildefines.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_tessmesh.h" +#include "BKE_customdata.h" +#include "BKE_DerivedMesh.h" +#include "BKE_multires.h" #include "bmesh.h" #include "bmesh_private.h" @@ -97,7 +110,7 @@ int bmesh_test_sysflag(BMHeader *head, int flag) * */ -BMesh *BM_Make_Mesh(int allocsize[4]) +BMesh *BM_Make_Mesh(struct Object *ob, int allocsize[4]) { /*allocate the structure*/ BMesh *bm = MEM_callocN(sizeof(BMesh),"BM"); @@ -119,7 +132,8 @@ BMesh *BM_Make_Mesh(int allocsize[4]) } bm->baselevel = baselevel; - + bm->ob = ob; + /*allocate the memory pools for the mesh elements*/ bm->vpool = BLI_mempool_create(vsize, allocsize[0], allocsize[0], 0, 1); bm->epool = BLI_mempool_create(esize, allocsize[1], allocsize[1], 0, 1); @@ -292,11 +306,69 @@ void BM_Compute_Normals(BMesh *bm) * */ -void bmesh_begin_edit(BMesh *UNUSED(bm)){ +void bmesh_set_mdisps_space(BMesh *bm, int from, int to) +{ + /*switch multires data out of tangent space*/ + if (CustomData_has_layer(&bm->ldata, CD_MDISPS)) { + Object *ob = bm->ob; + BMEditMesh *em = BMEdit_Create(bm); + DerivedMesh *dm = CDDM_from_BMEditMesh(em, NULL, 1); + MDisps *mdisps; + BMFace *f; + BMIter iter; + int i; + + multires_set_space(dm, ob, from, to); + + mdisps = CustomData_get_layer(&dm->loopData, CD_MDISPS); + + BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) { + BMLoop *l; + BMIter liter; + BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) { + MDisps *lmd = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MDISPS); + + if (!lmd->disps) { + printf("eck!\n"); + } + + if (lmd->disps && lmd->totdisp == mdisps->totdisp) { + memcpy(lmd->disps, mdisps->disps, sizeof(float)*3*lmd->totdisp); + } else if (mdisps->disps) { + if (lmd->disps) + BLI_cellalloc_free(lmd->disps); + + lmd->disps = BLI_cellalloc_dupalloc(mdisps->disps); + lmd->totdisp = mdisps->totdisp; + } + + mdisps++; + i += 1; + } + } + + dm->needsFree = 1; + dm->release(dm); + + /*setting this to NULL prevents BMEdit_Free from freeing it*/ + em->bm = NULL; + BMEdit_Free(em); + MEM_freeN(em); + } } -void bmesh_end_edit(BMesh *bm, int UNUSED(flag)){ +void bmesh_begin_edit(BMesh *bm, int flag) { + /*switch multires data out of tangent space*/ + if ((flag & BMOP_UNTAN_MULTIRES) && CustomData_has_layer(&bm->ldata, CD_MDISPS)) + bmesh_set_mdisps_space(bm, MULTIRES_SPACE_TANGENT, MULTIRES_SPACE_ABSOLUTE); +} + +void bmesh_end_edit(BMesh *bm, int flag){ /*compute normals, clear temp flags and flush selections*/ BM_Compute_Normals(bm); BM_SelectMode_Flush(bm); + + /*switch multires data into tangent space*/ + if ((flag & BMOP_UNTAN_MULTIRES) && CustomData_has_layer(&bm->ldata, CD_MDISPS)) + bmesh_set_mdisps_space(bm, MULTIRES_SPACE_ABSOLUTE, MULTIRES_SPACE_TANGENT); } diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index 1759d6ae365..1ebfd481a4d 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -390,7 +390,8 @@ void BM_Collapse_Vert(BMesh *bm, BMEdge *ke, BMVert *kv, float fac){ tv2 = BM_OtherEdgeVert(e2, kv); f2 = BM_Join_Faces(bm, faces, BLI_array_count(faces)); - BM_Split_Face(bm, f2, tv, tv2, NULL, NULL); + if (f2) + BM_Split_Face(bm, f2, tv, tv2, NULL, NULL); } else if (faces && BLI_array_count(faces) == 1) { BMLoop **loops = NULL; BMEdge *e; diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index a9fd22a9e2e..22ae20de797 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -96,7 +96,7 @@ BMOpDefine def_righthandfaces = { {0} /*null-terminating sentinel*/, }, bmesh_righthandfaces_exec, - 0 + BMOP_UNTAN_MULTIRES }; /* @@ -135,7 +135,7 @@ BMOpDefine def_edgerotate = { {0} /*null-terminating sentinel*/, }, bmesh_edgerotate_exec, - 0 + BMOP_UNTAN_MULTIRES }; /* @@ -150,7 +150,7 @@ BMOpDefine def_reversefaces = { {0} /*null-terminating sentinel*/, }, bmesh_reversefaces_exec, - 0 + BMOP_UNTAN_MULTIRES }; /* @@ -167,7 +167,7 @@ BMOpDefine def_edgebisect = { {0} /*null-terminating sentinel*/, }, esplit_exec, - 0 + BMOP_UNTAN_MULTIRES }; /* @@ -221,7 +221,7 @@ BMOpDefine def_removedoubles = { {BMOP_OPSLOT_FLT, "dist"}, //minimum distance {0, /*null-terminating sentinel*/}}, bmesh_removedoubles_exec, - 0, + BMOP_UNTAN_MULTIRES, }; /* @@ -237,7 +237,7 @@ BMOpDefine def_automerge = { {BMOP_OPSLOT_FLT, "dist"}, //minimum distance {0, /*null-terminating sentinel*/}}, bmesh_automerge_exec, - 0, + BMOP_UNTAN_MULTIRES, }; /* @@ -250,7 +250,7 @@ BMOpDefine def_collapse = { {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, /*input edges*/ {0, /*null-terminating sentinel*/}}, bmesh_collapse_exec, - 0, + BMOP_UNTAN_MULTIRES, }; @@ -294,7 +294,7 @@ BMOpDefine def_pointmerge = { {BMOP_OPSLOT_VEC, "mergeco"}, {0, /*null-terminating sentinel*/}}, bmesh_pointmerge_exec, - 0, + BMOP_UNTAN_MULTIRES, }; /* @@ -322,7 +322,7 @@ BMOpDefine def_weldverts = { {{BMOP_OPSLOT_MAPPING, "targetmap"}, /*maps welded vertices to verts they should weld to.*/ {0, /*null-terminating sentinel*/}}, bmesh_weldverts_exec, - 0, + BMOP_UNTAN_MULTIRES, }; /* @@ -358,7 +358,7 @@ BMOpDefine def_join_triangles= { {BMOP_OPSLOT_FLT, "limit"}, {0, /*null-terminating sentinel*/}}, bmesh_jointriangles_exec, - 0, + BMOP_UNTAN_MULTIRES, }; /* @@ -378,7 +378,7 @@ BMOpDefine def_contextual_create= { {BMOP_OPSLOT_ELEMENT_BUF, "faceout"}, //newly-made face(s) {0, /*null-terminating sentinel*/}}, bmesh_contextual_create_exec, - 0, + BMOP_UNTAN_MULTIRES, }; BMOpDefine def_edgenet_fill= { @@ -532,7 +532,7 @@ BMOpDefine def_extrude_indivface = { {BMOP_OPSLOT_ELEMENT_BUF, "skirtout"}, //output skirt geometry, faces and edges {0} /*null-terminating sentinel*/}, bmesh_extrude_face_indiv_exec, - 0 + BMOP_UNTAN_MULTIRES }; /* @@ -547,7 +547,7 @@ BMOpDefine def_extrude_onlyedge = { {BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, //output geometry {0} /*null-terminating sentinel*/}, bmesh_extrude_onlyedge_exec, - 0 + BMOP_UNTAN_MULTIRES }; /* @@ -562,35 +562,16 @@ BMOpDefine def_extrudeverts_indiv = { {BMOP_OPSLOT_ELEMENT_BUF, "vertout"}, //output vertices {0} /*null-terminating sentinel*/}, extrude_vert_indiv_exec, - 0 + BMOP_UNTAN_MULTIRES }; -#if 0 -BMOpDefine def_makeprim = { - "makeprim", - {{BMOP_OPSLOT_INT, "type"}, - {BMOP_OPSLOT_INT, "tot", /*rows/cols also applies to spheres*/ - {BMOP_OPSLOT_INT, "seg", - {BMOP_OPSLOT_INT, "subdiv"}, - {BMOP_OPSLOT_INT, "ext"}, - {BMOP_OPSLOT_INT, "fill"}, - {BMOP_OPSLOT_FLT, "dia"}, - {BMOP_OPSLOT_FLT, "depth"}, - {BMOP_OPSLOT_PNT, "mat"}, - {BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, //won't be implemented right away - {0}} - makeprim_exec, - 0 -}; -#endif - BMOpDefine def_connectverts = { "connectverts", {{BMOP_OPSLOT_ELEMENT_BUF, "verts"}, {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"}, {0} /*null-terminating sentinel*/}, connectverts_exec, - 0 + BMOP_UNTAN_MULTIRES }; BMOpDefine def_extrudefaceregion = { @@ -600,7 +581,7 @@ BMOpDefine def_extrudefaceregion = { {BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, {0} /*null-terminating sentinel*/}, extrude_edge_context_exec, - 0 + BMOP_UNTAN_MULTIRES }; BMOpDefine def_dissolvevertsop = { @@ -608,7 +589,7 @@ BMOpDefine def_dissolvevertsop = { {{BMOP_OPSLOT_ELEMENT_BUF, "verts"}, {0} /*null-terminating sentinel*/}, dissolveverts_exec, - 0 + BMOP_UNTAN_MULTIRES }; BMOpDefine def_dissolveedgessop = { @@ -617,7 +598,7 @@ BMOpDefine def_dissolveedgessop = { {BMOP_OPSLOT_ELEMENT_BUF, "regionout"}, {0} /*null-terminating sentinel*/}, dissolveedges_exec, - 0 + BMOP_UNTAN_MULTIRES }; BMOpDefine def_dissolveedgeloopsop = { @@ -626,7 +607,7 @@ BMOpDefine def_dissolveedgeloopsop = { {BMOP_OPSLOT_ELEMENT_BUF, "regionout"}, {0} /*null-terminating sentinel*/}, dissolve_edgeloop_exec, - 0 + BMOP_UNTAN_MULTIRES }; BMOpDefine def_dissolvefacesop = { @@ -635,7 +616,7 @@ BMOpDefine def_dissolvefacesop = { {BMOP_OPSLOT_ELEMENT_BUF, "regionout"}, {0} /*null-terminating sentinel*/}, dissolvefaces_exec, - 0 + BMOP_UNTAN_MULTIRES }; @@ -647,7 +628,7 @@ BMOpDefine def_triangop = { {BMOP_OPSLOT_MAPPING, "facemap"}, {0} /*null-terminating sentinel*/}, triangulate_exec, - 0 + BMOP_UNTAN_MULTIRES }; BMOpDefine def_subdop = { @@ -673,7 +654,7 @@ BMOpDefine def_subdop = { {0} /*null-terminating sentinel*/, }, esubdivide_exec, - 0 + BMOP_UNTAN_MULTIRES }; BMOpDefine def_delop = { @@ -838,7 +819,7 @@ BMOpDefine def_edgesplit = { {BMOP_OPSLOT_ELEMENT_BUF, "edgeout2"}, /* new output disconnected edges */ {0} /*null-terminating sentinel*/}, bmesh_edgesplitop_exec, - 0 + BMOP_UNTAN_MULTIRES }; /* @@ -952,7 +933,7 @@ BMOpDefine def_bevel = { {BMOP_OPSLOT_FLT, "percent"}, /* percentage to expand bevelled edges*/ {0} /*null-terminating sentinel*/}, bmesh_bevel_exec, - 0 + BMOP_UNTAN_MULTIRES }; BMOpDefine *opdefines[] = { diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 4cf9e29fd9f..7b45a36d907 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -131,11 +131,11 @@ void BMO_Exec_Op(BMesh *bm, BMOperator *op) BMO_push(bm, op); if(bm->stackdepth == 2) - bmesh_begin_edit(bm); + bmesh_begin_edit(bm, opdefines[op->type]->flag); op->exec(bm, op); if(bm->stackdepth == 2) - bmesh_end_edit(bm,0); + bmesh_end_edit(bm, opdefines[op->type]->flag); BMO_pop(bm); } diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 8eea93e0223..acdbc6473f8 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -356,6 +356,7 @@ static void shrink_edgef(float *v1, float *v2, float fac) add_v3_v3v3(v2, v2, mid); } + /* * POLY ROTATE PLANE * diff --git a/source/blender/bmesh/intern/bmesh_private.h b/source/blender/bmesh/intern/bmesh_private.h index fa3172055d8..40ef7a72d29 100644 --- a/source/blender/bmesh/intern/bmesh_private.h +++ b/source/blender/bmesh/intern/bmesh_private.h @@ -57,7 +57,7 @@ int bmesh_radial_length(struct BMLoop *l); int bmesh_disk_count(BMVert *v); /*start/stop edit*/ -void bmesh_begin_edit(struct BMesh *bm); +void bmesh_begin_edit(struct BMesh *bm, int flag); void bmesh_end_edit(struct BMesh *bm, int flag); /*internal selection flushing*/ diff --git a/source/blender/bmesh/operators/bmesh_dupeops.c b/source/blender/bmesh/operators/bmesh_dupeops.c index 86ab8ed7cf4..8b0c76a5645 100644 --- a/source/blender/bmesh/operators/bmesh_dupeops.c +++ b/source/blender/bmesh/operators/bmesh_dupeops.c @@ -257,37 +257,6 @@ static void copy_mesh(BMOperator *op, BMesh *source, BMesh *target) MEM_freeN(edar); } -/* -BMesh *bmesh_make_mesh_from_mesh(BMesh *bm, int allocsize[4]) -{ - BMesh *target = NULL; - target = bmesh_make_mesh(allocsize); - - - CustomData_copy(&bm->vdata, &target->vdata, CD_MASK_BMESH, CD_CALLOC, 0); - CustomData_copy(&bm->edata, &target->edata, CD_MASK_BMESH, CD_CALLOC, 0); - CustomData_copy(&bm->ldata, &target->ldata, CD_MASK_BMESH, CD_CALLOC, 0); - CustomData_copy(&bm->pdata, &target->pdata, CD_MASK_BMESH, CD_CALLOC, 0); - - - CustomData_bmesh_init_pool(&target->vdata, allocsize[0]); - CustomData_bmesh_init_pool(&target->edata, allocsize[1]); - CustomData_bmesh_init_pool(&target->ldata, allocsize[2]); - CustomData_bmesh_init_pool(&target->pdata, allocsize[3]); - - bmesh_begin_edit(bm); - bmesh_begin_edit(target); - - bmesh_copy_mesh(bm, target, 0); - - bmesh_end_edit(bm); - bmesh_end_edit(target); - - return target; - -} -*/ - /* * Duplicate Operator * diff --git a/source/blender/editors/mesh/bmesh_tools.c b/source/blender/editors/mesh/bmesh_tools.c index 5b33a6b5d1c..5d868ade488 100644 --- a/source/blender/editors/mesh/bmesh_tools.c +++ b/source/blender/editors/mesh/bmesh_tools.c @@ -3741,7 +3741,7 @@ static int mesh_separate_selected(Main *bmain, Scene *scene, Base *editbase, wmO if (!em) return OPERATOR_CANCELLED; - bmnew = BM_Make_Mesh(allocsize); + bmnew = BM_Make_Mesh(obedit, allocsize); CustomData_copy(&bmnew->vdata, &em->bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0); CustomData_copy(&bmnew->edata, &em->bm->edata, CD_MASK_BMESH, CD_CALLOC, 0); CustomData_copy(&bmnew->ldata, &em->bm->ldata, CD_MASK_BMESH, CD_CALLOC, 0); diff --git a/source/blender/editors/mesh/bmeshutils.c b/source/blender/editors/mesh/bmeshutils.c index de5b468d93c..0a33a9ceada 100644 --- a/source/blender/editors/mesh/bmeshutils.c +++ b/source/blender/editors/mesh/bmeshutils.c @@ -563,6 +563,7 @@ static void *getEditMesh(bContext *C) typedef struct undomesh { Mesh me; int selectmode; + char obname[64]; } undomesh; /*undo simply makes copies of a bmesh*/ @@ -570,7 +571,9 @@ static void *editbtMesh_to_undoMesh(void *emv, void *obdata) { BMEditMesh *em = emv; Mesh *obme = obdata; + undomesh *me = MEM_callocN(sizeof(undomesh), "undo Mesh"); + strcpy(me->obname, em->bm->ob->id.name+2); /*make sure shape keys work*/ me->me.key = obme->key ? copy_key_nolib(obme->key) : NULL; @@ -588,19 +591,18 @@ static void *editbtMesh_to_undoMesh(void *emv, void *obdata) static void undoMesh_to_editbtMesh(void *umv, void *emv, void *obdata) { BMEditMesh *em = emv, *em2; - Object ob = {0,}; + Object *ob; undomesh *me = umv; BMesh *bm; int allocsize[4] = {512, 512, 2048, 512}; - - ob.data = me; - ob.type = OB_MESH; - ob.shapenr = em->bm->shapenr; + + ob = find_id("OB", me->obname); + ob->shapenr = em->bm->shapenr; BMEdit_Free(em); - bm = BM_Make_Mesh(allocsize); - BMO_CallOpf(bm, "mesh_to_bmesh mesh=%p object=%p", me, &ob); + bm = BM_Make_Mesh(ob, allocsize); + BMO_CallOpf(bm, "mesh_to_bmesh mesh=%p object=%p", me, ob); em2 = BMEdit_Create(bm); *em = *em2; diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c index 08d22f12448..097438cf5a2 100644 --- a/source/blender/modifiers/intern/MOD_armature.c +++ b/source/blender/modifiers/intern/MOD_armature.c @@ -143,7 +143,7 @@ static void deformVertsEM( ArmatureModifierData *amd = (ArmatureModifierData*) md; DerivedMesh *dm = derivedData; - if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data); + if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data, 0); armature_deform_verts(amd->object, ob, dm, vertexCos, NULL, numVerts, amd->deformflag, NULL, amd->defgrp_name); @@ -159,7 +159,7 @@ static void deformMatricesEM( ArmatureModifierData *amd = (ArmatureModifierData*) md; DerivedMesh *dm = derivedData; - if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data); + if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data, 0); armature_deform_verts(amd->object, ob, dm, vertexCos, defMats, numVerts, amd->deformflag, NULL, amd->defgrp_name); diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 8ed1bcc1b45..51fbfc54840 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -312,7 +312,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, int initFlags) { DerivedMesh *cddm = dm; //copying shouldn't be necassary here, as all modifiers return CDDM's - BMEditMesh *em = CDDM_To_BMesh(cddm, NULL); + BMEditMesh *em = CDDM_To_BMesh(ob, cddm, NULL); BMOperator op, oldop, weldop; int i, j, indexLen; /* offset matrix */ @@ -505,7 +505,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, BMO_Finish_Op(em->bm, &weldop); BMEdit_RecalcTesselation(em); - cddm = CDDM_from_BMEditMesh(em, NULL); + cddm = CDDM_from_BMEditMesh(em, NULL, 0); BMEdit_Free(em); MEM_freeN(indexMap); diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c index 3a707818d3d..8b8273aab62 100644 --- a/source/blender/modifiers/intern/MOD_curve.c +++ b/source/blender/modifiers/intern/MOD_curve.c @@ -130,7 +130,7 @@ static void deformVertsEM( { DerivedMesh *dm = derivedData; - if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data); + if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data, 0); deformVerts(md, ob, dm, vertexCos, numVerts, 0, 0); diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index 3f74d97c332..dae1ac0cac6 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -272,7 +272,7 @@ static void deformVertsEM( { DerivedMesh *dm = derivedData; - if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data); + if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data, 0); deformVerts(md, ob, dm, vertexCos, numVerts, 0, 0); diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c index 9057dfe592b..8d57846f335 100644 --- a/source/blender/modifiers/intern/MOD_lattice.c +++ b/source/blender/modifiers/intern/MOD_lattice.c @@ -125,7 +125,7 @@ static void deformVertsEM( { DerivedMesh *dm = derivedData; - if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data); + if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data, 0); deformVerts(md, ob, dm, vertexCos, numVerts, 0, 0); diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index b3baf15ae29..323531702fa 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -132,7 +132,7 @@ DerivedMesh *get_dm(Object *ob, struct EditMesh *em, DerivedMesh *dm, float (*ve return dm; if(ob->type==OB_MESH) { - if(em) dm= CDDM_from_BMEditMesh(em, ob->data); + if(em) dm= CDDM_from_BMEditMesh(em, ob->data, 0); else dm = CDDM_from_mesh((struct Mesh *)(ob->data), ob); if(vertexCos) { -- cgit v1.2.3