merge with 2.5 (not trunk, last merge message said that on accident) at r22252
[blender.git] / source / blender / editors / mesh / editmesh.c
index e32dd0e8ac70f8aabec4ad362e7ca13de141b58d..5892af0060b2c499641ba0017dab9907a5a27eb3 100644 (file)
@@ -53,6 +53,7 @@
 #include "BLI_editVert.h"
 #include "BLI_dynstr.h"
 #include "BLI_rand.h"
+#include "BLI_mempool.h"
 
 #include "BKE_cloth.h"
 #include "BKE_context.h"
@@ -71,6 +72,7 @@
 #include "BKE_softbody.h"
 #include "BKE_texture.h"
 #include "BKE_utildefines.h"
+#include "BKE_tessmesh.h"
 
 #include "LBM_fluidsim.h"
 
@@ -91,6 +93,8 @@
 /* own include */
 #include "mesh_intern.h"
 
+#include "bmesh.h"
+
 /* 
 editmesh.c:
        - add/alloc/free data
@@ -112,22 +116,21 @@ static void error() {}
 
 /* ************ ADD / REMOVE / FIND ****************** */
 
-static void *calloc_em(EditMesh *em, size_t size, size_t nr)
-{
-       return calloc(size, nr);
+static void init_editMesh(EditMesh *em) {
+       if (!em->vertpool) em->vertpool = BLI_mempool_create(sizeof(EditVert), 1, 512);
+       if (!em->edgepool) em->edgepool = BLI_mempool_create(sizeof(EditEdge), 1, 512);
+       if (!em->facepool) em->facepool = BLI_mempool_create(sizeof(EditFace), 1, 512);
 }
 
-/* used to bypass normal calloc with fast one */
-static void *(*callocvert)(EditMesh *, size_t, size_t) = calloc_em;
-static void *(*callocedge)(EditMesh *, size_t, size_t) = calloc_em;
-static void *(*callocface)(EditMesh *, size_t, size_t) = calloc_em;
-
 EditVert *addvertlist(EditMesh *em, float *vec, EditVert *example)
 {
        EditVert *eve;
        static int hashnr= 0;
+       
+       if (!em->vertpool) init_editMesh(em);
+
+       eve= BLI_mempool_calloc(em->vertpool);
 
-       eve= callocvert(em, sizeof(EditVert), 1);
        BLI_addtail(&em->verts, eve);
        em->totvert++;
        
@@ -157,8 +160,7 @@ void free_editvert (EditMesh *em, EditVert *eve)
 
        EM_remove_selection(em, eve, EDITVERT);
        CustomData_em_free_block(&em->vdata, &eve->data);
-       if(eve->fast==0)
-               free(eve);
+       BLI_mempool_free(em->vertpool, eve);
        
        em->totvert--;
 }
@@ -256,11 +258,12 @@ EditEdge *addedgelist(EditMesh *em, EditVert *v1, EditVert *v2, EditEdge *exampl
        }
        
        /* find in hashlist */
+       if (!em->edgepool) init_editMesh(em);
        eed= findedgelist(em, v1, v2);
 
        if(eed==NULL) {
        
-               eed= (EditEdge *)callocedge(em, sizeof(EditEdge), 1);
+               eed= (EditEdge *)BLI_mempool_calloc(em->edgepool);
                eed->v1= v1;
                eed->v2= v2;
                BLI_addtail(&em->edges, eed);
@@ -293,9 +296,8 @@ void remedge(EditMesh *em, EditEdge *eed)
 void free_editedge(EditMesh *em, EditEdge *eed)
 {
        EM_remove_selection(em, eed, EDITEDGE);
-       if(eed->fast==0){ 
-               free(eed);
-       }
+
+       BLI_mempool_free(em->edgepool, eed);
 }
 
 void free_editface(EditMesh *em, EditFace *efa)
@@ -307,8 +309,7 @@ void free_editface(EditMesh *em, EditFace *efa)
        }
                
        CustomData_em_free_block(&em->fdata, &efa->data);
-       if(efa->fast==0)
-               free(efa);
+       BLI_mempool_free(em->facepool, efa);
        
        em->totface--;
 }
@@ -384,7 +385,9 @@ EditFace *addfacelist(EditMesh *em, EditVert *v1, EditVert *v2, EditVert *v3, Ed
        if(v1==v2 || v2==v3 || v1==v3) return NULL;
        if(e2==0) return NULL;
 
-       efa= (EditFace *)callocface(em, sizeof(EditFace), 1);
+       if (!em->facepool) init_editMesh(em);
+       efa= (EditFace *)BLI_mempool_calloc(em->facepool);
+
        efa->v1= v1;
        efa->v2= v2;
        efa->v3= v3;
@@ -467,55 +470,10 @@ int editface_containsEdge(EditFace *efa, EditEdge *eed)
 
 /* ************************ stuct EditMesh manipulation ***************************** */
 
-/* fake callocs for fastmalloc below */
-static void *calloc_fastvert(EditMesh *em, size_t size, size_t nr)
-{
-       EditVert *eve= em->curvert++;
-       eve->fast= 1;
-       return eve;
-}
-static void *calloc_fastedge(EditMesh *em, size_t size, size_t nr)
-{
-       EditEdge *eed= em->curedge++;
-       eed->fast= 1;
-       return eed;
-}
-static void *calloc_fastface(EditMesh *em, size_t size, size_t nr)
-{
-       EditFace *efa= em->curface++;
-       efa->fast= 1;
-       return efa;
-}
-
-/* allocate 1 chunk for all vertices, edges, faces. These get tagged to
-   prevent it from being freed
-*/
-static void init_editmesh_fastmalloc(EditMesh *em, int totvert, int totedge, int totface)
-{
-       if(totvert) em->allverts= MEM_callocN(totvert*sizeof(EditVert), "allverts");
-       else em->allverts= NULL;
-       em->curvert= em->allverts;
-       
-       if(totedge==0) totedge= 4*totface;      // max possible
-
-       if(totedge) em->alledges= MEM_callocN(totedge*sizeof(EditEdge), "alledges");
-       else em->alledges= NULL;
-       em->curedge= em->alledges;
-       
-       if(totface) em->allfaces= MEM_callocN(totface*sizeof(EditFace), "allfaces");
-       else em->allfaces= NULL;
-       em->curface= em->allfaces;
-
-       callocvert= calloc_fastvert;
-       callocedge= calloc_fastedge;
-       callocface= calloc_fastface;
-}
-
-static void end_editmesh_fastmalloc(void)
+void set_editMesh(EditMesh *dst, EditMesh *src)
 {
-       callocvert= calloc_em;
-       callocedge= calloc_em;
-       callocface= calloc_em;
+       free_editMesh(dst);
+       *dst = *src;
 }
 
 /* do not free editmesh itself here */
@@ -527,7 +485,12 @@ void free_editMesh(EditMesh *em)
        if(em->edges.first) free_edgelist(em, &em->edges);
        if(em->faces.first) free_facelist(em, &em->faces);
        if(em->selected.first) BLI_freelistN(&(em->selected));
-
+       
+       if (em->vertpool) BLI_mempool_destroy(em->vertpool);
+       if (em->edgepool) BLI_mempool_destroy(em->edgepool);
+       if (em->facepool) BLI_mempool_destroy(em->facepool);
+       em->vertpool = em->edgepool = em->facepool = NULL;
+       
        CustomData_free(&em->vdata, 0);
        CustomData_free(&em->fdata, 0);
 
@@ -815,7 +778,7 @@ static int editmesh_pointcache_edit(Scene *scene, Object *ob, int totvert, PTCac
 }
 
 /* turns Mesh into editmesh */
-void make_editMesh(Scene *scene, Object *ob)
+EditMesh *make_editMesh(Scene *scene, Object *ob)
 {
        Mesh *me= ob->data;
        MFace *mface;
@@ -833,13 +796,7 @@ void make_editMesh(Scene *scene, Object *ob)
        float cacheco[3], cachemat[4][4], *co;
        int tot, a, cacheedit= 0, eekadoodle= 0;
 
-       if(me->edit_mesh==NULL)
-               me->edit_mesh= MEM_callocN(sizeof(EditMesh), "editmesh");
-       else 
-               /* because of reload */
-               free_editMesh(me->edit_mesh);
-       
-       em= me->edit_mesh;
+       em= MEM_callocN(sizeof(EditMesh), "editmesh");
        
        em->selectmode= scene->toolsettings->selectmode; // warning needs to be synced
        em->act_face = NULL;
@@ -847,18 +804,9 @@ void make_editMesh(Scene *scene, Object *ob)
        em->totedge= me->totedge;
        em->totface= me->totface;
        
-       if(tot==0) {
-               return;
-       }
-       
-       /* initialize fastmalloc for editmesh */
-       init_editmesh_fastmalloc(em, me->totvert, me->totedge, me->totface);
-
        actkey = ob_get_keyblock(ob);
        if(actkey) {
                tot= actkey->totelem;
-               /* undo-ing in past for previous editmode sessions gives corrupt 'keyindex' values */
-               undo_editmode_clear();
        }
 
        
@@ -979,8 +927,6 @@ void make_editMesh(Scene *scene, Object *ob)
                error("This Mesh has old style edgecodes, please put it in the bugtracker!");
        
        MEM_freeN(evlist);
-
-       end_editmesh_fastmalloc();      // resets global function pointers
        
        if(me->mselect){
                //restore editselections
@@ -1014,18 +960,18 @@ void make_editMesh(Scene *scene, Object *ob)
        /* vertex coordinates change with cache edit, need to recalc */
        if(cacheedit)
                recalc_editnormals(em);
-       
+
+       return em;
 }
 
 /* makes Mesh out of editmesh */
-void load_editMesh(Scene *scene, Object *ob)
+void load_editMesh(Scene *scene, Object *ob, EditMesh *em)
 {
        Mesh *me= ob->data;
        MVert *mvert, *oldverts;
        MEdge *medge;
        MFace *mface;
        MSelect *mselect;
-       EditMesh *em= me->edit_mesh;
        EditVert *eve;
        EditFace *efa, *efa_act;
        EditEdge *eed;
@@ -1489,8 +1435,8 @@ static int mesh_separate_selected(Scene *scene, Base *editbase)
        /* 2 */
        basenew->object->data= menew= add_mesh(me->id.name);    /* empty */
        me->id.us--;
-       make_editMesh(scene, basenew->object);
-       emnew= menew->edit_mesh;
+       emnew = make_editMesh(scene, basenew->object);
+       //emnew= menew->edit_mesh;
        
        /* 3 */
        /* SPLIT: first make duplicate */
@@ -1531,7 +1477,7 @@ static int mesh_separate_selected(Scene *scene, Base *editbase)
        }
 
        /* 5 */
-       load_editMesh(scene, basenew->object);
+       load_editMesh(scene, basenew->object, emnew);
        free_editMesh(emnew);
        
        /* hashedges are invalid now, make new! */
@@ -1682,6 +1628,7 @@ typedef struct UndoMesh {
        EditVertC *verts;
        EditEdgeC *edges;
        EditFaceC *faces;
+       EditFaceC *act_face;
        EditSelectionC *selected;
        int totvert, totedge, totface, totsel;
        short selectmode;
@@ -1690,247 +1637,6 @@ typedef struct UndoMesh {
        CustomData vdata, edata, fdata;
 } UndoMesh;
 
-/* for callbacks */
-
-static void free_undoMesh(void *umv)
-{
-       UndoMesh *um= umv;
-       
-       if(um->verts) MEM_freeN(um->verts);
-       if(um->edges) MEM_freeN(um->edges);
-       if(um->faces) MEM_freeN(um->faces);
-       if(um->selected) MEM_freeN(um->selected);
-// XXX if(um->retopo_paint_data) retopo_free_paint_data(um->retopo_paint_data);
-       CustomData_free(&um->vdata, um->totvert);
-       CustomData_free(&um->edata, um->totedge);
-       CustomData_free(&um->fdata, um->totface);
-       MEM_freeN(um);
-}
-
-static void *editMesh_to_undoMesh(void *emv)
-{
-       EditMesh *em= (EditMesh *)emv;
-       UndoMesh *um;
-       EditVert *eve;
-       EditEdge *eed;
-       EditFace *efa;
-       EditSelection *ese;
-       EditVertC *evec=NULL;
-       EditEdgeC *eedc=NULL;
-       EditFaceC *efac=NULL;
-       EditSelectionC *esec=NULL;
-       int a;
-
-       um= MEM_callocN(sizeof(UndoMesh), "undomesh");
-       
-       um->selectmode = em->selectmode;
-       
-       for(eve=em->verts.first; eve; eve= eve->next) um->totvert++;
-       for(eed=em->edges.first; eed; eed= eed->next) um->totedge++;
-       for(efa=em->faces.first; efa; efa= efa->next) um->totface++;
-       for(ese=em->selected.first; ese; ese=ese->next) um->totsel++; 
-       /* malloc blocks */
-       
-       if(um->totvert) evec= um->verts= MEM_callocN(um->totvert*sizeof(EditVertC), "allvertsC");
-       if(um->totedge) eedc= um->edges= MEM_callocN(um->totedge*sizeof(EditEdgeC), "alledgesC");
-       if(um->totface) efac= um->faces= MEM_callocN(um->totface*sizeof(EditFaceC), "allfacesC");
-       if(um->totsel) esec= um->selected= MEM_callocN(um->totsel*sizeof(EditSelectionC), "allselections");
-
-       if(um->totvert) CustomData_copy(&em->vdata, &um->vdata, CD_MASK_EDITMESH, CD_CALLOC, um->totvert);
-       if(um->totedge) CustomData_copy(&em->edata, &um->edata, CD_MASK_EDITMESH, CD_CALLOC, um->totedge);
-       if(um->totface) CustomData_copy(&em->fdata, &um->fdata, CD_MASK_EDITMESH, CD_CALLOC, um->totface);
-       
-       /* now copy vertices */
-       a = 0;
-       for(eve=em->verts.first; eve; eve= eve->next, evec++, a++) {
-               VECCOPY(evec->co, eve->co);
-               VECCOPY(evec->no, eve->no);
-
-               evec->f= eve->f;
-               evec->h= eve->h;
-               evec->keyindex= eve->keyindex;
-               eve->tmp.l = a; /*store index*/
-               evec->bweight= (short)(eve->bweight*255.0);
-
-               CustomData_from_em_block(&em->vdata, &um->vdata, eve->data, a);
-       }
-       
-       /* copy edges */
-       a = 0;
-       for(eed=em->edges.first; eed; eed= eed->next, eedc++, a++)  {
-               eedc->v1= (int)eed->v1->tmp.l;
-               eedc->v2= (int)eed->v2->tmp.l;
-               eedc->f= eed->f;
-               eedc->h= eed->h;
-               eedc->seam= eed->seam;
-               eedc->sharp= eed->sharp;
-               eedc->crease= (short)(eed->crease*255.0);
-               eedc->bweight= (short)(eed->bweight*255.0);
-               eedc->fgoni= eed->fgoni;
-               eed->tmp.l = a; /*store index*/
-               CustomData_from_em_block(&em->edata, &um->edata, eed->data, a);
-       
-       }
-       
-       /* copy faces */
-       a = 0;
-       for(efa=em->faces.first; efa; efa= efa->next, efac++, a++) {
-               efac->v1= (int)efa->v1->tmp.l;
-               efac->v2= (int)efa->v2->tmp.l;
-               efac->v3= (int)efa->v3->tmp.l;
-               if(efa->v4) efac->v4= (int)efa->v4->tmp.l;
-               else efac->v4= -1;
-               
-               efac->mat_nr= efa->mat_nr;
-               efac->flag= efa->flag;
-               efac->f= efa->f;
-               efac->h= efa->h;
-               efac->fgonf= efa->fgonf;
-
-               efa->tmp.l = a; /*store index*/
-
-               CustomData_from_em_block(&em->fdata, &um->fdata, efa->data, a);
-       }
-       
-       a = 0;
-       for(ese=em->selected.first; ese; ese=ese->next, esec++){
-               esec->type = ese->type;
-               if(ese->type == EDITVERT) a = esec->index = ((EditVert*)ese->data)->tmp.l; 
-               else if(ese->type == EDITEDGE) a = esec->index = ((EditEdge*)ese->data)->tmp.l; 
-               else if(ese->type == EDITFACE) a = esec->index = ((EditFace*)ese->data)->tmp.l;
-       }
-
-// XXX um->retopo_paint_data= retopo_paint_data_copy(em->retopo_paint_data);
-//     um->retopo_mode= scene->toolsettings->retopo_mode;
-       
-       return um;
-}
-
-static void undoMesh_to_editMesh(void *umv, void *emv)
-{
-       EditMesh *em= (EditMesh *)emv;
-       UndoMesh *um= (UndoMesh *)umv;
-       EditVert *eve, **evar=NULL;
-       EditEdge *eed;
-       EditFace *efa;
-       EditSelection *ese;
-       EditVertC *evec;
-       EditEdgeC *eedc;
-       EditFaceC *efac;
-       EditSelectionC *esec;
-       int a=0;
-
-       free_editMesh(em);
-       
-       /* malloc blocks */
-       memset(em, 0, sizeof(EditMesh));
-               
-       em->selectmode = um->selectmode;
-       
-       init_editmesh_fastmalloc(em, um->totvert, um->totedge, um->totface);
-
-       CustomData_free(&em->vdata, 0);
-       CustomData_free(&em->edata, 0);
-       CustomData_free(&em->fdata, 0);
-
-       CustomData_copy(&um->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
-       CustomData_copy(&um->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0);
-       CustomData_copy(&um->fdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
-
-       /* now copy vertices */
-
-       if(um->totvert) evar= MEM_mallocN(um->totvert*sizeof(EditVert *), "vertex ar");
-       for(a=0, evec= um->verts; a<um->totvert; a++, evec++) {
-               eve= addvertlist(em, evec->co, NULL);
-               evar[a]= eve;
-
-               VECCOPY(eve->no, evec->no);
-               eve->f= evec->f;
-               eve->h= evec->h;
-               eve->keyindex= evec->keyindex;
-               eve->bweight= ((float)evec->bweight)/255.0f;
-
-               CustomData_to_em_block(&um->vdata, &em->vdata, a, &eve->data);
-       }
-
-       /* copy edges */
-       for(a=0, eedc= um->edges; a<um->totedge; a++, eedc++) {
-               eed= addedgelist(em, evar[eedc->v1], evar[eedc->v2], NULL);
-
-               eed->f= eedc->f;
-               eed->h= eedc->h;
-               eed->seam= eedc->seam;
-               eed->sharp= eedc->sharp;
-               eed->fgoni= eedc->fgoni;
-               eed->crease= ((float)eedc->crease)/255.0f;
-               eed->bweight= ((float)eedc->bweight)/255.0f;
-               CustomData_to_em_block(&um->edata, &em->edata, a, &eed->data);
-       }
-       
-       /* copy faces */
-       for(a=0, efac= um->faces; a<um->totface; a++, efac++) {
-               if(efac->v4 != -1)
-                       efa= addfacelist(em, evar[efac->v1], evar[efac->v2], evar[efac->v3], evar[efac->v4], NULL, NULL);
-               else 
-                       efa= addfacelist(em, evar[efac->v1], evar[efac->v2], evar[efac->v3], NULL, NULL ,NULL);
-
-               efa->mat_nr= efac->mat_nr;
-               efa->flag= efac->flag;
-               efa->f= efac->f;
-               efa->h= efac->h;
-               efa->fgonf= efac->fgonf;
-               
-               CustomData_to_em_block(&um->fdata, &em->fdata, a, &efa->data);
-       }
-       
-       end_editmesh_fastmalloc();
-       if(evar) MEM_freeN(evar);
-       
-       em->totvert = um->totvert;
-       em->totedge = um->totedge;
-       em->totface = um->totface;
-       /*restore stored editselections*/
-       if(um->totsel){
-               EM_init_index_arrays(em, 1,1,1);
-               for(a=0, esec= um->selected; a<um->totsel; a++, esec++){
-                       ese = MEM_callocN(sizeof(EditSelection), "Edit Selection");
-                       ese->type = esec->type;
-                       if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(esec->index); else
-                       if(ese->type == EDITEDGE) ese->data = EM_get_edge_for_index(esec->index); else
-                       if(ese->type == EDITFACE) ese->data = EM_get_face_for_index(esec->index);
-                       BLI_addtail(&(em->selected),ese);
-               }
-               EM_free_index_arrays();
-       }
-
-// XXX retopo_free_paint();
-//     em->retopo_paint_data= retopo_paint_data_copy(um->retopo_paint_data);
-//     scene->toolsettings->retopo_mode= um->retopo_mode;
-//     if(scene->toolsettings->retopo_mode) {
-// XXX         if(G.vd->depths) G.vd->depths->damaged= 1;
-//             retopo_queue_updates(G.vd);
-//             retopo_paint_view_update(G.vd);
-//     }
-       
-}
-
-static void *getEditMesh(bContext *C)
-{
-       Object *obedit= CTX_data_edit_object(C);
-       if(obedit && obedit->type==OB_MESH) {
-               Mesh *me= obedit->data;
-               return me->edit_mesh;
-       }
-       return NULL;
-}
-
-/* and this is all the undo system needs to know */
-void undo_push_mesh(bContext *C, char *name)
-{
-       undo_editmode_push(C, name, getEditMesh, free_undoMesh, undoMesh_to_editMesh, editMesh_to_undoMesh, NULL);
-}
-
-
 
 /* *************** END UNDO *************/
 
@@ -2033,6 +1739,6 @@ void em_setup_viewcontext(bContext *C, ViewContext *vc)
        
        if(vc->obedit) {
                Mesh *me= vc->obedit->data;
-               vc->em= me->edit_mesh;
+               vc->em= me->edit_btmesh;
        }
 }