[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