Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2014-01-09 14:19:51 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2014-01-09 14:33:53 +0400
commitcc31722a412b19645aebedb8192502d3a3e73cdb (patch)
tree6086dc9c15fbca8057989d9cd2055258a5035aeb /source/blender/blenkernel
parent113ff5147675b37082efabb6afd020b51dc531f3 (diff)
Fix T38000: vertex parent crash due to threading issues
Issue is causes by vertex parent modifies original BMesh from a multiple threads. Ideally this is to be done as a separate update callback for mesh datablock, but it's not so much simple now (would need to do some re-arranges to DAG which might conflict with the work from Ali or will double amount of work we did). So for now use simple solution with mutex lock. Based on the patch from Campbell Barton with some fixes to make changes really thread-safe. Differential Revision: https://developer.blender.org/D168
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/intern/object.c65
1 files changed, 39 insertions, 26 deletions
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 4dccffec0e0..d0d4c6f8833 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -62,6 +62,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
+#include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "BLI_linklist.h"
#include "BLI_kdtree.h"
@@ -122,6 +123,18 @@
#include "GPU_material.h"
+/* Vertex parent modifies original BMesh which is not safe for threading.
+ * Ideally such a modification should be handled as a separate DAG update
+ * callback for mesh datablock, but for until it is actually supported use
+ * simpler solution with a mutex lock.
+ * - sergey -
+ */
+#define VPARENT_THREADING_HACK
+
+#ifdef VPARENT_THREADING_HACK
+static ThreadMutex vparent_lock = BLI_MUTEX_INITIALIZER;
+#endif
+
void BKE_object_workob_clear(Object *workob)
{
memset(workob, 0, sizeof(Object));
@@ -2081,32 +2094,13 @@ static void ob_parbone(Object *ob, Object *par, float mat[4][4])
static void give_parvert(Object *par, int nr, float vec[3])
{
- BMEditMesh *em;
-
zero_v3(vec);
if (par->type == OB_MESH) {
Mesh *me = par->data;
+ BMEditMesh *em = me->edit_btmesh;
DerivedMesh *dm;
- em = me->edit_btmesh;
-
-#if 0 /* this was bmesh only, better, evaluate why this was needed - campbell*/
- if (em) {
- BMVert *eve;
- BMIter iter;
-
- BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
- int *keyindex = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX);
-
- if (keyindex && *keyindex == nr) {
- copy_v3_v3(vec, eve->co);
- break;
- }
- }
- }
-#endif
-
dm = (em) ? em->derivedFinal : par->derivedFinal;
if (dm) {
@@ -2114,22 +2108,41 @@ static void give_parvert(Object *par, int nr, float vec[3])
int numVerts = dm->getNumVerts(dm);
if (nr < numVerts) {
- MVert *mvert = dm->getVertArray(dm);
- int *index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
+ /* avoid dm->getVertDataArray() since it allocates arrays in the dm (not thread safe) */
int i;
+ if (em && dm->type == DM_TYPE_EDITBMESH) {
+ if (em->bm->elem_table_dirty & BM_VERT) {
+#ifdef VPARENT_THREADING_HACK
+ BLI_mutex_lock(&vparent_lock);
+ if (em->bm->elem_table_dirty & BM_VERT) {
+ BM_mesh_elem_table_ensure(em->bm, BM_VERT);
+ }
+ BLI_mutex_unlock(&vparent_lock);
+#else
+ BLI_assert(!"Not safe for threading");
+ BM_mesh_elem_table_ensure(em->bm, BM_VERT);
+#endif
+ }
+ }
+
/* get the average of all verts with (original index == nr) */
- if (index) {
+ if (CustomData_has_layer(&dm->vertData, CD_ORIGINDEX)) {
for (i = 0; i < numVerts; i++) {
- if (index[i] == nr) {
- add_v3_v3(vec, mvert[i].co);
+ const int *index = dm->getVertData(dm, i, CD_ORIGINDEX);
+ if (*index == nr) {
+ float co[3];
+ dm->getVertCo(dm, i, co);
+ add_v3_v3(vec, co);
count++;
}
}
}
else {
if (nr < numVerts) {
- add_v3_v3(vec, mvert[nr].co);
+ float co[3];
+ dm->getVertCo(dm, nr, co);
+ add_v3_v3(vec, co);
count++;
}
}