From 44b634bcb1363fa600e0f9300dcaa76402b47738 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Dec 2012 06:53:39 +0000 Subject: make EDBM_index_arrays's stay in memory, blender was allocating an array and filling it for verts/edges/faces on every redraw. this may introduce bugs which I didn't catch, but they are very easy to identify in a debug build which has asserts to ensure the arrays are valid before use. in my own test drawing ~98,304 quads - this gave an overall ~16% drawing speedup. --- source/blender/blenkernel/BKE_tessmesh.h | 1 - source/blender/editors/include/ED_mesh.h | 9 +- source/blender/editors/mesh/editface.c | 7 +- source/blender/editors/mesh/editmesh_add.c | 2 +- source/blender/editors/mesh/editmesh_knife.c | 2 +- source/blender/editors/mesh/editmesh_rip.c | 2 +- source/blender/editors/mesh/editmesh_select.c | 12 +-- source/blender/editors/mesh/editmesh_slide.c | 4 +- source/blender/editors/mesh/editmesh_tools.c | 108 ++++++++++----------- source/blender/editors/mesh/editmesh_utils.c | 91 +++++++++++------ source/blender/editors/mesh/mesh_navmesh.c | 4 +- source/blender/editors/space_view3d/drawobject.c | 8 +- .../editors/space_view3d/view3d_iterators.c | 9 +- source/blender/editors/space_view3d/view3d_snap.c | 3 +- source/blender/editors/transform/transform_snap.c | 10 +- source/blender/editors/uvedit/uvedit_ops.c | 20 ++-- .../blender/editors/uvedit/uvedit_smart_stitch.c | 3 +- source/blender/editors/uvedit/uvedit_unwrap_ops.c | 4 +- 18 files changed, 156 insertions(+), 143 deletions(-) diff --git a/source/blender/blenkernel/BKE_tessmesh.h b/source/blender/blenkernel/BKE_tessmesh.h index 6967f1b2951..9462822e25f 100644 --- a/source/blender/blenkernel/BKE_tessmesh.h +++ b/source/blender/blenkernel/BKE_tessmesh.h @@ -80,7 +80,6 @@ typedef struct BMEditMesh { /*temp variables for x-mirror editing*/ int mirror_cdlayer; /* -1 is invalid */ - int mirr_free_arrays; } BMEditMesh; void BMEdit_RecalcTessellation(BMEditMesh *em); diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 06e94e0dbda..23c67f837b8 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -89,8 +89,12 @@ void EDBM_mesh_make(struct ToolSettings *ts, struct Scene *scene, struct Object void EDBM_mesh_free(struct BMEditMesh *em); void EDBM_mesh_load(struct Object *ob); +void EDBM_index_arrays_ensure(struct BMEditMesh *em, const char htype); void EDBM_index_arrays_init(struct BMEditMesh *em, const char htype); void EDBM_index_arrays_free(struct BMEditMesh *em); +#ifdef DEBUG +int EDBM_index_arrays_check(struct BMEditMesh *em); +#endif struct BMVert *EDBM_vert_at_index(struct BMEditMesh *em, int index); struct BMEdge *EDBM_edge_at_index(struct BMEditMesh *em, int index); struct BMFace *EDBM_face_at_index(struct BMEditMesh *em, int index); @@ -115,7 +119,8 @@ int EDBM_vert_color_check(struct BMEditMesh *em); void EDBM_mesh_hide(struct BMEditMesh *em, int swap); void EDBM_mesh_reveal(struct BMEditMesh *em); -void EDBM_update_generic(struct bContext *C, struct BMEditMesh *em, const short do_tessface); +void EDBM_update_generic(struct bContext *C, struct BMEditMesh *em, + const short do_tessface, const short is_destructive); struct UvElementMap *EDBM_uv_element_map_create(struct BMEditMesh *em, int selected, int doIslands); void EDBM_uv_element_map_free(struct UvElementMap *vmap); @@ -126,7 +131,7 @@ struct MTexPoly *EDBM_mtexpoly_active_get(struct BMEditMesh *em, struct BMFace * void EDBM_uv_vert_map_free(struct UvVertMap *vmap); struct UvMapVert *EDBM_uv_vert_map_at_index(struct UvVertMap *vmap, unsigned int v); -struct UvVertMap *EDBM_uv_vert_map_create(struct BMEditMesh *em, int selected, int do_face_idx_array, const float limit[2]); +struct UvVertMap *EDBM_uv_vert_map_create(struct BMEditMesh *em, int selected, const float limit[2]); void EDBM_flag_enable_all(struct BMEditMesh *em, const char hflag); void EDBM_flag_disable_all(struct BMEditMesh *em, const char hflag); diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 8c0777b2426..05f2269c359 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -852,7 +852,7 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to if (em) { if (skip_em_vert_array_init == FALSE) { - EDBM_index_arrays_init(em, BM_VERT); + EDBM_index_arrays_ensure(em, BM_VERT); } } @@ -888,11 +888,6 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to last = a; } } - if (em) { - if (skip_em_vert_array_init == FALSE) { - EDBM_index_arrays_free(em); - } - } MEM_freeN(topo_pairs); topo_pairs = NULL; diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 763c6c98a99..94ff32c5aed 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -90,7 +90,7 @@ static void make_prim_finish(bContext *C, Object *obedit, int *state, int enter_ EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX); /* only recalc editmode tessface if we are staying in editmode */ - EDBM_update_generic(C, em, !exit_editmode); + EDBM_update_generic(C, em, !exit_editmode, TRUE); /* userdef */ if (exit_editmode) { diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index b7b71be0df9..31415cf98d2 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -2841,7 +2841,7 @@ static void knifetool_finish(bContext *C, wmOperator *op) #endif EDBM_mesh_normals_update(kcd->em); - EDBM_update_generic(C, kcd->em, TRUE); + EDBM_update_generic(C, kcd->em, TRUE, TRUE); } /* copied from paint_image.c */ diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 9b8f90bc7cf..01a2579520a 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -1044,7 +1044,7 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index a98345cacec..e3f918b66c9 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -725,7 +725,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -767,7 +767,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -812,7 +812,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) EDBM_selectmode_flush(em); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -1487,7 +1487,7 @@ static int mouse_mesh_shortest_path_edge(bContext *C, ViewContext *vc) break; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); return TRUE; } @@ -1678,7 +1678,7 @@ static int mouse_mesh_shortest_path_face(bContext *C, ViewContext *vc) BM_active_face_set(em->bm, f_dst); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); return TRUE; } @@ -2635,7 +2635,7 @@ static int edbm_select_nth_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c index 4fbe9c2534f..d5ca2e928da 100644 --- a/source/blender/editors/mesh/editmesh_slide.c +++ b/source/blender/editors/mesh/editmesh_slide.c @@ -264,7 +264,7 @@ static void vtx_slide_confirm(bContext *C, wmOperator *op) EDBM_selectmode_flush(em); /* NC_GEOM | ND_DATA & Retess */ - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); ED_region_tag_redraw(vso->active_region); } @@ -752,7 +752,7 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u if (do_update) { /* Update Geometry */ - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); } return OPERATOR_FINISHED; diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index ad1077156ba..41d5cedbc2c 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -112,7 +112,7 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op) RNA_boolean_get(op->ptr, "quadtri"), TRUE, FALSE, RNA_int_get(op->ptr, "seed")); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -181,7 +181,7 @@ static int edbm_unsubdivide_exec(bContext *C, wmOperator *op) } EDBM_selectmode_flush(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -463,7 +463,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op) EDBM_mesh_normals_update(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -585,7 +585,7 @@ static int edbm_extrude_region_exec(bContext *C, wmOperator *op) * done.*/ EDBM_mesh_normals_update(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -678,7 +678,7 @@ static int edbm_extrude_faces_exec(bContext *C, wmOperator *op) edbm_extrude_discrete_faces(em, op, BM_ELEM_SELECT, nor); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -936,7 +936,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent * done. */ EDBM_mesh_normals_update(vc.em); - EDBM_update_generic(C, vc.em, TRUE); + EDBM_update_generic(C, vc.em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1001,7 +1001,7 @@ static int edbm_delete_exec(bContext *C, wmOperator *op) EDBM_flag_disable_all(em, BM_ELEM_SELECT); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1034,7 +1034,7 @@ static int edbm_collapse_edge_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "collapse edges=%he", BM_ELEM_SELECT)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1062,7 +1062,7 @@ static int edbm_collapse_edge_loop_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "dissolve_edge_loop edges=%he", BM_ELEM_SELECT)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1121,7 +1121,7 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1176,7 +1176,7 @@ static int edbm_mark_seam(bContext *C, wmOperator *op) } ED_uvedit_live_unwrap(scene, obedit); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1230,7 +1230,7 @@ static int edbm_mark_sharp(bContext *C, wmOperator *op) } } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1272,7 +1272,7 @@ static int edbm_vert_connect(bContext *C, wmOperator *op) else { EDBM_selectmode_flush(em); /* so newly created edges get the selection state from the vertex */ - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } @@ -1310,7 +1310,7 @@ static int edbm_edge_split_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } @@ -1349,7 +1349,7 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1388,7 +1388,7 @@ static int edbm_flip_normals_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "reverse_faces faces=%hf", BM_ELEM_SELECT)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1469,7 +1469,7 @@ static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1500,7 +1500,7 @@ static int edbm_hide_exec(bContext *C, wmOperator *op) EDBM_mesh_hide(em, RNA_boolean_get(op->ptr, "unselected")); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1530,7 +1530,7 @@ static int edbm_reveal_exec(bContext *C, wmOperator *UNUSED(op)) EDBM_mesh_reveal(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1563,7 +1563,7 @@ static int edbm_normals_make_consistent_exec(bContext *C, wmOperator *op) if (RNA_boolean_get(op->ptr, "inside")) EDBM_op_callf(em, op, "reverse_faces faces=%hf", BM_ELEM_SELECT); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1645,7 +1645,7 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op) EDBM_verts_mirror_cache_end(em); } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1721,7 +1721,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op) EDBM_verts_mirror_cache_end(em); } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1775,7 +1775,7 @@ static int edbm_faces_shade_smooth_exec(bContext *C, wmOperator *UNUSED(op)) mesh_set_smooth_faces(em, 1); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); return OPERATOR_FINISHED; } @@ -1802,7 +1802,7 @@ static int edbm_faces_shade_flat_exec(bContext *C, wmOperator *UNUSED(op)) mesh_set_smooth_faces(em, 0); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); return OPERATOR_FINISHED; } @@ -1845,7 +1845,7 @@ static int edbm_rotate_uvs_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -1868,7 +1868,7 @@ static int edbm_reverse_uvs_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -1895,7 +1895,7 @@ static int edbm_rotate_colors_exec(bContext *C, wmOperator *op) } /* dependencies graph and notification stuff */ - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -1919,7 +1919,7 @@ static int edbm_reverse_colors_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -2104,7 +2104,7 @@ static int edbm_merge_exec(bContext *C, wmOperator *op) if (!status) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -2221,7 +2221,7 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op) count = totvert_orig - em->bm->totvert; BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", count); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -2328,7 +2328,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op) EDBM_selectmode_flush(em); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -2403,7 +2403,7 @@ static int edbm_shape_propagate_to_all_exec(bContext *C, wmOperator *op) shape_propagate(em, op); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); return OPERATOR_FINISHED; } @@ -2474,7 +2474,7 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op) } } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -2665,7 +2665,7 @@ static int edbm_solidify_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -2990,7 +2990,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3232,7 +3232,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op) else BLI_assert(0); if (retval) { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); } } else { @@ -3332,7 +3332,7 @@ static int edbm_fill_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; @@ -3361,7 +3361,7 @@ static int edbm_beautify_fill_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "beautify_fill faces=%hf", BM_ELEM_SELECT)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3392,7 +3392,7 @@ static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "triangulate faces=%hf use_beauty=%b", BM_ELEM_SELECT, use_beauty)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3433,7 +3433,7 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3489,7 +3489,7 @@ static int edbm_dissolve_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3561,7 +3561,7 @@ static int edbm_dissolve_limited_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3606,7 +3606,7 @@ static int edbm_split_exec(bContext *C, wmOperator *op) /* Geometry has changed, need to recalc normals and looptris */ EDBM_mesh_normals_update(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3665,7 +3665,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3788,7 +3788,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -4603,7 +4603,7 @@ static int edbm_noise_exec(bContext *C, wmOperator *op) EDBM_mesh_normals_update(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -4827,7 +4827,7 @@ static int edbm_bevel_calc(bContext *C, wmOperator *op) EDBM_mesh_normals_update(opdata->em); - EDBM_update_generic(C, opdata->em, TRUE); + EDBM_update_generic(C, opdata->em, TRUE, TRUE); return 1; } @@ -4859,7 +4859,7 @@ static int edbm_bevel_cancel(bContext *C, wmOperator *op) BevelData *opdata = op->customdata; if (opdata->is_modal) { EDBM_redo_state_free(&opdata->mesh_backup, opdata->em, TRUE); - EDBM_update_generic(C, opdata->em, FALSE); + EDBM_update_generic(C, opdata->em, FALSE, TRUE); } edbm_bevel_exit(C, op); @@ -5140,7 +5140,7 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op) } else { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } } @@ -5263,7 +5263,7 @@ static int edbm_inset_cancel(bContext *C, wmOperator *op) opdata = op->customdata; if (opdata->is_modal) { EDBM_redo_state_free(&opdata->backup, opdata->em, TRUE); - EDBM_update_generic(C, opdata->em, FALSE); + EDBM_update_generic(C, opdata->em, FALSE, TRUE); } edbm_inset_exit(C, op); @@ -5318,7 +5318,7 @@ static int edbm_inset_calc(bContext *C, wmOperator *op) return 0; } else { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return 1; } } @@ -5581,7 +5581,7 @@ static int edbm_wireframe_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } } @@ -5671,7 +5671,7 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); EDBM_selectmode_flush(em); return OPERATOR_FINISHED; } @@ -5726,7 +5726,7 @@ static int mesh_symmetrize_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); EDBM_selectmode_flush(em); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 7259559603a..61bce9f8d1e 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -391,11 +391,13 @@ void EDBM_mesh_free(BMEditMesh *em) BMEdit_Free(em); } -void EDBM_index_arrays_init(BMEditMesh *em, const char htype) + +void EDBM_index_arrays_ensure(BMEditMesh *em, const char htype) { BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); - EDBM_index_arrays_free(em); + /* in debug mode double check we didn't need to recalculate */ + BLI_assert(EDBM_index_arrays_check(em) == TRUE); if (htype & BM_VERT) { em->vert_index = MEM_mallocN(sizeof(void **) * em->bm->totvert, "em->vert_index"); @@ -430,6 +432,16 @@ void EDBM_index_arrays_init(BMEditMesh *em, const char htype) } } +/* use EDBM_index_arrays_ensure where possible to avoid full rebuild */ +void EDBM_index_arrays_init(BMEditMesh *em, const char htype) +{ + BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); + + /* force recalc */ + EDBM_index_arrays_free(em); + EDBM_index_arrays_ensure(em, htype); +} + void EDBM_index_arrays_free(BMEditMesh *em) { if (em->vert_index) { @@ -448,6 +460,42 @@ void EDBM_index_arrays_free(BMEditMesh *em) } } +/* debug check only - no need to optimize */ +#ifdef DEBUG +int EDBM_index_arrays_check(BMEditMesh *em) +{ + BMIter iter; + BMElem *ele; + int i; + + if (em->vert_index) { + BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_VERTS_OF_MESH, i) { + if (ele != (BMElem *)em->vert_index[i]) { + return FALSE; + } + } + } + + if (em->edge_index) { + BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_EDGES_OF_MESH, i) { + if (ele != (BMElem *)em->edge_index[i]) { + return FALSE; + } + } + } + + if (em->face_index) { + BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_FACES_OF_MESH, i) { + if (ele != (BMElem *)em->face_index[i]) { + return FALSE; + } + } + } + + return TRUE; +} +#endif + BMVert *EDBM_vert_at_index(BMEditMesh *em, int index) { return em->vert_index && index < em->bm->totvert ? em->vert_index[index] : NULL; @@ -634,7 +682,7 @@ void undo_push_mesh(bContext *C, const char *name) } /* write comment here */ -UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx_array, const float limit[2]) +UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, const float limit[2]) { BMVert *ev; BMFace *efa; @@ -647,11 +695,8 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx MLoopUV *luv; unsigned int a; int totverts, i, totuv; - - if (do_face_idx_array) - EDBM_index_arrays_init(em, BM_FACE); - BM_mesh_elem_index_ensure(em->bm, BM_VERT); + BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); totverts = em->bm->totvert; totuv = 0; @@ -663,14 +708,10 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx } if (totuv == 0) { - if (do_face_idx_array) - EDBM_index_arrays_free(em); return NULL; } vmap = (UvVertMap *)MEM_callocN(sizeof(*vmap), "UvVertMap"); if (!vmap) { - if (do_face_idx_array) - EDBM_index_arrays_free(em); return NULL; } @@ -679,8 +720,6 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx if (!vmap->vert || !vmap->buf) { BKE_mesh_uv_vert_map_free(vmap); - if (do_face_idx_array) - EDBM_index_arrays_free(em); return NULL; } @@ -757,10 +796,7 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx vmap->vert[a] = newvlist; a++; } - - if (do_face_idx_array) - EDBM_index_arrays_free(em); - + return vmap; } @@ -1105,10 +1141,7 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const short use_select) topo = 1; } - if (!em->vert_index) { - EDBM_index_arrays_init(em, BM_VERT); - em->mirr_free_arrays = 1; - } + EDBM_index_arrays_ensure(em, BM_VERT); if (!CustomData_get_layer_named(&bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID)) { BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID); @@ -1200,11 +1233,6 @@ void EDBM_verts_mirror_cache_clear(BMEditMesh *em, BMVert *v) void EDBM_verts_mirror_cache_end(BMEditMesh *em) { - if (em->mirr_free_arrays) { - MEM_freeN(em->vert_index); - em->vert_index = NULL; - } - em->mirror_cdlayer = -1; } @@ -1309,7 +1337,8 @@ void EDBM_mesh_reveal(BMEditMesh *em) /* so many tools call these that we better make it a generic function. */ -void EDBM_update_generic(bContext *C, BMEditMesh *em, const short do_tessface) +void EDBM_update_generic(bContext *C, BMEditMesh *em, + const short do_tessface, const short is_destructive) { Object *ob = em->ob; /* order of calling isn't important */ @@ -1319,4 +1348,12 @@ void EDBM_update_generic(bContext *C, BMEditMesh *em, const short do_tessface) if (do_tessface) { BMEdit_RecalcTessellation(em); } + + if (is_destructive) { + EDBM_index_arrays_free(em); + } + else { + /* in debug mode double check we didn't need to recalculate */ + BLI_assert(EDBM_index_arrays_check(em) == TRUE); + } } diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c index bae2c6cde9d..21564d2d348 100644 --- a/source/blender/editors/mesh/mesh_navmesh.c +++ b/source/blender/editors/mesh/mesh_navmesh.c @@ -375,7 +375,7 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh, BM_vert_create(em->bm, co, NULL, 0); } - EDBM_index_arrays_init(em, BM_VERT); + EDBM_index_arrays_ensure(em, BM_VERT); /* create faces */ for (j = 0; j < trinum; j++) { @@ -399,8 +399,6 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh, polygonIdx = (int *)CustomData_bmesh_get(&em->bm->pdata, newFace->head.data, CD_RECAST); *polygonIdx = i + 1; /* add 1 to avoid zero idx */ } - - EDBM_index_arrays_free(em); } recast_destroyPolyMesh(pmesh); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 75fe1e27bf5..780b7426d51 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2838,7 +2838,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, } } - EDBM_index_arrays_init(em, BM_VERT | BM_EDGE | BM_FACE); + EDBM_index_arrays_ensure(em, BM_VERT | BM_EDGE | BM_FACE); if (dt > OB_WIRE) { if (check_object_draw_texture(scene, v3d, dt)) { @@ -2989,8 +2989,6 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, bglPolygonOffset(rv3d->dist, 0.0); GPU_disable_material(); } - - EDBM_index_arrays_free(em); } /* Mesh drawing routines */ @@ -7123,7 +7121,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec DerivedMesh *dm = editbmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH); - EDBM_index_arrays_init(em, BM_VERT | BM_EDGE | BM_FACE); + EDBM_index_arrays_ensure(em, BM_VERT | BM_EDGE | BM_FACE); bbs_mesh_solid_EM(em, scene, v3d, ob, dm, ts->selectmode & SCE_SELECT_FACE); if (ts->selectmode & SCE_SELECT_FACE) @@ -7149,8 +7147,6 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec bglPolygonOffset(rv3d->dist, 0.0); dm->release(dm); - - EDBM_index_arrays_free(em); } else { Mesh *me = ob->data; diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c index 04d47e6cf5d..a0b36e57d69 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.c +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -113,9 +113,8 @@ void mesh_foreachScreenVert( ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ } - EDBM_index_arrays_init(vc->em, BM_VERT); + EDBM_index_arrays_ensure(vc->em, BM_VERT); dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data); - EDBM_index_arrays_free(vc->em); dm->release(dm); } @@ -172,9 +171,8 @@ void mesh_foreachScreenEdge( ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ } - EDBM_index_arrays_init(vc->em, BM_EDGE); + EDBM_index_arrays_ensure(vc->em, BM_EDGE); dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data); - EDBM_index_arrays_free(vc->em); dm->release(dm); } @@ -209,9 +207,8 @@ void mesh_foreachScreenFace( ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - EDBM_index_arrays_init(vc->em, BM_FACE); + EDBM_index_arrays_ensure(vc->em, BM_FACE); dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data); - EDBM_index_arrays_free(vc->em); dm->release(dm); } diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index e60eed42770..f570ec38ae3 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -340,9 +340,8 @@ static void make_trans_verts(Object *obedit, float min[3], float max[3], int mod } if (transvmain && em->derivedCage) { - EDBM_index_arrays_init(em, BM_VERT); + EDBM_index_arrays_ensure(em, BM_VERT); em->derivedCage->foreachMappedVert(em->derivedCage, set_mapped_co, userdata); - EDBM_index_arrays_free(em); } } else if (obedit->type == OB_ARMATURE) { diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index b1e48448fac..5577619901a 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1417,7 +1417,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh if (em != NULL) { index_array = dm->getVertDataArray(dm, CD_ORIGINDEX); - EDBM_index_arrays_init(em, BM_VERT); + EDBM_index_arrays_ensure(em, BM_VERT); } for (i = 0; i < totvert; i++) { @@ -1452,9 +1452,6 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh } } - if (em != NULL) { - EDBM_index_arrays_free(em); - } break; } case SCE_SNAP_MODE_EDGE: @@ -1468,7 +1465,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh if (em != NULL) { index_array = dm->getEdgeDataArray(dm, CD_ORIGINDEX); - EDBM_index_arrays_init(em, BM_EDGE); + EDBM_index_arrays_ensure(em, BM_EDGE); } for (i = 0; i < totedge; i++) { @@ -1505,9 +1502,6 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh } } - if (em != NULL) { - EDBM_index_arrays_free(em); - } break; } } diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 46b7db32334..4336eb02752 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -999,8 +999,8 @@ static int select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit int a, looking, nverts, starttotf, select; /* setup */ - EDBM_index_arrays_init(em, BM_FACE); - vmap = EDBM_uv_vert_map_create(em, 0, 0, limit); + EDBM_index_arrays_ensure(em, BM_FACE); + vmap = EDBM_uv_vert_map_create(em, 0, limit); BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); @@ -1091,7 +1091,6 @@ static int select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit /* cleanup */ EDBM_uv_vert_map_free(vmap); - EDBM_index_arrays_free(em); return (select) ? 1 : -1; } @@ -1111,8 +1110,8 @@ static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float unsigned int a; char *flag; - EDBM_index_arrays_init(em, BM_FACE); /* we can use this too */ - vmap = EDBM_uv_vert_map_create(em, 1, 1, limit); + EDBM_index_arrays_ensure(em, BM_FACE); /* we can use this too */ + vmap = EDBM_uv_vert_map_create(em, 1, limit); if (vmap == NULL) return; @@ -1270,7 +1269,6 @@ static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float MEM_freeN(stack); MEM_freeN(flag); EDBM_uv_vert_map_free(vmap); - EDBM_index_arrays_free(em); } /* WATCH IT: this returns first selected UV, @@ -2608,8 +2606,8 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s uvedit_pixel_to_float(sima, limit, 0.05); - EDBM_index_arrays_init(em, BM_FACE); - vmap = EDBM_uv_vert_map_create(em, 0, 0, limit); + EDBM_index_arrays_ensure(em, BM_FACE); + vmap = EDBM_uv_vert_map_create(em, 0, limit); /* verts are numbered above in make_uv_vert_map_EM, make sure this stays true! */ if (vmap == NULL) { @@ -2662,7 +2660,6 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s } } } - EDBM_index_arrays_free(em); EDBM_uv_vert_map_free(vmap); } @@ -3795,8 +3792,8 @@ static int seams_from_islands_exec(bContext *C, wmOperator *op) } /* This code sets editvert->tmp.l to the index. This will be useful later on. */ - EDBM_index_arrays_init(em, BM_FACE); - vmap = EDBM_uv_vert_map_create(em, 0, 0, limit); + EDBM_index_arrays_ensure(em, BM_FACE); + vmap = EDBM_uv_vert_map_create(em, 0, limit); BM_ITER_MESH (editedge, &iter, bm, BM_EDGES_OF_MESH) { /* flags to determine if we uv is separated from first editface match */ @@ -3875,7 +3872,6 @@ static int seams_from_islands_exec(bContext *C, wmOperator *op) me->drawflag |= ME_DRAWSEAMS; EDBM_uv_vert_map_free(vmap); - EDBM_index_arrays_free(em); DAG_id_tag_update(&me->id, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index b67747ead5a..9c99eb196c2 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1256,7 +1256,7 @@ static int stitch_init(bContext *C, wmOperator *op) int faceIndex, elementIndex; UvElement *element; - EDBM_index_arrays_init(em, BM_FACE); + EDBM_index_arrays_ensure(em, BM_FACE); RNA_BEGIN (op->ptr, itemptr, "selection") { @@ -1268,7 +1268,6 @@ static int stitch_init(bContext *C, wmOperator *op) } RNA_END; - EDBM_index_arrays_free(em); /* Clear the selection */ RNA_collection_clear(op->ptr, "selection"); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 6ef680f368d..6c385527977 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -434,7 +434,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B faceMap = MEM_mallocN(numOfFaces * sizeof(BMFace *), "unwrap_edit_face_map"); BM_mesh_elem_index_ensure(em->bm, BM_VERT); - EDBM_index_arrays_init(em, BM_EDGE | BM_FACE); + EDBM_index_arrays_ensure(em, BM_EDGE | BM_FACE); /* map subsurfed faces to original editFaces */ for (i = 0; i < numOfFaces; i++) @@ -449,8 +449,6 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B EDBM_edge_at_index(em, origEdgeIndices[i]) : NULL; } - EDBM_index_arrays_free(em); - /* Prepare and feed faces to the solver */ for (i = 0; i < numOfFaces; i++) { ParamKey key, vkeys[4]; -- cgit v1.2.3