Пример #1
0
NLContext nlNewContext(void) {
	__NLContext* result	  = __NL_NEW(__NLContext);
	result->state			= __NL_STATE_INITIAL;
	result->matrix_vector_prod = __nlMatrixVectorProd_default;
	result->nb_rhs = 1;
	nlMakeCurrent(result);
	return result;
}
Пример #2
0
NLContext nlNewContext(void) {
	__NLContext* result	  = __NL_NEW(__NLContext);
	result->state			= __NL_STATE_INITIAL;
	result->right_hand_side  = 0.0;
	result->matrix_vector_prod = __nlMatrixVectorProd_default;
	nlMakeCurrent(result);
	return result;
}
Пример #3
0
void rigid_deform_iteration()
{
	LaplacianSystem *sys= RigidDeformSystem;
	EditMesh *em;
	EditVert *eve;
	EditFace *efa;
	int a, i;

	if(!sys)
		return;
	
	nlMakeCurrent(sys->context);
	em= sys->rigid.mesh;

	/* compute R */
	memset(sys->rigid.R, 0, sizeof(float)*3*3*sys->totvert);
	memset(sys->rigid.rhs, 0, sizeof(float)*3*sys->totvert);

	for(a=0, efa=em->faces.first; efa; efa=efa->next, a++) {
		rigid_add_edge_to_R(sys, efa->v1, efa->v2, sys->fweights[a][2]);
		rigid_add_edge_to_R(sys, efa->v2, efa->v3, sys->fweights[a][0]);
		rigid_add_edge_to_R(sys, efa->v3, efa->v1, sys->fweights[a][1]);

		if(efa->v4) {
			a++;
			rigid_add_edge_to_R(sys, efa->v1, efa->v3, sys->fweights[a][2]);
			rigid_add_edge_to_R(sys, efa->v3, efa->v4, sys->fweights[a][0]);
			rigid_add_edge_to_R(sys, efa->v4, efa->v1, sys->fweights[a][1]);
		}
	}

	for(a=0, eve=em->verts.first; eve; eve=eve->next, a++) {
		rigid_orthogonalize_R(sys->rigid.R[a]);
		eve->tmp.l= a;
	}
	
	/* compute right hand sides for solving */
	for(a=0, efa=em->faces.first; efa; efa=efa->next, a++) {
		rigid_add_edge_to_rhs(sys, efa->v1, efa->v2, sys->fweights[a][2]);
		rigid_add_edge_to_rhs(sys, efa->v2, efa->v3, sys->fweights[a][0]);
		rigid_add_edge_to_rhs(sys, efa->v3, efa->v1, sys->fweights[a][1]);

		if(efa->v4) {
			a++;
			rigid_add_edge_to_rhs(sys, efa->v1, efa->v3, sys->fweights[a][2]);
			rigid_add_edge_to_rhs(sys, efa->v3, efa->v4, sys->fweights[a][0]);
			rigid_add_edge_to_rhs(sys, efa->v4, efa->v1, sys->fweights[a][1]);
		}
	}

	/* solve for positions, for X,Y and Z separately */
	for(i=0; i<3; i++) {
		laplacian_begin_solve(sys, i);

		for(a=0; a<sys->totvert; a++)
			if(!sys->vpinned[a])
				laplacian_add_right_hand_side(sys, a, sys->rigid.rhs[a][i]);

		if(laplacian_system_solve(sys)) {
			for(a=0, eve=em->verts.first; eve; eve=eve->next, a++)
				eve->co[i]= laplacian_system_get_solution(a);
		}
		else {
			if(!sys->rigid.thrownerror) {
				error("RigidDeform: failed to find solution.");
				sys->rigid.thrownerror= 1;
			}
			break;
		}
	}
}
static void laplacianDeformPreview(LaplacianSystem *sys, float (*vertexCos)[3])
{
	int vid, i, j, n, na;
	n = sys->total_verts;
	na = sys->total_anchors;

#ifdef OPENNL_THREADING_HACK
	modifier_opennl_lock();
#endif

	if (!sys->is_matrix_computed) {
		nlNewContext();
		sys->context = nlGetCurrent();

		nlSolverParameteri(NL_NB_VARIABLES, n);
		nlSolverParameteri(NL_SYMMETRIC, NL_FALSE);
		nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE);
		nlSolverParameteri(NL_NB_ROWS, n + na);
		nlSolverParameteri(NL_NB_RIGHT_HAND_SIDES, 3);
		nlBegin(NL_SYSTEM);
		for (i = 0; i < n; i++) {
			nlSetVariable(0, i, sys->co[i][0]);
			nlSetVariable(1, i, sys->co[i][1]);
			nlSetVariable(2, i, sys->co[i][2]);
		}
		for (i = 0; i < na; i++) {
			vid = sys->index_anchors[i];
			nlSetVariable(0, vid, vertexCos[vid][0]);
			nlSetVariable(1, vid, vertexCos[vid][1]);
			nlSetVariable(2, vid, vertexCos[vid][2]);
		}
		nlBegin(NL_MATRIX);

		initLaplacianMatrix(sys);
		computeImplictRotations(sys);

		for (i = 0; i < n; i++) {
			nlRightHandSideSet(0, i, sys->delta[i][0]);
			nlRightHandSideSet(1, i, sys->delta[i][1]);
			nlRightHandSideSet(2, i, sys->delta[i][2]);
		}
		for (i = 0; i < na; i++) {
			vid = sys->index_anchors[i];
			nlRightHandSideSet(0, n + i, vertexCos[vid][0]);
			nlRightHandSideSet(1, n + i, vertexCos[vid][1]);
			nlRightHandSideSet(2, n + i, vertexCos[vid][2]);
			nlMatrixAdd(n + i, vid, 1.0f);
		}
		nlEnd(NL_MATRIX);
		nlEnd(NL_SYSTEM);
		if (nlSolveAdvanced(NULL, NL_TRUE)) {
			sys->has_solution = true;

			for (j = 1; j <= sys->repeat; j++) {
				nlBegin(NL_SYSTEM);
				nlBegin(NL_MATRIX);
				rotateDifferentialCoordinates(sys);

				for (i = 0; i < na; i++) {
					vid = sys->index_anchors[i];
					nlRightHandSideSet(0, n + i, vertexCos[vid][0]);
					nlRightHandSideSet(1, n + i, vertexCos[vid][1]);
					nlRightHandSideSet(2, n + i, vertexCos[vid][2]);
				}

				nlEnd(NL_MATRIX);
				nlEnd(NL_SYSTEM);
				if (!nlSolveAdvanced(NULL, NL_FALSE)) {
					sys->has_solution = false;
					break;
				}
			}
			if (sys->has_solution) {
				for (vid = 0; vid < sys->total_verts; vid++) {
					vertexCos[vid][0] = nlGetVariable(0, vid);
					vertexCos[vid][1] = nlGetVariable(1, vid);
					vertexCos[vid][2] = nlGetVariable(2, vid);
				}
			}
			else {
				sys->has_solution = false;
			}

		}
		else {
			sys->has_solution = false;
		}
		sys->is_matrix_computed = true;

	}
	else if (sys->has_solution) {
		nlMakeCurrent(sys->context);

		nlBegin(NL_SYSTEM);
		nlBegin(NL_MATRIX);

		for (i = 0; i < n; i++) {
			nlRightHandSideSet(0, i, sys->delta[i][0]);
			nlRightHandSideSet(1, i, sys->delta[i][1]);
			nlRightHandSideSet(2, i, sys->delta[i][2]);
		}
		for (i = 0; i < na; i++) {
			vid = sys->index_anchors[i];
			nlRightHandSideSet(0, n + i, vertexCos[vid][0]);
			nlRightHandSideSet(1, n + i, vertexCos[vid][1]);
			nlRightHandSideSet(2, n + i, vertexCos[vid][2]);
			nlMatrixAdd(n + i, vid, 1.0f);
		}

		nlEnd(NL_MATRIX);
		nlEnd(NL_SYSTEM);
		if (nlSolveAdvanced(NULL, NL_FALSE)) {
			sys->has_solution = true;
			for (j = 1; j <= sys->repeat; j++) {
				nlBegin(NL_SYSTEM);
				nlBegin(NL_MATRIX);
				rotateDifferentialCoordinates(sys);

				for (i = 0; i < na; i++) {
					vid = sys->index_anchors[i];
					nlRightHandSideSet(0, n + i, vertexCos[vid][0]);
					nlRightHandSideSet(1, n + i, vertexCos[vid][1]);
					nlRightHandSideSet(2, n + i, vertexCos[vid][2]);
				}
				nlEnd(NL_MATRIX);
				nlEnd(NL_SYSTEM);
				if (!nlSolveAdvanced(NULL, NL_FALSE)) {
					sys->has_solution = false;
					break;
				}
			}
			if (sys->has_solution) {
				for (vid = 0; vid < sys->total_verts; vid++) {
					vertexCos[vid][0] = nlGetVariable(0, vid);
					vertexCos[vid][1] = nlGetVariable(1, vid);
					vertexCos[vid][2] = nlGetVariable(2, vid);
				}
			}
			else {
				sys->has_solution = false;
			}
		}
		else {
			sys->has_solution = false;
		}
	}

#ifdef OPENNL_THREADING_HACK
	modifier_opennl_unlock();
#endif
}