diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-04-16 17:27:55 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-04-16 18:56:50 +0300 |
commit | bfc9d426bb95e2bc0dd4541d6b4c5f802909149c (patch) | |
tree | 37702887bc3185309a13612613efd2752ebe0639 /source/blender/editors/mesh/editmesh_tools.c | |
parent | 80bb4254c6fb638cee0d33868c81c76c104817bf (diff) |
Multi-Object Editing
This adds initial multi-object editing support.
- Selected objects are used when entering edit & pose modes.
- Selection & tools work on all objects however many tools need porting
See: T54641 for remaining tasks.
Indentation will be done separately.
See patch: D3101
Diffstat (limited to 'source/blender/editors/mesh/editmesh_tools.c')
-rw-r--r-- | source/blender/editors/mesh/editmesh_tools.c | 129 |
1 files changed, 105 insertions, 24 deletions
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index bf70cc3fa7e..78d563c64e9 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -93,7 +93,14 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op) { - Object *obedit = CTX_data_edit_object(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + + uint objects_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len); + + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); const int cuts = RNA_int_get(op->ptr, "number_cuts"); float smooth = RNA_float_get(op->ptr, "smoothness"); @@ -116,6 +123,9 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op) RNA_int_get(op->ptr, "seed")); EDBM_update_generic(em, true, true); + } + + MEM_SAFE_FREE(objects); return OPERATOR_FINISHED; } @@ -367,16 +377,22 @@ enum { MESH_DELETE_ONLY_FACE = 4, }; -static void edbm_report_delete_info(ReportList *reports, BMesh *bm, const int totelem[3]) +static void edbm_report_delete_info(ReportList *reports, const int totelem_old[3], const int totelem_new[3]) { BKE_reportf(reports, RPT_INFO, "Removed: %d vertices, %d edges, %d faces", - totelem[0] - bm->totvert, totelem[1] - bm->totedge, totelem[2] - bm->totface); + totelem_old[0] - totelem_new[0], totelem_old[1] - totelem_new[1], totelem_old[2] - totelem_new[2]); } static int edbm_delete_exec(bContext *C, wmOperator *op) { - Object *obedit = CTX_data_edit_object(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + + uint objects_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len); + + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; BMEditMesh *em = BKE_editmesh_from_object(obedit); const int type = RNA_enum_get(op->ptr, "type"); @@ -412,6 +428,8 @@ static int edbm_delete_exec(bContext *C, wmOperator *op) EDBM_update_generic(em, true, true); + } /* objects */ + return OPERATOR_FINISHED; } @@ -467,17 +485,25 @@ static bool bm_face_is_loose(BMFace *f) static int edbm_delete_loose_exec(bContext *C, wmOperator *op) { - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BKE_editmesh_from_object(obedit); - BMesh *bm = em->bm; - BMIter iter; + ViewLayer *view_layer = CTX_data_view_layer(C); + int totelem_old_sel[3]; + int totelem_old[3]; + + uint objects_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len); + + EDBM_mesh_stats_multi(objects, objects_len, totelem_old, totelem_old_sel); - const bool use_verts = (RNA_boolean_get(op->ptr, "use_verts") && bm->totvertsel); - const bool use_edges = (RNA_boolean_get(op->ptr, "use_edges") && bm->totedgesel); - const bool use_faces = (RNA_boolean_get(op->ptr, "use_faces") && bm->totfacesel); + const bool use_verts = (RNA_boolean_get(op->ptr, "use_verts") && totelem_old_sel[0]); + const bool use_edges = (RNA_boolean_get(op->ptr, "use_edges") && totelem_old_sel[1]); + const bool use_faces = (RNA_boolean_get(op->ptr, "use_faces") && totelem_old_sel[2]); - const int totelem[3] = {bm->totvert, bm->totedge, bm->totface}; + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; + BMIter iter; BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false); @@ -520,8 +546,14 @@ static int edbm_delete_loose_exec(bContext *C, wmOperator *op) EDBM_flag_disable_all(em, BM_ELEM_SELECT); EDBM_update_generic(em, true, true); + } + + int totelem_new[3]; + EDBM_mesh_stats_multi(objects, objects_len, totelem_new, NULL); - edbm_report_delete_info(op->reports, bm, totelem); + edbm_report_delete_info(op->reports, totelem_old, totelem_new); + + MEM_SAFE_FREE(objects); return OPERATOR_FINISHED; } @@ -4096,11 +4128,18 @@ void MESH_OT_poke(wmOperatorType *ot) static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op) { - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BKE_editmesh_from_object(obedit); - BMOperator bmop; const int quad_method = RNA_enum_get(op->ptr, "quad_method"); const int ngon_method = RNA_enum_get(op->ptr, "ngon_method"); + ViewLayer *view_layer = CTX_data_view_layer(C); + + uint objects_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len); + + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMOperator bmop; BMOIter oiter; BMFace *f; @@ -4117,11 +4156,15 @@ static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op) EDBM_selectmode_flush(em); + // XXX, TODO +#if 0 if (!EDBM_op_finish(em, &bmop, op, true)) { return OPERATOR_CANCELLED; } +#endif EDBM_update_generic(em, true, true); + } return OPERATOR_FINISHED; } @@ -4155,7 +4198,22 @@ void MESH_OT_quads_convert_to_tris(wmOperatorType *ot) static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op) { - Object *obedit = CTX_data_edit_object(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + + uint objects_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len); + + bool is_face_pair; + + { + int totelem_sel[3]; + EDBM_mesh_stats_multi(objects, objects_len, NULL, totelem_sel); + is_face_pair = (totelem_sel[2] == 2); + } + + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); bool do_seam, do_sharp, do_uvs, do_vcols, do_materials; float angle_face_threshold, angle_shape_threshold; @@ -4164,7 +4222,7 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op) /* When joining exactly 2 faces, no limit. * this is useful for one off joins while editing. */ prop = RNA_struct_find_property(op->ptr, "face_threshold"); - if ((em->bm->totfacesel == 2) && + if (is_face_pair && (RNA_property_is_set(op->ptr, prop) == false)) { angle_face_threshold = DEG2RADF(180.0f); @@ -4174,7 +4232,7 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op) } prop = RNA_struct_find_property(op->ptr, "shape_threshold"); - if ((em->bm->totfacesel == 2) && + if (is_face_pair && (RNA_property_is_set(op->ptr, prop) == false)) { angle_shape_threshold = DEG2RADF(180.0f); @@ -4197,10 +4255,11 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op) BM_ELEM_SELECT, angle_face_threshold, angle_shape_threshold, do_seam, do_sharp, do_uvs, do_vcols, do_materials)) { - return OPERATOR_CANCELLED; + continue; } EDBM_update_generic(em, true, true); + } return OPERATOR_FINISHED; } @@ -4727,11 +4786,28 @@ void MESH_OT_dissolve_limited(wmOperatorType *ot) static int edbm_dissolve_degenerate_exec(bContext *C, wmOperator *op) { - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BKE_editmesh_from_object(obedit); + ViewLayer *view_layer = CTX_data_view_layer(C); + int totelem_old[3] = {0, 0, 0}; + int totelem_new[3] = {0, 0, 0}; + + uint objects_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len); + + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; + totelem_old[0] += bm->totvert; + totelem_old[1] += bm->totedge; + totelem_old[2] += bm->totface; + } /* objects */ + const float thresh = RNA_float_get(op->ptr, "threshold"); + + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; - const int totelem[3] = {bm->totvert, bm->totedge, bm->totface}; if (!EDBM_op_callf( em, op, @@ -4746,7 +4822,12 @@ static int edbm_dissolve_degenerate_exec(bContext *C, wmOperator *op) EDBM_update_generic(em, true, true); - edbm_report_delete_info(op->reports, bm, totelem); + totelem_new[0] += bm->totvert; + totelem_new[1] += bm->totedge; + totelem_new[2] += bm->totface; + } + + edbm_report_delete_info(op->reports, totelem_old, totelem_new); return OPERATOR_FINISHED; } |