From d28431a6481a7698105ad45fc68a410e3cd71939 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 22 Nov 2015 05:15:56 +0100 Subject: OpenNL: make the API thread safe by always passing context. Previously two laplacian smooth or deform modifiers executing simultaneously could crash. --- source/blender/editors/armature/meshlaplacian.c | 93 ++++++++++++------------- 1 file changed, 45 insertions(+), 48 deletions(-) (limited to 'source/blender/editors/armature/meshlaplacian.c') diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 956cbe25c3b..3f27a58930d 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -182,18 +182,18 @@ static void laplacian_triangle_weights(LaplacianSystem *sys, int f, int i1, int t2 = cotangent_tri_weight_v3(v2, v3, v1) / laplacian_edge_count(sys->edgehash, i3, i1); t3 = cotangent_tri_weight_v3(v3, v1, v2) / laplacian_edge_count(sys->edgehash, i1, i2); - nlMatrixAdd(i1, i1, (t2 + t3) * varea[i1]); - nlMatrixAdd(i2, i2, (t1 + t3) * varea[i2]); - nlMatrixAdd(i3, i3, (t1 + t2) * varea[i3]); + nlMatrixAdd(sys->context, i1, i1, (t2 + t3) * varea[i1]); + nlMatrixAdd(sys->context, i2, i2, (t1 + t3) * varea[i2]); + nlMatrixAdd(sys->context, i3, i3, (t1 + t2) * varea[i3]); - nlMatrixAdd(i1, i2, -t3 * varea[i1]); - nlMatrixAdd(i2, i1, -t3 * varea[i2]); + nlMatrixAdd(sys->context, i1, i2, -t3 * varea[i1]); + nlMatrixAdd(sys->context, i2, i1, -t3 * varea[i2]); - nlMatrixAdd(i2, i3, -t1 * varea[i2]); - nlMatrixAdd(i3, i2, -t1 * varea[i3]); + nlMatrixAdd(sys->context, i2, i3, -t1 * varea[i2]); + nlMatrixAdd(sys->context, i3, i2, -t1 * varea[i3]); - nlMatrixAdd(i3, i1, -t2 * varea[i3]); - nlMatrixAdd(i1, i3, -t2 * varea[i1]); + nlMatrixAdd(sys->context, i3, i1, -t2 * varea[i3]); + nlMatrixAdd(sys->context, i1, i3, -t2 * varea[i1]); if (sys->storeweights) { sys->fweights[f][0] = t1 * varea[i1]; @@ -219,12 +219,10 @@ static LaplacianSystem *laplacian_system_construct_begin(int totvert, int totfac sys->storeweights = 0; /* create opennl context */ - nlNewContext(); - nlSolverParameteri(NL_NB_VARIABLES, totvert); + sys->context = nlNewContext(); + nlSolverParameteri(sys->context, NL_NB_VARIABLES, totvert); if (lsq) - nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE); - - sys->context = nlGetCurrent(); + nlSolverParameteri(sys->context, NL_LEAST_SQUARES, NL_TRUE); return sys; } @@ -274,7 +272,7 @@ static void laplacian_system_construct_end(LaplacianSystem *sys) /* for heat weighting */ if (sys->heat.H) - nlMatrixAdd(a, a, sys->heat.H[a]); + nlMatrixAdd(sys->context, a, a, sys->heat.H[a]); } if (sys->storeweights) @@ -312,41 +310,41 @@ void laplacian_begin_solve(LaplacianSystem *sys, int index) int a; if (!sys->nlbegun) { - nlBegin(NL_SYSTEM); + nlBegin(sys->context, NL_SYSTEM); if (index >= 0) { for (a = 0; a < sys->totvert; a++) { if (sys->vpinned[a]) { - nlSetVariable(0, a, sys->verts[a][index]); - nlLockVariable(a); + nlSetVariable(sys->context, 0, a, sys->verts[a][index]); + nlLockVariable(sys->context, a); } } } - nlBegin(NL_MATRIX); + nlBegin(sys->context, NL_MATRIX); sys->nlbegun = 1; } } -void laplacian_add_right_hand_side(LaplacianSystem *UNUSED(sys), int v, float value) +void laplacian_add_right_hand_side(LaplacianSystem *sys, int v, float value) { - nlRightHandSideAdd(0, v, value); + nlRightHandSideAdd(sys->context, 0, v, value); } int laplacian_system_solve(LaplacianSystem *sys) { - nlEnd(NL_MATRIX); - nlEnd(NL_SYSTEM); + nlEnd(sys->context, NL_MATRIX); + nlEnd(sys->context, NL_SYSTEM); sys->nlbegun = 0; - //nlPrintMatrix(); + //nlPrintMatrix(sys->context, ); - return nlSolve(NL_TRUE); + return nlSolve(sys->context, NL_TRUE); } -float laplacian_system_get_solution(int v) +float laplacian_system_get_solution(LaplacianSystem *sys, int v) { - return nlGetVariable(0, v); + return nlGetVariable(sys->context, 0, v); } /************************* Heat Bone Weighting ******************************/ @@ -723,7 +721,7 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource, if (mask && !mask[a]) continue; - solution = laplacian_system_get_solution(a); + solution = laplacian_system_get_solution(sys, a); if (bbone) { if (solution > 0.0f) @@ -1286,7 +1284,7 @@ static float meshdeform_boundary_total_weight(MeshDeformBind *mdb, int x, int y, return totweight; } -static void meshdeform_matrix_add_cell(MeshDeformBind *mdb, int x, int y, int z) +static void meshdeform_matrix_add_cell(MeshDeformBind *mdb, NLContext *context, int x, int y, int z) { MDefBoundIsect *isect; float weight, totweight; @@ -1296,7 +1294,7 @@ static void meshdeform_matrix_add_cell(MeshDeformBind *mdb, int x, int y, int z) if (mdb->tag[acenter] == MESHDEFORM_TAG_EXTERIOR) return; - nlMatrixAdd(mdb->varidx[acenter], mdb->varidx[acenter], 1.0f); + nlMatrixAdd(context, mdb->varidx[acenter], mdb->varidx[acenter], 1.0f); totweight = meshdeform_boundary_total_weight(mdb, x, y, z); for (i = 1; i <= 6; i++) { @@ -1307,12 +1305,12 @@ static void meshdeform_matrix_add_cell(MeshDeformBind *mdb, int x, int y, int z) isect = mdb->boundisect[acenter][i - 1]; if (!isect) { weight = (1.0f / mdb->width[0]) / totweight; - nlMatrixAdd(mdb->varidx[acenter], mdb->varidx[a], -weight); + nlMatrixAdd(context, mdb->varidx[acenter], mdb->varidx[a], -weight); } } } -static void meshdeform_matrix_add_rhs(MeshDeformBind *mdb, int x, int y, int z, int cagevert) +static void meshdeform_matrix_add_rhs(MeshDeformBind *mdb, NLContext *context, int x, int y, int z, int cagevert) { MDefBoundIsect *isect; float rhs, weight, totweight; @@ -1333,7 +1331,7 @@ static void meshdeform_matrix_add_rhs(MeshDeformBind *mdb, int x, int y, int z, if (isect) { weight = (1.0f / isect->len) / totweight; rhs = weight * meshdeform_boundary_phi(mdb, isect, cagevert); - nlRightHandSideAdd(0, mdb->varidx[acenter], rhs); + nlRightHandSideAdd(context, 0, mdb->varidx[acenter], rhs); } } } @@ -1406,39 +1404,38 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind progress_bar(0, "Starting mesh deform solve"); /* setup opennl solver */ - nlNewContext(); - context = nlGetCurrent(); + context = nlNewContext(); - nlSolverParameteri(NL_NB_VARIABLES, totvar); - nlSolverParameteri(NL_NB_ROWS, totvar); - nlSolverParameteri(NL_NB_RIGHT_HAND_SIDES, 1); + nlSolverParameteri(context, NL_NB_VARIABLES, totvar); + nlSolverParameteri(context, NL_NB_ROWS, totvar); + nlSolverParameteri(context, NL_NB_RIGHT_HAND_SIDES, 1); - nlBegin(NL_SYSTEM); - nlBegin(NL_MATRIX); + nlBegin(context, NL_SYSTEM); + nlBegin(context, NL_MATRIX); /* build matrix */ for (z = 0; z < mdb->size; z++) for (y = 0; y < mdb->size; y++) for (x = 0; x < mdb->size; x++) - meshdeform_matrix_add_cell(mdb, x, y, z); + meshdeform_matrix_add_cell(mdb, context, x, y, z); /* solve for each cage vert */ for (a = 0; a < mdb->totcagevert; a++) { if (a != 0) { - nlBegin(NL_SYSTEM); - nlBegin(NL_MATRIX); + nlBegin(context, NL_SYSTEM); + nlBegin(context, NL_MATRIX); } /* fill in right hand side and solve */ for (z = 0; z < mdb->size; z++) for (y = 0; y < mdb->size; y++) for (x = 0; x < mdb->size; x++) - meshdeform_matrix_add_rhs(mdb, x, y, z, a); + meshdeform_matrix_add_rhs(mdb, context, x, y, z, a); - nlEnd(NL_MATRIX); - nlEnd(NL_SYSTEM); + nlEnd(context, NL_MATRIX); + nlEnd(context, NL_SYSTEM); - if (nlSolve(NL_TRUE)) { + if (nlSolve(context, NL_TRUE)) { for (z = 0; z < mdb->size; z++) for (y = 0; y < mdb->size; y++) for (x = 0; x < mdb->size; x++) @@ -1451,7 +1448,7 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind for (b = 0; b < mdb->size3; b++) { if (mdb->tag[b] != MESHDEFORM_TAG_EXTERIOR) - mdb->phi[b] = nlGetVariable(0, mdb->varidx[b]); + mdb->phi[b] = nlGetVariable(context, 0, mdb->varidx[b]); mdb->totalphi[b] += mdb->phi[b]; } -- cgit v1.2.3