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:
authorCampbell Barton <ideasman42@gmail.com>2015-02-27 01:46:56 +0300
committerCampbell Barton <ideasman42@gmail.com>2015-02-27 01:53:23 +0300
commit87dc01e690d12b1cf50aa274c59d584e355f3c86 (patch)
tree005f372a67c525f9fe0d6ee871f65804efbf6dde /source/blender/editors/mesh/editmesh_knife.c
parent90cc2643e9903bb324502c1ba5d24e13fc5e4469 (diff)
Fix T43806: Knife project crashes
Need to re-create the bmbvh after executing the cut.
Diffstat (limited to 'source/blender/editors/mesh/editmesh_knife.c')
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c57
1 files changed, 41 insertions, 16 deletions
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index e8a5202029b..b6b5dfd0d93 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 */