forked from bartvdbraak/blender
remove more unused files.
This commit is contained in:
parent
b1a3d3cea1
commit
4504ac27a6
@ -80,28 +80,29 @@ set(SRC
|
|||||||
operators/bmo_triangulate.c
|
operators/bmo_triangulate.c
|
||||||
operators/bmo_utils.c
|
operators/bmo_utils.c
|
||||||
|
|
||||||
intern/bmesh_newcore.c
|
intern/bmesh_construct.c
|
||||||
|
intern/bmesh_inline.c
|
||||||
intern/bmesh_interp.c
|
intern/bmesh_interp.c
|
||||||
intern/bmesh_iterators.c
|
intern/bmesh_iterators.c
|
||||||
intern/bmesh_iterators_inline.c
|
intern/bmesh_iterators_inline.c
|
||||||
intern/bmesh_marking.c
|
intern/bmesh_marking.c
|
||||||
intern/bmesh_mesh.c
|
intern/bmesh_mesh.c
|
||||||
intern/bmesh_mods.c
|
intern/bmesh_mods.c
|
||||||
intern/bmesh_structure.h
|
intern/bmesh_newcore.c
|
||||||
intern/bmesh_construct.c
|
|
||||||
intern/bmesh_operators_private.h
|
|
||||||
intern/bmesh_structure.c
|
|
||||||
intern/bmesh_polygon.c
|
|
||||||
intern/bmesh_queries.c
|
|
||||||
intern/bmesh_opdefines.c
|
intern/bmesh_opdefines.c
|
||||||
intern/bmesh_operators.c
|
intern/bmesh_operators.c
|
||||||
|
intern/bmesh_operators_private.h
|
||||||
|
intern/bmesh_polygon.c
|
||||||
intern/bmesh_private.h
|
intern/bmesh_private.h
|
||||||
|
intern/bmesh_queries.c
|
||||||
|
intern/bmesh_structure.c
|
||||||
|
intern/bmesh_structure.h
|
||||||
intern/bmesh_walkers.c
|
intern/bmesh_walkers.c
|
||||||
intern/bmesh_walkers_impl.c
|
intern/bmesh_walkers_impl.c
|
||||||
intern/bmesh_walkers_private.h
|
intern/bmesh_walkers_private.h
|
||||||
intern/bmesh_inline.c
|
|
||||||
|
|
||||||
tools/BME_bevel.c
|
tools/BME_bevel.c
|
||||||
|
|
||||||
bmesh.h
|
bmesh.h
|
||||||
bmesh_class.h
|
bmesh_class.h
|
||||||
bmesh_error.h
|
bmesh_error.h
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,322 +0,0 @@
|
|||||||
#if 0
|
|
||||||
|
|
||||||
/*
|
|
||||||
* BME_DUPLICATE.C
|
|
||||||
*
|
|
||||||
* This file contains functions for duplicating, copying, and splitting
|
|
||||||
* elements from a bmesh.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* COPY VERTEX
|
|
||||||
*
|
|
||||||
* Copy an existing vertex from one bmesh to another.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
static BMVert *copy_vertex(BMMesh *source_mesh, BMVert *source_vertex, BMMesh *target_mesh, GHash *vhash)
|
|
||||||
{
|
|
||||||
BMVert *target_vertex = NULL;
|
|
||||||
|
|
||||||
/*create a new vertex*/
|
|
||||||
target_vertex = BM_vert_create(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_vert_select_set(target_mesh, target_vertex, TRUE);
|
|
||||||
if(BM_Is_Hidden((BMHeader*)source_vertex)) BM_Mark_Hidden((BMHeader*)target_vertex, 1);
|
|
||||||
|
|
||||||
BMO_elem_flag_enable(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(BMMesh *source_mesh, BMEdge *source_edge, BMMesh *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_edge_create(target_mesh, target_vert1, target_vert2, NULL, FALSE);
|
|
||||||
|
|
||||||
/*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*/
|
|
||||||
if(BM_Is_Selected((BMHeader*) source_edge)) BM_edge_select_set(target_mesh, target_edge, TRUE);
|
|
||||||
if(BM_Is_Hidden((BMHeader*) source_edge)) BM_Mark_Hidden(target_mesh, target_edge, 1);
|
|
||||||
if(BM_Is_Sharp((BMHeader*) source_edge)) BM_Mark_Sharp(target_edge, 1);
|
|
||||||
if(BM_Is_Seam((BMHeader*) source_edge)) BM_Mark_Seam(target_edge, 1);
|
|
||||||
if(BM_Is_Fgon((BMHeader*) source_edge)) BM_Mark_Fgon(target_edge, 1);
|
|
||||||
|
|
||||||
BMO_elem_flag_enable(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(BMMesh *source_mesh, BMFace *source_face, BMMesh *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->lbase->v);
|
|
||||||
target_vert2 = BLI_ghash_lookup(vhash, source_face->lbase->next->v);
|
|
||||||
|
|
||||||
/*lookup edges*/
|
|
||||||
i = 0;
|
|
||||||
source_loop = source_face->lbase;
|
|
||||||
do{
|
|
||||||
edar[i] = BLI_ghash_lookup(ehash, source_loop->e);
|
|
||||||
i++;
|
|
||||||
source_loop = source_loop->next;
|
|
||||||
}while(source_loop != source_face->lbase);
|
|
||||||
|
|
||||||
/*create new face*/
|
|
||||||
target_face = BM_face_create_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*/
|
|
||||||
if(BM_Is_Selected((BMHeader*)source_face)) BM_Select_face(target, target_face, TRUE);
|
|
||||||
if(BM_Is_Hidden((BMHeader*)source_face)) BM_Mark_Hidden((BMHeader*)target_face, 1);
|
|
||||||
|
|
||||||
/*mark the face for output*/
|
|
||||||
BMO_elem_flag_enable(target_mesh, (BMHeader*)target_face, DUPE_NEW);
|
|
||||||
|
|
||||||
/*copy per-loop custom data*/
|
|
||||||
source_loop = source_face->lbase;
|
|
||||||
target_loop = target_face->lbase;
|
|
||||||
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->lbase);
|
|
||||||
|
|
||||||
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(BMMesh *source, BMMesh *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 = BM_iter_new(&faces, source, BM_FACES, source, 0, NULL); f; f = BM_iter_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 = BM_iter_new(&faces, source, BM_FACES, source, 0, NULL); f; f= BM_iter_step(&faces)){
|
|
||||||
if(BMO_elem_flag_test(source, (BMHeader*)f, DUPE_INPUT)){
|
|
||||||
/*vertex pass*/
|
|
||||||
for(v = BM_iter_new(&verts, source, BM_VERT_OF_FACE, f, 0, NULL); v; v = BM_iter_step(&verts)){
|
|
||||||
if(!BMO_elem_flag_test(source, (BMHeader*)v, DUPE_DONE)){
|
|
||||||
copy_vertex(source,v, target, vhash);
|
|
||||||
BMO_elem_flag_enable(source, (BMHeader*)v, DUPE_DONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*edge pass*/
|
|
||||||
for(e = BM_iter_new(&edges, source, BM_EDGE_OF_FACE, f, 0, NULL); e; e = BMeshIter_step(&edges)){
|
|
||||||
if(!BMO_elem_flag_test(source, (BMHeader*)e, DUPE_DONE)){
|
|
||||||
copy_edge(source, e, target, vhash, ehash);
|
|
||||||
BMO_elem_flag_enable(source, (BMHeader*)e, DUPE_DONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
copy_face(source, f, target, edar, vhash, ehash);
|
|
||||||
BMO_elem_flag_enable(source, (BMHeader*)f, DUPE_DONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*now we dupe all the edges*/
|
|
||||||
for(e = BM_iter_new(&edges, source, BM_EDGES, source, 0, NULL); e; e = BM_iter_step(&edges)){
|
|
||||||
if(BMO_elem_flag_test(source, (BMHeader*)e, DUPE_INPUT) && (!BMO_elem_flag_test(source, (BMHeader*)e, DUPE_DONE))){
|
|
||||||
/*make sure that verts are copied*/
|
|
||||||
if(!BMO_elem_flag_test(source, (BMHeader*)e->v1, DUPE_DONE){
|
|
||||||
copy_vertex(source, e->v1, target, vhash);
|
|
||||||
BMO_elem_flag_enable(source, (BMHeader*)e->v1, DUPE_DONE);
|
|
||||||
}
|
|
||||||
if(!BMO_elem_flag_test(source, (BMHeader*)e->v2, DUPE_DONE){
|
|
||||||
copy_vertex(source, e->v2, target, vhash);
|
|
||||||
BMO_elem_flag_enable(source, (BMHeader*)e->v2, DUPE_DONE);
|
|
||||||
}
|
|
||||||
/*now copy the actual edge*/
|
|
||||||
copy_edge(source, e, target, vhash, ehash);
|
|
||||||
BMO_elem_flag_enable(source, (BMHeader*)e, DUPE_DONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*finally dupe all loose vertices*/
|
|
||||||
for(v = BM_iter_new(&verts, source, BM_VERTS, source, 0, NULL); v; v = BM_iter_step(&verts)){
|
|
||||||
if(BMO_elem_flag_test(source, (BMHeader*)v, DUPE_INPUT) && (!BMO_elem_flag_test(source, (BMHeader*)v, DUPE_DONE))){
|
|
||||||
copy_vertex(source, v, target, vhash);
|
|
||||||
BMO_elem_flag_enable(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);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
BMMesh *bmesh_make_mesh_from_mesh(BMMesh *bm, int allocsize[4])
|
|
||||||
{
|
|
||||||
BMMesh *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;
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void dupeop_exec(BMMesh *bm, BMOperator *op)
|
|
||||||
{
|
|
||||||
BMOperator *dupeop = op;
|
|
||||||
BMOpSlot *vinput, *einput, *finput, *vnew, *enew, *fnew;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
vinput = BMO_Get_Slot(dupeop, BMOP_DUPE_VINPUT);
|
|
||||||
einput = BMO_Get_Slot(dupeop, BMOP_DUPE_EINPUT);
|
|
||||||
finput = BMO_Get_Slot(dupeop, BMOP_DUPE_FINPUT);
|
|
||||||
|
|
||||||
/*go through vinput, einput, and finput and flag elements with private flags*/
|
|
||||||
BMO_slot_buffer_flag_enable(bm, dupeop, BMOP_DUPE_VINPUT, DUPE_INPUT);
|
|
||||||
BMO_slot_buffer_flag_enable(bm, dupeop, BMOP_DUPE_EINPUT, DUPE_INPUT);
|
|
||||||
BMO_slot_buffer_flag_enable(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_Copy_Opslot_Buffer_Alloc(dupeop, vinput, BMO_Get_Slot(dupeop, BMOP_DUPE_VORIGINAL));
|
|
||||||
BMO_Copy_Opslot_Buffer_Alloc(dupeop, einput, BMO_Get_Slot(dupeop, BMOP_DUPE_EORIGINAL));
|
|
||||||
BMO_Copy_Opslot_Buffer_Alloc(dupeop, finput, BMO_Get_Slot(dupeop, BMOP_DUPE_FORIGINAL));
|
|
||||||
|
|
||||||
/*Now alloc the new output buffers*/
|
|
||||||
BMO_slot_from_flag(bm, dupeop, BMOP_DUPE_VNEW, DUPE_NEW, BMESH_VERT);
|
|
||||||
BMO_slot_from_flag(bm, dupeop, BMOP_DUPE_ENEW, DUPE_NEW, BMESH_EDGE);
|
|
||||||
BMO_slot_from_flag(bm, dupeop, BMOP_DUPE_FNEW, DUPE_NEW, BMESH_FACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void splitop_exec(BMMesh *bm, BMOperator *op)
|
|
||||||
{
|
|
||||||
BMOperator *splitop = op;
|
|
||||||
BMOperator dupeop;
|
|
||||||
BMOperator delop;
|
|
||||||
|
|
||||||
/*initialize our sub-operators*/
|
|
||||||
BMO_op_init(&dupeop, BMOP_DUPE);
|
|
||||||
BMO_op_init(&delop, BMOP_DEL);
|
|
||||||
|
|
||||||
BMO_Connect(BMO_Get_Slot(splitop, BMOP_SPLIT_VINPUT),BMO_Get_Slot(&dupeop, BMOP_DUPE_VINPUT));
|
|
||||||
BMO_Connect(BMO_Get_Slot(splitop, BMOP_SPLIT_EINPUT),BMO_Get_Slot(&dupeop, BMOP_DUPE_EINPUT));
|
|
||||||
BMO_Connect(BMO_Get_Slot(splitop, BMOP_SPLIT_FINPUT),BMO_Get_Slot(&dupeop, BMOP_DUPE_FINPUT));
|
|
||||||
|
|
||||||
BMO_op_exec(&dupeop);
|
|
||||||
|
|
||||||
/*connect outputs of dupe to delete*/
|
|
||||||
BMO_Connect(BMO_Get_Slot(&dupeop, BMOP_DUPE_VORIGINAL), BMO_Get_Slot(&delop, BMOP_DEL_VINPUT));
|
|
||||||
BMO_Connect(BMO_Get_Slot(&dupeop, BMOP_DUPE_EORIGINAL), BMO_Get_Slot(&delop, BMOP_DEL_EINPUT));
|
|
||||||
BMO_Connect(BMO_Get_Slot(&dupeop, BMOP_DUPE_FORIGINAL), BMO_Get_Slot(&delop, BMOP_DEL_FINPUT));
|
|
||||||
|
|
||||||
BMO_op_exec(&delop);
|
|
||||||
|
|
||||||
/*now we make our outputs by copying the dupe outputs*/
|
|
||||||
BMO_Copy_Buffer_Alloc(BMO_Get_Slot(&dupeop, BMOP_DUPE_VNEW), BMO_Get_Slot(splitop, BMOP_SPLIT_VOUTPUT));
|
|
||||||
BMO_Copy_Buffer_Alloc(BMO_Get_Slot(&dupeop, BMOP_DUPE_ENEW), BMO_Get_Slot(splitop, BMOP_SPLIT_EOUTPUT));
|
|
||||||
BMO_Copy_Buffer_Alloc(BMO_Get_Slot(&dupeop, BMOP_DUPE_FNEW), BMO_Get_Slot(splitop, BMOP_SPLIT_FOUTPUT));
|
|
||||||
|
|
||||||
/*cleanup*/
|
|
||||||
BMO_op_finish(&dupeop);
|
|
||||||
BMO_op_finish(&delop);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,310 +0,0 @@
|
|||||||
#if 0
|
|
||||||
|
|
||||||
/*
|
|
||||||
* BME_DUPLICATE.C
|
|
||||||
*
|
|
||||||
* This file contains functions for duplicating, copying, and splitting
|
|
||||||
* elements from a bmesh.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* BMESH COPY VERTEX
|
|
||||||
*
|
|
||||||
* Copy an existing vertex from one bmesh to another.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
static BMVert *bmesh_copy_vertex(BMMesh *source_mesh, BMVert *source_vertex, BMMesh *target_mesh, GHash *vhash)
|
|
||||||
{
|
|
||||||
BMVert *target_vertex = NULL;
|
|
||||||
|
|
||||||
/*create a new vertex*/
|
|
||||||
target_vertex = bmesh_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 flags*/
|
|
||||||
if(bmesh_test_flag(source_vertex, BMESH_SELECT)) bmesh_set_flag(target_vertex, BMESH_SELECT);
|
|
||||||
if(bmesh_test_flag(source_vertex, BMESH_HIDDEN)) bmesh_set_flag(target_vertex, BMESH_HIDDEN);
|
|
||||||
|
|
||||||
return target_vertex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* BMESH COPY EDGE
|
|
||||||
*
|
|
||||||
* Copy an existing edge from one bmesh to another.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
static BMEdge *bmesh_copy_edge(BMMesh *source_mesh, BMEdge *source_edge, BMMesh *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 = bmesh_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*/
|
|
||||||
if(bmesh_test_flag(source_edge, BMESH_SELECT)) bmesh_set_flag(target_edge, BMESH_SELECT);
|
|
||||||
if(bmesh_test_flag(source_edge, BMESH_HIDDEN)) bmesh_set_flag(target_edge, BMESH_SELECT);
|
|
||||||
if(bmesh_test_flag(source_edge, BMESH_SHARP)) bmesh_set_flag(target_edge, BMESH_SHARP);
|
|
||||||
if(bmesh_test_flag(source_edge, BMESH_SEAM)) bmesh_set_flag(target_edge, BMESH_SEAM);
|
|
||||||
if(bmesh_test_flag(source_edge, BMESH_FGON)) bmesh_set_flag(target_edge, BMESH_FGON);
|
|
||||||
|
|
||||||
return target_edge;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* BMESH COPY FACE
|
|
||||||
*
|
|
||||||
* Copy an existing face from one bmesh to another.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
static BMFace *bmesh_copy_face(BMMesh *source_mesh, BMFace *source_face, BMMesh *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->lbase->v);
|
|
||||||
target_vert2 = BLI_ghash_lookup(vhash, source_face->lbase->next->v);
|
|
||||||
|
|
||||||
/*lookup edges*/
|
|
||||||
i = 0;
|
|
||||||
source_loop = source_face->lbase;
|
|
||||||
do{
|
|
||||||
edar[i] = BLI_ghash_lookup(ehash, source_loop->e);
|
|
||||||
i++;
|
|
||||||
source_loop = source_loop->next;
|
|
||||||
}while(source_loop != source_face->lbase);
|
|
||||||
|
|
||||||
/*create new face*/
|
|
||||||
target_face = bmesh_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*/
|
|
||||||
if(bmesh_test_flag(source_face, BMESH_SELECT)) bmesh_set_flag(target_face, BMESH_SELECT);
|
|
||||||
if(bmesh_test_flag(source_face, BMESH_HIDDEN)) bmesh_set_flag(target_face, BMESH_HIDDEN);
|
|
||||||
|
|
||||||
/*mark the face as dirty for normal and tesselation calcs*/
|
|
||||||
bmesh_set_flag(target_face, BMESH_DIRTY);
|
|
||||||
|
|
||||||
/*copy per-loop custom data*/
|
|
||||||
source_loop = source_face->lbase;
|
|
||||||
target_loop = target_face->lbase;
|
|
||||||
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->lbase);
|
|
||||||
|
|
||||||
return target_face;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* BMESH COPY MESH
|
|
||||||
*
|
|
||||||
* Internal Copy function. copies flagged elements from
|
|
||||||
* source to target, which may in fact be the same mesh.
|
|
||||||
* Note that if __flag is 0, all elements will be copied.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void bmesh_copy_mesh(BMMesh *source, BMMesh *target, int __flag)
|
|
||||||
{
|
|
||||||
|
|
||||||
BMVert *v;
|
|
||||||
BMEdge *e, **edar;
|
|
||||||
BMLoop *l;
|
|
||||||
BMFace *f;
|
|
||||||
|
|
||||||
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 = BMeshIter_init(faces, BM_FACES, source, 0); f; f = BMeshIter_step(faces)){
|
|
||||||
if(f->len > maxlength) maxlength = f->len;
|
|
||||||
}
|
|
||||||
edar = MEM_callocN(sizeof(BMEdge*) * maxlength, "BM copy mesh edge pointer array");
|
|
||||||
|
|
||||||
/*begin modelling loop for target*/
|
|
||||||
bmesh_begin_edit(target);
|
|
||||||
|
|
||||||
/*we make special exception for __flag == 0... we copy all*/
|
|
||||||
if(!__flag){
|
|
||||||
flag = BMESH_DUPE;
|
|
||||||
for(v = BMeshIter_init(verts, BM_VERTS, source, 0); v; v = BMeshIter_step(verts)) bmesh_set_flag(v, BMESH_DUPE);
|
|
||||||
for(e = BMeshIter_init(verts, BM_EDGES, source, 0); e; e = BMeshIter_step(edges)) bmesh_set_flag(e, BMESH_DUPE);
|
|
||||||
for(f = BMeshIter_init(faces, BM_FACES, source, 0); f; f = BMeshIter_step(faces)) bmesh_set_flag(f, BMESH_DUPE);
|
|
||||||
} else{
|
|
||||||
flag = __flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*first we dupe all flagged faces and their elements from source*/
|
|
||||||
for(f = BMeshIter_init(faces, BM_FACES, source, 0); f; f= BMeshIter_step(faces)){
|
|
||||||
if(bmesh_test_flag(f, flag)){
|
|
||||||
/*vertex pass*/
|
|
||||||
for(l = BMeshIter_init(loops, BMESH_LOOP_OF_MESH, f, 0); l; l = BMeshIter_step(loops)){
|
|
||||||
if(!bmesh_test_flag(l->v, BMESH_DUPED)){
|
|
||||||
bmesh_copy_vertex(source,l->v, target, vhash);
|
|
||||||
bmesh_set_flag(l->v, BMESH_DUPED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*edge pass*/
|
|
||||||
for(l = BMeshIter_init(loops, BMESH_LOOP_OF_MESH, f, 0); l; l = BMeshIter_step(loops)){
|
|
||||||
if(!bmesh_test_flag(l->e, BMESH_DUPED)){
|
|
||||||
bmesh_copy_edge(source, l->e, target, vhash, ehash);
|
|
||||||
bmesh_set_flag(l->e, BMESH_DUPED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bmesh_copy_face(source, f, target, edar, vhash, ehash);
|
|
||||||
bmesh_set_flag(f, BMESH_DUPED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*now we dupe all the edges*/
|
|
||||||
for(e = BMeshIter_init(edges, BM_EDGES, source, 0); e; e = BMeshIter_step(edges)){
|
|
||||||
if(bmesh_test_flag(e, flag) && (!bmesh_test_flag(e, BMESH_DUPED))){
|
|
||||||
/*make sure that verts are copied*/
|
|
||||||
if(!bmesh_test_flag(e->v1, BMESH_DUPED)){
|
|
||||||
bmesh_copy_vertex(source, e->v1, target, vhash);
|
|
||||||
bmesh_set_flag(e->v1, BMESH_DUPED);
|
|
||||||
}
|
|
||||||
if(!bmesh_test_flag(e->v2, BMESH_DUPED)){
|
|
||||||
bmesh_copy_vertex(source, e->v2, target, vhash);
|
|
||||||
bmesh_set_flag(e->v2, BMESH_DUPED);
|
|
||||||
}
|
|
||||||
/*now copy the actual edge*/
|
|
||||||
bmesh_copy_edge(source, e, target, vhash, ehash);
|
|
||||||
bmesh_set_flag(e, BMESH_DUPED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*finally dupe all loose vertices*/
|
|
||||||
for(v = BMeshIter_init(verts, BM_VERTS, bm, 0); v; v = BMeshIter_step(verts)){
|
|
||||||
if(bmesh_test_flag(v, flag) && (!bmesh_test_flag(v, BMESH_DUPED))){
|
|
||||||
bmesh_copy_vertex(source, v, target, vhash);
|
|
||||||
bmesh_set_flag(v, BMESH_DUPED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*finish*/
|
|
||||||
bmesh_end_edit(target, BMESH_CALC_NORM | BMESH_CALC_TESS);
|
|
||||||
|
|
||||||
/*free pointer hashes*/
|
|
||||||
BLI_ghash_free(vhash, NULL, NULL);
|
|
||||||
BLI_ghash_free(ehash, NULL, NULL);
|
|
||||||
|
|
||||||
/*free edge pointer array*/
|
|
||||||
MEM_freeN(edar);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* BMESH MAKE MESH FROM MESH
|
|
||||||
*
|
|
||||||
* Creates a new mesh by duplicating an existing one.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
BMMesh *bmesh_make_mesh_from_mesh(BMMesh *bm, int allocsize[4])
|
|
||||||
{
|
|
||||||
BMMesh *target = NULL;
|
|
||||||
target = bmesh_make_mesh(allocsize);
|
|
||||||
|
|
||||||
/*copy custom data layout*/
|
|
||||||
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);
|
|
||||||
|
|
||||||
/*initialize memory pools*/
|
|
||||||
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); /* copy all elements */
|
|
||||||
|
|
||||||
bmesh_end_edit(bm);
|
|
||||||
bmesh_end_edit(target);
|
|
||||||
|
|
||||||
return target;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* BMESH SPLIT MESH
|
|
||||||
*
|
|
||||||
* Copies flagged elements then deletes them.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void bmesh_split_mesh(BMMesh *bm, int flag)
|
|
||||||
{
|
|
||||||
BMVert *v;
|
|
||||||
BMEdge *e;
|
|
||||||
BMFace *f;
|
|
||||||
|
|
||||||
BMIter verts;
|
|
||||||
BMIter edges;
|
|
||||||
BMIter faces;
|
|
||||||
|
|
||||||
bmesh_begin_edit(bm);
|
|
||||||
bmesh_copy_mesh(bm, bm, flag);
|
|
||||||
|
|
||||||
/*mark verts for deletion*/
|
|
||||||
for(v = BMeshIter_init(verts, BM_VERTS, bm, 0); v; v = BMeshIter_step(verts)){
|
|
||||||
if(bmesh_test_flag(v, flag)) bmesh_delete_vert(bm, v);
|
|
||||||
}
|
|
||||||
/*mark edges for deletion*/
|
|
||||||
for(e = BMeshIter_init(edges, BM_EDGES, bm, 0); e; e = BMeshIter_step(edges)){
|
|
||||||
if(bmesh_test_flag(e, flag)) bmesh_delete_edge(bm, e);
|
|
||||||
|
|
||||||
}
|
|
||||||
/*mark faces for deletion*/
|
|
||||||
for(f = BMeshIter_init(faces, BM_FACES, bm, 0); f; f= BMeshIter_step(faces)){
|
|
||||||
if(bmesh_tes t_flag(f, flag)) bmesh_delete_face(bm, f);
|
|
||||||
|
|
||||||
}
|
|
||||||
bmesh_end_edit(bm);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,341 +0,0 @@
|
|||||||
#if
|
|
||||||
|
|
||||||
/*
|
|
||||||
* BME_WELD.C
|
|
||||||
*
|
|
||||||
* This file contains functions for welding
|
|
||||||
* elements in a mesh togather (remove doubles,
|
|
||||||
* collapse, ect).
|
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
* -Rewrite this to fit into the new API
|
|
||||||
* -Seperate out find doubles code and put it in
|
|
||||||
* BME_queries.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/********* qsort routines *********/
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct xvertsort {
|
|
||||||
float x;
|
|
||||||
BMVert *v1;
|
|
||||||
} xvertsort;
|
|
||||||
|
|
||||||
static int vergxco(const void *v1, const void *v2)
|
|
||||||
{
|
|
||||||
const xvertsort *x1=v1, *x2=v2;
|
|
||||||
|
|
||||||
if( x1->x > x2->x ) return 1;
|
|
||||||
else if( x1->x < x2->x) return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct facesort {
|
|
||||||
unsigned long x;
|
|
||||||
struct BMFace *f;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static int vergface(const void *v1, const void *v2)
|
|
||||||
{
|
|
||||||
const struct facesort *x1=v1, *x2=v2;
|
|
||||||
|
|
||||||
if( x1->x > x2->x ) return 1;
|
|
||||||
else if( x1->x < x2->x) return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*break this into two functions.... 'find doubles' and 'remove doubles'?*/
|
|
||||||
|
|
||||||
static void BME_remove_doubles__splitface(BME_Mesh *bm,BMFace *f,GHash *vhash)
|
|
||||||
{
|
|
||||||
BMVert *doub=NULL, *target=NULL;
|
|
||||||
BME_Loop *l;
|
|
||||||
BMFace *f2=NULL;
|
|
||||||
int split=0;
|
|
||||||
|
|
||||||
l=f->loopbase;
|
|
||||||
do{
|
|
||||||
if(l->v->tflag1 == 2){
|
|
||||||
target = BLI_ghash_lookup(vhash,l->v);
|
|
||||||
if((BME_vert_in_face(target,f)) && (target != l->next->v) && (target != l->prev->v)){
|
|
||||||
doub = l->v;
|
|
||||||
split = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
l= l->next;
|
|
||||||
}while(l!= f->loopbase);
|
|
||||||
|
|
||||||
if(split){
|
|
||||||
f2 = BME_SFME(bm,f,doub,target,NULL);
|
|
||||||
BME_remove_doubles__splitface(bm,f,vhash);
|
|
||||||
BME_remove_doubles__splitface(bm,f2,vhash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int BME_remove_doubles(BME_Mesh *bm, float limit)
|
|
||||||
{
|
|
||||||
|
|
||||||
/* all verts with (flag & 'flag') are being evaluated */
|
|
||||||
BMVert *v, *v2, *target;
|
|
||||||
BMEdge *e, **edar, *ne;
|
|
||||||
BME_Loop *l;
|
|
||||||
BMFace *f, *nf;
|
|
||||||
xvertsort *sortblock, *sb, *sb1;
|
|
||||||
struct GHash *vhash;
|
|
||||||
struct facesort *fsortblock, *vsb, *vsb1;
|
|
||||||
int a, b, test, amount=0, found;
|
|
||||||
float dist;
|
|
||||||
|
|
||||||
/*Build a hash table of doubles to thier target vert/edge.*/
|
|
||||||
vhash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
|
|
||||||
|
|
||||||
/*count amount of selected vertices*/
|
|
||||||
for(v=BME_first(bm,BME_VERT);v;v=BME_next(bm,BME_VERT,v)){
|
|
||||||
if(BME_SELECTED(v))amount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*qsort vertices based upon average of coordinate. We test this way first.*/
|
|
||||||
sb= sortblock= MEM_mallocN(sizeof(xvertsort)*amount,"sortremovedoub");
|
|
||||||
|
|
||||||
for(v=BME_first(bm,BME_VERT);v;v=BME_next(bm,BME_VERT,v)){
|
|
||||||
if(BME_SELECTED(v)){
|
|
||||||
sb->x = v->co[0]+v->co[1]+v->co[2];
|
|
||||||
sb->v1 = v;
|
|
||||||
sb++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
qsort(sortblock, amount, sizeof(xvertsort), vergxco);
|
|
||||||
|
|
||||||
/* test for doubles */
|
|
||||||
sb= sortblock;
|
|
||||||
for(a=0; a<amount; a++) {
|
|
||||||
v= sb->v1;
|
|
||||||
if(!(v->tflag1)) { //have we tested yet?
|
|
||||||
sb1= sb+1;
|
|
||||||
for(b=a+1; b<amount; b++) {
|
|
||||||
/* first test: simple distance. Simple way to discard*/
|
|
||||||
dist= sb1->x - sb->x;
|
|
||||||
if(dist > limit) break;
|
|
||||||
|
|
||||||
/* second test: have we already done this vertex?
|
|
||||||
(eh this should be swapped, simple equality test should be cheaper than math above... small savings
|
|
||||||
though) */
|
|
||||||
v2= sb1->v1;
|
|
||||||
if(!(v2->tflag1)) {
|
|
||||||
dist= fabsf(v2->co[0]-v->co[0]);
|
|
||||||
if(dist<=limit) {
|
|
||||||
dist= fabsf(v2->co[1]-v->co[1]);
|
|
||||||
if(dist<=limit) {
|
|
||||||
dist= fabsf(v2->co[2]-v->co[2]);
|
|
||||||
if(dist<=limit) {
|
|
||||||
/*v2 is a double of v. We want to throw out v1 and relink everything to v*/
|
|
||||||
BLI_ghash_insert(vhash,v2, v);
|
|
||||||
v->tflag1 = 1; //mark this vertex as a target
|
|
||||||
v->tflag2++; //increase user count for this vert.
|
|
||||||
v2->tflag1 = 2; //mark this vertex as a double.
|
|
||||||
BME_VISIT(v2); //mark for delete
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sb1++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sb++;
|
|
||||||
}
|
|
||||||
MEM_freeN(sortblock);
|
|
||||||
|
|
||||||
|
|
||||||
/*todo... figure out what this is for...
|
|
||||||
for(eve = em->verts.first; eve; eve=eve->next)
|
|
||||||
if((eve->f & flag) && (eve->f & 128))
|
|
||||||
EM_data_interp_from_verts(eve, eve->tmp.v, eve->tmp.v, 0.5f);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*We cannot collapse a vertex onto another vertex if they share a face and are not connected via a collapsable edge.
|
|
||||||
so to deal with this we simply find these offending vertices and split the faces. Note that this is not optimal, but works.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
for(f=BME_first(bm,BME_POLY);f;f=BME_next(bm,BME_POLY,f)){
|
|
||||||
if(!(BME_NEWELEM(f))){
|
|
||||||
BME_remove_doubles__splitface(bm,f,vhash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(e=BME_first(bm,BME_EDGE);e;e=BME_next(bm,BME_EDGE,e)){
|
|
||||||
/*If either vertices of this edge are a double, we must mark it for removal and we create a new one.*/
|
|
||||||
if(e->v1->tflag1 == 2 || e->v2->tflag1 == 2){
|
|
||||||
v = v2 = NULL;
|
|
||||||
/*For each vertex in the edge, test to find out what it should equal now.*/
|
|
||||||
if(e->v1->tflag1 == 2) v= BLI_ghash_lookup(vhash,e->v1);
|
|
||||||
else v = e->v1;
|
|
||||||
if(e->v2->tflag1 == 2) v2 = BLI_ghash_lookup(vhash,e->v2);
|
|
||||||
else v2 = e->v2;
|
|
||||||
|
|
||||||
/*small optimization, test to see if the edge needs to be rebuilt at all*/
|
|
||||||
if((e->v1 != v) || (e->v2 != v2)){ /*will this always be true of collapsed edges?*/
|
|
||||||
if(v == v2) e->tflag1 = 2; /*mark as a collapsed edge*/
|
|
||||||
else if(!BME_disk_existedge(v,v2)) ne = BME_ME(bm,v,v2);
|
|
||||||
BME_VISIT(e); /*mark for delete*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* need to remove double edges as well. To do this we decide on one edge to keep,
|
|
||||||
* and if its inserted into hash then we need to remove all other
|
|
||||||
* edges incident upon and relink.*/
|
|
||||||
/*
|
|
||||||
* REBUILD FACES
|
|
||||||
*
|
|
||||||
* Loop through double faces and if they have vertices that have been flagged, they need to be rebuilt.
|
|
||||||
* We do this by looking up the face rebuild faces.
|
|
||||||
* loop through original face, for each loop, if the edge it is attached to is marked for delete and has no
|
|
||||||
* other edge in the hash edge, then we know to skip that loop on face recreation. Simple.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*1st loop through, just marking elements*/
|
|
||||||
for(f=BME_first(bm,BME_POLY);f;f=BME_next(bm,BME_POLY,f)){ //insert bit here about double edges, mark with a flag (e->tflag2) so that we can nuke it later.
|
|
||||||
l = f->loopbase;
|
|
||||||
do{
|
|
||||||
if(l->v->tflag1 == 2) f->tflag1 = 1; //double, mark for rebuild
|
|
||||||
if(l->e->tflag1 != 2) f->tflag2++; //count number of edges in the new face.
|
|
||||||
l=l->next;
|
|
||||||
}while(l!=f->loopbase);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*now go through and create new faces*/
|
|
||||||
for(f=BME_first(bm,BME_POLY);f;f=BME_next(bm,BME_POLY,f)){
|
|
||||||
if(f->tflag1 && f->tflag2 < 3) BME_VISIT(f); //mark for delete
|
|
||||||
else if (f->tflag1 == 1){ /*is the face marked for rebuild*/
|
|
||||||
edar = MEM_callocN(sizeof(BMEdge *)*f->tflag2,"Remove doubles face creation array.");
|
|
||||||
a=0;
|
|
||||||
l = f->loopbase;
|
|
||||||
do{
|
|
||||||
v = l->v;
|
|
||||||
v2 = l->next->v;
|
|
||||||
if(l->v->tflag1 == 2) v = BLI_ghash_lookup(vhash,l->v);
|
|
||||||
if(l->next->v->tflag1 == 2) v2 = BLI_ghash_lookup(vhash,l->next->v);
|
|
||||||
ne = BME_disk_existedge(v,v2); //use BME_disk_next_edgeflag here or something to find the edge that is marked as 'target'.
|
|
||||||
//add in call here to edge doubles hash array... then bobs your uncle.
|
|
||||||
if(ne){
|
|
||||||
edar[a] = ne;
|
|
||||||
a++;
|
|
||||||
}
|
|
||||||
l=l->next;
|
|
||||||
}while(l!=f->loopbase);
|
|
||||||
|
|
||||||
if(BME_vert_in_edge(edar[1],edar[0]->v2)){
|
|
||||||
v = edar[0]->v1;
|
|
||||||
v2 = edar[0]->v2;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
v = edar[0]->v2;
|
|
||||||
v2 = edar[0]->v1;
|
|
||||||
}
|
|
||||||
|
|
||||||
nf = BME_MF(bm,v,v2,edar,f->tflag2);
|
|
||||||
|
|
||||||
/*copy per loop data here*/
|
|
||||||
if(nf){
|
|
||||||
BME_VISIT(f); //mark for delete
|
|
||||||
}
|
|
||||||
MEM_freeN(edar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*count amount of removed vert doubles*/
|
|
||||||
a = 0;
|
|
||||||
for(v=BME_first(bm,BME_VERT);v;v=BME_next(bm,BME_VERT,v)){
|
|
||||||
if(v->tflag1 == 2) a++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*free memory and return amount removed*/
|
|
||||||
remove_tagged_polys(bm);
|
|
||||||
remove_tagged_edges(bm);
|
|
||||||
remove_tagged_verts(bm);
|
|
||||||
BLI_ghash_free(vhash,NULL, NULL);
|
|
||||||
BME_selectmode_flush(bm);
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void BME_MeshWalk__collapsefunc(void *userData, BMEdge *applyedge)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
GHash *collected = userData;
|
|
||||||
index = BLI_ghash_size(collected);
|
|
||||||
if(!BLI_ghash_lookup(collected,applyedge->v1)){
|
|
||||||
BLI_ghash_insert(collected,index,applyedge->v1);
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
if(!BLI_ghash_lookup(collected,applyedge->v2)){
|
|
||||||
BLI_ghash_insert(collected,index,applyedge->v2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BME_collapse_edges(BME_Mesh *bm)
|
|
||||||
{
|
|
||||||
|
|
||||||
BMVert *v, *cvert;
|
|
||||||
GHash *collected;
|
|
||||||
float min[3], max[3], cent[3];
|
|
||||||
int size, i=0, j, num=0;
|
|
||||||
|
|
||||||
for(v=BME_first(bm,BME_VERT);v;v=BME_next(bm,BME_VERT,v)){
|
|
||||||
if(!(BME_ISVISITED(v)) && v->edge){
|
|
||||||
/*initiate hash table*/
|
|
||||||
collected = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
|
|
||||||
/*do the walking.*/
|
|
||||||
BME_MeshWalk(bm,v,BME_MeshWalk__collapsefunc,collected,BME_RESTRICTSELECT);
|
|
||||||
/*now loop through the hash table twice, once to calculate bounding box, second time to do the actual collapse*/
|
|
||||||
size = BLI_ghash_size(collected);
|
|
||||||
/*initial values*/
|
|
||||||
copy_v3_v3(min,v->co);
|
|
||||||
copy_v3_v3(max,v->co);
|
|
||||||
cent[0] = cent[1] = cent[2]=0;
|
|
||||||
for(i=0; i<size; i++){
|
|
||||||
cvert = BLI_ghash_lookup(collected,i);
|
|
||||||
cent[0] = cent[0] + cvert->co[0];
|
|
||||||
cent[1] = cent[1] + cvert->co[1];
|
|
||||||
cent[2] = cent[2] + cvert->co[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
cent[0] = cent[0] / size;
|
|
||||||
cent[1] = cent[1] / size;
|
|
||||||
cent[2] = cent[2] / size;
|
|
||||||
|
|
||||||
for(i=0; i<size; i++){
|
|
||||||
cvert = BLI_ghash_lookup(collected,i);
|
|
||||||
copy_v3_v3(cvert->co,cent);
|
|
||||||
num++;
|
|
||||||
}
|
|
||||||
/*free the hash table*/
|
|
||||||
BLI_ghash_free(collected,NULL, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*if any collapsed, call remove doubles*/
|
|
||||||
if(num){
|
|
||||||
//need to change selection mode here, OR do something else? Or does tool change selection mode?
|
|
||||||
//selectgrep
|
|
||||||
//first clear flags
|
|
||||||
BMEdge *e;
|
|
||||||
BMFace *f;
|
|
||||||
BME_clear_flag_all(bm,BME_VISITED);
|
|
||||||
for(v=BME_first(bm,BME_VERT); v; v=BME_next(bm,BME_VERT,v)) v->tflag1 = v->tflag2 = 0;
|
|
||||||
for(e=BME_first(bm,BME_EDGE); e; e=BME_next(bm,BME_EDGE,e)) e->tflag1 = e->tflag2 = 0;
|
|
||||||
for(f=BME_first(bm,BME_POLY); f; f=BME_next(bm,BME_POLY,f)) f->tflag1 = f->tflag2 = 0;
|
|
||||||
/*now call remove doubles*/
|
|
||||||
BME_remove_doubles(bm,0.0000001);
|
|
||||||
}
|
|
||||||
BME_selectmode_flush(bm);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -38,18 +38,18 @@ set(INC_SYS
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(SRC
|
set(SRC
|
||||||
meshtools.c
|
|
||||||
loopcut.c
|
|
||||||
mesh_ops.c
|
|
||||||
editmesh_bvh.c
|
|
||||||
editmesh_add.c
|
|
||||||
bmesh_selecthistory.c
|
|
||||||
bmesh_select.c
|
bmesh_select.c
|
||||||
bmesh_utils.c
|
bmesh_selecthistory.c
|
||||||
mesh_data.c
|
|
||||||
bmesh_tools.c
|
bmesh_tools.c
|
||||||
knifetool.c
|
bmesh_utils.c
|
||||||
editface.c
|
editface.c
|
||||||
|
editmesh_add.c
|
||||||
|
editmesh_bvh.c
|
||||||
|
knifetool.c
|
||||||
|
loopcut.c
|
||||||
|
mesh_data.c
|
||||||
|
mesh_ops.c
|
||||||
|
meshtools.c
|
||||||
|
|
||||||
editmesh_bvh.h
|
editmesh_bvh.h
|
||||||
mesh_intern.h
|
mesh_intern.h
|
||||||
|
Loading…
Reference in New Issue
Block a user