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. --- .../blender/modifiers/intern/MOD_laplaciandeform.c | 149 ++++++++++----------- .../blender/modifiers/intern/MOD_laplaciansmooth.c | 65 +++++---- 2 files changed, 105 insertions(+), 109 deletions(-) (limited to 'source/blender/modifiers/intern') diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c index 916f8b8a36d..fdaacc7cd9e 100644 --- a/source/blender/modifiers/intern/MOD_laplaciandeform.c +++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c @@ -283,9 +283,9 @@ static void initLaplacianMatrix(LaplacianSystem *sys) sys->delta[idv[0]][1] -= v3[1] * w3; sys->delta[idv[0]][2] -= v3[2] * w3; - nlMatrixAdd(idv[0], idv[1], -w2); - nlMatrixAdd(idv[0], idv[2], -w3); - nlMatrixAdd(idv[0], idv[0], w2 + w3); + nlMatrixAdd(sys->context, idv[0], idv[1], -w2); + nlMatrixAdd(sys->context, idv[0], idv[2], -w3); + nlMatrixAdd(sys->context, idv[0], idv[0], w2 + w3); } } } @@ -338,9 +338,9 @@ static void rotateDifferentialCoordinates(LaplacianSystem *sys) beta = dot_v3v3(uij, di); gamma = dot_v3v3(e2, di); - pi[0] = nlGetVariable(0, i); - pi[1] = nlGetVariable(1, i); - pi[2] = nlGetVariable(2, i); + pi[0] = nlGetVariable(sys->context, 0, i); + pi[1] = nlGetVariable(sys->context, 1, i); + pi[2] = nlGetVariable(sys->context, 2, i); zero_v3(ni); num_fni = 0; num_fni = sys->ringf_map[i].count; @@ -349,9 +349,9 @@ static void rotateDifferentialCoordinates(LaplacianSystem *sys) fidn = sys->ringf_map[i].indices; vin = sys->tris[fidn[fi]]; for (j = 0; j < 3; j++) { - vn[j][0] = nlGetVariable(0, vin[j]); - vn[j][1] = nlGetVariable(1, vin[j]); - vn[j][2] = nlGetVariable(2, vin[j]); + vn[j][0] = nlGetVariable(sys->context, 0, vin[j]); + vn[j][1] = nlGetVariable(sys->context, 1, vin[j]); + vn[j][2] = nlGetVariable(sys->context, 2, vin[j]); if (vin[j] == sys->unit_verts[i]) { copy_v3_v3(pj, vn[j]); } @@ -372,14 +372,14 @@ static void rotateDifferentialCoordinates(LaplacianSystem *sys) fni[2] = alpha * ni[2] + beta * uij[2] + gamma * e2[2]; if (len_squared_v3(fni) > FLT_EPSILON) { - nlRightHandSideSet(0, i, fni[0]); - nlRightHandSideSet(1, i, fni[1]); - nlRightHandSideSet(2, i, fni[2]); + nlRightHandSideSet(sys->context, 0, i, fni[0]); + nlRightHandSideSet(sys->context, 1, i, fni[1]); + nlRightHandSideSet(sys->context, 2, i, fni[2]); } else { - nlRightHandSideSet(0, i, sys->delta[i][0]); - nlRightHandSideSet(1, i, sys->delta[i][1]); - nlRightHandSideSet(2, i, sys->delta[i][2]); + nlRightHandSideSet(sys->context, 0, i, sys->delta[i][0]); + nlRightHandSideSet(sys->context, 1, i, sys->delta[i][1]); + nlRightHandSideSet(sys->context, 2, i, sys->delta[i][2]); } } } @@ -395,71 +395,70 @@ static void laplacianDeformPreview(LaplacianSystem *sys, float (*vertexCos)[3]) #endif if (!sys->is_matrix_computed) { - nlNewContext(); - sys->context = nlGetCurrent(); - - nlSolverParameteri(NL_NB_VARIABLES, n); - nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE); - nlSolverParameteri(NL_NB_ROWS, n + na); - nlSolverParameteri(NL_NB_RIGHT_HAND_SIDES, 3); - nlBegin(NL_SYSTEM); + sys->context = nlNewContext(); + + nlSolverParameteri(sys->context, NL_NB_VARIABLES, n); + nlSolverParameteri(sys->context, NL_LEAST_SQUARES, NL_TRUE); + nlSolverParameteri(sys->context, NL_NB_ROWS, n + na); + nlSolverParameteri(sys->context, NL_NB_RIGHT_HAND_SIDES, 3); + nlBegin(sys->context, 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]); + nlSetVariable(sys->context, 0, i, sys->co[i][0]); + nlSetVariable(sys->context, 1, i, sys->co[i][1]); + nlSetVariable(sys->context, 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]); + nlSetVariable(sys->context, 0, vid, vertexCos[vid][0]); + nlSetVariable(sys->context, 1, vid, vertexCos[vid][1]); + nlSetVariable(sys->context, 2, vid, vertexCos[vid][2]); } - nlBegin(NL_MATRIX); + nlBegin(sys->context, 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]); + nlRightHandSideSet(sys->context, 0, i, sys->delta[i][0]); + nlRightHandSideSet(sys->context, 1, i, sys->delta[i][1]); + nlRightHandSideSet(sys->context, 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); + nlRightHandSideSet(sys->context, 0, n + i, vertexCos[vid][0]); + nlRightHandSideSet(sys->context, 1, n + i, vertexCos[vid][1]); + nlRightHandSideSet(sys->context, 2, n + i, vertexCos[vid][2]); + nlMatrixAdd(sys->context, n + i, vid, 1.0f); } - nlEnd(NL_MATRIX); - nlEnd(NL_SYSTEM); - if (nlSolve(NL_TRUE)) { + nlEnd(sys->context, NL_MATRIX); + nlEnd(sys->context, NL_SYSTEM); + if (nlSolve(sys->context, NL_TRUE)) { sys->has_solution = true; for (j = 1; j <= sys->repeat; j++) { - nlBegin(NL_SYSTEM); - nlBegin(NL_MATRIX); + nlBegin(sys->context, NL_SYSTEM); + nlBegin(sys->context, 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]); + nlRightHandSideSet(sys->context, 0, n + i, vertexCos[vid][0]); + nlRightHandSideSet(sys->context, 1, n + i, vertexCos[vid][1]); + nlRightHandSideSet(sys->context, 2, n + i, vertexCos[vid][2]); } - nlEnd(NL_MATRIX); - nlEnd(NL_SYSTEM); - if (!nlSolve(NL_FALSE)) { + nlEnd(sys->context, NL_MATRIX); + nlEnd(sys->context, NL_SYSTEM); + if (!nlSolve(sys->context, 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); + vertexCos[vid][0] = nlGetVariable(sys->context, 0, vid); + vertexCos[vid][1] = nlGetVariable(sys->context, 1, vid); + vertexCos[vid][2] = nlGetVariable(sys->context, 2, vid); } } else { @@ -474,51 +473,49 @@ static void laplacianDeformPreview(LaplacianSystem *sys, float (*vertexCos)[3]) } else if (sys->has_solution) { - nlMakeCurrent(sys->context); - - nlBegin(NL_SYSTEM); - nlBegin(NL_MATRIX); + nlBegin(sys->context, NL_SYSTEM); + nlBegin(sys->context, 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]); + nlRightHandSideSet(sys->context, 0, i, sys->delta[i][0]); + nlRightHandSideSet(sys->context, 1, i, sys->delta[i][1]); + nlRightHandSideSet(sys->context, 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); + nlRightHandSideSet(sys->context, 0, n + i, vertexCos[vid][0]); + nlRightHandSideSet(sys->context, 1, n + i, vertexCos[vid][1]); + nlRightHandSideSet(sys->context, 2, n + i, vertexCos[vid][2]); + nlMatrixAdd(sys->context, n + i, vid, 1.0f); } - nlEnd(NL_MATRIX); - nlEnd(NL_SYSTEM); - if (nlSolve(NL_FALSE)) { + nlEnd(sys->context, NL_MATRIX); + nlEnd(sys->context, NL_SYSTEM); + if (nlSolve(sys->context, NL_FALSE)) { sys->has_solution = true; for (j = 1; j <= sys->repeat; j++) { - nlBegin(NL_SYSTEM); - nlBegin(NL_MATRIX); + nlBegin(sys->context, NL_SYSTEM); + nlBegin(sys->context, 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]); + nlRightHandSideSet(sys->context, 0, n + i, vertexCos[vid][0]); + nlRightHandSideSet(sys->context, 1, n + i, vertexCos[vid][1]); + nlRightHandSideSet(sys->context, 2, n + i, vertexCos[vid][2]); } - nlEnd(NL_MATRIX); - nlEnd(NL_SYSTEM); - if (!nlSolve(NL_FALSE)) { + nlEnd(sys->context, NL_MATRIX); + nlEnd(sys->context, NL_SYSTEM); + if (!nlSolve(sys->context, 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); + vertexCos[vid][0] = nlGetVariable(sys->context, 0, vid); + vertexCos[vid][1] = nlGetVariable(sys->context, 1, vid); + vertexCos[vid][2] = nlGetVariable(sys->context, 2, vid); } } else { diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c index aef28d24a51..189ceb11d08 100644 --- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c +++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c @@ -300,16 +300,16 @@ static void fill_laplacian_matrix(LaplacianSystem *sys) /* Is ring if number of faces == number of edges around vertice*/ if (sys->numNeEd[l_curr->v] == sys->numNeFa[l_curr->v] && sys->zerola[l_curr->v] == 0) { - nlMatrixAdd(l_curr->v, l_next->v, sys->fweights[l_curr_index][2] * sys->vweights[l_curr->v]); - nlMatrixAdd(l_curr->v, l_prev->v, sys->fweights[l_curr_index][1] * sys->vweights[l_curr->v]); + nlMatrixAdd(sys->context, l_curr->v, l_next->v, sys->fweights[l_curr_index][2] * sys->vweights[l_curr->v]); + nlMatrixAdd(sys->context, l_curr->v, l_prev->v, sys->fweights[l_curr_index][1] * sys->vweights[l_curr->v]); } if (sys->numNeEd[l_next->v] == sys->numNeFa[l_next->v] && sys->zerola[l_next->v] == 0) { - nlMatrixAdd(l_next->v, l_curr->v, sys->fweights[l_curr_index][2] * sys->vweights[l_next->v]); - nlMatrixAdd(l_next->v, l_prev->v, sys->fweights[l_curr_index][0] * sys->vweights[l_next->v]); + nlMatrixAdd(sys->context, l_next->v, l_curr->v, sys->fweights[l_curr_index][2] * sys->vweights[l_next->v]); + nlMatrixAdd(sys->context, l_next->v, l_prev->v, sys->fweights[l_curr_index][0] * sys->vweights[l_next->v]); } if (sys->numNeEd[l_prev->v] == sys->numNeFa[l_prev->v] && sys->zerola[l_prev->v] == 0) { - nlMatrixAdd(l_prev->v, l_curr->v, sys->fweights[l_curr_index][1] * sys->vweights[l_prev->v]); - nlMatrixAdd(l_prev->v, l_next->v, sys->fweights[l_curr_index][0] * sys->vweights[l_prev->v]); + nlMatrixAdd(sys->context, l_prev->v, l_curr->v, sys->fweights[l_curr_index][1] * sys->vweights[l_prev->v]); + nlMatrixAdd(sys->context, l_prev->v, l_next->v, sys->fweights[l_curr_index][0] * sys->vweights[l_prev->v]); } } } @@ -323,8 +323,8 @@ static void fill_laplacian_matrix(LaplacianSystem *sys) sys->zerola[idv1] == 0 && sys->zerola[idv2] == 0) { - nlMatrixAdd(idv1, idv2, sys->eweights[i] * sys->vlengths[idv1]); - nlMatrixAdd(idv2, idv1, sys->eweights[i] * sys->vlengths[idv2]); + nlMatrixAdd(sys->context, idv1, idv2, sys->eweights[i] * sys->vlengths[idv1]); + nlMatrixAdd(sys->context, idv2, idv1, sys->eweights[i] * sys->vlengths[idv2]); } } } @@ -342,13 +342,13 @@ static void validate_solution(LaplacianSystem *sys, short flag, float lambda, fl if (sys->zerola[i] == 0) { lam = sys->numNeEd[i] == sys->numNeFa[i] ? (lambda >= 0.0f ? 1.0f : -1.0f) : (lambda_border >= 0.0f ? 1.0f : -1.0f); if (flag & MOD_LAPLACIANSMOOTH_X) { - sys->vertexCos[i][0] += lam * ((float)nlGetVariable(0, i) - sys->vertexCos[i][0]); + sys->vertexCos[i][0] += lam * ((float)nlGetVariable(sys->context, 0, i) - sys->vertexCos[i][0]); } if (flag & MOD_LAPLACIANSMOOTH_Y) { - sys->vertexCos[i][1] += lam * ((float)nlGetVariable(1, i) - sys->vertexCos[i][1]); + sys->vertexCos[i][1] += lam * ((float)nlGetVariable(sys->context, 1, i) - sys->vertexCos[i][1]); } if (flag & MOD_LAPLACIANSMOOTH_Z) { - sys->vertexCos[i][2] += lam * ((float)nlGetVariable(2, i) - sys->vertexCos[i][2]); + sys->vertexCos[i][2] += lam * ((float)nlGetVariable(sys->context, 2, i) - sys->vertexCos[i][2]); } } } @@ -390,21 +390,20 @@ static void laplaciansmoothModifier_do( modifier_opennl_lock(); #endif - nlNewContext(); - sys->context = nlGetCurrent(); - nlSolverParameteri(NL_NB_VARIABLES, numVerts); - nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE); - nlSolverParameteri(NL_NB_ROWS, numVerts); - nlSolverParameteri(NL_NB_RIGHT_HAND_SIDES, 3); + sys->context = nlNewContext(); + nlSolverParameteri(sys->context, NL_NB_VARIABLES, numVerts); + nlSolverParameteri(sys->context, NL_LEAST_SQUARES, NL_TRUE); + nlSolverParameteri(sys->context, NL_NB_ROWS, numVerts); + nlSolverParameteri(sys->context, NL_NB_RIGHT_HAND_SIDES, 3); init_laplacian_matrix(sys); for (iter = 0; iter < smd->repeat; iter++) { - nlBegin(NL_SYSTEM); + nlBegin(sys->context, NL_SYSTEM); for (i = 0; i < numVerts; i++) { - nlSetVariable(0, i, vertexCos[i][0]); - nlSetVariable(1, i, vertexCos[i][1]); - nlSetVariable(2, i, vertexCos[i][2]); + nlSetVariable(sys->context, 0, i, vertexCos[i][0]); + nlSetVariable(sys->context, 1, i, vertexCos[i][1]); + nlSetVariable(sys->context, 2, i, vertexCos[i][2]); if (iter == 0) { add_v3_v3(sys->vert_centroid, vertexCos[i]); } @@ -413,12 +412,12 @@ static void laplaciansmoothModifier_do( mul_v3_fl(sys->vert_centroid, 1.0f / (float)numVerts); } - nlBegin(NL_MATRIX); + nlBegin(sys->context, NL_MATRIX); dv = dvert; for (i = 0; i < numVerts; i++) { - nlRightHandSideSet(0, i, vertexCos[i][0]); - nlRightHandSideSet(1, i, vertexCos[i][1]); - nlRightHandSideSet(2, i, vertexCos[i][2]); + nlRightHandSideSet(sys->context, 0, i, vertexCos[i][0]); + nlRightHandSideSet(sys->context, 1, i, vertexCos[i][1]); + nlRightHandSideSet(sys->context, 2, i, vertexCos[i][2]); if (iter == 0) { if (dv) { wpaint = defvert_find_weight(dv, defgrp_index); @@ -435,10 +434,10 @@ static void laplaciansmoothModifier_do( w = sys->vlengths[i]; sys->vlengths[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda_border) * wpaint * 2.0f / w; if (sys->numNeEd[i] == sys->numNeFa[i]) { - nlMatrixAdd(i, i, 1.0f + fabsf(smd->lambda) * wpaint); + nlMatrixAdd(sys->context, i, i, 1.0f + fabsf(smd->lambda) * wpaint); } else { - nlMatrixAdd(i, i, 1.0f + fabsf(smd->lambda_border) * wpaint * 2.0f); + nlMatrixAdd(sys->context, i, i, 1.0f + fabsf(smd->lambda_border) * wpaint * 2.0f); } } else { @@ -448,15 +447,15 @@ static void laplaciansmoothModifier_do( sys->vlengths[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda_border) * wpaint * 2.0f / w; if (sys->numNeEd[i] == sys->numNeFa[i]) { - nlMatrixAdd(i, i, 1.0f + fabsf(smd->lambda) * wpaint / (4.0f * sys->ring_areas[i])); + nlMatrixAdd(sys->context, i, i, 1.0f + fabsf(smd->lambda) * wpaint / (4.0f * sys->ring_areas[i])); } else { - nlMatrixAdd(i, i, 1.0f + fabsf(smd->lambda_border) * wpaint * 2.0f); + nlMatrixAdd(sys->context, i, i, 1.0f + fabsf(smd->lambda_border) * wpaint * 2.0f); } } } else { - nlMatrixAdd(i, i, 1.0f); + nlMatrixAdd(sys->context, i, i, 1.0f); } } } @@ -465,10 +464,10 @@ static void laplaciansmoothModifier_do( fill_laplacian_matrix(sys); } - nlEnd(NL_MATRIX); - nlEnd(NL_SYSTEM); + nlEnd(sys->context, NL_MATRIX); + nlEnd(sys->context, NL_SYSTEM); - if (nlSolve(NL_TRUE)) { + if (nlSolve(sys->context, NL_TRUE)) { validate_solution(sys, smd->flag, smd->lambda, smd->lambda_border); } } -- cgit v1.2.3