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:
authorNicholas Bishop <nicholasbishop@gmail.com>2008-06-21 22:20:32 +0400
committerNicholas Bishop <nicholasbishop@gmail.com>2008-06-21 22:20:32 +0400
commita076ff140863cbca99bad900a9795ba566db3aa8 (patch)
tree700589c6e4909f671b151334ba2d681a9104736a /source/blender/blenkernel/intern
parent5de9776575d15e9f2cb13ec174d9a560c52b63e2 (diff)
Displacements over subdivided edges work correctly now (both for display and updating the highest level.)
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c36
-rw-r--r--source/blender/blenkernel/intern/multires.c117
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c20
3 files changed, 156 insertions, 17 deletions
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 73af2c61cf8..281cfabdb2e 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -42,6 +42,7 @@
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
+#include "BKE_multires.h"
#include "BKE_utildefines.h"
#include "BLI_arithb.h"
@@ -1148,9 +1149,15 @@ typedef struct MultiresDM {
int lvl, totlvl;
float (*orco)[3];
float (*subco)[3];
+ MEdge *ored;
MFace *orfa;
+ int totorco;
+ int totored;
int totorfa;
+ ListBase *vert_face_map;
+ IndexNode *vert_face_map_mem;
+
void (*update)(DerivedMesh*);
} MultiresDM;
@@ -1163,9 +1170,14 @@ static void MultiresDM_release(DerivedMesh *dm)
mrdm->update(dm);
if(DM_release(dm)) {
+ MEM_freeN(mrdm->ored);
MEM_freeN(mrdm->orfa);
MEM_freeN(mrdm->subco);
MEM_freeN(mrdm->orco);
+ if(mrdm->vert_face_map)
+ MEM_freeN(mrdm->vert_face_map);
+ if(mrdm->vert_face_map_mem)
+ MEM_freeN(mrdm->vert_face_map_mem);
MEM_freeN(mrdm);
}
}
@@ -1197,8 +1209,11 @@ DerivedMesh *MultiresDM_new(DerivedMesh *orig, int numVerts, int numEdges, int n
mrdm->orco = MEM_callocN(sizeof(float) * 3 * orig->getNumVerts(orig), "multires orco");
for(i = 0; i < orig->getNumVerts(orig); ++i)
VecCopyf(mrdm->orco[i], mvert[i].co);
+ mrdm->totorco = orig->getNumVerts(orig);
mrdm->orfa = MEM_dupallocN(CustomData_get_layer(&orig->faceData, CD_MFACE));
mrdm->totorfa = orig->getNumFaces(orig);
+ mrdm->ored = MEM_dupallocN(CustomData_get_layer(&orig->edgeData, CD_MEDGE));
+ mrdm->totored = orig->getNumEdges(orig);
}
else
DM_init(dm, numVerts, numEdges, numFaces);
@@ -1241,6 +1256,16 @@ int MultiresDM_get_totorfa(struct DerivedMesh *dm)
return ((MultiresDM*)dm)->totorfa;
}
+MEdge *MultiresDM_get_ored(DerivedMesh *dm)
+{
+ return ((MultiresDM*)dm)->ored;
+}
+
+int MultiresDM_get_totored(struct DerivedMesh *dm)
+{
+ return ((MultiresDM*)dm)->totored;
+}
+
int MultiresDM_get_totlvl(DerivedMesh *dm)
{
return ((MultiresDM*)dm)->totlvl;
@@ -1260,3 +1285,14 @@ void MultiresDM_set_update(DerivedMesh *dm, void (*update)(DerivedMesh*))
{
((MultiresDM*)dm)->update = update;
}
+
+ListBase *MultiresDM_get_vert_face_map(DerivedMesh *dm)
+{
+ MultiresDM *mrdm = (MultiresDM*)dm;
+
+ if(!mrdm->vert_face_map)
+ create_vert_face_map(&mrdm->vert_face_map, &mrdm->vert_face_map_mem, mrdm->orfa,
+ mrdm->totorco, mrdm->totorfa);
+
+ return mrdm->vert_face_map;
+}
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index c41e1cce463..7bf9366a2d1 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -1309,6 +1309,24 @@ void multires_edge_level_update(Object *ob, Mesh *me)
}
}
+void create_vert_face_map(ListBase **map, IndexNode **mem, const MFace *mface, const int totvert, const int totface)
+{
+ int i,j;
+ IndexNode *node = NULL;
+
+ (*map) = MEM_callocN(sizeof(ListBase) * totvert, "vert face map");
+ (*mem) = MEM_callocN(sizeof(IndexNode) * totface*4, "vert face map mem");
+ node = *mem;
+
+ /* Find the users */
+ for(i = 0; i < totface; ++i){
+ for(j = 0; j < (mface[i].v4?4:3); ++j, ++node) {
+ node->index = i;
+ BLI_addtail(&(*map)[((unsigned int*)(&mface[i]))[j]], node);
+ }
+ }
+}
+
/* MULTIRES MODIFIER */
static const int multires_max_levels = 13;
static const int multires_quad_tot[] = {4, 9, 25, 81, 289, 1089, 4225, 16641, 66049, 263169, 1050625, 4198401, 16785409};
@@ -1414,29 +1432,31 @@ void multiresModifier_setLevel(void *mmd_v, void *ob_v)
}
void multires_displacer_init(MultiresDisplacer *d, DerivedMesh *dm,
- const int face_index, const int sides, const int invert)
+ const int face_index, const int invert)
{
- MFace *face;
float inv[3][3];
- face = MultiresDM_get_orfa(dm) + face_index;
+ d->face = MultiresDM_get_orfa(dm) + face_index;
/* Get the multires grid from customdata and calculate the TS matrix */
d->grid = (MDisps*)dm->getFaceDataArray(dm, CD_MDISPS);
if(d->grid)
d->grid += face_index;
- d->subco = MultiresDM_get_subco(dm);
- calc_face_ts_mat_dm(d->mat, MultiresDM_get_orco(dm), face);
+ calc_face_ts_mat_dm(d->mat, MultiresDM_get_orco(dm), d->face);
if(invert) {
Mat3Inv(inv, d->mat);
Mat3CpyMat3(d->mat, inv);
}
- d->sides = sides;
d->spacing = pow(2, MultiresDM_get_totlvl(dm) - MultiresDM_get_lvl(dm));
d->sidetot = multires_side_tot[MultiresDM_get_totlvl(dm) - 1];
d->invert = invert;
}
+void multires_displacer_weight(MultiresDisplacer *d, const float w)
+{
+ d->weight = w;
+}
+
void multires_displacer_anchor(MultiresDisplacer *d, const int type, const int side_index)
{
d->sidendx = side_index;
@@ -1476,6 +1496,46 @@ void multires_displacer_anchor(MultiresDisplacer *d, const int type, const int s
d->ay = d->y;
}
+void multires_displacer_anchor_edge(MultiresDisplacer *d, int v1, int v2, int x)
+{
+ const int mov = d->spacing * x;
+
+ d->type = 4;
+
+ if(v1 == d->face->v1) {
+ d->x = 0;
+ d->y = 0;
+ if(v2 == d->face->v2)
+ d->x += mov;
+ else
+ d->y += mov;
+ }
+ else if(v1 == d->face->v2) {
+ d->x = d->sidetot - 1;
+ d->y = 0;
+ if(v2 == d->face->v1)
+ d->x -= mov;
+ else
+ d->y += mov;
+ }
+ else if(v1 == d->face->v3) {
+ d->x = d->sidetot - 1;
+ d->y = d->sidetot - 1;
+ if(v2 == d->face->v2)
+ d->y -= mov;
+ else
+ d->x -= mov;
+ }
+ else if(v1 == d->face->v4) {
+ d->x = 0;
+ d->y = d->sidetot - 1;
+ if(v2 == d->face->v3)
+ d->x += mov;
+ else
+ d->y -= mov;
+ }
+}
+
void multires_displacer_jump(MultiresDisplacer *d)
{
if(d->sidendx == 0) {
@@ -1505,10 +1565,8 @@ void multires_displace(MultiresDisplacer *d, float co[3])
data = d->grid->disps[d->y * d->sidetot + d->x];
- if(d->invert) {
+ if(d->invert)
VecSubf(disp, co, *d->subco);
- ++d->subco;
- }
else
VecCopyf(disp, data);
@@ -1518,8 +1576,11 @@ void multires_displace(MultiresDisplacer *d, float co[3])
VecCopyf(data, disp);
}
- else
+ else {
+ if(d->type == 4)
+ VecMulf(disp, d->weight);
VecAddf(co, co, disp);
+ }
if(d->type == 2) {
if(d->sidendx == 0)
@@ -1547,6 +1608,7 @@ static void multiresModifier_update(DerivedMesh *dm)
{
MDisps *mdisps;
MVert *mvert;
+ MEdge *medge;
MFace *mface;
int i;
@@ -1557,29 +1619,34 @@ static void multiresModifier_update(DerivedMesh *dm)
if(mdisps) {
MultiresDisplacer d;
- float (*subco)[3] = MultiresDM_get_subco(dm);
+ const int gridFaces = multires_side_tot[MultiresDM_get_totlvl(dm) - 2] - 1;
+ const int edgeSize = multires_side_tot[MultiresDM_get_totlvl(dm) - 1] - 1;
+ ListBase *map = MultiresDM_get_vert_face_map(dm);
+ int S, x, y;
mvert = CDDM_get_verts(dm);
+ medge = MultiresDM_get_ored(dm);
mface = MultiresDM_get_orfa(dm);
+ d.subco = MultiresDM_get_subco(dm);
+
/* For now just handle top-level sculpts */
for(i = 0; i < MultiresDM_get_totorfa(dm); ++i) {
- int gridFaces = multires_side_tot[MultiresDM_get_totlvl(dm) - 2] - 1;
const int numVerts = mface[i].v4 ? 4 : 3;
- int S, x, y;
// convert from mvert->co to disps
- multires_displacer_init(&d, dm, i, numVerts, 1);
- d.subco = subco;
+ multires_displacer_init(&d, dm, i, 1);
multires_displacer_anchor(&d, 1, 0);
multires_displace(&d, mvert->co);
++mvert;
+ ++d.subco;
for(S = 0; S < numVerts; ++S) {
multires_displacer_anchor(&d, 2, S);
for(x = 1; x < gridFaces; ++x) {
multires_displace(&d, mvert->co);
++mvert;
+ ++d.subco;
}
}
@@ -1589,12 +1656,30 @@ static void multiresModifier_update(DerivedMesh *dm)
for(x = 1; x < gridFaces; x++) {
multires_displace(&d, mvert->co);
++mvert;
+ ++d.subco;
}
multires_displacer_jump(&d);
}
}
+ }
- subco = d.subco;
+ for(i = 0; i < MultiresDM_get_totored(dm); ++i) {
+ const MEdge *e = &medge[i];
+ for(x = 1; x < edgeSize; ++x) {
+ IndexNode *n1, *n2;
+ /* TODO: Better to have these loops outside the x loop */
+ for(n1 = map[e->v1].first; n1; n1 = n1->next) {
+ for(n2 = map[e->v2].first; n2; n2 = n2->next) {
+ if(n1->index == n2->index) {
+ multires_displacer_init(&d, dm, n1->index, 1);
+ multires_displacer_anchor_edge(&d, e->v1, e->v2, x);
+ multires_displace(&d, mvert->co);
+ }
+ }
+ }
+ ++mvert;
+ ++d.subco;
+ }
}
}
}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 1b3ce1db57d..a53c6637b3a 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -567,7 +567,7 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
if(mmd) {
VecCopyf(mr_orig, mvert->co);
mr_orig += 3;
- multires_displacer_init(&d, result, index, numVerts, 0);
+ multires_displacer_init(&d, result, index, 0);
multires_displacer_anchor(&d, 1, 0);
multires_displace(&d, mvert->co);
}
@@ -656,6 +656,24 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
w[0] = 1 - w[1];
DM_interp_vert_data(dm, result, vertIdx, w, 2, i);
VecCopyf(mvert->co, ccgSubSurf_getEdgeData(ss, e, x));
+ if(mmd) {
+ int numFaces = ccgSubSurf_getEdgeNumFaces(ss, e);
+ int edgeface;
+
+ VecCopyf(mr_orig, mvert->co);
+ mr_orig += 3;
+
+ multires_displacer_weight(&d, 1.0f / numFaces);
+ /* Could be made more efficient by moving this outside the x loop */
+ for(edgeface = 0; edgeface < numFaces; ++edgeface) {
+ CCGFace *f = ccgSubSurf_getEdgeFace(ss, e, edgeface);
+ int faceIdx = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
+ multires_displacer_init(&d, result, faceIdx, 0);
+ multires_displacer_anchor_edge(&d, vertIdx[0], vertIdx[1], x);
+ multires_displace(&d, mvert->co);
+ }
+
+ }
*origIndex = ORIGINDEX_NONE;
++mvert;
++origIndex;