diff options
Diffstat (limited to 'source/blender/editors/mesh/meshtools.c')
-rw-r--r-- | source/blender/editors/mesh/meshtools.c | 225 |
1 files changed, 137 insertions, 88 deletions
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 763e82b8b53..aa38950884b 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -68,6 +68,7 @@ #include "BKE_mesh.h" #include "BKE_material.h" #include "BKE_report.h" +#include "BKE_tessmesh.h" #include "BKE_multires.h" #include "BLO_sys_types.h" // for intptr_t support @@ -81,14 +82,14 @@ /* own include */ #include "mesh_intern.h" - +#include "uvedit_intern.h" /* * ********************** no editmode!!! *********** */ /*********************** JOIN ***************************/ /* join selected meshes into the active mesh, context sensitive -return 0 if no join is made (error) and 1 of the join is done */ +return 0 if no join is made (error) and 1 if the join is done */ int join_mesh_exec(bContext *C, wmOperator *op) { @@ -100,15 +101,17 @@ int join_mesh_exec(bContext *C, wmOperator *op) MVert *mvert, *mv; MEdge *medge = NULL; MFace *mface = NULL; + MPoly *mpoly = NULL; + MLoop *mloop = NULL; Key *key, *nkey=NULL; KeyBlock *kb, *okb, *kbn; float imat[4][4], cmat[4][4], *fp1, *fp2, curpos; int a, b, totcol, totmat=0, totedge=0, totvert=0, totface=0, ok=0; - int vertofs, *matmap=NULL; - int i, j, index, haskey=0, edgeofs, faceofs; + int totloop=0, totpoly=0, vertofs, *matmap=NULL; + int i, j, index, haskey=0, edgeofs, faceofs, loopofs, polyofs; bDeformGroup *dg, *odg; MDeformVert *dvert; - CustomData vdata, edata, fdata; + CustomData vdata, edata, fdata, ldata, pdata; if(scene->obedit) { BKE_report(op->reports, RPT_WARNING, "Cant join while in editmode"); @@ -129,6 +132,8 @@ int join_mesh_exec(bContext *C, wmOperator *op) totvert+= me->totvert; totedge+= me->totedge; totface+= me->totface; + totloop+= me->totloop; + totpoly+= me->totpoly; totmat+= base->object->totcol; if(base->object == ob) @@ -282,14 +287,20 @@ int join_mesh_exec(bContext *C, wmOperator *op) memset(&vdata, 0, sizeof(vdata)); memset(&edata, 0, sizeof(edata)); memset(&fdata, 0, sizeof(fdata)); + memset(&ldata, 0, sizeof(ldata)); + memset(&pdata, 0, sizeof(pdata)); mvert= CustomData_add_layer(&vdata, CD_MVERT, CD_CALLOC, NULL, totvert); medge= CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge); mface= CustomData_add_layer(&fdata, CD_MFACE, CD_CALLOC, NULL, totface); + mloop= CustomData_add_layer(&ldata, CD_MLOOP, CD_CALLOC, NULL, totloop); + mpoly= CustomData_add_layer(&pdata, CD_MPOLY, CD_CALLOC, NULL, totpoly); vertofs= 0; edgeofs= 0; faceofs= 0; + loopofs= 0; + polyofs= 0; /* inverse transform for all selected meshes in this object */ invert_m4_m4(imat, ob->obmat); @@ -413,9 +424,6 @@ int join_mesh_exec(bContext *C, wmOperator *op) } } - if(base->object!=ob) - multiresModifier_prepare_join(scene, base->object, ob); - CustomData_merge(&me->fdata, &fdata, CD_MASK_MESH, CD_DEFAULT, totface); CustomData_copy_data(&me->fdata, &fdata, 0, faceofs, me->totface); @@ -442,14 +450,51 @@ int join_mesh_exec(bContext *C, wmOperator *op) medge->v1+= vertofs; medge->v2+= vertofs; } + } + + if (me->totloop) { + if(base->object!=ob) + multiresModifier_prepare_join(scene, base->object, ob); - edgeofs += me->totedge; + CustomData_merge(&me->ldata, &ldata, CD_MASK_MESH, CD_DEFAULT, totloop); + CustomData_copy_data(&me->ldata, &ldata, 0, loopofs, me->totloop); + + for(a=0; a<me->totloop; a++, mloop++) { + mloop->v += vertofs; + mloop->e += edgeofs; + } } - /* vertofs is used to help newly added verts be reattached to their edge/face - * (cannot be set earlier, or else reattaching goes wrong) + if(me->totpoly) { + /* make mapping for materials */ + for(a=1; a<=base->object->totcol; a++) { + ma= give_current_material(base->object, a); + + for(b=0; b<totcol; b++) { + if(ma == matar[b]) { + matmap[a-1]= b; + break; + } + } + } + + CustomData_merge(&me->pdata, &pdata, CD_MASK_MESH, CD_DEFAULT, totpoly); + CustomData_copy_data(&me->pdata, &pdata, 0, polyofs, me->totpoly); + + for(a=0; a<me->totpoly; a++, mpoly++) { + mpoly->loopstart += loopofs; + mpoly->mat_nr= matmap ? matmap[(int)mpoly->mat_nr] : 0; + } + + polyofs += me->totpoly; + } + + /* these are used for relinking (cannot be set earlier, + * or else reattaching goes wrong) */ vertofs += me->totvert; + edgeofs += me->totedge; + loopofs += me->totloop; /* free base, now that data is merged */ if(base->object != ob) @@ -464,14 +509,20 @@ int join_mesh_exec(bContext *C, wmOperator *op) CustomData_free(&me->vdata, me->totvert); CustomData_free(&me->edata, me->totedge); CustomData_free(&me->fdata, me->totface); + CustomData_free(&me->ldata, me->totloop); + CustomData_free(&me->pdata, me->totpoly); me->totvert= totvert; me->totedge= totedge; me->totface= totface; + me->totloop= totloop; + me->totpoly= totpoly; me->vdata= vdata; me->edata= edata; me->fdata= fdata; + me->ldata= ldata; + me->pdata= pdata; mesh_update_customdata_pointers(me); @@ -530,11 +581,11 @@ int join_mesh_exec(bContext *C, wmOperator *op) ED_object_exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR|EM_DO_UNDO); #else /* toggle editmode using lower level functions so this can be called from python */ - make_editMesh(scene, ob); - load_editMesh(scene, ob); - free_editMesh(me->edit_mesh); - MEM_freeN(me->edit_mesh); - me->edit_mesh= NULL; + EDBM_MakeEditBMesh(scene->toolsettings, scene, ob); + EDBM_LoadEditBMesh(scene, ob); + EDBM_FreeEditBMesh(me->edit_btmesh); + MEM_freeN(me->edit_btmesh); + me->edit_btmesh= NULL; DAG_id_tag_update(&ob->id, OB_RECALC_OB|OB_RECALC_DATA); #endif WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene); @@ -761,7 +812,7 @@ static struct { /* mode is 's' start, or 'e' end, or 'u' use */ /* if end, ob can be NULL */ -intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode) +intptr_t mesh_octree_table(Object *ob, BMEditMesh *em, float *co, char mode) { MocNode **bt; @@ -787,10 +838,11 @@ intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode) * we are using the undeformed coordinates*/ INIT_MINMAX(min, max); - if(em && me->edit_mesh==em) { - EditVert *eve; + if(em && me->edit_btmesh==em) { + BMIter iter; + BMVert *eve; - for(eve= em->verts.first; eve; eve= eve->next) + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) DO_MINMAX(eve->co, min, max) } else { @@ -822,10 +874,11 @@ intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode) MeshOctree.table= MEM_callocN(MOC_RES*MOC_RES*MOC_RES*sizeof(void *), "sym table"); - if(em && me->edit_mesh==em) { - EditVert *eve; + if(em && me->edit_btmesh==em) { + BMVert *eve; + BMIter iter; - for(eve= em->verts.first; eve; eve= eve->next) { + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { mesh_octree_add_nodes(MeshOctree.table, eve->co, MeshOctree.offs, MeshOctree.div, (intptr_t)(eve)); } } @@ -887,27 +940,23 @@ long mesh_mirrtopo_table(Object *ob, char mode) Mesh *me= ob->data; if( (mesh_topo_lookup==NULL) || (mesh_topo_lookup_mode != ob->mode) || - (me->edit_mesh && me->edit_mesh->totvert != mesh_topo_lookup_tot) || - (me->edit_mesh==NULL && me->totvert != mesh_topo_lookup_tot) + (me->edit_btmesh && me->edit_btmesh->bm->totvert != mesh_topo_lookup_tot) || + (me->edit_btmesh==NULL && me->totvert != mesh_topo_lookup_tot) ) { mesh_mirrtopo_table(ob, 's'); } } else if(mode=='s') { /* start table */ Mesh *me= ob->data; MEdge *medge; - EditMesh *em= me->edit_mesh; - void **eve_tmp_back= NULL; /* some of the callers are using eve->tmp so restore after */ - - - /* editmode*/ - EditEdge *eed; - - int a, last, totvert; - int totUnique= -1, totUniqueOld= -1; - + BMEditMesh *em= me->edit_btmesh; + BMEdge *eed; + BMIter iter; MIRRHASH_TYPE *MirrTopoHash = NULL; MIRRHASH_TYPE *MirrTopoHash_Prev = NULL; MirrTopoPair *MirrTopoPairs; + int a, last, totvert; + int totUnique= -1, totUniqueOld= -1; + mesh_topo_lookup_mode= ob->mode; /* reallocate if needed */ @@ -917,12 +966,12 @@ long mesh_mirrtopo_table(Object *ob, char mode) } if(em) { - EditVert *eve; + BMVert *eve; + totvert= 0; - eve_tmp_back= MEM_callocN( em->totvert * sizeof(void *), "TopoMirr" ); - for(eve= em->verts.first; eve; eve= eve->next) { - eve_tmp_back[totvert]= eve->tmp.p; - eve->tmp.l = totvert++; + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + BM_SetIndex(eve, totvert); + totvert++; } } else { @@ -933,9 +982,9 @@ long mesh_mirrtopo_table(Object *ob, char mode) /* Initialize the vert-edge-user counts used to detect unique topology */ if(em) { - for(eed=em->edges.first; eed; eed= eed->next) { - MirrTopoHash[eed->v1->tmp.l]++; - MirrTopoHash[eed->v2->tmp.l]++; + BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) { + MirrTopoHash[BM_GetIndex(eed->v1)]++; + MirrTopoHash[BM_GetIndex(eed->v2)]++; } } else { for(a=0, medge=me->medge; a<me->totedge; a++, medge++) { @@ -951,9 +1000,9 @@ long mesh_mirrtopo_table(Object *ob, char mode) /* use the number of edges per vert to give verts unique topology IDs */ if(em) { - for(eed=em->edges.first; eed; eed= eed->next) { - MirrTopoHash[eed->v1->tmp.l] += MirrTopoHash_Prev[eed->v2->tmp.l]; - MirrTopoHash[eed->v2->tmp.l] += MirrTopoHash_Prev[eed->v1->tmp.l]; + BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) { + MirrTopoHash[BM_GetIndex(eed->v1)] += MirrTopoHash_Prev[BM_GetIndex(eed->v2)]; + MirrTopoHash[BM_GetIndex(eed->v2)] += MirrTopoHash_Prev[BM_GetIndex(eed->v1)]; } } else { for(a=0, medge=me->medge; a<me->totedge; a++, medge++) { @@ -985,19 +1034,6 @@ long mesh_mirrtopo_table(Object *ob, char mode) memcpy(MirrTopoHash_Prev, MirrTopoHash, sizeof(MIRRHASH_TYPE) * totvert); } - /* restore eve->tmp.* */ - if(eve_tmp_back) { - EditVert *eve; - totvert= 0; - for(eve= em->verts.first; eve; eve= eve->next) { - eve->tmp.p= eve_tmp_back[totvert++]; - } - - MEM_freeN(eve_tmp_back); - eve_tmp_back= NULL; - } - - /* Hash/Index pairs are needed for sorting to find index pairs */ MirrTopoPairs= MEM_callocN( sizeof(MirrTopoPair) * totvert, "MirrTopoPairs"); @@ -1005,7 +1041,7 @@ long mesh_mirrtopo_table(Object *ob, char mode) mesh_topo_lookup = MEM_mallocN( totvert * sizeof(long), "mesh_topo_lookup" ); if(em) { - EM_init_index_arrays(em,1,0,0); + EDBM_init_index_arrays(em,1,0,0); } @@ -1029,8 +1065,8 @@ long mesh_mirrtopo_table(Object *ob, char mode) if ((a==totvert) || (MirrTopoPairs[a-1].hash != MirrTopoPairs[a].hash)) { if (a-last==2) { if(em) { - mesh_topo_lookup[MirrTopoPairs[a-1].vIndex] = (long)EM_get_vert_for_index(MirrTopoPairs[a-2].vIndex); - mesh_topo_lookup[MirrTopoPairs[a-2].vIndex] = (long)EM_get_vert_for_index(MirrTopoPairs[a-1].vIndex); + mesh_topo_lookup[MirrTopoPairs[a-1].vIndex] = (long)EDBM_get_vert_for_index(em, MirrTopoPairs[a-2].vIndex); + mesh_topo_lookup[MirrTopoPairs[a-2].vIndex] = (long)EDBM_get_vert_for_index(em, MirrTopoPairs[a-1].vIndex); } else { mesh_topo_lookup[MirrTopoPairs[a-1].vIndex] = MirrTopoPairs[a-2].vIndex; mesh_topo_lookup[MirrTopoPairs[a-2].vIndex] = MirrTopoPairs[a-1].vIndex; @@ -1040,7 +1076,7 @@ long mesh_mirrtopo_table(Object *ob, char mode) } } if(em) { - EM_free_index_arrays(); + EDBM_free_index_arrays(em); } MEM_freeN( MirrTopoPairs ); @@ -1090,9 +1126,10 @@ int mesh_get_x_mirror_vert(Object *ob, int index) } else { return mesh_get_x_mirror_vert_spacial(ob, index); } + return 0; } -static EditVert *editmesh_get_x_mirror_vert_spacial(Object *ob, EditMesh *em, float *co) +static BMVert *editbmesh_get_x_mirror_vert_spacial(Object *ob, BMEditMesh *em, float *co) { float vec[3]; intptr_t poinval; @@ -1110,20 +1147,28 @@ static EditVert *editmesh_get_x_mirror_vert_spacial(Object *ob, EditMesh *em, fl poinval= mesh_octree_table(ob, em, vec, 'u'); if(poinval != -1) - return (EditVert *)(poinval); + return (BMVert *)(poinval); return NULL; } -static EditVert *editmesh_get_x_mirror_vert_topo(Object *ob, struct EditMesh *em, EditVert *eve, int index) +static BMVert *editbmesh_get_x_mirror_vert_topo(Object *ob, struct BMEditMesh *em, BMVert *eve, int index) { long poinval; if (mesh_mirrtopo_table(ob, 'u')==-1) return NULL; if (index == -1) { - index = BLI_findindex(&em->verts, eve); - - if (index == -1) { + BMIter iter; + BMVert *v; + + index = 0; + BM_ITER(v, &iter, em->bm, BM_EDGES_OF_MESH, NULL) { + if (v == eve) + break; + index++; + } + + if (index == em->bm->totvert) { return NULL; } } @@ -1131,22 +1176,23 @@ static EditVert *editmesh_get_x_mirror_vert_topo(Object *ob, struct EditMesh *em poinval= mesh_topo_lookup[ index ]; if(poinval != -1) - return (EditVert *)(poinval); + return (BMVert *)(poinval); return NULL; } -EditVert *editmesh_get_x_mirror_vert(Object *ob, struct EditMesh *em, EditVert *eve, float *co, int index) +BMVert *editbmesh_get_x_mirror_vert(Object *ob, struct BMEditMesh *em, BMVert *eve, float *co, int index) { + //BMESH_TODO use this flag, ME_EDIT_MIRROR_TOPO, at appropriate places if (((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_TOPO) { - return editmesh_get_x_mirror_vert_topo(ob, em, eve, index); + return editbmesh_get_x_mirror_vert_topo(ob, em, eve, index); } else { - return editmesh_get_x_mirror_vert_spacial(ob, em, co); + return editbmesh_get_x_mirror_vert_spacial(ob, em, co); } } -#if 0 -float *editmesh_get_mirror_uv(int axis, float *uv, float *mirrCent, float *face_cent) + +static float *editmesh_get_mirror_uv(BMEditMesh *em, int axis, float *uv, float *mirrCent, float *face_cent) { float vec[2]; float cent_vec[2]; @@ -1174,26 +1220,29 @@ float *editmesh_get_mirror_uv(int axis, float *uv, float *mirrCent, float *face_ /* TODO - Optimize */ { - EditFace *efa; - int i, len; - for(efa=em->faces.first; efa; efa=efa->next) { - MTFace *tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - uv_center(tf->uv, cent, (void *)efa->v4); - + BMIter iter; + BMFace *efa; + + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + poly_uv_center(em, efa, cent); + if ( (fabs(cent[0] - cent_vec[0]) < 0.001) && (fabs(cent[1] - cent_vec[1]) < 0.001) ) { - len = efa->v4 ? 4 : 3; - for (i=0; i<len; i++) { - if ( (fabs(tf->uv[i][0] - vec[0]) < 0.001) && (fabs(tf->uv[i][1] - vec[1]) < 0.001) ) { - return tf->uv[i]; - } + BMIter liter; + BMLoop *l; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + if ( (fabs(luv->uv[0] - vec[0]) < 0.001) && (fabs(luv->uv[1] - vec[1]) < 0.001) ) { + return luv->uv; + } } } } + } return NULL; } -#endif static unsigned int mirror_facehash(const void *ptr) { @@ -1241,7 +1290,7 @@ static int mirror_facecmp(const void *a, const void *b) return (mirror_facerotation((MFace*)a, (MFace*)b) == -1); } -int *mesh_get_x_mirror_faces(Object *ob, EditMesh *em) +int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em) { Mesh *me= ob->data; MVert *mv, *mvert= me->mvert; |