[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