diff options
author | Joseph Eagar <joeedh@gmail.com> | 2009-09-01 03:07:05 +0400 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2009-09-01 03:07:05 +0400 |
commit | c91e8e6ca15436fd39c66dbf512344c47012b0a3 (patch) | |
tree | f098138649797725a9927020f2f56f62375b4cdd /source/blender | |
parent | 4c849249bccb03562223aac15083553e177ddb83 (diff) |
finished bmeshafying merge, though probably needs further testing and debugging. also fixed nasty bug in DM_to_mesh.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 2 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_opdefines.c | 31 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_operators_private.h | 3 | ||||
-rw-r--r-- | source/blender/bmesh/operators/removedoubles.c | 113 | ||||
-rw-r--r-- | source/blender/editors/mesh/bmesh_tools.c | 177 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_tools.c | 158 |
6 files changed, 319 insertions, 165 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index d1a20c6a3c8..401cfba2fbd 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -406,6 +406,8 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me) totloop += iter->len; } iter->free(iter); + + tmp.totloop = totloop; CustomData_copy(&dm->vertData, &tmp.vdata, CD_MASK_MESH, CD_DUPLICATE, totvert); CustomData_copy(&dm->edgeData, &tmp.edata, CD_MASK_MESH, CD_DUPLICATE, totedge); diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index b8e8e86ffaa..35d69fbe9cd 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -238,6 +238,35 @@ BMOpDefine def_collapse = { /* + Facedata point Merge + + Merge uv/vcols at a specific vertex. +*/ +BMOpDefine def_pointmerge_facedata = { + "pointmerge_facedata", + {{BMOP_OPSLOT_ELEMENT_BUF, "verts"}, /*input vertices*/ + {BMOP_OPSLOT_ELEMENT_BUF, "snapv"}, /*snap vertex*/ + {0, /*null-terminating sentinel*/}}, + bmesh_pointmerge_facedata_exec, + 0, +}; + +/* + Average Vertices Facevert Data + + Merge uv/vcols associated with the input vertices at + the bounding box center. (I know, it's not averaging but + the vert_snap_to_bb_center is just too long). +*/ +BMOpDefine def_vert_average_facedata = { + "vert_average_facedata", + {{BMOP_OPSLOT_ELEMENT_BUF, "verts"}, /*input vertices*/ + {0, /*null-terminating sentinel*/}}, + bmesh_vert_average_facedata_exec, + 0, +}; + +/* Point Merge Merge verts together at a point. @@ -704,6 +733,8 @@ BMOpDefine *opdefines[] = { &def_similarfaces, &def_similaredges, &def_similarverts, + &def_pointmerge_facedata, + &def_vert_average_facedata, }; int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*)); diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h index f8e0685fa15..f99a2322bd8 100644 --- a/source/blender/bmesh/intern/bmesh_operators_private.h +++ b/source/blender/bmesh/intern/bmesh_operators_private.h @@ -49,4 +49,7 @@ void bmesh_collapse_exec(BMesh *bm, BMOperator *op); void bmesh_similarfaces_exec(BMesh *bm, BMOperator *op); void bmesh_similaredges_exec(BMesh *bm, BMOperator *op); void bmesh_similarverts_exec(BMesh *bm, BMOperator *op); +void bmesh_pointmerge_facedata_exec(BMesh *bm, BMOperator *op); +void bmesh_vert_average_facedata_exec(BMesh *bm, BMOperator *op); + #endif diff --git a/source/blender/bmesh/operators/removedoubles.c b/source/blender/bmesh/operators/removedoubles.c index 12f652ce964..24d57b6b1fd 100644 --- a/source/blender/bmesh/operators/removedoubles.c +++ b/source/blender/bmesh/operators/removedoubles.c @@ -213,17 +213,120 @@ static int vergaverco(const void *e1, const void *e2) #define EDGE_MARK 1 +void bmesh_pointmerge_facedata_exec(BMesh *bm, BMOperator *op) +{ + BMOIter siter; + BMIter iter; + BMVert *v, *snapv; + BMLoop *l, *firstl = NULL; + float fac; + int i, tot; + + snapv = BMO_IterNew(&siter, bm, op, "snapv", BM_VERT); + tot = BM_Vert_FaceCount(snapv); + + if (!tot) + return; + + fac = 1.0f / tot; + BM_ITER(l, &iter, bm, BM_LOOPS_OF_VERT, snapv) { + if (!firstl) { + firstl = l; + } + + for (i=0; i<bm->ldata.totlayer; i++) { + if (CustomData_layer_has_math(&bm->ldata, i)) { + int type = bm->ldata.layers[i].type; + void *e1, *e2; + + e1 = CustomData_bmesh_get_layer_n(&bm->ldata, firstl->head.data, i); + e2 = CustomData_bmesh_get_layer_n(&bm->ldata, l->head.data, i); + + CustomData_data_multiply(type, e2, fac); + + if (l != firstl) + CustomData_data_add(type, e1, e2); + } + } + } + + BMO_ITER(v, &siter, bm, op, "verts", BM_VERT) { + BM_ITER(l, &iter, bm, BM_LOOPS_OF_VERT, v) { + if (l == firstl) + continue; + + CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, firstl->head.data, &l->head.data); + } + } +} + +void bmesh_vert_average_facedata_exec(BMesh *bm, BMOperator *op) +{ + BMOIter siter; + BMIter iter; + BMVert *v; + BMLoop *l, *firstl = NULL; + CDBlockBytes min, max; + void *block; + int i, type; + + for (i=0; i<bm->ldata.totlayer; i++) { + if (!CustomData_layer_has_math(&bm->ldata, i)) + continue; + + type = bm->ldata.layers[i].type; + CustomData_data_initminmax(type, &min, &max); + + BMO_ITER(v, &siter, bm, op, "verts", BM_VERT) { + BM_ITER(l, &iter, bm, BM_LOOPS_OF_VERT, v) { + block = CustomData_bmesh_get_layer_n(&bm->ldata, l->head.data, i); + CustomData_data_dominmax(type, block, &min, &max); + } + } + + CustomData_data_multiply(type, &min, 0.5f); + CustomData_data_multiply(type, &max, 0.5f); + CustomData_data_add(type, &min, &max); + + BMO_ITER(v, &siter, bm, op, "verts", BM_VERT) { + BM_ITER(l, &iter, bm, BM_LOOPS_OF_VERT, v) { + block = CustomData_bmesh_get_layer_n(&bm->ldata, l->head.data, i); + CustomData_data_copy_value(type, &min, block); + } + } + } +} + void bmesh_pointmerge_exec(BMesh *bm, BMOperator *op) { + BMOperator weldop; + BMOIter siter; + BMVert *v, *snapv = NULL; + float vec[3]; + + BMO_Get_Vec(op, "mergeco", vec); + + //BMO_CallOpf(bm, "collapse_uvs edges=%s", op, "edges"); + BMO_Init_Op(&weldop, "weldverts"); + + BMO_ITER(v, &siter, bm, op, "verts", BM_VERT) { + if (!snapv) { + snapv = v; + VECCOPY(snapv->co, vec); + } else { + BMO_Insert_MapPointer(bm, &weldop, "targetmap", v, snapv); + } + } + + BMO_Exec_Op(bm, &weldop); + BMO_Finish_Op(bm, &weldop); } void bmesh_collapse_exec(BMesh *bm, BMOperator *op) { BMOperator weldop; BMWalker walker; - BMOIter siter; - BMIter iter, liter, liter2; - BMVert *v; + BMIter iter; BMEdge *e, **edges = NULL; V_DECLARE(edges); float min[3], max[3]; @@ -276,11 +379,9 @@ void bmesh_collapse_exec(BMesh *bm, BMOperator *op) /*uv collapse function*/ void bmesh_collapsecon_do_layer(BMesh *bm, BMOperator *op, int layer) { - BMIter iter, liter, liter2; + BMIter iter, liter; BMFace *f; BMLoop *l, *l2; - BMEdge *e; - BMVert *v; BMWalker walker; void **blocks = NULL; V_DECLARE(blocks); diff --git a/source/blender/editors/mesh/bmesh_tools.c b/source/blender/editors/mesh/bmesh_tools.c index 4f8c55e3119..59ff6b389ba 100644 --- a/source/blender/editors/mesh/bmesh_tools.c +++ b/source/blender/editors/mesh/bmesh_tools.c @@ -1632,7 +1632,6 @@ static int edge_rotate_selected(bContext *C, wmOperator *op) Object *obedit= CTX_data_edit_object(C); BMEditMesh *em= ((Mesh *)obedit->data)->edit_btmesh; BMOperator bmop; - BMOIter siter; BMEdge *eed; BMIter iter; int ccw = RNA_int_get(op->ptr, "direction") == 1; // direction == 2 when clockwise and ==1 for counter CW. @@ -2423,3 +2422,179 @@ void MESH_OT_colors_mirror(wmOperatorType *ot) /* props */ RNA_def_enum(ot->srna, "axis", axis_items, DIRECTION_CW, "Axis", "Axis to mirror colors around."); } + + +static int merge_firstlast(BMEditMesh *em, int first, int uvmerge, wmOperator *wmop) +{ + BMVert *mergevert; + BMEditSelection *ese; + + /* do sanity check in mergemenu in edit.c ?*/ + if(first == 0){ + ese = em->bm->selected.last; + mergevert= (BMVert*)ese->data; + } + else{ + ese = em->bm->selected.first; + mergevert = (BMVert*)ese->data; + } + + if (!BM_TestHFlag(mergevert, BM_SELECT)) + return OPERATOR_CANCELLED; + + if (uvmerge) { + if (!EDBM_CallOpf(em, wmop, "pointmerge_facedata verts=%hv snapv=%e", BM_SELECT, mergevert)) + return OPERATOR_CANCELLED; + } + + if (!EDBM_CallOpf(em, wmop, "pointmerge verts=%hv mergeco=%v", BM_SELECT, mergevert->co)) + return OPERATOR_CANCELLED; + + return OPERATOR_FINISHED; +} + +static int merge_target(BMEditMesh *em, Scene *scene, View3D *v3d, + int target, int uvmerge, wmOperator *wmop) +{ + BMIter iter; + BMVert *v; + float *co, cent[3] = {0.0f, 0.0f, 0.0f}, fac; + int i; + + if (target) { + co = give_cursor(scene, v3d); + } else { + i = 0; + BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + if (!BM_TestHFlag(v, BM_SELECT)) + continue; + VECADD(cent, cent, v->co); + i++; + } + + if (!i) + return OPERATOR_CANCELLED; + + fac = 1.0f / (float)i; + VECMUL(cent, fac); + co = cent; + } + + if (!co) + return OPERATOR_CANCELLED; + + if (uvmerge) { + if (!EDBM_CallOpf(em, wmop, "vert_average_facedata verts=%hv", BM_SELECT)) + return OPERATOR_CANCELLED; + } + + if (!EDBM_CallOpf(em, wmop, "pointmerge verts=%hv mergeco=%v", BM_SELECT, co)) + return OPERATOR_CANCELLED; + + return OPERATOR_FINISHED; +} + +static int merge_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + View3D *v3d = CTX_wm_view3d(C); + Object *obedit= CTX_data_edit_object(C); + BMEditMesh *em= ((Mesh *)obedit->data)->edit_btmesh; + int status= 0, uvs= RNA_boolean_get(op->ptr, "uvs"); + + switch(RNA_enum_get(op->ptr, "type")) { + case 3: + status = merge_target(em, scene, v3d, 0, uvs, op); + break; + case 4: + status = merge_target(em, scene, v3d, 1, uvs, op); + break; + case 1: + status = merge_firstlast(em, 0, uvs, op); + break; + case 6: + status = merge_firstlast(em, 1, uvs, op); + break; + case 5: + status = 1; + if (!EDBM_CallOpf(em, op, "collapse edges=%he", BM_SELECT)) + status = 0; + break; + } + + if(!status) + return OPERATOR_CANCELLED; + + DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + + return OPERATOR_FINISHED; +} + +static EnumPropertyItem merge_type_items[]= { + {6, "FIRST", 0, "At First", ""}, + {1, "LAST", 0, "At Last", ""}, + {3, "CENTER", 0, "At Center", ""}, + {4, "CURSOR", 0, "At Cursor", ""}, + {5, "COLLAPSE", 0, "Collapse", ""}, + {0, NULL, 0, NULL, NULL}}; + +static EnumPropertyItem *merge_type_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + Object *obedit; + EnumPropertyItem *item= NULL; + int totitem= 0; + + if(!C) /* needed for docs */ + return merge_type_items; + + obedit= CTX_data_edit_object(C); + if(obedit && obedit->type == OB_MESH) { + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; + + if(em->selectmode & SCE_SELECT_VERTEX) { + if(em->bm->selected.first && em->bm->selected.last && + ((BMEditSelection*)em->bm->selected.first)->type == BM_VERT && ((BMEditSelection*)em->bm->selected.last)->type == BM_VERT) { + RNA_enum_items_add_value(&item, &totitem, merge_type_items, 6); + RNA_enum_items_add_value(&item, &totitem, merge_type_items, 1); + } + else if(em->bm->selected.first && ((BMEditSelection*)em->bm->selected.first)->type == BM_VERT) + RNA_enum_items_add_value(&item, &totitem, merge_type_items, 1); + else if(em->bm->selected.last && ((BMEditSelection*)em->bm->selected.last)->type == BM_VERT) + RNA_enum_items_add_value(&item, &totitem, merge_type_items, 6); + } + + RNA_enum_items_add_value(&item, &totitem, merge_type_items, 3); + RNA_enum_items_add_value(&item, &totitem, merge_type_items, 4); + RNA_enum_items_add_value(&item, &totitem, merge_type_items, 5); + RNA_enum_item_end(&item, &totitem); + + *free= 1; + + return item; + } + + return NULL; +} + +void MESH_OT_merge(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name= "Merge"; + ot->idname= "MESH_OT_merge"; + + /* api callbacks */ + ot->exec= merge_exec; + ot->invoke= WM_menu_invoke; + ot->poll= ED_operator_editmesh; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + prop= RNA_def_enum(ot->srna, "type", merge_type_items, 3, "Type", "Merge method to use."); + RNA_def_enum_funcs(prop, merge_type_itemf); + RNA_def_boolean(ot->srna, "uvs", 0, "UVs", "Move UVs according to merge."); +} diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 10e85166d05..0729d139fb6 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -5417,164 +5417,6 @@ int collapseEdges(EditMesh *em) return mergecount; } -int merge_firstlast(EditMesh *em, int first, int uvmerge) -{ - EditVert *eve,*mergevert; - EditSelection *ese; - - /* do sanity check in mergemenu in edit.c ?*/ - if(first == 0){ - ese = em->selected.last; - mergevert= (EditVert*)ese->data; - } - else{ - ese = em->selected.first; - mergevert = (EditVert*)ese->data; - } - - if(mergevert->f&SELECT){ - for (eve=em->verts.first; eve; eve=eve->next){ - if (eve->f&SELECT) - VECCOPY(eve->co,mergevert->co); - } - } - - if(uvmerge && CustomData_has_layer(&em->fdata, CD_MTFACE)){ - - for(eve=em->verts.first; eve; eve=eve->next) eve->f1 = 0; - for(eve=em->verts.first; eve; eve=eve->next){ - if(eve->f&SELECT) eve->f1 = 1; - } - collapseuvs(em, mergevert); - } - - return removedoublesflag(em, 1, 0, MERGELIMIT); -} - -int merge_target(EditMesh *em, int target, int uvmerge) -{ - EditVert *eve; - - // XXX not working - if(target) snap_sel_to_curs(); - else snap_to_center(); - - if(uvmerge && CustomData_has_layer(&em->fdata, CD_MTFACE)){ - for(eve=em->verts.first; eve; eve=eve->next) eve->f1 = 0; - for(eve=em->verts.first; eve; eve=eve->next){ - if(eve->f&SELECT) eve->f1 = 1; - } - collapseuvs(em, NULL); - } - - return removedoublesflag(em, 1, 0, MERGELIMIT); -} -#undef MERGELIMIT - -static int merge_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); - int count= 0, uvs= RNA_boolean_get(op->ptr, "uvs"); - - switch(RNA_enum_get(op->ptr, "type")) { - case 3: - count = merge_target(em, 0, uvs); - break; - case 4: - count = merge_target(em, 1, uvs); - break; - case 1: - count = merge_firstlast(em, 0, uvs); - break; - case 6: - count = merge_firstlast(em, 1, uvs); - break; - case 2: - count = collapseEdges(em); - break; - } - - if(!count) - return OPERATOR_CANCELLED; - - BKE_mesh_end_editmesh(obedit->data, em); - - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); - - return OPERATOR_FINISHED; -} - -static EnumPropertyItem merge_type_items[]= { - {6, "FIRST", 0, "At First", ""}, - {1, "LAST", 0, "At Last", ""}, - {3, "CENTER", 0, "At Center", ""}, - {4, "CURSOR", 0, "At Cursor", ""}, - {5, "COLLAPSE", 0, "Collapse", ""}, - {0, NULL, 0, NULL, NULL}}; - -static EnumPropertyItem *merge_type_itemf(bContext *C, PointerRNA *ptr, int *free) -{ - Object *obedit; - EnumPropertyItem *item= NULL; - int totitem= 0; - - if(!C) /* needed for docs */ - return merge_type_items; - - obedit= CTX_data_edit_object(C); - if(obedit && obedit->type == OB_MESH) { - EditMesh *em= BKE_mesh_get_editmesh(obedit->data); - - if(em->selectmode & SCE_SELECT_VERTEX) { - if(em->selected.first && em->selected.last && - ((EditSelection*)em->selected.first)->type == EDITVERT && ((EditSelection*)em->selected.last)->type == EDITVERT) { - RNA_enum_items_add_value(&item, &totitem, merge_type_items, 6); - RNA_enum_items_add_value(&item, &totitem, merge_type_items, 1); - } - else if(em->selected.first && ((EditSelection*)em->selected.first)->type == EDITVERT) - RNA_enum_items_add_value(&item, &totitem, merge_type_items, 1); - else if(em->selected.last && ((EditSelection*)em->selected.last)->type == EDITVERT) - RNA_enum_items_add_value(&item, &totitem, merge_type_items, 6); - } - - RNA_enum_items_add_value(&item, &totitem, merge_type_items, 3); - RNA_enum_items_add_value(&item, &totitem, merge_type_items, 4); - RNA_enum_items_add_value(&item, &totitem, merge_type_items, 5); - RNA_enum_item_end(&item, &totitem); - - *free= 1; - - return item; - } - - return NULL; -} - -void MESH_OT_merge(wmOperatorType *ot) -{ - PropertyRNA *prop; - - /* identifiers */ - ot->name= "Merge"; - ot->idname= "MESH_OT_merge"; - - /* api callbacks */ - ot->exec= merge_exec; - ot->invoke= WM_menu_invoke; - ot->poll= ED_operator_editmesh; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* properties */ - prop= RNA_def_enum(ot->srna, "type", merge_type_items, 3, "Type", "Merge method to use."); - RNA_def_enum_funcs(prop, merge_type_itemf); - RNA_def_boolean(ot->srna, "uvs", 0, "UVs", "Move UVs according to merge."); -} - /************************ Vertex Path Operator *************************/ typedef struct PathNode { |