merge with 2.5 at revision 18432, made bmesh compile, and also made msvc use incremen...
authorJoseph Eagar <joeedh@gmail.com>
Fri, 9 Jan 2009 18:32:33 +0000 (18:32 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Fri, 9 Jan 2009 18:32:33 +0000 (18:32 +0000)
1  2 
config/win32-vc-config.py
source/blender/SConscript
source/blender/bmesh/SConscript
source/blender/bmesh/intern/bmesh_to_editmesh.c
source/blender/bmesh/intern/editmesh_to_bmesh.c
source/blender/editors/mesh/SConscript
source/blender/editors/mesh/mesh_intern.h
tools/Blender.py

index b21c50c913e66adb93ab8455797ae02a521dfd01,b21c50c913e66adb93ab8455797ae02a521dfd01..2fbc1b8e586213386af4add8067ed8ef7826a627
@@@ -180,7 -180,7 +180,7 @@@ CXX_WARN = [
  
  LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid']
  
--PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:IX86','/ENTRY:mainCRTStartup','/INCREMENTAL:NO','/NODEFAULTLIB:"msvcprt.lib"','/NODEFAULTLIB:"glut32.lib"','/NODEFAULTLIB:"libc.lib"','/NODEFAULTLIB:"libcd.lib"','/NODEFAULTLIB:"libcpd.lib"','/NODEFAULTLIB:"libcp.lib"','/LARGEADDRESSAWARE']
++PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:IX86','/ENTRY:mainCRTStartup','/INCREMENTAL:YES','/NODEFAULTLIB:"msvcprt.lib"','/NODEFAULTLIB:"glut32.lib"','/NODEFAULTLIB:"libc.lib"','/NODEFAULTLIB:"libcd.lib"','/NODEFAULTLIB:"libcpd.lib"','/NODEFAULTLIB:"libcp.lib"','/LARGEADDRESSAWARE']
  
  # # Todo
  # BF_PROFILE_CCFLAGS = ['-pg', '-g ']
index 93acf8a8430653b52834453b5d4a0642817ec14b,93acf8a8430653b52834453b5d4a0642817ec14b..cd00776440ae2ea4133a877402ef221401649c42
@@@ -3,6 -3,6 +3,7 @@@ Import ('env'
  import sys
  
  SConscript(['avi/SConscript',
++                      'bmesh/SConscript',
              'blenkernel/SConscript',
              'blenlib/SConscript',
              'blenloader/SConscript',
index 5cbe5f967f07997c7c68bc5636a6cfa22607ed3c,0000000000000000000000000000000000000000..d7cfa9ca942d6dbde616ec641143753adebb8023
mode 100644,000000..100644
--- /dev/null
@@@ -1,37 -1,0 +1,38 @@@
- incs.append('../include')
 +#!/usr/bin/python
 +Import ('env')
 +
 +cflags=''
 +"""
 +sources = ['intern/bmesh_eulers.c']
 +sources.append('intern/bmesh_mesh.c')
 +sources.append('intern/bmesh_polygon.c')
 +sources.append('intern/bmesh_structure.c')
 +sources.append('intern/bmesh_marking.c')
 +
 +sources.append('intern/bmesh_construct.c')
 +sources.append('intern/bmesh_interp.c')
 +sources.append('intern/bmesh_filters.c')
 +sources.append('intern/bmesh_iterators.c')
 +sources.append('intern/bmesh_mods.c')
 +sources.append('intern/bmesh_queries.c')
 +sources.append('intern/bmesh_operators.c')
 +"""
 +#sources.append('api/BME_walkers.c')
 +
 +
 +sources = env.Glob('intern/*.c')
 +sources += env.Glob('operators/*.c')
 +
 +#sources += env.Glob('tools/*.c')
 +
 +incs = ['#/intern/guardedalloc'] 
 +incs.append('../blenlib') 
 +incs.append('../makesdna')
 +incs.append('../blenkernel')
 +incs.append('./')
 +incs.append('./intern')
++incs.append('../editors/mesh')
++incs.append('../editors/include')
 +
 +defs = []
 +env.BlenderLib ( libname = 'bf_bmesh', sources = sources, includes = Split(incs), libtype = 'core', defines=defs, priority=100, compileflags=cflags )
index 8ddcac23bbb803ebdf15d6b32b1db732b64e95fc,0000000000000000000000000000000000000000..1c2630a98042c508233b13a7004128b0bcdf45f4
mode 100644,000000..100644
--- /dev/null
@@@ -1,244 -1,0 +1,243 @@@
- #include "BIF_editmesh.h"
- #include "editmesh.h"
 +#include "MEM_guardedalloc.h"
 +#include "BKE_customdata.h" 
 +#include "DNA_listBase.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"
-       eve = addvertlist(v->co, NULL);
++#include "mesh_intern.h"
++#include "ED_mesh.h"
++
 +#include "BLI_blenlib.h"
 +#include "BLI_edgehash.h"
 +
 +#include "bmesh.h"
 +
 +/*
 + * BMESH TO EDITMESH
 + *
 + * This file contains functions for converting 
 + * from a bmesh to an editmesh
 + *
 +*/
 +
 +/*
 + * LOOPS TO EDITMESH CORNERS
 + *
 + * Converts N-Gon loop (face-edge)
 + * data (UVs, Verts Colors, ect) to
 + * face corner data.
 + *
 +*/
 +
 +static void loops_to_editmesh_corners(BMesh *bm, CustomData *facedata, void *face_block, BMFace *f,int numCol, int numTex){
 +      int i, j;
 +      BMLoop *l;
 +      MTFace *texface;
 +      MTexPoly *texpoly;
 +      MCol *mcol;
 +      MLoopCol *mloopcol;
 +      MLoopUV *mloopuv;
 +
 +      for(i=0; i < numTex; i++){
 +              texface = CustomData_em_get_n(facedata, face_block, CD_MTFACE, i);
 +              texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
 +              
 +              texface->tpage = texpoly->tpage;
 +              texface->flag = texpoly->flag;
 +              texface->transp = texpoly->transp;
 +              texface->mode = texpoly->mode;
 +              texface->tile = texpoly->tile;
 +              texface->unwrap = texpoly->unwrap;
 +
 +              j = 0;
 +              l = f->loopbase;
 +              do {
 +                      mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
 +                      texface->uv[j][0] = mloopuv->uv[0];
 +                      texface->uv[j][1] = mloopuv->uv[1];
 +                      j++;
 +                      l = ((BMLoop*)(l->head.next));
 +              } while(l!=f->loopbase);
 +
 +      }
 +
 +      for(i=0; i < numCol; i++){
 +              mcol = CustomData_em_get_n(facedata, face_block, CD_MCOL, i);
 +              j = 0;
 +              l = f->loopbase;
 +              do {
 +                      mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
 +                      mcol[j].r = mloopcol->r;
 +                      mcol[j].g = mloopcol->g;
 +                      mcol[j].b = mloopcol->b;
 +                      mcol[j].a = mloopcol->a;
 +                      j++;
 +                      l = ((BMLoop*)(l->head.next));
 +              } while(l!=f->loopbase);
 +      }
 +}
 +
 +static EditVert *bmeshvert_to_editvert(BMesh *bm, EditMesh *em, BMVert *v, int index, EditVert **evlist)
 +{
 +      EditVert *eve = NULL;
 +
 +      v->head.eflag1 = index; /*abuse!*/
-       if(!(findedgelist(evlist[e->v1->head.eflag1], evlist[e->v2->head.eflag1]))){
-               eed= addedgelist(evlist[e->v1->head.eflag1], evlist[e->v2->head.eflag1], NULL);
++      eve = addvertlist(em, v->co, NULL);
 +      eve->keyindex = index;
 +      evlist[index]= eve;
 +      
 +      /*copy flags*/
 +      if(v->head.flag & BM_HIDDEN) eve->h = 1;
 +      if (v->head.flag & BM_SELECT) eve->f |= SELECT;
 +
 +      eve->bweight = v->bweight;
 +      CustomData_em_copy_data(&bm->vdata, &em->vdata, v->data, &eve->data);
 +      /*copy normal*/
 +      eve->no[0] = v->no[0];
 +      eve->no[1] = v->no[1];
 +      eve->no[2] = v->no[2];
 +
 +      return eve;
 +}
 +
 +static void bmeshedge_to_editedge_internal(BMesh *bm, EditMesh *em, BMEdge *e, EditEdge *eed)
 +{
 +      eed->crease = e->crease;
 +      eed->bweight = e->bweight;
 +      
 +      //copy relavent flags
 +      if (e->head.flag & BM_SELECT) eed->f |= SELECT;
 +      if (e->head.flag & BM_SEAM) eed->seam = 1;
 +      if (e->head.flag & BM_SHARP) eed->sharp = 1;
 +      if (e->head.flag & BM_HIDDEN) eed->h = 1;
 +      if (e->head.flag & BM_FGON) eed->h |= EM_FGON;
 +
 +      CustomData_em_copy_data(&bm->edata, &em->edata, e->data, &eed->data);
 +}
 +
 +static EditEdge *bmeshedge_to_editedge(BMesh *bm, EditMesh *em, BMEdge *e, EditVert **evlist)
 +{
 +      EditEdge *eed = NULL;
 +
-       efa = addfacelist(eve1, eve2, eve3, eve4, NULL, NULL);
++      if(!(findedgelist(em, evlist[e->v1->head.eflag1], evlist[e->v2->head.eflag1]))){
++              eed= addedgelist(em, evlist[e->v1->head.eflag1], evlist[e->v2->head.eflag1], NULL);
 +              bmeshedge_to_editedge_internal(bm, em, e, eed);
 +      }
 +
 +      return eed;
 +}
 +
 +static EditFace *bmeshface_to_editface(BMesh *bm, EditMesh *em, BMFace *f, EditVert **evlist, int numCol, int numTex)
 +{
 +      EditVert *eve1, *eve2, *eve3, *eve4;
 +      EditFace *efa = NULL;
 +      int len;
 +      
 +      len = f->len;
 +
 +      eve1= evlist[f->loopbase->v->head.eflag1];
 +      eve2= evlist[((BMLoop*)(f->loopbase->head.next))->v->head.eflag1];
 +      eve3= evlist[((BMLoop*)(f->loopbase->head.next->next))->v->head.eflag1];
 +      if (len == 4) {
 +              eve4= evlist[ ((BMLoop*)(f->loopbase->head.prev))->v->head.eflag1];
 +      }
 +      else {
 +              eve4= NULL;
 +      }
 +
-       em = G.editMesh;
-       if (em == NULL) return NULL; //what?
-       em->act_face = NULL;
++      efa = addfacelist(em, eve1, eve2, eve3, eve4, NULL, NULL);
 +
 +      bmeshedge_to_editedge_internal(bm, em, f->loopbase->e, efa->e1);
 +      bmeshedge_to_editedge_internal(bm, em, ((BMLoop*)(f->loopbase->head.next))->e, efa->e2);
 +      bmeshedge_to_editedge_internal(bm, em, ((BMLoop*)(f->loopbase->head.next->next))->e, efa->e3);
 +      if(eve4)
 +              bmeshedge_to_editedge_internal(bm, em, ((BMLoop*)(f->loopbase->head.prev))->e, efa->e4);
 +
 +      efa->mat_nr = (unsigned char)f->mat_nr;
 +
 +
 +      /*Copy normal*/
 +      efa->n[0] = f->no[0];
 +      efa->n[1] = f->no[1];
 +      efa->n[2] = f->no[2];
 +      
 +      //copy relavent original flags
 +      if (f->head.flag & BM_SELECT) efa->f |= SELECT;
 +      if (f->head.flag & BM_HIDDEN) efa->h = 1;
 +      if (f->head.flag & BM_SMOOTH) efa->flag |= ME_SMOOTH;
 +
 +      CustomData_em_copy_data(&bm->pdata, &em->fdata, f->data, &efa->data);
 +      loops_to_editmesh_corners(bm, &em->fdata, efa->data, f, numCol,numTex);
 +      
 +      return efa;
 +}
 +
 +EditMesh *bmesh_to_editmesh_intern(BMesh *bm) 
 +{
 +      BMVert *v;
 +      BMEdge *e;
 +      BMFace *f;
 +
 +      BMIter verts;
 +      BMIter edges;
 +      BMIter faces;
 +
 +      EditMesh *em;
 +      EditVert *eve, **evlist;
 +
 +      int totvert, i, numTex, numCol;
 +
-       countall();
++      em = MEM_callocN(sizeof(EditMesh), "EditMesh from bmesh");
++      em->selectmode= bm->selectmode;
 +
 +      CustomData_copy(&bm->vdata, &em->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
 +      CustomData_copy(&bm->edata, &em->edata, CD_MASK_BMESH, CD_CALLOC, 0);
 +      CustomData_copy(&bm->pdata, &em->fdata, CD_MASK_BMESH, CD_CALLOC, 0);
 +      CustomData_from_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata,0);
 +      numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
 +      numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
 +
 +      totvert = BM_Count_Element(bm, BM_VERT);
 +      evlist= MEM_mallocN(totvert*sizeof(EditVert *),"evlist");
 +
 +      /* make vertices */
 +      for(i=0, v = BMIter_New(&verts, bm, BM_VERTS, bm); v; v = BMIter_Step(&verts), i++) 
 +              eve = bmeshvert_to_editvert(bm, em, v, i, evlist);
 +
 +      /* make edges */
 +      for(e = BMIter_New(&edges, bm, BM_EDGES, bm); e; e = BMIter_Step(&edges))
 +              bmeshedge_to_editedge(bm, em, e, evlist);
 +
 +      /* make faces */
 +      for(f = BMIter_New(&faces, bm, BM_FACES, bm); f; f = BMIter_Step(&faces))
 +              bmeshface_to_editface(bm, em, f, evlist, numCol, numTex);
 +                      
 +      MEM_freeN(evlist);
 +      return em;
 +}
 +
 +void bmesh2edit_exec(BMesh *bmesh, BMOperator *op)
 +{
 +      BMO_Set_Pnt(op, BMOP_TO_EDITMESH_EMOUT, bmesh_to_editmesh_intern(bmesh));
 +}
 +
 +EditMesh *bmesh_to_editmesh(BMesh *bmesh)
 +{
 +      BMOperator conv;
 +      EditMesh *em;
 +
 +      BMO_Init_Op(&conv, BMOP_TO_EDITMESH);
 +      BMO_Exec_Op(bmesh, &conv);
 +      em = conv.slots[BMOP_TO_EDITMESH_EMOUT].data.p;
 +      BMO_Finish_Op(bmesh, &conv);
 +
 +      return em;
 +}
index 26c1a821fca76aab383860690b985900559672ba,0000000000000000000000000000000000000000..062a71181cf0af76bb6a72389438f7c9c32c1150
mode 100644,000000..100644
--- /dev/null
@@@ -1,411 -1,0 +1,413 @@@
- #include "BIF_editmesh.h"
- #include "editmesh.h"
 +#include "MEM_guardedalloc.h"
 +#include "BKE_customdata.h" 
 +#include "DNA_listBase.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"
-       EM_fgon_flags();
++#include "mesh_intern.h"
++#include "ED_mesh.h"
++
 +#include "BLI_blenlib.h"
 +#include "BLI_edgehash.h"
 +
 +#include "bmesh.h"
 +
 +/*
 + * EDITMESH TO BMESH.C
 + *
 + * This file contains functions
 + * for converting an editmesh
 + * into a Bmesh
 + *
 +*/
 +
 +/*
 + * EDITMESH CORNERS TO LOOPS
 + * 
 + * Converts editmesh face corner data
 + * (UVs, Vert colors, ect) to N-Gon 
 + * face-edge ('loop') data.
 + *
 +*/
 +
 +static void editmesh_corners_to_loops(BMesh *bm, CustomData *facedata, void *face_block, BMFace *f,int numCol, int numTex){
 +      int i, j;
 +      BMLoop *l;
 +      MTFace *texface;
 +      MTexPoly *texpoly;
 +      MCol *mcol;
 +      MLoopCol *mloopcol;
 +      MLoopUV *mloopuv;
 +      BMIter iter;
 +
 +      for(i=0; i < numTex; i++){
 +              texface = CustomData_em_get_n(facedata, face_block, CD_MTFACE, i);
 +              texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
 +              
 +              texpoly->tpage = texface->tpage;
 +              texpoly->flag = texface->flag;
 +              texpoly->transp = texface->transp;
 +              texpoly->mode = texface->mode;
 +              texpoly->tile = texface->tile;
 +              texpoly->unwrap = texface->unwrap;
 +              
 +              for (j=0, l=BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, f); f; j++, f=BMIter_Step(&iter)) {
 +                      mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
 +                      mloopuv->uv[0] = texface->uv[j][0];
 +                      mloopuv->uv[1] = texface->uv[j][1];
 +              }
 +
 +      }
 +      for(i=0; i < numCol; i++){
 +              mcol = CustomData_em_get_n(facedata, face_block, CD_MCOL, i);
 +              for (j=0, l=BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, f); f; j++, f=BMIter_Step(&iter)) {
 +                      mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
 +                      mloopcol->r = mcol[j].r;
 +                      mloopcol->g = mcol[j].g;
 +                      mloopcol->b = mcol[j].b;
 +                      mloopcol->a = mcol[j].a;
 +              }
 +      }
 +}
 +
 +/*
 + * EDITVERT TO BMVert
 + *
 + * Converts an editvert to
 + * a BMVert.
 + *
 +*/
 +
 +static BMVert *editvert_to_BMVert(BMesh *bm, EditMesh *em, EditVert *eve)
 +{
 +              BMVert *v = NULL;
 +
 +              v = BM_Make_Vert(bm, eve->co, NULL);
 +              
 +              /*transfer flags*/
 +              v->head.flag = eve->h ? BM_HIDDEN : 0;
 +              if(eve->f & SELECT) BM_Select_Vert(bm, v, 1);
 +              v->bweight = eve->bweight;
 +
 +              /*Copy Custom Data*/
 +              CustomData_bmesh_copy_data(&em->vdata, &bm->vdata, eve->data, &v->data);
 +              
 +              return v;
 +}     
 +
 +/*
 + * EDITEDGE TO BMEdge
 + *
 + * Converts an editedge to 
 + * a BMEdge
 + *
 +*/
 +
 +static void editedge_to_BMEdge_internal(BMesh *bm, EditMesh *em, BMEdge *e, EditEdge *eed)
 +{
 +      e->crease = eed->crease;
 +      e->bweight = eed->bweight;
 +      
 +      e->head.flag = eed->f & SELECT ? BM_SELECT : 0;
 +      e->head.flag |= eed->seam ? BM_SEAM : 0;
 +      e->head.flag |= eed->h & 1 ? BM_HIDDEN : 0;
 +      e->head.flag |= eed->h & EM_FGON ? BM_FGON : 0;
 +      e->head.flag |= eed->sharp ? BM_SHARP : 0;
 +
 +      CustomData_bmesh_copy_data(&em->edata, &bm->edata, eed->data, &e->data);
 +}
 +
 +static BMEdge *editedge_to_BMEdge(BMesh *bm, EditMesh *em, EditEdge *eed)
 +{
 +              BMVert *v1 = NULL, *v2 = NULL;
 +              BMEdge *e = NULL;
 +              
 +              v1 = eed->v1->tmp.p;
 +              v2 = eed->v2->tmp.p;
 +      
 +              e = BM_Make_Edge(bm, v1, v2,NULL, 0); 
 +
 +              editedge_to_BMEdge_internal(bm, em, e, eed);
 +
 +              return e;
 +}
 +/*
 + * EDITFACE TO BMFace
 + *
 + * Converts an editface to a BMFace.
 + * Note that this also convert per-face
 + * corner data as well.
 + *
 +*/
 +
 +static BMFace *editface_to_BMFace(BMesh *bm, EditMesh *em, EditFace *efa, int numCol, int numTex)
 +{
 +              BMVert *v1 = NULL, *v2 = NULL;
 +              BMFace *f = NULL;
 +              BMEdge *edar[4];
 +              int len;
 +
 +              edar[0] = BM_Make_Edge(bm, efa->v1->tmp.p, efa->v2->tmp.p, NULL, 1); 
 +              edar[1] = BM_Make_Edge(bm, efa->v2->tmp.p, efa->v3->tmp.p, NULL, 1); 
 +              if(efa->v4){
 +                      edar[2] = BM_Make_Edge(bm, efa->v3->tmp.p, efa->v4->tmp.p, NULL, 1); 
 +                      edar[3] = BM_Make_Edge(bm, efa->v4->tmp.p, efa->v1->tmp.p, NULL, 1); 
 +              }else{
 +                      edar[2] = BM_Make_Edge(bm, efa->v3->tmp.p, efa->v1->tmp.p, NULL, 1); 
 +              }
 +
 +              editedge_to_BMEdge_internal(bm, em, edar[0], efa->e1);
 +              editedge_to_BMEdge_internal(bm, em, edar[1], efa->e2);
 +              editedge_to_BMEdge_internal(bm, em, edar[2], efa->e3);
 +              if(efa->v4)
 +                      editedge_to_BMEdge_internal(bm, em, edar[3], efa->e4);
 +
 +
 +              if(efa->e1->fgoni) edar[0]->head.flag |= BM_FGON;
 +              if(efa->e2->fgoni) edar[1]->head.flag |= BM_FGON;
 +              if(efa->e3->fgoni) edar[2]->head.flag |= BM_FGON;
 +              if(efa->v4 && efa->e4->fgoni) edar[3]->head.flag |= BM_FGON;
 +
 +              if(efa->v4) len = 4;
 +              else len = 3;
 +
 +              /*find v1 and v2*/
 +              v1 = efa->v1->tmp.p;
 +              v2 = efa->v2->tmp.p;
 +
 +              f = BM_Make_Ngon(bm, v1, v2, edar, len, 0);
 +              f->head.flag = 0;
 +              f->mat_nr = efa->mat_nr;
 +              if(efa->f & SELECT) BM_Select_Face(bm, f, 1);
 +              if(efa->h) f->head.flag |= BM_HIDDEN;
 +              
 +              CustomData_bmesh_copy_data(&em->fdata, &bm->pdata, efa->data, &f->data);
 +              editmesh_corners_to_loops(bm, &em->fdata, efa->data, f,numCol,numTex);
 +
 +              return f;
 +}
 +
 +/*
 + * BMESH FGONCONVERT
 + *
 + * This function and its associated structures
 + * /helpers (fgonsort, sortfgon, fuse_fgon) are
 + * used to convert f-gons to bmesh n-gons. This
 + * is accomplished by sorting a list of fgon faces
 + * such that faces that are part of the same fgon
 + * are next to each other. These faces are then
 + * converted as is into bmesh faces and
 + * fused togather.
 + *
 + * Note that currently, there is no support for 
 + * holes in faces in the bmesh structure, so 
 + * f-gons with holes will only partially convert.
 + *
 +*/
 +
 +typedef struct fgonsort {
 +      unsigned long x;
 +      struct EditFace *efa;
 +      struct BMFace *f;
 +      int done;
 +}fgonsort;
 +
 +static int sortfgon(const void *v1, const void *v2)
 +{
 +      const struct fgonsort *x1=v1, *x2=v2;
 +      
 +      if( x1->x > x2->x ) return 1;
 +      else if( x1->x < x2->x) return -1;
 +      return 0;
 +}
 +
 +static void fuse_fgon(BMesh *bm, BMFace *f)
 +{
 +      BMFace *sf;
 +      BMLoop *l;
 +      int done;
 +
 +      sf = f;
 +      done = 0;
 +      while(!done){
 +              done = 1;
 +              l = sf->loopbase;
 +              do{
 +                      if(l->e->head.flag & BM_FGON){ 
 +                              sf = BM_Join_Faces(bm,l->f, ((BMLoop*)l->radial.next->data)->f, l->e, 0,0);
 +                              if(sf){
 +                                      done = 0;
 +                                      break;
 +                              } else { /*we have to get out of here...*/
 +                                      return;
 +                              }
 +                      }
 +                      l = ((BMLoop*)(l->head.next));
 +              }while(l != sf->loopbase);
 +      }
 +}
 +
 +static BM_fgonconvert(BMesh *bm, EditMesh *em, int numCol, int numTex)
 +{
 +      EditFace *efa;
 +      struct fgonsort *sortblock, *sb, *sb1;
 +      int a, b, amount=0;
 +
 +      /*zero out efa->tmp, we store fgon index here*/
 +      for(efa = em->faces.first; efa; efa = efa->next){ 
 +              efa->tmp.l = 0;
 +              amount++;
 +      }
 +      /*go through and give each editface an fgon index*/
 +      for(efa = em->faces.first; efa; efa = efa->next){
 +              if(efa->e1->fgoni) efa->tmp.l = efa->e1->fgoni;
 +              else if(efa->e2->fgoni) efa->tmp.l = efa->e2->fgoni;
 +              else if(efa->e3->fgoni) efa->tmp.l = efa->e3->fgoni;
 +              else if(efa->e4 && efa->e4->fgoni) efa->tmp.l = efa->e4->fgoni;
 +      }
 +
 +      sb= sortblock= MEM_mallocN(sizeof(fgonsort)* amount,"fgon sort block");
 +
 +      for(efa = em->faces.first; efa; efa=efa->next){
 +              sb->x = efa->tmp.l;
 +              sb->efa = efa;
 +              sb->done = 0;
 +              sb++;
 +      }
 +
 +      qsort(sortblock, amount, sizeof(fgonsort), sortfgon);
 +
 +      sb = sortblock;
 +      for(a=0; a<amount; a++, sb++) {
 +              if(sb->x && sb->done == 0){
 +                      /*first pass: add in faces for this fgon*/
 +                      for(b=a, sb1 = sb; b<amount && sb1->x == sb->x; b++, sb1++){
 +                              efa = sb1->efa;
 +                              sb1->f = editface_to_BMFace(bm, em, efa, numCol, numTex);
 +                              sb1->done = 1;
 +                      }
 +                      /*fuse fgon*/
 +                      fuse_fgon(bm, sb->f);
 +              }
 +      }
 +      MEM_freeN(sortblock);
 +}
 +
 +/*
 + * TAG WIRE EDGES
 + *
 + * Flags editedges 'f1' member
 + * if the edge has no faces.
 + *
 +*/
 +
 +static void tag_wire_edges(EditMesh *em){
 +      EditFace *efa;
 +      EditEdge *eed;
 +      for(eed = em->edges.first; eed; eed = eed->next) eed->f1 = 1;
 +      for(efa = em->faces.first; efa; efa = efa->next){
 +              efa->e1->f1 = 0;
 +              efa->e2->f1 = 0;
 +              efa->e3->f1 = 0;
 +              if(efa->e4) efa->e4->f1 = 0;
 +      }
 +}
 +
 +/*
 + * EDITMESH TO BMESH
 + *
 + * Function to convert an editmesh to a bmesh
 + * Currently all custom data as well as 
 + * f-gons should be converted correctly.
 + *
 +*/
 +
 +BMesh *editmesh_to_bmesh_intern(EditMesh *em, BMesh *bm) {
 +      BMVert *v;
 +      EditVert *eve;
 +      EditEdge *eed;
 +      EditFace *efa;
 +      int allocsize[4] = {512,512,2048,512}, numTex, numCol;
 +
 +      /*make sure to update FGon flags*/
-       if(G.scene->selectmode & SCE_SELECT_VERTEX) bm->selectmode |= BM_VERT;
-       if(G.scene->selectmode & SCE_SELECT_EDGE) bm->selectmode |= BM_EDGE;
-       if(G.scene->selectmode & SCE_SELECT_FACE) bm->selectmode |= BM_FACE;
++      EM_fgon_flags(em);
 +
 +      /*copy custom data layout*/
 +      CustomData_copy(&em->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
 +      CustomData_copy(&em->edata, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0);
 +      CustomData_copy(&em->fdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
 +
 +      /*copy face corner data*/
 +      CustomData_to_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata);
 +      /*initialize memory pools*/
 +      CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
 +      CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
 +      CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]);
 +      CustomData_bmesh_init_pool(&bm->pdata, allocsize[3]);
 +      /*needed later*/
 +      numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
 +      numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
 +
 +      /*copy over selection mode*/
 +      bm->selectmode = 0;
++      if(bm->selectmode & SCE_SELECT_VERTEX) bm->selectmode |= BM_VERT;
++      if(bm->selectmode & SCE_SELECT_EDGE) bm->selectmode |= BM_EDGE;
++      if(bm->selectmode & SCE_SELECT_FACE) bm->selectmode |= BM_FACE;
 +
 +
 +      /*begin editloop*/
 +      //BM_Begin_Edit(bm);
 +
 +      /*tag wire edges*/
 +      tag_wire_edges(em);
 +
 +      /*add verts*/
 +      for(eve = em->verts.first; eve; eve = eve->next){
 +              v = editvert_to_BMVert(bm, em, eve);
 +              eve->tmp.p = v;
 +      }
 +      /*convert f-gons*/
 +      BM_fgonconvert(bm, em, numCol, numTex);
 +      
 +      /*do quads + triangles*/
 +      for(efa = em->faces.first; efa; efa = efa->next){
 +              if(!efa->tmp.l) editface_to_BMFace(bm, em, efa, numCol, numTex);
 +      }
 +
 +      /*add wire edges*/      
 +      for(eed = em->edges.first; eed; eed = eed->next){
 +              if(eed->f1) editedge_to_BMEdge(bm, em, eed);
 +      }
 +      //BM_end_edit(bm, BM_CALC_NORM);
 +      return bm;
 +}
 +
 +void edit2bmesh_exec(BMesh *bmesh, BMOperator *op)
 +{
 +      editmesh_to_bmesh_intern(op->slots[BMOP_FROM_EDITMESH_EM].data.p, bmesh);
 +}
 +
 +BMesh *editmesh_to_bmesh(EditMesh *em)
 +{
 +      BMOperator conv;
 +      BMesh *bm;
 +      int allocsize[4] = {512,512,2048,512}, numTex, numCol;
 +
 +      /*allocate a bmesh*/
 +      bm = BM_Make_Mesh(allocsize);
 +
 +      BMO_Init_Op(&conv, BMOP_FROM_EDITMESH);
 +      BMO_Set_Pnt(&conv, BMOP_FROM_EDITMESH_EM, em);
 +      BMO_Exec_Op(bm, &conv);
 +      BMO_Finish_Op(bm, &conv);
 +
 +      return bm;
 +}
index e99351e1a705490f48f2a857c1ceecde39bf62fb,e99351e1a705490f48f2a857c1ceecde39bf62fb..bd6d355d84c1b7bf1be847941329087bad9242b0
@@@ -7,5 -7,5 +7,6 @@@ incs = '../include ../../blenlib ../../
  incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
  incs += ' #/intern/guardedalloc #intern/bmfont ../../gpu'
  incs += ' ../../makesrna ../../render/extern/include  #/intern/elbeem/extern'
++incs += ' ../../bmesh '
  
  env.BlenderLib ( 'bf_editors_mesh', sources, Split(incs), [], libtype=['core'], priority=[45] )
index 90a328bb49a5032d8179928e7075d5bb1a37f525,111be9c07aea61f3110939c04dbc09f274100469..bd49c2e8cf6c2bc8d633d68d2e72e6efc570778d
@@@ -34,6 -34,6 +34,7 @@@
  
  struct bContext;
  struct wmOperatorType;
++struct ViewContext;
  
  #define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float));
  
@@@ -92,7 -91,7 +92,7 @@@ int editedge_containsVert(struct EditEd
  int editface_containsVert(struct EditFace *efa, struct EditVert *eve);
  int editface_containsEdge(struct EditFace *efa, struct EditEdge *eed);
  
--void em_setup_viewcontext(struct bContext *C, ViewContext *vc);
++void em_setup_viewcontext(struct bContext *C, struct ViewContext *vc);
  
  /* ******************* editmesh_add.c */
  
@@@ -162,7 -161,7 +162,7 @@@ extern struct EditFace *EM_face_from_fa
  
  void MESH_OT_de_select_all(struct wmOperatorType *ot);
  
--extern EditEdge *findnearestedge(ViewContext *vc, int *dist);
++extern EditEdge *findnearestedge(struct ViewContext *vc, int *dist);
  extern void EM_automerge(int update);
  void editmesh_select_by_material(EditMesh *em, int index);
  void righthandfaces(EditMesh *em, int select);        /* makes faces righthand turning */
@@@ -177,7 -176,7 +177,7 @@@ void EM_select_more(EditMesh *em)
   *            if 0, unselected vertice are given the bias
   * strict: if 1, the vertice corresponding to the sel parameter are ignored and not just biased 
   */
--extern EditVert *findnearestvert(ViewContext *vc, int *dist, short sel, short strict);
++extern EditVert *findnearestvert(struct ViewContext *vc, int *dist, short sel, short strict);
  
  
  /* ******************* editmesh_tools.c */
index c52bbaa0613cad3651df153d42626bd022035686,c52bbaa0613cad3651df153d42626bd022035686..99c4a7753fb86d16b910c1aae2522e2e6b2f9615
@@@ -486,6 -486,6 +486,9 @@@ class BlenderEnvironment(SConsEnvironme
                         lenv.Append(LIBS = lenv['BF_QUICKTIME_LIB'])
                         lenv.Append(LIBPATH = lenv['BF_QUICKTIME_LIBPATH'])
                prog = lenv.Program(target=builddir+'bin/'+progname, source=sources)
++              #needed for incremental linking
++              if lenv['OURPLATFORM'] == 'win32-vc': prog = lenv.Precious(prog)
++      
                if lenv['BF_DEBUG'] and lenv['OURPLATFORM']=='win32-vc' and lenv['BF_BSC']:
                        f = lenv.File(progname + '.bsc', builddir)
                        brs = lenv.Command(f, prog, [bsc])