[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16134] branches/soc-2008-nicholasbishop/ source/blender/blenkernel/intern: Initial implementations of the interp and swap customdata functions for MDisps .

Nicholas Bishop nicholasbishop at gmail.com
Sat Aug 16 21:57:16 CEST 2008


Revision: 16134
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16134
Author:   nicholasbishop
Date:     2008-08-16 21:57:16 +0200 (Sat, 16 Aug 2008)

Log Message:
-----------
Initial implementations of the interp and swap customdata functions for MDisps.

Modified Paths:
--------------
    branches/soc-2008-nicholasbishop/source/blender/blenkernel/intern/cdderivedmesh.c
    branches/soc-2008-nicholasbishop/source/blender/blenkernel/intern/customdata.c
    branches/soc-2008-nicholasbishop/source/blender/blenkernel/intern/multires.c

Modified: branches/soc-2008-nicholasbishop/source/blender/blenkernel/intern/cdderivedmesh.c
===================================================================
--- branches/soc-2008-nicholasbishop/source/blender/blenkernel/intern/cdderivedmesh.c	2008-08-16 16:29:12 UTC (rev 16133)
+++ branches/soc-2008-nicholasbishop/source/blender/blenkernel/intern/cdderivedmesh.c	2008-08-16 19:57:16 UTC (rev 16134)
@@ -752,6 +752,7 @@
 {
 	CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
 	DerivedMesh *dm = &cddm->dm;
+	CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
 	int i, *index, alloctype;
 
 	/* this does a referenced copy, the only new layers being ORIGINDEX,
@@ -770,11 +771,11 @@
 	else
 		alloctype= CD_REFERENCE;
 
-	CustomData_merge(&mesh->vdata, &dm->vertData, CD_MASK_MESH, alloctype,
+	CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
 	                 mesh->totvert);
-	CustomData_merge(&mesh->edata, &dm->edgeData, CD_MASK_MESH, alloctype,
+	CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
 	                 mesh->totedge);
-	CustomData_merge(&mesh->fdata, &dm->faceData, CD_MASK_MESH, alloctype,
+	CustomData_merge(&mesh->fdata, &dm->faceData, mask, alloctype,
 	                 mesh->totface);
 
 	cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);

Modified: branches/soc-2008-nicholasbishop/source/blender/blenkernel/intern/customdata.c
===================================================================
--- branches/soc-2008-nicholasbishop/source/blender/blenkernel/intern/customdata.c	2008-08-16 16:29:12 UTC (rev 16133)
+++ branches/soc-2008-nicholasbishop/source/blender/blenkernel/intern/customdata.c	2008-08-16 19:57:16 UTC (rev 16134)
@@ -34,6 +34,7 @@
 
 #include "BKE_customdata.h"
 
+#include "BLI_arithb.h"
 #include "BLI_blenlib.h"
 #include "BLI_linklist.h"
 #include "BLI_mempool.h"
@@ -44,6 +45,7 @@
 
 #include "MEM_guardedalloc.h"
 
+#include <math.h>
 #include <string.h>
 
 /* number of layers to add when growing a CustomData object */
@@ -379,8 +381,125 @@
 		osf[i] = default_osf;
 }
 
-void layerCopy_mdisps(const void *source, void *dest, int count)
+/* Adapted from sculptmode.c */
+static void mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, float v)
 {
+	int x, y, x2, y2;
+	const int st_max = st - 1;
+	float urat, vrat, uopp;
+	float d[4][3], d2[2][3];
+
+	if(u < 0)
+		u = 0;
+	else if(u >= st)
+		u = st_max;
+	if(v < 0)
+		v = 0;
+	else if(v >= st)
+		v = st_max;
+
+	x = floor(u);
+	y = floor(v);
+	x2 = x + 1;
+	y2 = y + 1;
+
+	if(x2 >= st) x2 = st_max;
+	if(y2 >= st) y2 = st_max;
+	
+	urat = u - x;
+	vrat = v - y;
+	uopp = 1 - urat;
+
+	VecCopyf(d[0], disps[y * st + x]);
+	VecCopyf(d[1], disps[y * st + x2]);
+	VecCopyf(d[2], disps[y2 * st + x]);
+	VecCopyf(d[3], disps[y2 * st + x2]);
+	VecMulf(d[0], uopp);
+	VecMulf(d[1], urat);
+	VecMulf(d[2], uopp);
+	VecMulf(d[3], urat);
+
+	VecAddf(d2[0], d[0], d[1]);
+	VecAddf(d2[1], d[2], d[3]);
+	VecMulf(d2[0], 1 - vrat);
+	VecMulf(d2[1], vrat);
+
+	VecAddf(out, d2[0], d2[1]);
+}
+
+static void layerSwap_mdisps(void *data, int *ci)
+{
+	MDisps *s = data;
+	float (*d)[3] = NULL;
+	int x, y, st;
+
+	if(!(ci[0] == 2 && ci[1] == 3 && ci[2] == 0 && ci[3] == 1)) return;
+
+	d = MEM_callocN(sizeof(float) * 3 * s->totdisp, "mdisps swap");
+	st = sqrt(s->totdisp);
+
+	for(y = 0; y < st; ++y) {
+		for(x = 0; x < st; ++x) {
+			VecCopyf(d[(st - y - 1) * st + (st - x - 1)], s->disps[y * st + x]);
+		}
+	}
+	
+	if(s->disps)
+		MEM_freeN(s->disps);
+	s->disps = d;
+}
+
+static void layerInterp_mdisps(void **sources, float *weights, float *sub_weights,
+			       int count, void *dest)
+{
+	MDisps *d = dest;
+	MDisps *s = NULL;
+	int st, stl;
+	int i, x, y;
+	float crn[4][2];
+	float (*sw)[4] = NULL;
+
+	/* Initialize the destination */
+	for(i = 0; i < d->totdisp; ++i) {
+		float z[3] = {0,0,0};
+		VecCopyf(d->disps[i], z);
+	}
+
+	/* For now, some restrictions on the input */
+	if(count != 1 || !sub_weights) return;
+
+	st = sqrt(d->totdisp);
+	stl = st - 1;
+
+	sw = (void*)sub_weights;
+	for(i = 0; i < 4; ++i) {
+		crn[i][0] = 0 * sw[i][0] + stl * sw[i][1] + stl * sw[i][2] + 0 * sw[i][3];
+		crn[i][1] = 0 * sw[i][0] + 0 * sw[i][1] + stl * sw[i][2] + stl * sw[i][3];
+	}
+
+	s = sources[0];
+	for(y = 0; y < st; ++y) {
+		for(x = 0; x < st; ++x) {
+			/* One suspects this code could be cleaner. */
+			float xl = (float)x / (st - 1);
+			float yl = (float)y / (st - 1);
+			float mid1[2] = {crn[0][0] * (1 - xl) + crn[1][0] * xl,
+					 crn[0][1] * (1 - xl) + crn[1][1] * xl};
+			float mid2[2] = {crn[3][0] * (1 - xl) + crn[2][0] * xl,
+					 crn[3][1] * (1 - xl) + crn[2][1] * xl};
+			float mid3[2] = {mid1[0] * (1 - yl) + mid2[0] * yl,
+					 mid1[1] * (1 - yl) + mid2[1] * yl};
+
+			float srcdisp[3];
+
+			mdisps_bilinear(srcdisp, s->disps, st, mid3[0], mid3[1]);
+			VecCopyf(d->disps[y * st + x], srcdisp);
+		}
+	}
+}
+
+static void layerCopy_mdisps(const void *source, void *dest, int count)
+{
 	int i;
 	const MDisps *s = source;
 	MDisps *d = dest;
@@ -398,7 +517,7 @@
 	}
 }
 
-void layerFree_mdisps(void *data, int count, int size)
+static void layerFree_mdisps(void *data, int count, int size)
 {
 	int i;
 	MDisps *d = data;
@@ -588,7 +707,7 @@
 	{sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol},
 	{sizeof(float)*3*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
 	{sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps,
-	 layerFree_mdisps, NULL, NULL, NULL}
+	 layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL}
 };
 
 const char *LAYERTYPENAMES[CD_NUMTYPES] = {

Modified: branches/soc-2008-nicholasbishop/source/blender/blenkernel/intern/multires.c
===================================================================
--- branches/soc-2008-nicholasbishop/source/blender/blenkernel/intern/multires.c	2008-08-16 16:29:12 UTC (rev 16133)
+++ branches/soc-2008-nicholasbishop/source/blender/blenkernel/intern/multires.c	2008-08-16 19:57:16 UTC (rev 16134)
@@ -876,11 +876,12 @@
 void multires_displacer_init(MultiresDisplacer *d, DerivedMesh *dm,
 			     const int face_index, const int invert)
 {
+	Mesh *me = MultiresDM_get_mesh(dm);
 	float inv[3][3];
 
-	d->face = MultiresDM_get_mesh(dm)->mface + face_index;
+	d->face = me->mface + face_index;
 	/* Get the multires grid from customdata and calculate the TS matrix */
-	d->grid = (MDisps*)dm->getFaceDataArray(dm, CD_MDISPS);
+	d->grid = CustomData_get_layer(&me->fdata, CD_MDISPS);
 	if(d->grid)
 		d->grid += face_index;
 	calc_face_ts_mat_dm(d->mat, MultiresDM_get_orco(dm), d->face);
@@ -1110,13 +1111,14 @@
 	MEdge *medge = MultiresDM_get_mesh(dm)->medge;
 	MFace *mface = MultiresDM_get_mesh(dm)->mface;
 	ListBase *map = MultiresDM_get_vert_face_map(dm);
+	Mesh *me = MultiresDM_get_mesh(dm);
 	MultiresDisplacer d;
 	int i, S, x, y;
 
 	if(subco)
 		d.subco = subco;
 
-	for(i = 0; i < MultiresDM_get_mesh(dm)->totface; ++i) {
+	for(i = 0; i < me->totface; ++i) {
 		const int numVerts = mface[i].v4 ? 4 : 3;
 			
 		multires_displacer_init(&d, dm, i, invert);
@@ -1147,7 +1149,7 @@
 		}
 	}
 
-	for(i = 0; i < MultiresDM_get_mesh(dm)->totedge; ++i) {
+	for(i = 0; i < me->totedge; ++i) {
 		const MEdge *e = &medge[i];
 		for(x = 1; x < edgeSize; ++x) {
 			IndexNode *n1, *n2;
@@ -1174,7 +1176,7 @@
 		}
 	}
 		
-	for(i = 0; i < MultiresDM_get_mesh(dm)->totvert; ++i) {
+	for(i = 0; i < me->totvert; ++i) {
 		IndexNode *n;
 		multires_displacer_weight(&d, 1.0f / BLI_countlist(&map[i]));
 		for(n = map[i].first; n; n = n->next) {
@@ -1192,6 +1194,7 @@
 
 static void multiresModifier_update(DerivedMesh *dm)
 {
+	Mesh *me;
 	MDisps *mdisps;
 	MVert *mvert;
 	MEdge *medge;
@@ -1200,13 +1203,13 @@
 
 	if(!(G.f & G_SCULPTMODE) && !(*MultiresDM_get_flags(dm) & MULTIRES_DM_UPDATE_ALWAYS)) return;
 
-	mdisps = dm->getFaceDataArray(dm, CD_MDISPS);
+	me = MultiresDM_get_mesh(dm);
+	mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
 
 	if(mdisps) {
 		SubsurfModifierData smd;
 		const int lvl = MultiresDM_get_lvl(dm);
 		const int totlvl = MultiresDM_get_totlvl(dm);
-		Mesh *me = MultiresDM_get_mesh(dm);
 		DerivedMesh *orig, *subco_dm;
 		
 		mvert = CDDM_get_verts(dm);





More information about the Bf-blender-cvs mailing list