Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_cdderivedmesh.h4
-rw-r--r--source/blender/blenkernel/BKE_multires.h8
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c4
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c12
-rw-r--r--source/blender/blenkernel/intern/constraint.c2
-rw-r--r--source/blender/blenkernel/intern/editderivedbmesh.c4
-rw-r--r--source/blender/blenkernel/intern/mesh.c2
-rw-r--r--source/blender/blenkernel/intern/modifier.c3
-rw-r--r--source/blender/blenkernel/intern/modifiers_bmesh.c4
-rw-r--r--source/blender/blenkernel/intern/multires.c184
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c3
11 files changed, 191 insertions, 39 deletions
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; 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,