mesh DNA modficiations; two new structures added for storing ngons, MPoly and MLoop.

This commit is contained in:
Joseph Eagar 2009-05-26 04:17:47 +00:00
parent 87ce3d5626
commit 5bb09886fb
20 changed files with 540 additions and 55 deletions

View File

@ -43,6 +43,7 @@ struct MFace;
struct MEdge;
struct MVert;
struct MCol;
struct BMesh;
struct Object;
struct MTFace;
struct VecNor;
@ -54,6 +55,7 @@ extern "C" {
struct EditMesh *BKE_mesh_get_editmesh(struct Mesh *me);
void BKE_mesh_end_editmesh(struct Mesh *me, struct EditMesh *em);
struct BMesh *BKE_mesh_to_bmesh(struct Mesh *me);
void unlink_mesh(struct Mesh *me);
void free_mesh(struct Mesh *me);
@ -135,11 +137,6 @@ int mesh_layers_menu_charlen(struct CustomData *data, int type); /* use this to
void mesh_layers_menu_concat(struct CustomData *data, int type, char *str);
int mesh_layers_menu(struct CustomData *data, int type);
/*accessor functions for editmesh, all access to editmesh must
go through them!*/
struct EditMesh *EM_GetEditMesh(struct Mesh *me);
void EM_EndEditMesh(struct Mesh *me, struct EditMesh *em);
#ifdef __cplusplus
}
#endif

View File

@ -5,6 +5,12 @@ struct BMLoop;
struct DerivedMesh;
struct BMFace;
/*
ok: the EDBM module is for editmode bmesh stuff. in contrast, the
BMEdit module is for code shared with blenkernel that concerns
the BMEditMesh structure.
*/
typedef struct BMEditSelection
{
struct BMEditSelection *next, *prev;
@ -54,7 +60,7 @@ typedef struct BMEditMesh {
int mat_nr;
} BMEditMesh;
void TM_RecalcTesselation(BMEditMesh *tm);
BMEditMesh *TM_Create(BMesh *bm);
BMEditMesh *TM_Copy(BMEditMesh *tm);
void TM_Free(BMEditMesh *em);
void BMEdit_RecalcTesselation(BMEditMesh *tm);
BMEditMesh *BMEdit_Create(BMesh *bm);
BMEditMesh *BMEdit_Copy(BMEditMesh *tm);
void BMEdit_Free(BMEditMesh *em);

View File

@ -711,6 +711,8 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL},
{sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
{sizeof(MPoly), "MPoly", 1, "NGon Face", NULL, NULL, NULL, NULL, NULL},
{sizeof(MLoop), "MLoop", 1, "NGon Face-Vertex", NULL, NULL, NULL, NULL, NULL},
};
const char *LAYERTYPENAMES[CD_NUMTYPES] = {
@ -720,17 +722,20 @@ const char *LAYERTYPENAMES[CD_NUMTYPES] = {
"CDMloopCol", "CDTangent", "CDMDisps", "CDWeightMCol"};
const CustomDataMask CD_MASK_BAREMESH =
CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE | CD_MASK_MPOLY;
const CustomDataMask CD_MASK_MESH =
CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE |
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL |
CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS;
CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS |
CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MPOLY | CD_MASK_MLOOP;
const CustomDataMask CD_MASK_EDITMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV |
CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS;
const CustomDataMask CD_MASK_DERIVEDMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_WEIGHT_MCOL;
const CustomDataMask CD_MASK_BMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;

View File

@ -90,18 +90,18 @@
#include "bmesh.h"
BMEditMesh *TM_Create(BMesh *bm)
BMEditMesh *BMEdit_Create(BMesh *bm)
{
BMEditMesh *tm = MEM_callocN(sizeof(BMEditMesh), "tm");
tm->bm = bm;
TM_RecalcTesselation(tm);
BMEdit_RecalcTesselation(tm);
return tm;
}
BMEditMesh *TM_Copy(BMEditMesh *tm)
BMEditMesh *BMEdit_Copy(BMEditMesh *tm)
{
BMEditMesh *tm2 = MEM_callocN(sizeof(BMEditMesh), "tm2");
*tm2 = *tm;
@ -111,7 +111,7 @@ BMEditMesh *TM_Copy(BMEditMesh *tm)
tm2->looptris = NULL;
tm2->bm = BM_Copy_Mesh(tm->bm);
TM_RecalcTesselation(tm2);
BMEdit_RecalcTesselation(tm2);
tm2->vert_index = NULL;
tm2->edge_index = NULL;
@ -120,7 +120,7 @@ BMEditMesh *TM_Copy(BMEditMesh *tm)
return tm2;
}
void TM_RecalcTesselation(BMEditMesh *tm)
void BMEdit_RecalcTesselation(BMEditMesh *tm)
{
BMesh *bm = tm->bm;
BMLoop **looptris = NULL;
@ -198,7 +198,7 @@ void TM_RecalcTesselation(BMEditMesh *tm)
}
/*does not free the BMEditMesh struct itself*/
void TM_Free(BMEditMesh *em)
void BMEdit_Free(BMEditMesh *em)
{
if(em->derivedFinal) {
if (em->derivedFinal!=em->derivedCage) {
@ -221,6 +221,8 @@ void TM_Free(BMEditMesh *em)
if (em->vert_index) MEM_freeN(em->vert_index);
if (em->edge_index) MEM_freeN(em->edge_index);
if (em->face_index) MEM_freeN(em->face_index);
BM_Free_Mesh(em->bm);
}

View File

@ -72,6 +72,8 @@
#include "BLI_editVert.h"
#include "BLI_arithb.h"
#include "bmesh.h"
EditMesh *BKE_mesh_get_editmesh(Mesh *me)
{
return bmesh_to_editmesh(me->edit_btmesh->bm);
@ -79,10 +81,8 @@ EditMesh *BKE_mesh_get_editmesh(Mesh *me)
void BKE_mesh_end_editmesh(Mesh *me, EditMesh *em)
{
BM_Free_Mesh(me->edit_btmesh->bm);
me->edit_btmesh->bm = editmesh_to_bmesh(em);
TM_RecalcTesselation(me->edit_btmesh);
BMEdit_RecalcTesselation(me->edit_btmesh);
}
@ -97,6 +97,14 @@ void mesh_update_customdata_pointers(Mesh *me)
me->mface = CustomData_get_layer(&me->fdata, CD_MFACE);
me->mcol = CustomData_get_layer(&me->fdata, CD_MCOL);
me->mtface = CustomData_get_layer(&me->fdata, CD_MTFACE);
me->mpoly = CustomData_get_layer(&me->pdata, CD_MPOLY);
me->mloop = CustomData_get_layer(&me->ldata, CD_MLOOP);
me->mtpoly = CustomData_get_layer(&me->pdata, CD_MTEXPOLY);
me->mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
me->mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV);
}
/* Note: unlinking is called when me->id.us is 0, question remains how
@ -145,6 +153,8 @@ void free_mesh(Mesh *me)
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);
if(me->mat) MEM_freeN(me->mat);
@ -209,6 +219,7 @@ Mesh *copy_mesh(Mesh *me)
{
Mesh *men;
MTFace *tface;
MTexPoly *txface;
int a, i;
men= copy_libblock(me);
@ -222,6 +233,8 @@ Mesh *copy_mesh(Mesh *me)
CustomData_copy(&me->vdata, &men->vdata, CD_MASK_MESH, CD_DUPLICATE, men->totvert);
CustomData_copy(&me->edata, &men->edata, CD_MASK_MESH, CD_DUPLICATE, men->totedge);
CustomData_copy(&me->fdata, &men->fdata, CD_MASK_MESH, CD_DUPLICATE, men->totface);
CustomData_copy(&me->ldata, &men->ldata, CD_MASK_MESH, CD_DUPLICATE, men->totloop);
CustomData_copy(&me->pdata, &men->pdata, CD_MASK_MESH, CD_DUPLICATE, men->totpoly);
mesh_update_customdata_pointers(men);
/* ensure indirect linked data becomes lib-extern */
@ -234,7 +247,17 @@ Mesh *copy_mesh(Mesh *me)
id_lib_extern((ID*)tface->tpage);
}
}
for(i=0; i<me->pdata.totlayer; i++) {
if(me->pdata.layers[i].type == CD_MTEXPOLY) {
txface= (MTexPoly*)me->pdata.layers[i].data;
for(a=0; a<me->totpoly; a++, txface++)
if(txface->tpage)
id_lib_extern((ID*)txface->tpage);
}
}
men->mselect= NULL;
men->bb= MEM_dupallocN(men->bb);
@ -245,12 +268,43 @@ Mesh *copy_mesh(Mesh *me)
return men;
}
BMesh *BKE_mesh_to_bmesh(Mesh *me)
{
BMesh *bm;
int allocsize[4] = {512,512,2048,512};
bm = BM_Make_Mesh(allocsize);
BMO_CallOpf(bm, "mesh_to_bmesh mesh=%p", me);
return bm;
}
void make_local_tface(Mesh *me)
{
MTFace *tface;
MTexPoly *txface;
Image *ima;
int a, i;
for(i=0; i<me->pdata.totlayer; i++) {
if(me->pdata.layers[i].type == CD_MTEXPOLY) {
txface= (MTexPoly*)me->fdata.layers[i].data;
for(a=0; a<me->totpoly; a++, txface++) {
/* special case: ima always local immediately */
if(txface->tpage) {
ima= txface->tpage;
if(ima->id.lib) {
ima->id.lib= 0;
ima->id.flag= LIB_LOCAL;
new_id(0, (ID *)ima, 0);
}
}
}
}
}
for(i=0; i<me->fdata.totlayer; i++) {
if(me->fdata.layers[i].type == CD_MTFACE) {
tface= (MTFace*)me->fdata.layers[i].data;
@ -268,6 +322,7 @@ void make_local_tface(Mesh *me)
}
}
}
}
void make_local_mesh(Mesh *me)

View File

@ -3004,6 +3004,26 @@ static void lib_link_customdata_mtface(FileData *fd, Mesh *me, CustomData *fdata
}
static void lib_link_customdata_mtpoly(FileData *fd, Mesh *me, CustomData *pdata, int totface)
{
int i;
for(i=0; i<pdata->totlayer; i++) {
CustomDataLayer *layer = &pdata->layers[i];
if(layer->type == CD_MTEXPOLY) {
MTexPoly *tf= layer->data;
int i;
for (i=0; i<totface; i++, tf++) {
tf->tpage= newlibadr(fd, me->id.lib, tf->tpage);
if(tf->tpage && tf->tpage->id.us==0)
tf->tpage->id.us= 1;
}
}
}
}
static void lib_link_mesh(FileData *fd, Main *main)
{
Mesh *me;
@ -3030,6 +3050,7 @@ static void lib_link_mesh(FileData *fd, Main *main)
me->texcomesh= newlibadr_us(fd, me->id.lib, me->texcomesh);
lib_link_customdata_mtface(fd, me, &me->fdata, me->totface);
lib_link_customdata_mtpoly(fd, me, &me->pdata, me->totpoly);
if(me->mr && me->mr->levels.first)
lib_link_customdata_mtface(fd, me, &me->mr->fdata,
((MultiresLevel*)me->mr->levels.first)->totface);
@ -3093,12 +3114,17 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
mesh->mvert= newdataadr(fd, mesh->mvert);
mesh->medge= newdataadr(fd, mesh->medge);
mesh->mface= newdataadr(fd, mesh->mface);
mesh->mloop= newdataadr(fd, mesh->mloop);
mesh->mpoly= newdataadr(fd, mesh->mpoly);
mesh->tface= newdataadr(fd, mesh->tface);
mesh->mtface= newdataadr(fd, mesh->mtface);
mesh->mcol= newdataadr(fd, mesh->mcol);
mesh->msticky= newdataadr(fd, mesh->msticky);
mesh->dvert= newdataadr(fd, mesh->dvert);
mesh->mloopcol= newdataadr(fd, mesh->mloopcol);
mesh->mloopuv= newdataadr(fd, mesh->mloopuv);
mesh->mtpoly= newdataadr(fd, mesh->mtpoly);
/* Partial-mesh visibility (do this before using totvert, totface, or totedge!) */
mesh->pv= newdataadr(fd, mesh->pv);
if(mesh->pv) {
@ -3115,6 +3141,8 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
direct_link_customdata(fd, &mesh->vdata, mesh->pv ? mesh->pv->totvert : mesh->totvert);
direct_link_customdata(fd, &mesh->edata, mesh->pv ? mesh->pv->totedge : mesh->totedge);
direct_link_customdata(fd, &mesh->fdata, mesh->pv ? mesh->pv->totface : mesh->totface);
direct_link_customdata(fd, &mesh->ldata, mesh->totloop);
direct_link_customdata(fd, &mesh->pdata, mesh->totpoly);
mesh->bb= NULL;
mesh->mselect = NULL;

View File

@ -1336,6 +1336,8 @@ static void write_meshs(WriteData *wd, ListBase *idbase)
write_customdata(wd, mesh->totvert, &mesh->vdata, -1, 0);
write_customdata(wd, mesh->totedge, &mesh->edata, -1, 0);
write_customdata(wd, mesh->totface, &mesh->fdata, -1, 0);
write_customdata(wd, mesh->totloop, &mesh->ldata, -1, 0);
write_customdata(wd, mesh->totpoly, &mesh->pdata, -1, 0);
}
/* PMV data */

View File

@ -26,6 +26,10 @@
#define BM_EDGES_OF_MESH 2
#define BM_FACES_OF_MESH 3
#define BM_ITER(ele, iter, bm, type, data) \
ele = BMIter_New(iter, bm, type, data); \
for ( ; ele; ele=BMIter_Step(iter))
/*these are topological iterators.*/
#define BM_EDGES_OF_VERT 4
#define BM_FACES_OF_VERT 5

View File

@ -151,7 +151,8 @@ int BMO_CountFlag(struct BMesh *bm, int flag, int type);
the formatting codes are:
%d - put int in slot
%f - put float in float
%f - put float in slot
%p - put pointer in slot
%h[f/e/v] - put elements with a header flag in slot.
the letters after %h define which element types to use,
so e.g. %hf will do faces, %hfe will do faces and edges,

View File

@ -200,10 +200,10 @@ BMFace *bmesh_mf(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **elist, int len)
BMVert *curvert, *tv, **vlist;
int i, j, done, cont, edok;
if(len < 2) return NULL;
if(len < 2) goto error;
/*make sure that v1 and v2 are in elist[0]*/
if(bmesh_verts_in_edge(v1,v2,elist[0]) == 0) return NULL;
if(bmesh_verts_in_edge(v1,v2,elist[0]) == 0) goto error;
/*clear euler flags*/
for(i=0;i<len;i++) elist[i]->head.eflag1=elist[i]->head.eflag2 = 0;
@ -221,9 +221,9 @@ BMFace *bmesh_mf(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **elist, int len)
*/
for(i=0; i<len; i++){
edok = bmesh_disk_count_edgeflag(elist[i]->v1, MF_CANDIDATE, 0);
if(edok != 2) return NULL;
if(edok != 2) goto error;
edok = bmesh_disk_count_edgeflag(elist[i]->v2, MF_CANDIDATE, 0);
if(edok != 2) return NULL;
if(edok != 2) goto error;
}
/*set start edge, start vert and target vert for our loop traversal*/
@ -320,6 +320,10 @@ BMFace *bmesh_mf(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **elist, int len)
for(i=0;i<len;i++) elist[i]->head.eflag1=elist[i]->head.eflag2 = 0;
return f;
error:
for(i=0;i<len;i++) elist[i]->head.eflag1=elist[i]->head.eflag2 = 0;
return NULL;
}
/* KILL Eulers */

View File

@ -3,6 +3,26 @@
#include <stdio.h>
/*loads a bmesh into an object*/
BMOpDefine def_object_load_bmesh = {
"object_load_bmesh",
/*pointer to a mesh struct*/
{{BMOP_OPSLOT_PNT, "scene"},
{BMOP_OPSLOT_PNT, "object"},
{0, /*null-terminating sentinel*/}},
bmesh_to_mesh_exec,
0
};
BMOpDefine def_mesh_to_bmesh = {
"mesh_to_bmesh",
{{BMOP_OPSLOT_PNT, "me"},
{0, /*null-terminating sentinel*/}},
mesh_to_bmesh_exec,
0
};
BMOpDefine def_extrudeverts_indiv = {
"extrude_vert_indiv",
{{BMOP_OPSLOT_ELEMENT_BUF, "verts"},
@ -167,6 +187,8 @@ BMOpDefine *opdefines[] = {
&def_connectverts,
//&def_makeprim,
&def_extrudeverts_indiv,
&def_mesh_to_bmesh,
&def_object_load_bmesh,
};
int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));

View File

@ -966,10 +966,11 @@ static int bmesh_opname_to_opcode(char *opname) {
int BMO_VInitOpf(BMesh *bm, BMOperator *op, char *fmt, va_list vlist)
{
int i, n=strlen(fmt), stop, slotcode = -1, ret, type, state, c;
BMOpDefine *def;
char *opname, *ofmt;
char slotname[64] = {0};
BMOpDefine *def;
int i, n=strlen(fmt), stop, slotcode = -1, ret, type, state, c;
int noslot=0;
/*we muck around in here, so dup it*/
fmt = ofmt = strdup(fmt);
@ -978,9 +979,10 @@ int BMO_VInitOpf(BMesh *bm, BMOperator *op, char *fmt, va_list vlist)
i = strcspn(fmt, " \t");
opname = fmt;
if (!opname[i]) noslot = 1;
opname[i] = 0;
fmt += i + 1;
fmt += i + (noslot ? 0 : 1);
for (i=0; i<bmesh_total_ops; i++) {
if (!strcmp(opname, opdefines[i]->name)) break;
@ -1031,6 +1033,10 @@ int BMO_VInitOpf(BMesh *bm, BMOperator *op, char *fmt, va_list vlist)
BMO_Set_Int(op, slotname, va_arg(vlist, int));
state = 1;
break;
case 'p':
BMO_Set_Pnt(op, slotname, va_arg(vlist, void*));
state = 1;
break;
case 'f':
case 'h':
type = *fmt;

View File

@ -21,5 +21,7 @@ void extrude_edge_context_exec(BMesh *bm, BMOperator *op);
void connectverts_exec(BMesh *bm, BMOperator *op);
void makeprim_exec(BMesh *bm, BMOperator *op);
void extrude_vert_indiv_exec(BMesh *bm, BMOperator *op);
void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op);
void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op);
#endif

View File

@ -445,7 +445,7 @@ BMesh *editmesh_to_bmesh(EditMesh *em)
{
BMOperator conv;
BMesh *bm;
int allocsize[4] = {512,512,2048,512}, numTex, numCol;
int allocsize[4] = {512,512,2048,512};
/*allocate a bmesh*/
bm = BM_Make_Mesh(allocsize);

View File

@ -0,0 +1,301 @@
#include "MEM_guardedalloc.h"
#include "BKE_customdata.h"
#include "DNA_listBase.h"
#include "DNA_customdata_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include <string.h>
#include "BKE_utildefines.h"
#include "BKE_mesh.h"
#include "BKE_global.h"
#include "BKE_DerivedMesh.h"
#include "BKE_cdderivedmesh.h"
#include "BLI_editVert.h"
#include "mesh_intern.h"
#include "ED_mesh.h"
#include "BLI_blenlib.h"
#include "BLI_edgehash.h"
#include "bmesh.h"
/*
* MESH CONV.C
*
* This file contains functions
* for converting a Mesh
* into a Bmesh. will not support non-ngon
* meshes at first, use the editmesh functions
* until it's implemented, and remove this
* comment if it already is. -joeedh
*
*/
void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) {
Mesh *me = BMO_Get_Pnt(op, "me");
MVert *mvert;
MEdge *medge;
MLoop *ml;
MPoly *mpoly;
BMVert *v, **vt=NULL;
BMEdge *e, **fedges=NULL, **et;
V_DECLARE(fedges);
BMFace *f;
int i, j;
if (!me || !me->totvert) return; /*sanity check*/
mvert = me->mvert;
vt = MEM_mallocN(sizeof(void**)*me->totvert, "mesh to bmesh vtable");
for (i=0; i<me->totvert; i++, mvert++) {
v = BM_Make_Vert(bm, mvert->co, NULL);
VECCOPY(v->no, mvert->no);
vt[i] = v;
BMINDEX_SET(v, i);
/*transfer flags*/
v->head.flag = (mvert->flag & ME_HIDE) ? BM_HIDDEN : 0;
if(mvert->flag & SELECT) BM_Select_Vert(bm, v, 1);
v->bweight = (float)mvert->bweight / 255.0f;
/*Copy Custom Data*/
CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->data);
}
if (!me->totedge) return;
et = MEM_mallocN(sizeof(void**)*me->totedge, "mesh to bmesh etable");
medge = me->medge;
for (i=0; i<me->totedge; i++, medge++) {
e = BM_Make_Edge(bm, vt[medge->v1], vt[medge->v2], NULL, 0);
et[i] = e;
/*Copy Custom Data*/
CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->data);
e->crease = (float)medge->crease / 255.0f;
e->bweight = (float)medge->bweight / 255.0f;
if (medge->flag & SELECT) BM_Select_Edge(bm, e, 1);
if (medge->flag & ME_HIDE) BM_SetHFlag(e, BM_HIDDEN);
if (medge->flag & ME_SHARP) BM_SetHFlag(e, BM_SHARP);
if (medge->flag & ME_SEAM) BM_SetHFlag(e, BM_SEAM);
}
if (!me->totpoly) return;
mpoly = me->mpoly;
for (i=0; i<me->totpoly; i++, mpoly++) {
BMVert *v1, *v2;
V_RESET(fedges);
for (j=0; j<mpoly->totloop; j++) {
ml = &me->mloop[mpoly->loopstart+j];
v = vt[ml->v];
e = et[ml->e];
V_GROW(fedges);
fedges[j] = e;
}
v1 = vt[me->mloop[mpoly->loopstart].v];
v2 = vt[me->mloop[mpoly->loopstart+1].v];
if (v1 == fedges[0]->v1) v2 = fedges[0]->v2;
else {
v1 = fedges[0]->v2;
v2 = fedges[0]->v1;
}
f = BM_Make_Ngon(bm, v1, v2, fedges, mpoly->totloop, 0);
/*Copy Custom Data*/
CustomData_to_bmesh_block(&me->fdata, &bm->pdata, i, &f->data);
}
}
void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) {
BMesh *bmtess;
Object *ob = BMO_Get_Pnt(op, "object");
Scene *scene = BMO_Get_Pnt(op, "scene");
Mesh *me = ob->data;
MLoop *mloop;
MPoly *mpoly;
MVert *mvert, *oldverts;
MEdge *medge;
MFace *mface;
BMVert *v;
BMEdge *e;
BMLoop *l;
BMFace *f;
BMIter iter, liter;
int i, j, ototvert, totloop;
/*we'll going to have the bmesh-to-editmesh operator
do most the work, then layer in ngon data, hehehe*/
bmtess = BM_Copy_Mesh(bm);
BMO_CallOpf(bmtess, "makefgon");
/* new Vertex block */
if(bm->totvert==0) mvert= NULL;
else mvert= MEM_callocN(bm->totvert*sizeof(MVert), "loadeditbMesh vert");
/* new Edge block */
if(bm->totedge==0) medge= NULL;
else medge= MEM_callocN(bm->totedge*sizeof(MEdge), "loadeditbMesh edge");
/* new Face block */
if(bmtess->totface==0) mface= NULL;
else mface= MEM_callocN(bmtess->totface*sizeof(MFace), "loadeditbMesh face");
/*build ngon data*/
/* new Ngon Face block */
if(bm->totface==0) mpoly = NULL;
else mpoly= MEM_callocN(bm->totface*sizeof(MPoly), "loadeditbMesh poly");
/*find number of loops to allocate*/
totloop = 0;
BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
totloop += f->len;
}
if (totloop==0) mloop = NULL;
else mloop = MEM_callocN(totloop*sizeof(MLoop), "loadeditbMesh loop");
/* lets save the old verts just in case we are actually working on
* a key ... we now do processing of the keys at the end */
oldverts= me->mvert;
/* don't free this yet */
CustomData_set_layer(&me->vdata, CD_MVERT, NULL);
/* free custom data */
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);
/* add new custom data */
me->totvert= bm->totvert;
me->totedge= bm->totedge;
me->totface= bmtess->totface;
me->totloop= totloop;
me->totpoly= bm->totface;
CustomData_copy(&bm->vdata, &me->vdata, CD_MASK_MESH, CD_CALLOC, me->totvert);
CustomData_copy(&bm->edata, &me->edata, CD_MASK_MESH, CD_CALLOC, me->totedge);
CustomData_copy(&bm->ldata, &me->ldata, CD_MASK_MESH, CD_CALLOC, me->totloop);
CustomData_copy(&bm->pdata, &me->pdata, CD_MASK_MESH, CD_CALLOC, me->totpoly);
CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, mvert, me->totvert);
CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, me->totedge);
CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, mface, me->totface);
CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, mloop, me->totloop);
CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, mpoly, me->totpoly);
mesh_update_customdata_pointers(me);
/*set indices*/
i = 0;
BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
VECCOPY(mvert->co, v->co);
mvert->no[0] = (unsigned char) (v->no[0]*255.0f);
mvert->no[1] = (unsigned char) (v->no[1]*255.0f);
mvert->no[2] = (unsigned char) (v->no[2]*255.0f);
if (BM_TestHFlag(v, BM_SELECT)) mvert->flag |= SELECT;
if (BM_TestHFlag(v, BM_HIDDEN)) mvert->flag |= ME_HIDE;
BMINDEX_SET(v, i);
i++;
mvert++;
}
i = 0;
BM_ITER(v, &iter, bmtess, BM_VERTS_OF_MESH, NULL) {
BMINDEX_SET(v, i);
i++;
}
i = 0;
BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
medge->v1 = BMINDEX_GET(e->v1);
medge->v2 = BMINDEX_GET(e->v2);
if (BM_TestHFlag(e, BM_SELECT)) medge->flag |= SELECT;
if (BM_TestHFlag(e, BM_HIDDEN)) medge->flag |= ME_HIDE;
if (BM_TestHFlag(e, BM_SHARP)) medge->flag |= ME_SEAM;
if (BM_TestHFlag(e, BM_SEAM)) medge->flag |= ME_SHARP;
BMINDEX_SET(e, i);
i++;
medge++;
}
i = 0;
BM_ITER(f, &iter, bmtess, BM_FACES_OF_MESH, NULL) {
if (BM_TestHFlag(f, BM_SELECT)) mface->flag |= ME_FACE_SEL;
if (BM_TestHFlag(f, BM_HIDDEN)) mface->flag |= ME_HIDE;
if (BM_TestHFlag(f, BM_SMOOTH)) mface->flag |= ME_SMOOTH;
mface->mat_nr = f->mat_nr;
mface->v1 = BMINDEX_GET(f->loopbase->v);
mface->v2 = BMINDEX_GET(((BMLoop*)f->loopbase->head.next)->v);
if (f->len < 3) {
mface++;
i++;
continue;
}
mface->v3 = BMINDEX_GET(((BMLoop*)f->loopbase->head.next->next)->v);
if (f->len < 4) {
mface->v4 = 0;
mface++;
i++;
continue;
}
mface->v4 = BMINDEX_GET(((BMLoop*)f->loopbase->head.next->next->next)->v);
test_index_face(mface, &me->fdata, i, 1);
mface++;
i++;
}
i = 0;
j = 0;
BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
if (BM_TestHFlag(f, BM_SELECT)) mpoly->flag |= ME_FACE_SEL;
if (BM_TestHFlag(f, BM_HIDDEN)) mpoly->flag |= ME_HIDE;
if (BM_TestHFlag(f, BM_SMOOTH)) mpoly->flag |= ME_SMOOTH;
mpoly->loopstart = j;
mpoly->totloop = f->len;
mpoly->mat_nr = f->mat_nr;
//BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f);
for ( ; l; l=BMIter_Step(&liter)) {
mloop->e = BMINDEX_GET(l->e);
mloop->v = BMINDEX_GET(l->v);
mloop++;
j++;
}
i++;
mpoly++;
}
BM_Free_Mesh(bmtess);
}

View File

@ -189,7 +189,7 @@ int EDBM_CallOpfSilent(BMEditMesh *em, char *fmt, ...)
}
/*returns 0 on error, 1 on success*/
int EDBM_Finish(BMesh *bm, EditMesh *em, wmOperator *op, int report) {
int EDBM_Finish(BMesh *bm, BMEditMesh *em, wmOperator *op, int report) {
char *errmsg;
if (BMO_GetError(bm, &errmsg, NULL)) {
@ -208,29 +208,38 @@ void EDBM_MakeEditBMesh(Scene *scene, Object *ob)
EditMesh *em;
BMesh *bm;
em = make_editMesh(scene, ob);
bm = editmesh_to_bmesh(em);
if (!me->mpoly && me->totface) {
em = make_editMesh(scene, ob);
bm = editmesh_to_bmesh(em);
free_editMesh(em);
} else {
bm = BKE_mesh_to_bmesh(me);
}
me->edit_btmesh = TM_Create(bm);
me->edit_btmesh = BMEdit_Create(bm);
me->edit_btmesh->selectmode = scene->selectmode;
free_editMesh(em);
}
void EDBM_LoadEditBMesh(Scene *scene, Object *ob)
{
Mesh *me = ob->data;
BMesh *bm = me->edit_btmesh->bm;
BMO_CallOpf(bm, "object_load_bmesh scene=%p object=%p", scene, ob);
#if 0
EditMesh *em = bmesh_to_editmesh(me->edit_btmesh->bm);
load_editMesh(scene, ob, em);
free_editMesh(em);
MEM_freeN(em);
#endif
}
void EDBM_FreeEditBMesh(BMEditMesh *tm)
{
BM_Free_Mesh(tm->bm);
TM_Free(tm);
BMEdit_Free(tm);
}
void EDBM_init_index_arrays(BMEditMesh *tm, int forvert, int foredge, int forface)
@ -742,20 +751,19 @@ static void *getEditMesh(bContext *C)
static void *editbtMesh_to_undoMesh(void *emv)
{
/*we recalc the tesselation here, to avoid seeding calls to
TM_RecalcTesselation throughout the code.*/
TM_RecalcTesselation(emv);
BMEdit_RecalcTesselation throughout the code.*/
BMEdit_RecalcTesselation(emv);
return TM_Copy(emv);
return BMEdit_Copy(emv);
}
static void undoMesh_to_editbtMesh(void *umv, void *emv)
{
BMEditMesh *bm1 = umv, *bm2 = emv;
BM_Free_Mesh_Data(bm2->bm);
TM_Free(bm2);
BMEdit_Free(bm2);
*bm2 = *TM_Copy(bm1);
*bm2 = *BMEdit_Copy(bm1);
}
@ -763,8 +771,7 @@ static void free_undo(void *umv)
{
BMEditMesh *em = umv;
BM_Free_Mesh_Data(em->bm);
TM_Free(em);
BMEdit_Free(em);
}
/* and this is all the undo system needs to know */

View File

@ -48,6 +48,13 @@ struct BMFace;
#define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float));
/* ******************** bmeshutils.c */
/*
ok: the EDBM module is for editmode bmesh stuff. in contrast, the
BMEdit module is for code shared with blenkernel that concerns
the BMEditMesh structure.
*/
/*calls a bmesh op, reporting errors to the user, doing conversions,
etc.*/
int EDBM_CallOpf(struct BMEditMesh *em, struct wmOperator *op, char *fmt, ...);

View File

@ -76,7 +76,9 @@ typedef struct CustomData {
#define CD_TANGENT 18
#define CD_MDISPS 19
#define CD_WEIGHT_MCOL 20 /* for displaying weightpaint colors */
#define CD_NUMTYPES 21
#define CD_MPOLY 21
#define CD_MLOOP 22
#define CD_NUMTYPES 23
/* Bits for CustomDataMask */
#define CD_MASK_MVERT (1 << CD_MVERT)
@ -100,6 +102,8 @@ typedef struct CustomData {
#define CD_MASK_TANGENT (1 << CD_TANGENT)
#define CD_MASK_MDISPS (1 << CD_MDISPS)
#define CD_MASK_WEIGHT_MCOL (1 << CD_WEIGHT_MCOL)
#define CD_MASK_MPOLY (1 << CD_MPOLY)
#define CD_MASK_MLOOP (1 << CD_MLOOP)
/* derivedmesh wants CustomDataMask for weightpaint too, is not customdata though */
#define CD_MASK_WEIGHTPAINT (1 << CD_WEIGHTPAINT)

View File

@ -44,6 +44,11 @@ struct MCol;
struct MSticky;
struct Mesh;
struct OcInfo;
struct MPoly;
struct MTexPoly;
struct MLoop;
struct MLoopUV;
struct MLoopCol;
struct Multires;
struct PartialVisibility;
struct EditMesh;
@ -58,23 +63,35 @@ typedef struct Mesh {
struct Ipo *ipo;
struct Key *key;
struct Material **mat;
/*new face structures*/
struct MPoly *mpoly;
struct MTexPoly *mtpoly;
struct MLoop *mloop;
struct MLoopUV *mloopuv;
struct MLoopCol *mloopcol;
struct MFace *mface; /* array of mesh object mode faces */
struct MTFace *mtface; /* store face UV's and texture here */
/*mface stores the tesselation (triangulation) of the mesh,
real faces are now stored in nface.*/
struct MFace *mface; /* array of mesh object mode faces for tesselation */
struct MTFace *mtface; /* store tesselation face UV's and texture here */
struct TFace *tface; /* depecrated, use mtface */
struct MVert *mvert; /* array of verts */
struct MEdge *medge; /* array of edges */
struct MDeformVert *dvert; /* deformgroup vertices */
struct MCol *mcol; /* array of colors, this must be the number of faces * 4 */
/* array of colors for the tesselated faces, must be number of tesselated
faces * 4 in length */
struct MCol *mcol;
struct MSticky *msticky;
struct Mesh *texcomesh;
struct MSelect *mselect;
struct BMEditMesh *edit_btmesh; /* not saved in file! */
struct CustomData vdata, edata, fdata;
struct CustomData vdata, edata, fdata, pdata, ldata;
int totvert, totedge, totface, totselect;
int totvert, totedge, totface, totpoly, totloop, totselect;
/* the last selected vertex/edge/face are used for the active face however
* this means the active face must always be selected, this is to keep track

View File

@ -70,7 +70,22 @@ typedef struct MCol {
char a, r, g, b;
} MCol;
/*bmesh custom data stuff*/
/*new face structure, replaces MFace, which is now
only used for storing tesselations.*/
typedef struct MPoly {
/*offset into loop array and number of loops in the face*/
int loopstart, totloop;
char pad, mat_nr;
short flag;
} MPoly;
/*the e here is because we want to move away from
relying on edge hashes.*/
typedef struct MLoop {
int v; /*vertex index*/
int e; /*edge index*/
} MLoop;
typedef struct MTexPoly{
struct Image *tpage;
char flag, transp;