[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [61037] trunk/blender/source/blender/ editors/mesh/meshtools.c: fix for weight-paint crash picking the weight with the mask modifier ( or any modifier which removes geometry).

Campbell Barton ideasman42 at gmail.com
Fri Nov 1 02:14:36 CET 2013


Revision: 61037
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=61037
Author:   campbellbarton
Date:     2013-11-01 01:14:36 +0000 (Fri, 01 Nov 2013)
Log Message:
-----------
fix for weight-paint crash picking the weight with the mask modifier (or any modifier which removes geometry).
was incorrectly mixing indices from the DerivedMesh and the original mesh.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/mesh/meshtools.c

Modified: trunk/blender/source/blender/editors/mesh/meshtools.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/meshtools.c	2013-10-31 23:52:44 UTC (rev 61036)
+++ trunk/blender/source/blender/editors/mesh/meshtools.c	2013-11-01 01:14:36 UTC (rev 61037)
@@ -1231,6 +1231,29 @@
 
 	return true;
 }
+static void ed_mesh_pick_face_vert__mpoly_find(
+        /* context */
+        struct ARegion *ar, const float mval[2],
+        /* mesh data */
+        DerivedMesh *dm, MPoly *mp, MLoop *mloop,
+        /* return values */
+        float *r_len_best, int *r_v_idx_best)
+{
+	const MLoop *ml;
+	int j = mp->totloop;
+	for (ml = &mloop[mp->loopstart]; j--; ml++) {
+		float co[3], sco[2], len;
+		const int v_idx = ml->v;
+		dm->getVertCo(dm, v_idx, co);
+		if (ED_view3d_project_float_object(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+			len = len_manhattan_v2v2(mval, sco);
+			if (len < *r_len_best) {
+				*r_len_best = len;
+				*r_v_idx_best = v_idx;
+			}
+		}
+	}
+}
 /**
  * Use when the back buffer stores face index values. but we want a vert.
  * This gets the face then finds the closest vertex to mval.
@@ -1247,39 +1270,65 @@
 		struct ARegion *ar = CTX_wm_region(C);
 
 		/* derived mesh to find deformed locations */
-		DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
-		int v_idx_best = -1;
+		DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX);
 
-		if (dm->getVertCo) {
-			RegionView3D *rv3d = ar->regiondata;
+		int v_idx_best = ORIGINDEX_NONE;
 
-			/* find the vert closest to 'mval' */
-			const float mval_f[2] = {(float)mval[0],
-			                         (float)mval[1]};
-			MPoly *mp = &me->mpoly[poly_index];
-			int fidx;
-			float len_best = FLT_MAX;
+		/* find the vert closest to 'mval' */
+		const float mval_f[2] = {UNPACK2(mval)};
+		float len_best = FLT_MAX;
 
-			ED_view3d_init_mats_rv3d(ob, rv3d);
+		/* we need to be clever here
+		 * - tag all vertes from all faces that match this faces orig-index
+		 * - loop over all tagged verts and find closest
+		 */
+		MPoly *dm_mpoly;
+		MLoop *dm_mloop;
+		unsigned int dm_mpoly_tot;
+		const int *index_mp_to_orig;
 
-			fidx = mp->totloop - 1;
-			do {
-				float co[3], sco[2], len;
-				const int v_idx = me->mloop[mp->loopstart + fidx].v;
-				dm->getVertCo(dm, v_idx, co);
-				if (ED_view3d_project_float_object(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
-					len = len_manhattan_v2v2(mval_f, sco);
-					if (len < len_best) {
-						len_best = len;
-						v_idx_best = v_idx;
-					}
+		dm_mpoly = dm->getPolyArray(dm);
+		dm_mloop = dm->getLoopArray(dm);
+
+		dm_mpoly_tot = dm->getNumPolys(dm);
+
+		index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
+
+		/* tag all verts using this face */
+		if (index_mp_to_orig) {
+			unsigned int i;
+
+			for (i = 0; i < dm_mpoly_tot; i++) {
+				if (index_mp_to_orig[i] == poly_index) {
+					ed_mesh_pick_face_vert__mpoly_find(
+					        ar, mval_f,
+					        dm, &dm_mpoly[i], dm_mloop,
+					        &len_best, &v_idx_best);
 				}
-			} while (fidx--);
+			}
 		}
+		else {
+			if (poly_index < dm_mpoly_tot) {
+				ed_mesh_pick_face_vert__mpoly_find(
+				        ar, mval_f,
+				        dm, &dm_mpoly[poly_index], dm_mloop,
+				        &len_best, &v_idx_best);
+			}
+		}
 
+		/* map 'dm -> me' index if possible */
+		if (v_idx_best != ORIGINDEX_NONE) {
+			const int *index_mv_to_orig;
+
+			index_mv_to_orig = dm->getVertDataArray(dm, CD_ORIGINDEX);
+			if (index_mv_to_orig) {
+				v_idx_best = index_mv_to_orig[v_idx_best];
+			}
+		}
+
 		dm->release(dm);
 
-		if (v_idx_best != -1) {
+		if ((v_idx_best != ORIGINDEX_NONE) && (v_idx_best < me->totvert)) {
 			*index = v_idx_best;
 			return true;
 		}




More information about the Bf-blender-cvs mailing list