[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [57830] branches/soc-2013-sketch_mesh/ source/blender/bmesh/operators/bmo_deform_laplacian.c: implementation of the method to rotate the coordinate differentials

Alexander Pinzon apinzonf at gmail.com
Thu Jun 27 19:30:54 CEST 2013


Revision: 57830
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=57830
Author:   apinzonf
Date:     2013-06-27 17:30:53 +0000 (Thu, 27 Jun 2013)
Log Message:
-----------
implementation of the method to rotate the coordinate differentials

Modified Paths:
--------------
    branches/soc-2013-sketch_mesh/source/blender/bmesh/operators/bmo_deform_laplacian.c

Modified: branches/soc-2013-sketch_mesh/source/blender/bmesh/operators/bmo_deform_laplacian.c
===================================================================
--- branches/soc-2013-sketch_mesh/source/blender/bmesh/operators/bmo_deform_laplacian.c	2013-06-27 17:11:23 UTC (rev 57829)
+++ branches/soc-2013-sketch_mesh/source/blender/bmesh/operators/bmo_deform_laplacian.c	2013-06-27 17:30:53 UTC (rev 57830)
@@ -36,11 +36,13 @@
 struct BLaplacianSystem {
 	float *vweights;			/* Total sum of weights per vertice*/
 	float (*delta)[3];			/* Differential Coordinates*/
+	BMVert **uverts;				/* Unit vectors of projected edges onto the plane orthogonal to  n*/
 	int numVerts;				/* Number of verts*/
 	/* Pointers to data*/
 	BMesh *bm;
 	BMOperator *op;
-	NLContext *context;
+	NLContext *context;			/* System for solve general implicit rotations*/
+	NLContext *contextrot;		/* System for solve general Laplacian with rotated differential coordinates*/
 	vptrSpMatrixD spLapMatrix;  /* Sparse Laplacian Matrix*/
 	vptrVectorD VectorB;		/* Array to store vertex positions of handlers*/
 	vptrVectorD VectorX;		/* Array to  store solution */
@@ -80,9 +82,13 @@
 	if(!sys) return;
 	delete_void_pointer(sys->vweights);
 	delete_void_pointer(sys->delta);
+	delete_void_pointer(sys->uverts);
 	if (sys->context) {
 		nlDeleteContext(sys->context);
 	}
+	if (sys->contextrot) {
+		nlDeleteContext(sys->contextrot);
+	}
 	if (sys->spLapMatrix) {
 		delete_spmatrix(sys->spLapMatrix);
 	}
@@ -145,6 +151,12 @@
 		return NULL;
 	}
 
+	sys->uverts =  (BMVert **)MEM_callocN(sizeof(BMVert *) * sys->numVerts, "bmoLaplDeformuverts");
+	if (!sys->uverts) {
+		delete_laplacian_system(sys);
+		return NULL;
+	}
+
 	sys->delta =  (float (*)[3])MEM_callocN(sizeof(float) * sys->numVerts * 3, "bmoLaplDeformDelta");
 	if (!sys->delta) {
 		delete_laplacian_system(sys);
@@ -189,6 +201,7 @@
 			idv[2] = idv3;
 			idv[3] = idv4;
 
+			nlMakeCurrent(sys->context);
 			nlRightHandSideAdd(0, idv1						, 0.0f);
 			nlRightHandSideAdd(0, sys->numVerts + idv1		, 0.0f);
 			nlRightHandSideAdd(0, 2*sys->numVerts + idv1	, 0.0f);
@@ -214,10 +227,14 @@
 					sys->delta[idv1][1] -=  v4[1] * w4;
 					sys->delta[idv1][2] -=  v4[2] * w4;
 
+					nlMakeCurrent(sys->context);
 					nlMatrixAdd(idv1					, idv4						, -w4 );
 					nlMatrixAdd(sys->numVerts + idv1	, sys->numVerts + idv4		, -w4 );
 					nlMatrixAdd(sys->numVerts*2 + idv1	, sys->numVerts*2 + idv4	, -w4 );
 
+					nlMakeCurrent(sys->contextrot);
+					nlMatrixAdd(idv1					, idv4						, -w4 );
+
 					push_back_triplet(sys->tripletList, idv1					, idv4						, -w4 );
 					push_back_triplet(sys->tripletList, sys->numVerts + idv1	, sys->numVerts + idv4		, -w4 );
 					push_back_triplet(sys->tripletList, sys->numVerts*2 + idv1	, sys->numVerts*2 + idv4	, -w4 );
@@ -244,6 +261,7 @@
 				sys->delta[idv1][1] -=  v3[1] * w3;
 				sys->delta[idv1][2] -=  v3[2] * w3;
 
+				nlMakeCurrent(sys->context);
 				nlMatrixAdd(idv1					, idv2						, -w2);
 				nlMatrixAdd(sys->numVerts + idv1	, sys->numVerts + idv2		, -w2);
 				nlMatrixAdd(sys->numVerts*2 + idv1	, sys->numVerts*2 + idv2	, -w2);
@@ -256,6 +274,11 @@
 				nlMatrixAdd(sys->numVerts + idv1	, sys->numVerts + idv1		, w2 + w3 + w4);
 				nlMatrixAdd(sys->numVerts*2 + idv1	, sys->numVerts*2 + idv1	, w2 + w3 + w4);
 
+				nlMakeCurrent(sys->contextrot);
+				nlMatrixAdd(idv1					, idv2						, -w2);
+				nlMatrixAdd(idv1					, idv3						, -w3);
+				nlMatrixAdd(idv1					, idv1						, w2 + w3 + w4);
+
 				push_back_triplet(sys->tripletList, idv1					, idv2						, -w2);
 				push_back_triplet(sys->tripletList, sys->numVerts + idv1	, sys->numVerts + idv2		, -w2);
 				push_back_triplet(sys->tripletList, sys->numVerts*2 + idv1	, sys->numVerts*2 + idv2	, -w2);
@@ -281,10 +304,12 @@
 	BMVert *v;
 	BMVert *v2;
 	BMVert ** vn = NULL;
+	float minj, mjt, *qj, *qi, vj[3];
 	int i, j, ln, jid;
 	vptrMatrixD C, TDelta;
 	BLI_array_declare(vn);
 
+	nlMakeCurrent(sys->context);
 	BM_ITER_MESH (v, &viter, sys->bm, BM_VERTS_OF_MESH) {
 		i = BM_elem_index_get(v);
 		
@@ -298,6 +323,19 @@
 		}
 		BLI_array_append(vn, v);
 		ln = BLI_array_count(vn);
+		minj = 1000000.0f;
+		for (j = 0; j < (ln-1); j++) {
+			qj = vn[j]->co;
+			sub_v3_v3v3(vj, qj, v->co);
+			normalize_v3(vj);
+			mjt = fabs(dot_v3v3(vj, v->no));
+			if (mjt < minj) {
+				minj = mjt;
+				sys->uverts[i] = vn[j];
+				//copy_v3_v3(sys->uverts[i], vn[j]->co);
+			}
+		}
+
 		C = new_matrixd( ln*3, 7);
 		for (j = 0; j < ln; j++) {
 			v2 = vn[j];
@@ -361,6 +399,107 @@
 	}
 }
 
+/*
+	for i=1:n
+        j = nbr_i(i);
+        pi = xyz(i, :);
+        ni = normal(:, i)';
+        pj = xyz(j, :);
+        uij = pj -pi;
+        uij = uij - (dot(uij,ni))*ni;
+        uij = uij/max(norm(uij), 0.00001);
+        e2 = cross(ni, uij);
+        deltai = delta(i,:);
+        alpha = dot(ni,deltai);
+        beta = dot(uij,deltai);
+        gamma = dot(e2,deltai);
+        
+        pi = xyz_prime_nonh(i,:);
+        ni = normal_deform(:, i)';
+        pj = xyz_prime_nonh(j,:);
+        uij = pj -pi;
+        uij = uij - (dot(uij,ni))*ni;
+        uij = uij/max(norm(uij), 0.000001);
+        e2 = cross(ni, uij);  
+        
+        new_d = alpha*ni + beta*uij + gamma*e2;
+        new_delta(i,:) = new_d;
+    end
+		*/
+void rotate_differential_coordinates(LaplacianSystem *sys) 
+{
+	BMFace *f;
+	BMVert *v, *v2;
+	BMIter fiter;
+	BMIter viter, viter2;
+	float alpha, beta, gamma,
+		pj[3], ni[3], di[3], rdelta[3],
+		uij[3], dun[3], e2[3], pi[3], fni[3], vn[4][3];
+	int i, j, *vin, lvin, num_fni;
+
+	BLI_array_declare(vin);
+
+	BM_ITER_MESH (v, &viter, sys->bm, BM_VERTS_OF_MESH) {
+		i = BM_elem_index_get(v);
+		copy_v3_v3(pi, v->co);
+		copy_v3_v3(ni, v->no);
+		copy_v3_v3(pj, sys->uverts[i]->co);
+		sub_v3_v3v3(uij, pj, pi);
+		mul_v3_v3fl(dun, ni, dot_v3v3(uij, ni));
+		sub_v3_v3(uij, dun);
+		normalize_v3(uij);
+		cross_v3_v3v3(e2, ni, uij);
+		copy_v3_v3(di, sys->delta[i]);
+		alpha = dot_v3v3(ni, di);
+        beta = dot_v3v3(uij, di);
+        gamma = dot_v3v3(e2, di);
+
+		pi[0] = nlGetVariable(0, i);
+		pi[1] = nlGetVariable(0, i + sys->numVerts);
+		pi[2] = nlGetVariable(0, i + sys->numVerts*2);
+		ni[0] = 0.0f;	ni[1] = 0.0f;	ni[2] = 0.0f;
+		num_fni = 0;
+		nlMakeCurrent(sys->context);
+		BM_ITER_ELEM_INDEX(f, &fiter, v, BM_FACES_OF_VERT, num_fni) {
+			BM_ITER_ELEM(v2, &viter2, f, BM_VERTS_OF_FACE) {
+				BLI_array_append(vin, BM_elem_index_get(v2));
+			}
+			lvin = BLI_array_count(vin);
+			
+			for (j=0; j<lvin; j++ ) {
+				vn[j][0] = nlGetVariable(0, vin[j]);
+				vn[j][1] = nlGetVariable(0, vin[j] + sys->numVerts);
+				vn[j][2] = nlGetVariable(0, vin[j] + sys->numVerts*2);
+				if (j == BM_elem_index_get(sys->uverts[i])) {
+					copy_v3_v3(pj, vn[j]);
+				}
+			}
+			if (lvin == 3) {
+				normal_tri_v3(fni, vn[0], vn[1], vn[2]);
+			} 
+			else if(lvin == 4) {
+				normal_quad_v3(fni, vn[0], vn[1], vn[2], vn[3]);
+			} 
+			add_v3_v3(ni, fni);
+			BLI_array_free(vin);
+			BLI_array_empty(vin);
+			vin = NULL;
+		}
+		if (num_fni>0) mul_v3_fl(fni, 1.0f/num_fni);
+		sub_v3_v3v3(uij, pj, pi);
+		mul_v3_v3fl(dun, ni, dot_v3v3(uij, ni));
+		sub_v3_v3(uij, dun);
+		normalize_v3(uij);
+		cross_v3_v3v3(e2, ni, uij);
+
+		nlMakeCurrent(sys->contextrot);
+		nlRightHandSideSet(0, i, alpha*ni[0] + beta*uij[0] + gamma*e2[0]);
+		nlRightHandSideSet(1, i, alpha*ni[1] + beta*uij[1] + gamma*e2[1]);
+		nlRightHandSideSet(2, i, alpha*ni[2] + beta*uij[2] + gamma*e2[2]);
+	}
+	
+}
+
 void bmo_deform_laplacian_vert_exec(BMesh *bm, BMOperator *op)
 {
 	int vid;
@@ -378,15 +517,30 @@
 
 	nlNewContext();
 	sys->context = nlGetCurrent();
+	nlNewContext();
+	sys->contextrot = nlGetCurrent();
 
+	nlMakeCurrent(sys->context);
 	nlSolverParameteri(NL_NB_VARIABLES, bm->totvert*3);
 	nlSolverParameteri(NL_SYMMETRIC, NL_FALSE);
 	nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE);
 	nlSolverParameteri(NL_NB_ROWS, bm->totvert*3 + 40*3);
 	nlSolverParameteri(NL_NB_RIGHT_HAND_SIDES, 1);
 
+	nlMakeCurrent(sys->contextrot);
+	nlSolverParameteri(NL_NB_VARIABLES, bm->totvert);
+	nlSolverParameteri(NL_SYMMETRIC, NL_FALSE);
+	nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE);
+	nlSolverParameteri(NL_NB_ROWS, bm->totvert + 40);
+	nlSolverParameteri(NL_NB_RIGHT_HAND_SIDES, 3);
+
+	nlMakeCurrent(sys->context);
 	nlBegin(NL_SYSTEM);
 	nlBegin(NL_MATRIX);
+
+	nlMakeCurrent(sys->contextrot);
+	nlBegin(NL_SYSTEM);
+	nlBegin(NL_MATRIX);
 	
 	init_laplacian_matrix(sys);
 	compute_implicit_rotations(sys);
@@ -395,38 +549,52 @@
 	BMO_ITER (v, &siter, sys->op->slots_in, "verts", BM_VERT) {
 		vid = BM_elem_index_get(v);
 		if (vid < 10) {
+			nlMakeCurrent(sys->context);
 			nlRightHandSideAdd(0, bm->totvert * 3 + vid * 3	 	, v->co[0]);
 			nlRightHandSideAdd(0, bm->totvert * 3 + vid * 3 + 1	, v->co[1]);
 			nlRightHandSideAdd(0, bm->totvert * 3 + vid * 3 + 2	, v->co[2]);
 
+			nlMatrixAdd(bm->totvert * 3 + vid * 3		, vid					, 1.0f);
+			nlMatrixAdd(bm->totvert * 3	+ vid * 3 + 1   , bm->totvert + vid		, 1.0f);
+			nlMatrixAdd(bm->totvert * 3	+ vid * 3 + 2	, 2*bm->totvert + vid	, 1.0f);
+
+			nlMakeCurrent(sys->contextrot);
+			nlRightHandSideAdd(0, bm->totvert + vid 	 	, v->co[0]);
+			nlRightHandSideAdd(1, bm->totvert + vid 		, v->co[1]);
+			nlRightHandSideAdd(2, bm->totvert + vid 		, v->co[2]);
+
+			nlMatrixAdd(bm->totvert + vid 		, vid					, 1.0f);
+
 			set_vectord(sys->VectorB, bm->totvert * 3 + vid * 3	 	, v->co[0]);
 			set_vectord(sys->VectorB, bm->totvert * 3 + vid * 3 + 1	, v->co[1]);
 			set_vectord(sys->VectorB, bm->totvert * 3 + vid * 3 + 2	, v->co[2]);
-			
 
-			nlMatrixAdd(bm->totvert * 3 + vid * 3		, vid					, 1.0f);
-			nlMatrixAdd(bm->totvert * 3	+ vid * 3 + 1   , bm->totvert + vid		, 1.0f);
-			nlMatrixAdd(bm->totvert * 3	+ vid * 3 + 2	, 2*bm->totvert + vid	, 1.0f);
-
 			push_back_triplet(sys->tripletList, bm->totvert * 3 + vid * 3		, vid					, 1.0f);
 			push_back_triplet(sys->tripletList, bm->totvert * 3	+ vid * 3 + 1   , bm->totvert + vid		, 1.0f);
 			push_back_triplet(sys->tripletList, bm->totvert * 3	+ vid * 3 + 2	, 2*bm->totvert + vid	, 1.0f);
 			
 
 		} else if (vid <= 39) {
-			nlRightHandSideAdd(0, bm->totvert * 3 + vid * 3	 	, v->co[0]+2.0f);
-			nlRightHandSideAdd(0, bm->totvert * 3 + vid * 3 + 1	, v->co[1]+2.0f);
+			nlMakeCurrent(sys->context);
+			nlRightHandSideAdd(0, bm->totvert * 3 + vid * 3	 	, v->co[0]*2.0f+2.0f);
+			nlRightHandSideAdd(0, bm->totvert * 3 + vid * 3 + 1	, v->co[1]*2.0f+2.0f);
 			nlRightHandSideAdd(0, bm->totvert * 3 + vid * 3 + 2	, v->co[2]);
 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list