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; }
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; }
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 }