Revision: 18165 http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=18165 Author: joeedh Date: 2008-12-30 05:17:55 +0100 (Tue, 30 Dec 2008)
Log Message: ----------- forgot operators directory Added Paths: ----------- branches/bmesh/bmesh/operators/ branches/bmesh/bmesh/operators/bmesh_dupeops.c Added: branches/bmesh/bmesh/operators/bmesh_dupeops.c =================================================================== --- branches/bmesh/bmesh/operators/bmesh_dupeops.c (rev 0) +++ branches/bmesh/bmesh/operators/bmesh_dupeops.c 2008-12-30 04:17:55 UTC (rev 18165) @@ -0,0 +1,489 @@ +#include "bmesh.h" +#include "bmesh_operators_private.h" + + +/* + * COPY VERTEX + * + * Copy an existing vertex from one bmesh to another. + * +*/ +static BMVert *copy_vertex(BMesh *source_mesh, BMVert *source_vertex, BMesh *target_mesh, GHash *vhash) +{ + BMVert *target_vertex = NULL; + + /*create a new vertex*/ + target_vertex = BM_Make_Vert(target, source_vertex->co, NULL); + + /*insert new vertex into the vert hash*/ + BLI_ghash_insert(vhash, source_vertex, target_vertex); + + /*copy custom data in this function since we cannot be assured that byte layout is same between meshes*/ + CustomData_bmesh_copy_data(&source_mesh->vdata, &target_mesh->vdata, source_vertex->data, &target_vertex->data); + + /*Copy Markings*/ + if(BM_Is_Selected((BMHeader*)source_vertex)) BM_Select_Vert(target_mesh, target_vertex, 1); + if(BM_Is_Hidden((BMHeader*)source_vertex)) BM_Mark_Hidden((BMHeader*)target_vertex, 1); + + BMO_SetFlag(target_mesh, (BMHeader*)target_vertex, DUPE_NEW); + + return target_vertex; +} + +/* + * COPY EDGE + * + * Copy an existing edge from one bmesh to another. + * +*/ +static BMEdge *copy_edge(BMesh *source_mesh, BMEdge *source_edge, BMesh *target_mesh, GHash *vhash, GHash *ehash) +{ + BMEdge *target_edge = NULL; + BMVert *target_vert1, *target_vert2; + + /*lookup v1 and v2*/ + target_vert1 = BLI_ghash_lookup(vhash, source_edge->v1); + target_vert2 = BLI_ghash_lookup(vhash, source_edge->v2); + + /*create a new edge*/ + target_edge = BM_Make_Edge(target_mesh, target_vert1, target_vert2, NULL, 0); + + /*insert new edge into the edge hash*/ + BLI_ghash_insert(ehash, source_edge, target_edge); + + /*copy custom data in this function since we cannot be assured that byte layout is same between meshes*/ + CustomData_bmesh_copy_data(&source_mesh->edata, &target_mesh->edata, source_edge->data, &target_edge->data); + + /*copy flags*/ + target_edge->head.flag = source_edge->head.flag; + + BMO_SetFlag(target_mesh, (BMHeader*)target_edge, DUPE_NEW); + + return target_edge; +} + +/* + * COPY FACE + * + * Copy an existing face from one bmesh to another. + * +*/ +static BMFace *copy_face(BMesh *source_mesh, BMFace *source_face, BMesh *target_mesh, BMEdge **edar, GHash *verthash, GHash *ehash) +{ + BMEdge *target_edge; + BMVert *target_vert1, *target_vert2; + BMLoop *source_loop, *target_loop; + BMFace *target_face = NULL; + int i; + + /*lookup the first and second verts*/ + target_vert1 = BLI_ghash_lookup(vhash, source_face->loopbase->v); + target_vert2 = BLI_ghash_lookup(vhash, source_face->loopbase->next->v); + + /*lookup edges*/ + i = 0; + source_loop = source_face->loopbase; + do{ + edar[i] = BLI_ghash_lookup(ehash, source_loop->e); + i++; + source_loop = source_loop->next; + }while(source_loop != source_face->loopbase); + + /*create new face*/ + target_face = BM_Make_Ngon(target_mesh, target_vert1, target_vert2, edar, source_face->len, 0); + + /*we copy custom data by hand, we cannot assume that customdata byte layout will be exactly the same....*/ + CustomData_bmesh_copy_data(&source_mesh->pdata, &target_mesh->pdata, source_face->data, &target_face->data); + + /*copy flags*/ + target_face->head.flags = source_face->head.flags; + if(BM_Is_Selected((BMHeader*)source_face)) BM_Select_face(target, target_face, 1); + + /*mark the face for output*/ + BMO_SetFlag(target_mesh, (BMHeader*)target_face, DUPE_NEW); + + /*copy per-loop custom data*/ + source_loop = source_face->loopbase; + target_loop = target_face->loopbase; + do{ + CustomData_bmesh_copy_data(&source_mesh->ldata, &target_mesh->ldata, source_loop->data, &target_loop->data); + source_loop = source_loop->next; + target_loop = target_loop->next; + }while(source_loop != source_face->loopbase); + + return target_face; +} + /* + * COPY MESH + * + * Internal Copy function. +*/ + +/*local flag defines*/ +#define DUPE_INPUT 1 /*input from operator*/ +#define DUPE_NEW 2 +#define DUPE_DONE 3 + +static void copy_mesh(BMesh *source, BMesh *target) +{ + + BMVert *v = NULL; + BMEdge *e = NULL, **edar = NULL; + BMLoop *l = NULL; + BMFace *f = NULL; + + BMIter verts; + BMIter edges; + BMIter faces; + BMIter loops; + + GHash *vhash; + GHash *ehash; + + int maxlength = 0, flag; + + /*initialize pointer hashes*/ + vhash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); + ehash = BLI_ghash_new(BLI_ghashutil_ptrrhash, BLI_ghashutil_ptrcmp); + + /*initialize edge pointer array*/ + for(f = BMIter_New(&faces, source, BM_FACES, source); f; f = BMIter_Step(&faces)){ + if(f->len > maxlength) maxlength = f->len; + } + edar = MEM_callocN(sizeof(BMEdge*) * maxlength, "BM copy mesh edge pointer array"); + + + /*first we dupe all flagged faces and their elements from source*/ + for(f = BMIter_New(&faces, source, BM_FACES, source); f; f= BMIter_Step(&faces)){ + if(BMO_TestFlag(source, (BMHeader*)f, DUPE_INPUT)){ + /*vertex pass*/ + for(v = BMIter_New(&verts, source, BM_VERTS_OF_FACE, f); v; v = BMIter_Step(&verts)){ + if(!BMO_TestFlag(source, (BMHeader*)v, DUPE_DONE)){ + copy_vertex(source,v, target, vhash); + BMO_SetFlag(source, (BMHeader*)v, DUPE_DONE); + } + } + + /*edge pass*/ + for(e = BMIter_New(&edges, source, BM_EDGES_OF_FACE, f); e; e = BMeshIter_step(&edges)){ + if(!BMO_TestFlag(source, (BMHeader*)e, DUPE_DONE)){ + copy_edge(source, e, target, vhash, ehash); + BMO_SetFlag(source, (BMHeader*)e, DUPE_DONE); + } + } + copy_face(source, f, target, edar, vhash, ehash); + BMO_SetFlag(source, (BMHeader*)f, DUPE_DONE); + } + } + + /*now we dupe all the edges*/ + for(e = BMIter_New(&edges, source, BM_EDGES, source); e; e = BMIter_Step(&edges)){ + if(BMO_TestFlag(source, (BMHeader*)e, DUPE_INPUT) && (!BMO_TestFlag(source, (BMHeader*)e, DUPE_DONE))){ + /*make sure that verts are copied*/ + if(!BMO_TestFlag(source, (BMHeader*)e->v1, DUPE_DONE){ + copy_vertex(source, e->v1, target, vhash); + BMO_SetFlag(source, (BMHeader*)e->v1, DUPE_DONE); + } + if(!BMO_TestFlag(source, (BMHeader*)e->v2, DUPE_DONE){ + copy_vertex(source, e->v2, target, vhash); + BMO_SetFlag(source, (BMHeader*)e->v2, DUPE_DONE); + } + /*now copy the actual edge*/ + copy_edge(source, e, target, vhash, ehash); + BMO_SetFlag(source, (BMHeader*)e, DUPE_DONE); + } + } + + /*finally dupe all loose vertices*/ + for(v = BMIter_New(&verts, source, BM_VERTS, source); v; v = BMIter_Step(&verts)){ + if(BMO_TestFlag(source, (BMHeader*)v, DUPE_INPUT) && (!BMO_TestFlag(source, (BMHeader*)v, DUPE_DONE))){ + copy_vertex(source, v, target, vhash); + BMO_SetFlag(source, (BMHeader*)v, DUPE_DONE); + } + } + + /*free pointer hashes*/ + BLI_ghash_free(vhash, NULL, NULL); + BLI_ghash_free(ehash, NULL, NULL); + + /*free edge pointer array*/ + if(edar) + MEM_freeN(edar); +} +/* +BMesh *bmesh_make_mesh_from_mesh(BMesh *bm, int allocsize[4]) +{ + BMesh *target = NULL; + target = bmesh_make_mesh(allocsize); + + + CustomData_copy(&bm->vdata, &target->vdata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&bm->edata, &target->edata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&bm->ldata, &target->ldata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&bm->pdata, &target->pdata, CD_MASK_BMESH, CD_CALLOC, 0); + + + CustomData_bmesh_init_pool(&target->vdata, allocsize[0]); + CustomData_bmesh_init_pool(&target->edata, allocsize[1]); + CustomData_bmesh_init_pool(&target->ldata, allocsize[2]); + CustomData_bmesh_init_pool(&target->pdata, allocsize[3]); + + bmesh_begin_edit(bm); + bmesh_begin_edit(target); + + bmesh_copy_mesh(bm, target, 0); + + bmesh_end_edit(bm); + bmesh_end_edit(target); + + return target; + +} +*/ + +/* + * Duplicate Operator + * + * Duplicates verts, edges and faces of a mesh. + * + * INPUT SLOTS: + * + * BMOP_DUPE_VINPUT: Buffer containing pointers to mesh vertices to be duplicated + * BMOP_DUPE_EINPUT: Buffer containing pointers to mesh edges to be duplicated + * BMOP_DUPE_FINPUT: Buffer containing pointers to mesh faces to be duplicated + * + * OUTPUT SLOTS: + * + * BMOP_DUPE_VORIGINAL: Buffer containing pointers to the original mesh vertices + * BMOP_DUPE_EORIGINAL: Buffer containing pointers to the original mesh edges + * BMOP_DUPE_FORIGINAL: Buffer containing pointers to the original mesh faces + * BMOP_DUPE_VNEW: Buffer containing pointers to the new mesh vertices + * BMOP_DUPE_ENEW: Buffer containing pointers to the new mesh edges + * BMOP_DUPE_FNEW: Buffer containing pointers to the new mesh faces + * +*/ + +void dupeop_exec(BMesh *bm, BMOperator *op) +{ + BMOperator *dupeop = op; + BMOpSlot *vinput, *einput, *finput, *vnew, *enew, *fnew; + int i; + + vinput = BMO_GetSlot(dupeop, BMOP_DUPE_VINPUT); + einput = BMO_GetSlot(dupeop, BMOP_DUPE_EINPUT); + finput = BMO_GetSlot(dupeop, BMOP_DUPE_FINPUT); + + /*go through vinput, einput, and finput and flag elements with private flags*/ + BMO_Flag_Buffer(bm, dupeop, BMOP_DUPE_VINPUT, DUPE_INPUT); + BMO_Flag_Buffer(bm, dupeop, BMOP_DUPE_EINPUT, DUPE_INPUT); + BMO_Flag_Buffer(bm, dupeop, BMOP_DUPE_FINPUT, DUPE_INPUT); + + /*use the internal copy function*/ + copy_mesh(bm, bm); + + /*Output*/ + /*First copy the input buffers to output buffers - original data*/ + BMO_CopySlot(dupeop, dupeop, vinput->index, BMOP_DUPE_VORIGINAL); + BMO_CopySlot(dupeop, dupeop, einput->index, BMOP_DUPE_EORIGINAL); + BMO_CopySlot(dupeop, dupeop, finput->index, BMOP_DUPE_FORIGINAL); + + /*Now alloc the new output buffers*/ + BMO_Flag_To_Slot(bm, dupeop, BMOP_DUPE_VNEW, DUPE_NEW, BMESH_VERT); + BMO_Flag_To_Slot(bm, dupeop, BMOP_DUPE_ENEW, DUPE_NEW, BMESH_EDGE); + BMO_Flag_To_Slot(bm, dupeop, BMOP_DUPE_FNEW, DUPE_NEW, BMESH_FACE); +} + + +/* + * Split Operator + * + * Duplicates verts, edges and faces of a mesh but also deletes the originals. + * + * INPUT SLOTS: + * + * BMOP_DUPE_VINPUT: Buffer containing pointers to mesh vertices to be split + * BMOP_DUPE_EINPUT: Buffer containing pointers to mesh edges to be split + * BMOP_DUPE_FINPUT: Buffer containing pointers to mesh faces to be split + * + * OUTPUT SLOTS: + * + * BMOP_DUPE_VOUTPUT: Buffer containing pointers to the split mesh vertices + * BMOP_DUPE_EOUTPUT: Buffer containing pointers to the split mesh edges @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs