[Bf-blender-cvs] [87dc01e] master: Fix T43806: Knife project crashes

Campbell Barton noreply at git.blender.org
Thu Feb 26 23:53:47 CET 2015


Commit: 87dc01e690d12b1cf50aa274c59d584e355f3c86
Author: Campbell Barton
Date:   Fri Feb 27 09:46:56 2015 +1100
Branches: master
https://developer.blender.org/rB87dc01e690d12b1cf50aa274c59d584e355f3c86

Fix T43806: Knife project crashes

Need to re-create the bmbvh after executing the cut.

===================================================================

M	source/blender/editors/mesh/editmesh_knife.c

===================================================================

diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index e8a5202..b6b5dfd 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -158,6 +158,7 @@ typedef struct KnifeTool_OpData {
 	float mval[2];      /* mouse value with snapping applied */
 	//bContext *C;
 
+	Scene *scene;
 	Object *ob;
 	BMEditMesh *em;
 
@@ -242,6 +243,8 @@ static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2],
 
 static bool knife_verts_edge_in_face(KnifeVert *v1, KnifeVert *v2, BMFace *f);
 
+static void knifetool_free_bmbvh(KnifeTool_OpData *kcd);
+
 static void knife_update_header(bContext *C, KnifeTool_OpData *kcd)
 {
 #define HEADER_LENGTH 256
@@ -2776,6 +2779,9 @@ static void knifetool_finish_ex(KnifeTool_OpData *kcd)
 	EDBM_selectmode_flush(kcd->em);
 	EDBM_mesh_normals_update(kcd->em);
 	EDBM_update_generic(kcd->em, true, true);
+
+	/* re-tessellating makes this invalid, dont use again by accident */
+	knifetool_free_bmbvh(kcd);
 }
 static void knifetool_finish(wmOperator *op)
 {
@@ -2820,14 +2826,12 @@ static void knifetool_exit_ex(bContext *C, KnifeTool_OpData *kcd)
 	BLI_ghash_free(kcd->kedgefacemap, NULL, NULL);
 	BLI_ghash_free(kcd->facetrimap, NULL, NULL);
 
-	BKE_bmbvh_free(kcd->bmbvh);
 	BLI_memarena_free(kcd->arena);
 
 	/* tag for redraw */
 	ED_region_tag_redraw(kcd->ar);
 
-	if (kcd->cagecos)
-		MEM_freeN((void *)kcd->cagecos);
+	knifetool_free_bmbvh(kcd);
 
 	if (kcd->linehits)
 		MEM_freeN(kcd->linehits);
@@ -2858,6 +2862,29 @@ static void knifetool_update_mval_i(KnifeTool_OpData *kcd, const int mval_i[2])
 	knifetool_update_mval(kcd, mval);
 }
 
+static void knifetool_init_bmbvh(KnifeTool_OpData *kcd)
+{
+	BM_mesh_elem_index_ensure(kcd->em->bm, BM_VERT);
+
+	kcd->cagecos = (const float (*)[3])BKE_editmesh_vertexCos_get(kcd->em, kcd->scene, NULL);
+
+	kcd->bmbvh = BKE_bmbvh_new_from_editmesh(
+	        kcd->em,
+	        BMBVH_RETURN_ORIG |
+	        ((kcd->only_select && kcd->cut_through) ? BMBVH_RESPECT_SELECT : BMBVH_RESPECT_HIDDEN),
+	        kcd->cagecos, false);
+}
+
+static void knifetool_free_bmbvh(KnifeTool_OpData *kcd)
+{
+	if (kcd->bmbvh) {
+		BKE_bmbvh_free(kcd->bmbvh);
+		kcd->bmbvh = NULL;
+	}
+
+	MEM_SAFE_FREE(kcd->cagecos);
+}
+
 /* called when modal loop selection gets set up... */
 static void knifetool_init(bContext *C, KnifeTool_OpData *kcd,
                            const bool only_select, const bool cut_through, const bool is_interactive)
@@ -2866,6 +2893,7 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd,
 	Object *obedit = CTX_data_edit_object(C);
 
 	/* assign the drawing handle for drawing preview line... */
+	kcd->scene = scene;
 	kcd->ob = obedit;
 	kcd->ar = CTX_wm_region(C);
 
@@ -2873,15 +2901,12 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd,
 
 	kcd->em = BKE_editmesh_from_object(kcd->ob);
 
-	BM_mesh_elem_index_ensure(kcd->em->bm, BM_VERT);
+	/* cut all the way through the mesh if use_occlude_geometry button not pushed */
+	kcd->is_interactive = is_interactive;
+	kcd->cut_through = cut_through;
+	kcd->only_select = only_select;
 
-	kcd->cagecos = (const float (*)[3])BKE_editmesh_vertexCos_get(kcd->em, scene, NULL);
-
-	kcd->bmbvh = BKE_bmbvh_new_from_editmesh(
-	        kcd->em,
-	        BMBVH_RETURN_ORIG |
-	        ((only_select && cut_through) ? BMBVH_RESPECT_SELECT : BMBVH_RESPECT_HIDDEN),
-	        kcd->cagecos, false);
+	knifetool_init_bmbvh(kcd);
 
 	kcd->arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 15), "knife");
 	kcd->vthresh = KMAXDIST - 1;
@@ -2900,11 +2925,6 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd,
 	kcd->kedgefacemap = BLI_ghash_ptr_new("knife kedgefacemap");
 	kcd->facetrimap = BLI_ghash_ptr_new("knife facetrimap");
 
-	/* cut all the way through the mesh if use_occlude_geometry button not pushed */
-	kcd->is_interactive = is_interactive;
-	kcd->cut_through = cut_through;
-	kcd->only_select = only_select;
-
 	/* can't usefully select resulting edges in face mode */
 	kcd->select_result = (kcd->em->selectmode != SCE_SELECT_FACE);
 
@@ -3362,6 +3382,11 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
 
 			bool keep_search;
 
+			/* freed on knifetool_finish_ex, but we need again to check if points are visible */
+			if (kcd->cut_through == false) {
+				knifetool_init_bmbvh(kcd);
+			}
+
 			ED_view3d_ob_project_mat_get(kcd->ar->regiondata, kcd->ob, projmat);
 
 			/* use face-loop tag to store if we have intersected */




More information about the Bf-blender-cvs mailing list