merge with/from trunk at r35190
[blender.git] / source / blender / editors / mesh / mesh_data.c
index 42db085a0caa6dfed4b88c2c4417bce0379ef19f..0ae3076170c6be4ad55bea18fe59b877b452051d 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
 #include "DNA_scene_types.h"
 #include "DNA_view3d_types.h"
 
+#include "BLI_math.h"
+#include "BLI_editVert.h"
+#include "BLI_edgehash.h"
+#include "BLI_utildefines.h"
+
 #include "BKE_context.h"
 #include "BKE_depsgraph.h"
 #include "BKE_displist.h"
 #include "BKE_material.h"
 #include "BKE_mesh.h"
 #include "BKE_report.h"
-
-#include "BLI_math.h"
-#include "BLI_editVert.h"
-#include "BLI_edgehash.h"
+#include "BKE_tessmesh.h"
 
 #include "RNA_access.h"
 #include "RNA_define.h"
 
 #include "mesh_intern.h"
 
+#define GET_CD_DATA(me, data) (me->edit_btmesh ? &me->edit_btmesh->bm->data : &me->data)
+
 static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *layer)
 {
        Mesh *me = ob->data;
-       CustomData *data= (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata;
+       CustomData *data;
        void *actlayerdata, *rndlayerdata, *clonelayerdata, *stencillayerdata, *layerdata=layer->data;
        int type= layer->type;
-       int index= CustomData_get_layer_index(data, type);
-       int i, actindex, rndindex, cloneindex, stencilindex;
+       int index;
+       int i, actindex, rndindex, cloneindex, stencilindex, tot;
        
+       if (layer->type == CD_MLOOPCOL || layer->type == CD_MLOOPUV) {
+               data = (me->edit_btmesh)? &me->edit_btmesh->bm->ldata: &me->ldata;
+               tot = me->totloop;
+       } else {
+               data = (me->edit_btmesh)? &me->edit_btmesh->bm->pdata: &me->pdata;
+               tot = me->totpoly;
+       }
+       
+       index = CustomData_get_layer_index(data, type);
+
        /* ok, deleting a non-active layer needs to preserve the active layer indices.
          to do this, we store a pointer to the .data member of both layer and the active layer,
          (to detect if we're deleting the active layer or not), then use the active
@@ -88,15 +102,15 @@ static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *la
        stencillayerdata = data->layers[CustomData_get_stencil_layer_index(data, type)].data;
        CustomData_set_layer_active(data, type, layer - &data->layers[index]);
 
-       if(me->edit_mesh) {
-               EM_free_data_layer(me->edit_mesh, data, type);
+       if(me->edit_btmesh) {
+               BM_free_data_layer(me->edit_btmesh->bm, data, type);
        }
        else {
-               CustomData_free_layer_active(data, type, me->totface);
+               CustomData_free_layer_active(data, type, tot);
                mesh_update_customdata_pointers(me);
        }
 
-       if(!CustomData_has_layer(data, type) && (type == CD_MCOL && (ob->mode & OB_MODE_VERTEX_PAINT)))
+       if(!CustomData_has_layer(data, type) && (type == CD_MLOOPCOL && (ob->mode & OB_MODE_VERTEX_PAINT)))
                ED_object_toggle_modes(C, OB_MODE_VERTEX_PAINT);
 
        /* reconstruct active layer */
@@ -159,37 +173,48 @@ static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *la
 
 int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_set)
 {
-       EditMesh *em;
+       BMEditMesh *em;
        int layernum;
 
-       if(me->edit_mesh) {
-               em= me->edit_mesh;
+       if(me->edit_btmesh) {
+               em= me->edit_btmesh;
 
-               layernum= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
+               layernum= CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY);
                if(layernum >= MAX_MTFACE)
                        return 0;
 
-               EM_add_data_layer(em, &em->fdata, CD_MTFACE, name);
+               BM_add_data_layer(em->bm, &em->bm->pdata, CD_MTEXPOLY);
+               CustomData_set_layer_active(&em->bm->pdata, CD_MTEXPOLY, layernum);
+               if(active_set || layernum==0)
+                       CustomData_set_layer_active(&em->bm->pdata, CD_MTEXPOLY, layernum);
+
+               BM_add_data_layer(em->bm, &em->bm->ldata, CD_MLOOPUV);
+               CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPUV, layernum);
                if(active_set || layernum==0)
-                       CustomData_set_layer_active(&em->fdata, CD_MTFACE, layernum);
+                       CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPUV, layernum);
        }
        else {
-               layernum= CustomData_number_of_layers(&me->fdata, CD_MTFACE);
+               layernum= CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
                if(layernum >= MAX_MTFACE)
                        return 0;
 
-               if(me->mtface)
-                       CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DUPLICATE, me->mtface, me->totface, name);
-               else
-                       CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface, name);
-
-               if(active_set || layernum==0)
-                       CustomData_set_layer_active(&me->fdata, CD_MTFACE, layernum);
-
+               if(me->mtpoly) {
+                       CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DUPLICATE, me->mtpoly, me->totpoly, name);
+                       CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DUPLICATE, me->mloopuv, me->totloop, name);
+               } else {
+                       CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, name);
+                       CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, name);
+               }
+               
+               if(active_set || layernum==0) {
+                       CustomData_set_layer_active(&me->pdata, CD_MTEXPOLY, layernum);
+                       CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, layernum);
+               }
+               
                mesh_update_customdata_pointers(me);
        }
 
-       DAG_id_tag_update(&me->id, OB_RECALC_DATA);
+       DAG_id_tag_update(&me->id, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
 
        return 1;
@@ -197,18 +222,23 @@ int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_s
 
 int ED_mesh_uv_texture_remove(bContext *C, Object *ob, Mesh *me)
 {
-       CustomData *data= (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata;
-       CustomDataLayer *cdl;
+       CustomData *pdata = GET_CD_DATA(me, pdata), *ldata = GET_CD_DATA(me, ldata);
+       CustomDataLayer *cdlp, *cdlu;
        int index;
 
-       index= CustomData_get_active_layer_index(data, CD_MTFACE);
-       cdl= (index == -1) ? NULL: &data->layers[index];
+       index= CustomData_get_active_layer_index(pdata, CD_MTEXPOLY);
+       cdlp= (index == -1)? NULL: &pdata->layers[index];
 
-       if(!cdl)
+       index= CustomData_get_active_layer_index(ldata, CD_MLOOPUV);
+       cdlu= (index == -1)? NULL: &ldata->layers[index];
+       
+       if (!cdlp || !cdlu)
                return 0;
 
-       delete_customdata_layer(C, ob, cdl);
-       DAG_id_tag_update(&me->id, OB_RECALC_DATA);
+       delete_customdata_layer(C, ob, cdlp);
+       delete_customdata_layer(C, ob, cdlu);
+       
+       DAG_id_tag_update(&me->id, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
 
        return 1;
@@ -216,43 +246,48 @@ int ED_mesh_uv_texture_remove(bContext *C, Object *ob, Mesh *me)
 
 int ED_mesh_color_add(bContext *C, Scene *scene, Object *ob, Mesh *me, const char *name, int active_set)
 {
-       EditMesh *em;
-       MCol *mcol;
+       BMEditMesh *em;
+       MLoopCol *mcol;
        int layernum;
 
-       if(me->edit_mesh) {
-               em= me->edit_mesh;
+       if(me->edit_btmesh) {
+               em= me->edit_btmesh;
 
-               layernum= CustomData_number_of_layers(&em->fdata, CD_MCOL);
+               layernum= CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPCOL);
                if(layernum >= MAX_MCOL)
                        return 0;
 
-               EM_add_data_layer(em, &em->fdata, CD_MCOL, name);
+               BM_add_data_layer(em->bm, &em->bm->pdata, CD_MLOOPCOL);
+               CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPCOL, layernum);
+
                if(active_set || layernum==0)
-                       CustomData_set_layer_active(&em->fdata, CD_MCOL, layernum);
+                       CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPCOL, layernum);
+
        }
        else {
-               layernum= CustomData_number_of_layers(&me->fdata, CD_MCOL);
-               if(layernum >= MAX_MCOL)
+               layernum= CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL);
+               if(layernum >= CD_MLOOPCOL)
                        return 0;
 
-               mcol= me->mcol;
+               mcol= me->mloopcol;
 
-               if(me->mcol)
-                       CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mcol, me->totface, name);
+               if(me->mloopcol)
+                       CustomData_add_layer_named(&me->ldata, CD_MLOOPCOL, CD_DUPLICATE, me->mloopcol, me->totloop, name);
                else
-                       CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface, name);
+                       CustomData_add_layer_named(&me->ldata, CD_MLOOPCOL, CD_DEFAULT, NULL, me->totloop, name);
 
                if(active_set || layernum==0)
-                       CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum);
+                       CustomData_set_layer_active(&me->ldata, CD_MLOOPCOL, layernum);
 
                mesh_update_customdata_pointers(me);
 
+               /*BMESH_TODO
                if(!mcol)
                        shadeMeshMCol(scene, ob, me);
+               */
        }
 
-       DAG_id_tag_update(&me->id, OB_RECALC_DATA);
+       DAG_id_tag_update(&me->id, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
 
        return 1;
@@ -260,18 +295,17 @@ int ED_mesh_color_add(bContext *C, Scene *scene, Object *ob, Mesh *me, const cha
 
 int ED_mesh_color_remove(bContext *C, Object *ob, Mesh *me)
 {
-       CustomData *data= (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata;
        CustomDataLayer *cdl;
        int index;
 
-        index= CustomData_get_active_layer_index(data, CD_MCOL);
-       cdl= (index == -1)? NULL: &data->layers[index];
+       index= CustomData_get_active_layer_index(&me->ldata, CD_MLOOPCOL);
+       cdl= (index == -1)? NULL: &me->ldata.layers[index];
 
        if(!cdl)
                return 0;
 
        delete_customdata_layer(C, ob, cdl);
-       DAG_id_tag_update(&me->id, OB_RECALC_DATA);
+       DAG_id_tag_update(&me->id, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
 
        return 1;
@@ -315,6 +349,7 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot)
 static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
        Scene *scene= CTX_data_scene(C);
+       View3D *v3d= CTX_wm_view3d(C);
        Base *base= ED_view3d_give_base_under_cursor(C, event->mval);
        Image *ima= NULL;
        Mesh *me;
@@ -345,27 +380,31 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
                return OPERATOR_CANCELLED;
        }
        
-       /* turn mesh in editmode */
-       /* BKE_mesh_get/end_editmesh: ED_uvedit_assign_image also calls this */
+       /* put mesh in editmode */
 
        obedit= base->object;
        me= obedit->data;
-       if(me->edit_mesh==NULL) {
-               make_editMesh(scene, obedit);
+       if(me->edit_btmesh==NULL) {
+               EDBM_MakeEditBMesh(scene->toolsettings, scene, obedit);
                exitmode= 1;
        }
-       if(me->edit_mesh==NULL)
+
+       if(me->edit_btmesh==NULL)
                return OPERATOR_CANCELLED;
        
        ED_uvedit_assign_image(scene, obedit, ima, NULL);
 
        if(exitmode) {
-               load_editMesh(scene, obedit);
-               free_editMesh(me->edit_mesh);
-               MEM_freeN(me->edit_mesh);
-               me->edit_mesh= NULL;
+               EDBM_LoadEditBMesh(scene, obedit);
+               EDBM_FreeEditBMesh(me->edit_btmesh);
+               MEM_freeN(me->edit_btmesh);
+               me->edit_btmesh= NULL;
        }
 
+       /* dummie drop support; ensure view shows a result :) */
+       if(v3d)
+               v3d->flag2 |= V3D_SOLID_TEX;
+       
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
        
        return OPERATOR_FINISHED;
@@ -485,7 +524,7 @@ static int sticky_add_exec(bContext *C, wmOperator *UNUSED(op))
 
        RE_make_sticky(scene, v3d);
 
-       DAG_id_tag_update(&me->id, OB_RECALC_DATA);
+       DAG_id_tag_update(&me->id, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
 
        return OPERATOR_FINISHED;
@@ -517,7 +556,7 @@ static int sticky_remove_exec(bContext *C, wmOperator *UNUSED(op))
        CustomData_free_layer_active(&me->vdata, CD_MSTICKY, me->totvert);
        me->msticky= NULL;
 
-       DAG_id_tag_update(&me->id, OB_RECALC_DATA);
+       DAG_id_tag_update(&me->id, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
 
        return OPERATOR_FINISHED;
@@ -540,81 +579,14 @@ void MESH_OT_sticky_remove(wmOperatorType *ot)
 
 /************************** Add Geometry Layers *************************/
 
-static void mesh_calc_edges(Mesh *mesh, int update)
-{
-       CustomData edata;
-       EdgeHashIterator *ehi;
-       MFace *mf = mesh->mface;
-       MEdge *med, *med_orig;
-       EdgeHash *eh = BLI_edgehash_new();
-       int i, totedge, totface = mesh->totface;
-
-       if(mesh->totedge==0)
-               update= 0;
-
-       if(update) {
-               /* assume existing edges are valid
-                * useful when adding more faces and generating edges from them */
-               med= mesh->medge;
-               for(i= 0; i<mesh->totedge; i++, med++)
-                       BLI_edgehash_insert(eh, med->v1, med->v2, med);
-       }
-
-       for (i = 0; i < totface; i++, mf++) {
-               if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
-                       BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
-               if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
-                       BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
-               
-               if (mf->v4) {
-                       if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
-                               BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
-                       if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
-                               BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
-               } else {
-                       if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
-                               BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
-               }
-       }
-
-       totedge = BLI_edgehash_size(eh);
-
-       /* write new edges into a temporary CustomData */
-       memset(&edata, 0, sizeof(edata));
-       CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
-
-       ehi = BLI_edgehashIterator_new(eh);
-       med = CustomData_get_layer(&edata, CD_MEDGE);
-       for(i = 0; !BLI_edgehashIterator_isDone(ehi);
-               BLI_edgehashIterator_step(ehi), ++i, ++med) {
-
-               if(update && (med_orig=BLI_edgehashIterator_getValue(ehi))) {
-                       *med= *med_orig; /* copy from the original */
-               } else {
-                       BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
-                       med->flag = ME_EDGEDRAW|ME_EDGERENDER;
-               }
-       }
-       BLI_edgehashIterator_free(ehi);
-
-       /* free old CustomData and assign new one */
-       CustomData_free(&mesh->edata, mesh->totedge);
-       mesh->edata = edata;
-       mesh->totedge = totedge;
-
-       mesh->medge = CustomData_get_layer(&mesh->edata, CD_MEDGE);
-
-       BLI_edgehash_free(eh, NULL);
-}
-
 void ED_mesh_update(Mesh *mesh, bContext *C, int calc_edges)
 {
        if(calc_edges || (mesh->totface && mesh->totedge == 0))
-               mesh_calc_edges(mesh, calc_edges);
+               BKE_mesh_calc_edges(mesh, calc_edges);
 
        mesh_calc_normals(mesh->mvert, mesh->totvert, mesh->mface, mesh->totface, NULL);
 
-       DAG_id_tag_update(&mesh->id, OB_RECALC_DATA);
+       DAG_id_tag_update(&mesh->id, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, mesh);
 }
 
@@ -722,7 +694,7 @@ static void mesh_add_faces(Mesh *mesh, int len)
 /*
 void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, int faces)
 {
-       if(mesh->edit_mesh) {
+       if(mesh->edit_btmesh) {
                BKE_report(reports, RPT_ERROR, "Can't add geometry in edit mode.");
                return;
        }
@@ -738,19 +710,18 @@ void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges,
 
 void ED_mesh_faces_add(Mesh *mesh, ReportList *reports, int count)
 {
-       if(mesh->edit_mesh) {
+       if(mesh->edit_btmesh) {
                BKE_report(reports, RPT_ERROR, "Can't add faces in edit mode.");
                return;
        }
-
        mesh_add_faces(mesh, count);
 }
 
 void ED_mesh_edges_add(Mesh *mesh, ReportList *reports, int count)
 {
-       if(mesh->edit_mesh) {
+       if(mesh->edit_btmesh) {
                BKE_report(reports, RPT_ERROR, "Can't add edges in edit mode.");
-               return;
+                       return;
        }
 
        mesh_add_edges(mesh, count);
@@ -758,7 +729,7 @@ void ED_mesh_edges_add(Mesh *mesh, ReportList *reports, int count)
 
 void ED_mesh_vertices_add(Mesh *mesh, ReportList *reports, int count)
 {
-       if(mesh->edit_mesh) {
+       if(mesh->edit_btmesh) {
                BKE_report(reports, RPT_ERROR, "Can't add vertices in edit mode.");
                return;
        }
@@ -770,3 +741,4 @@ void ED_mesh_calc_normals(Mesh *me)
 {
        mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
 }
+