[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [48104] branches/soc-2012-sushi/source/ blender/modifiers/intern/MOD_laplaciansmooth.c: Implements laplacian smoothing for triangulated and quadrilateral meshes with base on Mean Laplace ?\226?\128?\147Beltrami Operator for Quadrilateral Meshes Xiong et.

Alexander Pinzon apinzonf at gmail.com
Wed Jun 20 07:42:03 CEST 2012


Revision: 48104
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=48104
Author:   apinzonf
Date:     2012-06-20 05:41:52 +0000 (Wed, 20 Jun 2012)
Log Message:
-----------
Implements laplacian smoothing for triangulated and quadrilateral meshes with base on Mean Laplace?\226?\128?\147Beltrami Operator for Quadrilateral Meshes Xiong et. al. 2011.

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 02:06:06 UTC (rev 48103)
+++ branches/soc-2012-sushi/source/blender/modifiers/intern/MOD_laplaciansmooth.c	2012-06-20 05:41:52 UTC (rev 48104)
@@ -85,6 +85,8 @@
 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)
 {
@@ -295,6 +297,79 @@
 	}
 }
 
+static void compute_weight_quad(ModLaplacianSystem * sys, MFace *mfaces, int index_face, float (*vertexCos)[3])
+{
+	unsigned int idv1, idv2, idv3, idv4, idv[4];
+	int i;
+	float *v1, *v2, *v3, *v4;
+	float w2, w3, w4;
+
+	idv[0] = mfaces[index_face].v1;
+	idv[1] = mfaces[index_face].v2;
+	idv[2] = mfaces[index_face].v3;
+	idv[3] = mfaces[index_face].v4;
+
+
+	for (i = 0; i < 4; i++) {
+		idv1 = idv[i];
+		idv2 = idv[(i + 1) % 4];
+		idv3 = idv[(i + 2) % 4];
+		idv4 = idv[(i + 3) % 4];
+
+		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);
+	
+		sys->vweights[idv1] = sys->vweights[idv1] + (w2 + w3 + w4) / 4.0f;
+	
+	}
+}
+
+static void set_laplacian_matrix_quad(ModLaplacianSystem * sys, MFace *mfaces, int index_face, float (*vertexCos)[3])
+{
+	unsigned int idv1, idv2, idv3, idv4, idv[4];
+	int i;
+	float *v1, *v2, *v3, *v4;
+	float w2, w3, w4;
+
+	idv[0] = mfaces[index_face].v1;
+	idv[1] = mfaces[index_face].v2;
+	idv[2] = mfaces[index_face].v3;
+	idv[3] = mfaces[index_face].v4;
+
+
+	for (i = 0; i < 4; i++) {
+		idv1 = idv[i];
+		idv2 = idv[(i + 1) % 4];
+		idv3 = idv[(i + 2) % 4];
+		idv4 = idv[(i + 3) % 4];
+
+		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;
+		
+		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]);
+		}
+	}
+}
+
 static void laplaciansmoothModifier_do(
         LaplacianSmoothModifierData *smd, Object *ob, DerivedMesh *dm,
         float (*vertexCos)[3], int numVerts)
@@ -302,12 +377,12 @@
 	ModLaplacianSystem *sys;
 	MDeformVert *dvert = NULL;
 	MDeformVert *dv = NULL;
-	float *v1, *v2, *v3;
+	float *v1, *v2, *v3, *v4;
 	float w1, w2, w3, wpaint;
 	float areaf;
 	int i, iter;
 	int defgrp_index;
-	unsigned int idv1, idv2, idv3;
+	unsigned int idv1, idv2, idv3, idv4;
 	MFace *mfaces = NULL;
 	MEdge *medges = NULL;
 
@@ -357,10 +432,17 @@
 			idv1 = mfaces[i].v1;
 			idv2 = mfaces[i].v2;
 			idv3 = mfaces[i].v3;
+			if ((&mfaces[i])->v4) {
+				idv4 = mfaces[i].v4;
+				v4 = vertexCos[idv4];
+			}
 
 			sys->numNeFa[idv1] = sys->numNeFa[idv1] + 1;
 			sys->numNeFa[idv2] = sys->numNeFa[idv2] + 1;
 			sys->numNeFa[idv3] = sys->numNeFa[idv3] + 1;
+			if ((&mfaces[i])->v4) {
+				sys->numNeFa[idv4] = sys->numNeFa[idv4] + 1;
+			}
 
 			v1 = vertexCos[idv1];
 			v2 = vertexCos[idv2];
@@ -370,24 +452,43 @@
 			w2 = cotan_weight(v2, v3, v1);
 			w3 = cotan_weight(v3, v1, v2);
 
-			areaf = area_tri_v3(v1, v2, v3);
-			if (fabs(areaf) < smd->min_area) { 
-				sys->zerola[idv1] = 1;
-				sys->zerola[idv2] = 1;
-				sys->zerola[idv3] = 1;
+			if ((&mfaces[i])->v4) {
+				areaf = area_quad_v3(v1, v2, v3, vertexCos[mfaces[i].v4]);
+				if (fabs(areaf) < smd->min_area) { 
+					sys->zerola[idv1] = 1;
+					sys->zerola[idv2] = 1;
+					sys->zerola[idv3] = 1;
+					sys->zerola[idv4] = 1;
+				}
+			} else {
+				areaf = area_tri_v3(v1, v2, v3);
+				if (fabs(areaf) < smd->min_area) { 
+					sys->zerola[idv1] = 1;
+					sys->zerola[idv2] = 1;
+					sys->zerola[idv3] = 1;
+				}
 			}
+			
+			if ((&mfaces[i])->v4) {
+				sys->ring_areas[idv1] = sys->ring_areas[idv1] + areaf;
+				sys->ring_areas[idv2] = sys->ring_areas[idv2] + areaf;
+				sys->ring_areas[idv3] = sys->ring_areas[idv3] + areaf;
+				sys->ring_areas[idv4] = sys->ring_areas[idv4] + areaf;
+				compute_weight_quad(sys, mfaces, i, vertexCos);
+			} else {
 
-			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->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;
+				sys->vweights[idv1] = sys->vweights[idv1] + w2 + w3;
+				sys->vweights[idv2] = sys->vweights[idv2] + w1 + w3;
+				sys->vweights[idv3] = sys->vweights[idv3] + w1 + w2;
 
-			sys->ring_areas[idv1] = sys->ring_areas[idv1] + areaf;
-			sys->ring_areas[idv2] = sys->ring_areas[idv2] + areaf;
-			sys->ring_areas[idv3] = sys->ring_areas[idv3] + areaf;
+				sys->ring_areas[idv1] = sys->ring_areas[idv1] + areaf;
+				sys->ring_areas[idv2] = sys->ring_areas[idv2] + areaf;
+				sys->ring_areas[idv3] = sys->ring_areas[idv3] + areaf;
+			}
 
 		}
 
@@ -444,20 +545,23 @@
 			idv1 = mfaces[i].v1;
 			idv2 = mfaces[i].v2;
 			idv3 = mfaces[i].v3;
-
-			/* 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 ((&mfaces[i])->v4) {
+				set_laplacian_matrix_quad(sys, mfaces, i, vertexCos);
+			} 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) { 
+					nlMatrixAdd(idv2, idv1, sys->fweights[i][2] * sys->vweights[idv2]);
+					nlMatrixAdd(idv2, idv3, sys->fweights[i][0] * sys->vweights[idv2]);
+				}
+				if (sys->numNeEd[idv3] == sys->numNeFa[idv3] && sys->zerola[idv3] == 0) { 
+					nlMatrixAdd(idv3, idv1, sys->fweights[i][1] * sys->vweights[idv3]);
+					nlMatrixAdd(idv3, idv2, sys->fweights[i][0] * sys->vweights[idv3]);
+				}
 			}
-			if (sys->numNeEd[idv2] == sys->numNeFa[idv2] && sys->zerola[idv2] == 0) { 
-				nlMatrixAdd(idv2, idv1, sys->fweights[i][2] * sys->vweights[idv2]);
-				nlMatrixAdd(idv2, idv3, sys->fweights[i][0] * sys->vweights[idv2]);
-			}
-			if (sys->numNeEd[idv3] == sys->numNeFa[idv3] && sys->zerola[idv3] == 0) { 
-				nlMatrixAdd(idv3, idv1, sys->fweights[i][1] * sys->vweights[idv3]);
-				nlMatrixAdd(idv3, idv2, sys->fweights[i][0] * sys->vweights[idv3]);
-			}
 
 		}
 




More information about the Bf-blender-cvs mailing list