[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [48143] branches/soc-2012-sushi/source/ blender/modifiers/intern/MOD_laplaciansmooth.c: Optimization code and apply coding style.

Alexander Pinzon apinzonf at gmail.com
Wed Jun 20 23:49:46 CEST 2012


Revision: 48143
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=48143
Author:   apinzonf
Date:     2012-06-20 21:49:41 +0000 (Wed, 20 Jun 2012)
Log Message:
-----------
Optimization code and apply coding style.

Modified Paths:
--------------
    branches/soc-2012-sushi/source/blender/modifiers/intern/MOD_laplaciansmooth.c

Modified: branches/soc-2012-sushi/source/blender/modifiers/intern/MOD_laplaciansmooth.c
===================================================================
--- branches/soc-2012-sushi/source/blender/modifiers/intern/MOD_laplaciansmooth.c	2012-06-20 21:12:38 UTC (rev 48142)
+++ branches/soc-2012-sushi/source/blender/modifiers/intern/MOD_laplaciansmooth.c	2012-06-20 21:49:41 UTC (rev 48143)
@@ -69,8 +69,15 @@
 	short *numNeFa;			/* Number of neighboors faces around vertice*/
 	short *numNeEd;			/* Number of neighboors Edges around vertice*/
 	short *zerola;			/* Is zero area or length*/
-	
+
+	/* Pointers to data*/
+	float (*vertexCos)[3];
+	MFace *mfaces;	
+	MEdge *medges;
 	NLContext *context;
+
+	/*Data*/
+	float min_area;
 };
 typedef struct BModLaplacianSystem ModLaplacianSystem;
 
@@ -80,13 +87,13 @@
 static void copyData(ModifierData *md, ModifierData *target);
 static void delete_ModLaplacianSystem(ModLaplacianSystem * sys);
 static void delete_void_MLS(void * data);
+static void fill_laplacian_matrix(ModLaplacianSystem * sys);
 static void initData(ModifierData *md);
+static void init_laplacian(ModLaplacianSystem * sys);
 static void memset_ModLaplacianSystem(ModLaplacianSystem *sys, int val);
 static void volume_preservation(float (*vertexCos)[3], int numVerts, float vini, float vend, short flag);
 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md);
 static ModLaplacianSystem * init_ModLaplacianSystem( int a_numEdges, int a_numFaces, int a_numVerts);
-static void compute_weight_quad(ModLaplacianSystem * sys, MFace *mfaces, int index_face, float (*vertexCos)[3]);
-static void set_laplacian_matrix_quad(ModLaplacianSystem * sys, MFace *mfaces, int index_face, float (*vertexCos)[3]);
 
 static void delete_void_MLS(void * data)
 {
@@ -109,6 +116,9 @@
 	if (sys->context) {
 		nlDeleteContext(sys->context);
 	}
+	sys->vertexCos = NULL;
+	sys->mfaces = NULL;	
+	sys->medges = NULL;
 	MEM_freeN(sys);
 }
 
@@ -124,7 +134,8 @@
 	memset(sys->zerola		, val, sizeof(short) * sys->numVerts);
 }
 
-static ModLaplacianSystem * init_ModLaplacianSystem( int a_numEdges, int a_numFaces, int a_numVerts) {
+static ModLaplacianSystem * init_ModLaplacianSystem( int a_numEdges, int a_numFaces, int a_numVerts) 
+{
 	ModLaplacianSystem * sys; 
 	sys = MEM_callocN(sizeof(ModLaplacianSystem), "ModLaplSmoothSystem");
 	sys->numEdges = a_numEdges;
@@ -249,11 +260,10 @@
 static float compute_volume(float (*vertexCos)[3], MFace *mfaces, int numFaces)
 {
 	float vol = 0.0f;
-	float x1, y1, z1, x2, y2, z2, x3, y3, z3;
+	float x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4;
 	int i;
-	float *vn;
-	float *vf[3];
-	for (i = 0; i<numFaces; i++){
+	float *vf[4];
+	for (i = 0; i<numFaces; i++) {
 		vf[0] = vertexCos[mfaces[i].v1];
 		vf[1] = vertexCos[mfaces[i].v2];
 		vf[2] = vertexCos[mfaces[i].v3];
@@ -269,8 +279,16 @@
 		x3 = vf[2][0];
 		y3 = vf[2][1];
 		z3 = vf[2][2];
+		
 
-		vol = vol + (1.0 / 6.0) * (0.0 - x3*y2*z1 + x2*y3*z1 + x3*y1*z2 - x1*y3*z2 - x2*y1*z3 + x1*y2*z3);
+		vol +=  (1.0 / 6.0) * (x2*y3*z1 + x3*y1*z2 - x1*y3*z2 - x2*y1*z3 + x1*y2*z3 - x3*y2*z1);
+		if ((&mfaces[i])->v4) {
+			vf[3] = vertexCos[mfaces[i].v4];
+			x4 = vf[3][0];
+			y4 = vf[3][1];
+			z4 = vf[3][2];
+			vol += (1.0 / 6.0) * (x1*y3*z4 - x1*y4*z3 - x3*y1*z4 + x3*z1*y4 + y1*x4*z3 - x4*y3*z1);
+		}
 	}
 	return fabs(vol);
 }
@@ -282,92 +300,207 @@
 
 	if (vend != 0.0f) {	
 		beta  = pow (vini / vend, 1.0f / 3.0f);
-		for (i = 0; i<numVerts; i++) {
+		for (i = 0; i < numVerts; i++) {
 			if (flag & MOD_LAPLACIANSMOOTH_X) {
-				vertexCos[i][0] = vertexCos[i][0] * beta;
+				vertexCos[i][0] *= beta;
 			}
 			if (flag & MOD_LAPLACIANSMOOTH_Y) {
-				vertexCos[i][1] = vertexCos[i][1] * beta;
+				vertexCos[i][1] *= beta;
 			}
 			if (flag & MOD_LAPLACIANSMOOTH_Z) {
-				vertexCos[i][2] = vertexCos[i][2] * beta;
+				vertexCos[i][2] *= beta;
 			}
 			
 		}
 	}
 }
 
-static void compute_weight_quad(ModLaplacianSystem * sys, MFace *mfaces, int index_face, float (*vertexCos)[3])
+static void init_laplacian(ModLaplacianSystem * sys)
 {
+	float *v1, *v2, *v3, *v4;
+	float w1, w2, w3, w4;
+	float areaf;
+	int i, j;
 	unsigned int idv1, idv2, idv3, idv4, idv[4];
-	int i;
-	float *v1, *v2, *v3, *v4;
-	float w2, w3, w4;
+	int has_4_vert ;
+	for ( i = 0; i < sys->numEdges; i++) {
+		idv1 = sys->medges[i].v1;
+		idv2 = sys->medges[i].v2;
 
-	idv[0] = mfaces[index_face].v1;
-	idv[1] = mfaces[index_face].v2;
-	idv[2] = mfaces[index_face].v3;
-	idv[3] = mfaces[index_face].v4;
+		v1 = sys->vertexCos[idv1];
+		v2 = sys->vertexCos[idv2];
 
+		sys->numNeEd[idv1] = sys->numNeEd[idv1] + 1;
+		sys->numNeEd[idv2] = sys->numNeEd[idv2] + 1;
+		w1 = len_v3v3(v1, v2);
+		if (fabs(w1) < sys->min_area) {
+			sys->zerola[idv1] = 1;
+			sys->zerola[idv2] = 1;
+		} else {
+			w1 = 1.0f / w1;
+		}
+		
+		sys->eweights[i] = w1;
+	}
+	for ( i = 0; i < sys->numFaces; i++) {
+		has_4_vert = ((&sys->mfaces[i])->v4) ? 1 : 0;
 
-	for (i = 0; i < 4; i++) {
-		idv1 = idv[i];
-		idv2 = idv[(i + 1) % 4];
-		idv3 = idv[(i + 2) % 4];
-		idv4 = idv[(i + 3) % 4];
+		idv1 = sys->mfaces[i].v1;
+		idv2 = sys->mfaces[i].v2;
+		idv3 = sys->mfaces[i].v3;
+		idv4 = has_4_vert ? sys->mfaces[i].v4 : 0;
+		
+		sys->numNeFa[idv1] += 1;
+		sys->numNeFa[idv2] += 1;
+		sys->numNeFa[idv3] += 1;
+		if (has_4_vert) sys->numNeFa[idv4] += 1;
 
-		v1 = vertexCos[idv1];
-		v2 = vertexCos[idv2];
-		v3 = vertexCos[idv3];
-		v4 = vertexCos[idv4];
+		v1 = sys->vertexCos[idv1];
+		v2 = sys->vertexCos[idv2];
+		v3 = sys->vertexCos[idv3];
+		v4 = has_4_vert ? sys->vertexCos[idv4] : 0;
+		
+		if (has_4_vert) {
+			areaf = area_quad_v3(v1, v2, v3, sys->vertexCos[sys->mfaces[i].v4]);
+		} else {
+			areaf = area_tri_v3(v1, v2, v3);
+		}
+		if (fabs(areaf) < sys->min_area) { 
+			sys->zerola[idv1] = 1;
+			sys->zerola[idv2] = 1;
+			sys->zerola[idv3] = 1;
+			if (has_4_vert) sys->zerola[idv4] = 1;
+		}
 
-		w2 = cotan_weight(v4, v1, v2) + cotan_weight(v3, v1, v2);
-		w3 = cotan_weight(v2, v3, v1) + cotan_weight(v4, v1, v3);
-		w4 = cotan_weight(v2, v4, v1) + cotan_weight(v3, v4, v1);
+		sys->ring_areas[idv1] += areaf;
+		sys->ring_areas[idv2] += areaf;
+		sys->ring_areas[idv3] += areaf;
+		if (has_4_vert) sys->ring_areas[idv4] += areaf;
+
+		if (has_4_vert) {
+			
+			idv[0] = idv1;
+			idv[1] = idv2;
+			idv[2] = idv3;
+			idv[3] = idv4;
+
+			for (j = 0; j < 4; j++) {
+				idv1 = idv[j];
+				idv2 = idv[(j + 1) % 4];
+				idv3 = idv[(j + 2) % 4];
+				idv4 = idv[(j + 3) % 4];
+
+				v1 = sys->vertexCos[idv1];
+				v2 = sys->vertexCos[idv2];
+				v3 = sys->vertexCos[idv3];
+				v4 = sys->vertexCos[idv4];
+
+				w2 = cotan_weight(v4, v1, v2) + cotan_weight(v3, v1, v2);
+				w3 = cotan_weight(v2, v3, v1) + cotan_weight(v4, v1, v3);
+				w4 = cotan_weight(v2, v4, v1) + cotan_weight(v3, v4, v1);
 	
-		sys->vweights[idv1] = sys->vweights[idv1] + (w2 + w3 + w4) / 4.0f;
-	
+				sys->vweights[idv1] += (w2 + w3 + w4) / 4.0f;
+			}
+		} else {			
+			w1 = cotan_weight(v1, v2, v3);
+			w2 = cotan_weight(v2, v3, v1);
+			w3 = cotan_weight(v3, v1, v2);
+
+			sys->fweights[i][0] = sys->fweights[i][0] + w1;
+			sys->fweights[i][1] = sys->fweights[i][1] + w2;
+			sys->fweights[i][2] = sys->fweights[i][2] + w3;
+			
+			sys->vweights[idv1] = sys->vweights[idv1] + w2 + w3;
+			sys->vweights[idv2] = sys->vweights[idv2] + w1 + w3;
+			sys->vweights[idv3] = sys->vweights[idv3] + w1 + w2;
+		}
 	}
+	for ( i = 0; i < sys->numEdges; i++) {
+		idv1 = sys->medges[i].v1;
+		idv2 = sys->medges[i].v2;
+		/* if is boundary, apply scale-dependent umbrella operator only with neighboors in boundary */
+		if (sys->numNeEd[idv1] != sys->numNeFa[idv1] && sys->numNeEd[idv2] != sys->numNeFa[idv2]) { 
+			sys->vlengths[idv1] += sys->eweights[i];
+			sys->vlengths[idv2] += sys->eweights[i];
+		}
+	}
+
 }
 
-static void set_laplacian_matrix_quad(ModLaplacianSystem * sys, MFace *mfaces, int index_face, float (*vertexCos)[3])
+static void fill_laplacian_matrix(ModLaplacianSystem * sys)
 {
+	float *v1, *v2, *v3, *v4;
+	float w1, w2, w3, w4;
+	int i, j;
+	int has_4_vert ;
 	unsigned int idv1, idv2, idv3, idv4, idv[4];
-	int i;
-	float *v1, *v2, *v3, *v4;
-	float w2, w3, w4;
+	
+	for ( i = 0; i < sys->numFaces; i++) {
+		idv1 = sys->mfaces[i].v1;
+		idv2 = sys->mfaces[i].v2;
+		idv3 = sys->mfaces[i].v3;
+		has_4_vert = ((&sys->mfaces[i])->v4) ? 1 : 0;
 
-	idv[0] = mfaces[index_face].v1;
-	idv[1] = mfaces[index_face].v2;
-	idv[2] = mfaces[index_face].v3;
-	idv[3] = mfaces[index_face].v4;
+		if (has_4_vert) {
+			idv[0] = sys->mfaces[i].v1;
+			idv[1] = sys->mfaces[i].v2;
+			idv[2] = sys->mfaces[i].v3;
+			idv[3] = sys->mfaces[i].v4;
+			for (j = 0; j < 4; j++) {
+				idv1 = idv[j];
+				idv2 = idv[(j + 1) % 4];
+				idv3 = idv[(j + 2) % 4];
+				idv4 = idv[(j + 3) % 4];
 
+				v1 = sys->vertexCos[idv1];
+				v2 = sys->vertexCos[idv2];
+				v3 = sys->vertexCos[idv3];
+				v4 = sys->vertexCos[idv4];
 
-	for (i = 0; i < 4; i++) {
-		idv1 = idv[i];
-		idv2 = idv[(i + 1) % 4];
-		idv3 = idv[(i + 2) % 4];
-		idv4 = idv[(i + 3) % 4];
+				w2 = cotan_weight(v4, v1, v2) + cotan_weight(v3, v1, v2);
+				w3 = cotan_weight(v2, v3, v1) + cotan_weight(v4, v1, v3);
+				w4 = cotan_weight(v2, v4, v1) + cotan_weight(v3, v4, v1);
 
-		v1 = vertexCos[idv1];
-		v2 = vertexCos[idv2];
-		v3 = vertexCos[idv3];
-		v4 = vertexCos[idv4];
-
-		w2 = cotan_weight(v4, v1, v2) + cotan_weight(v3, v1, v2);
-		w3 = cotan_weight(v2, v3, v1) + cotan_weight(v4, v1, v3);
-		w4 = cotan_weight(v2, v4, v1) + cotan_weight(v3, v4, v1);
-
-		w2 = w2 / 4.0f;
-		w3 = w3 / 4.0f;
-		w4 = w4 / 4.0f;
+				w2 = w2 / 4.0f;
+				w3 = w3 / 4.0f;
+				w4 = w4 / 4.0f;
 		
-		if (sys->numNeEd[idv1] == sys->numNeFa[idv1] && sys->zerola[idv1] == 0) { 
-			nlMatrixAdd(idv1, idv2, w2 * sys->vweights[idv1]);
-			nlMatrixAdd(idv1, idv3, w3 * sys->vweights[idv1]);
-			nlMatrixAdd(idv1, idv4, w4 * sys->vweights[idv1]);
+				if (sys->numNeEd[idv1] == sys->numNeFa[idv1] && sys->zerola[idv1] == 0) { 
+					nlMatrixAdd(idv1, idv2, w2 * sys->vweights[idv1]);
+					nlMatrixAdd(idv1, idv3, w3 * sys->vweights[idv1]);
+					nlMatrixAdd(idv1, idv4, w4 * sys->vweights[idv1]);
+				}
+			}
+		} else {
+			/* Is ring if number of faces == number of edges around vertice*/
+			if (sys->numNeEd[idv1] == sys->numNeFa[idv1] && sys->zerola[idv1] == 0) { 
+				nlMatrixAdd(idv1, idv2, sys->fweights[i][2] * sys->vweights[idv1]);
+				nlMatrixAdd(idv1, idv3, sys->fweights[i][1] * sys->vweights[idv1]);
+			}
+			if (sys->numNeEd[idv2] == sys->numNeFa[idv2] && sys->zerola[idv2] == 0) { 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list