rename RNA_property_is_set() --> RNA_struct_property_is_set() in preperation to add...
[blender.git] / source / blender / editors / mesh / mesh_data.c
index f45786d3abe1a2611eda02b3fdd9912151802113..e40c806fd173a79e21d477ecc54aa37b5225d125 100644 (file)
@@ -1,6 +1,4 @@
-/**
- * $Id$
- *
+/*
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
  * ***** END GPL LICENSE BLOCK *****
  */
 
+/** \file blender/editors/mesh/mesh_data.c
+ *  \ingroup edmesh
+ */
+
+
 #include <math.h>
 #include <stdlib.h>
 #include <string.h>
 #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_image.h"
 #include "BKE_library.h"
+#include "BKE_main.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 "RNA_access.h"
 #include "RNA_define.h"
 
@@ -157,7 +162,18 @@ static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *la
        }
 }
 
-int ED_mesh_uv_texture_add(bContext *C, Scene *scene, Object *ob, Mesh *me, const char *name, int active_set)
+static void copy_editface_active_customdata(EditMesh *em, int type, int index)
+{
+       EditFace *efa;
+       int n= CustomData_get_active_layer(&em->fdata, type);
+
+       for(efa= em->faces.first; efa; efa= efa->next) {
+               void *data= CustomData_em_get_n(&em->fdata, efa->data, type, n);
+               CustomData_em_set_n(&em->fdata, efa->data, type, index, data);
+       }
+}
+
+int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_set)
 {
        EditMesh *em;
        int layernum;
@@ -170,6 +186,10 @@ int ED_mesh_uv_texture_add(bContext *C, Scene *scene, Object *ob, Mesh *me, cons
                        return 0;
 
                EM_add_data_layer(em, &em->fdata, CD_MTFACE, name);
+
+               if(layernum) /* copy data from active UV */
+                       copy_editface_active_customdata(em, CD_MTFACE, layernum);
+
                if(active_set || layernum==0)
                        CustomData_set_layer_active(&em->fdata, CD_MTFACE, layernum);
        }
@@ -189,7 +209,7 @@ int ED_mesh_uv_texture_add(bContext *C, Scene *scene, Object *ob, Mesh *me, cons
                mesh_update_customdata_pointers(me);
        }
 
-       DAG_id_flush_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;
@@ -208,16 +228,15 @@ int ED_mesh_uv_texture_remove(bContext *C, Object *ob, Mesh *me)
                return 0;
 
        delete_customdata_layer(C, ob, cdl);
-       DAG_id_flush_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;
 }
 
-int ED_mesh_color_add(bContext *C, Scene *scene, Object *ob, Mesh *me, const char *name, int active_set)
+int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mesh *me, const char *name, int active_set)
 {
        EditMesh *em;
-       MCol *mcol;
        int layernum;
 
        if(me->edit_mesh) {
@@ -228,6 +247,10 @@ int ED_mesh_color_add(bContext *C, Scene *scene, Object *ob, Mesh *me, const cha
                        return 0;
 
                EM_add_data_layer(em, &em->fdata, CD_MCOL, name);
+
+               if(layernum) /* copy data from active vertex color layer */
+                       copy_editface_active_customdata(em, CD_MCOL, layernum);
+
                if(active_set || layernum==0)
                        CustomData_set_layer_active(&em->fdata, CD_MCOL, layernum);
        }
@@ -236,8 +259,6 @@ int ED_mesh_color_add(bContext *C, Scene *scene, Object *ob, Mesh *me, const cha
                if(layernum >= MAX_MCOL)
                        return 0;
 
-               mcol= me->mcol;
-
                if(me->mcol)
                        CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mcol, me->totface, name);
                else
@@ -247,12 +268,9 @@ int ED_mesh_color_add(bContext *C, Scene *scene, Object *ob, Mesh *me, const cha
                        CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum);
 
                mesh_update_customdata_pointers(me);
-
-               if(!mcol)
-                       shadeMeshMCol(scene, ob, me);
        }
 
-       DAG_id_flush_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;
@@ -264,14 +282,33 @@ int ED_mesh_color_remove(bContext *C, Object *ob, Mesh *me)
        CustomDataLayer *cdl;
        int index;
 
-        index= CustomData_get_active_layer_index(data, CD_MCOL);
+       index= CustomData_get_active_layer_index(data, CD_MCOL);
+       cdl= (index == -1)? NULL: &data->layers[index];
+
+       if(!cdl)
+               return 0;
+
+       delete_customdata_layer(C, ob, cdl);
+       DAG_id_tag_update(&me->id, 0);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
+
+       return 1;
+}
+
+int ED_mesh_color_remove_named(bContext *C, Object *ob, Mesh *me, const char *name)
+{
+       CustomData *data= (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata;
+       CustomDataLayer *cdl;
+       int index;
+
+       index= CustomData_get_named_layer_index(data, CD_MCOL, name);
        cdl= (index == -1)? NULL: &data->layers[index];
 
        if(!cdl)
                return 0;
 
        delete_customdata_layer(C, ob, cdl);
-       DAG_id_flush_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;
@@ -281,18 +318,17 @@ int ED_mesh_color_remove(bContext *C, Object *ob, Mesh *me)
 
 static int layers_poll(bContext *C)
 {
-       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+       Object *ob= ED_object_context(C);
        ID *data= (ob)? ob->data: NULL;
        return (ob && !ob->id.lib && ob->type==OB_MESH && data && !data->lib);
 }
 
 static int uv_texture_add_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       Scene *scene= CTX_data_scene(C);
-       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+       Object *ob= ED_object_context(C);
        Mesh *me= ob->data;
 
-       if(!ED_mesh_uv_texture_add(C, scene, ob, me, NULL, TRUE))
+       if(!ED_mesh_uv_texture_add(C, me, NULL, TRUE))
                return OPERATOR_CANCELLED;
 
        return OPERATOR_FINISHED;
@@ -301,8 +337,8 @@ static int uv_texture_add_exec(bContext *C, wmOperator *UNUSED(op))
 void MESH_OT_uv_texture_add(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Add UV Texture";
-       ot->description= "Add UV texture layer";
+       ot->name= "Add UV Map";
+       ot->description= "Add UV Map";
        ot->idname= "MESH_OT_uv_texture_add";
        
        /* api callbacks */
@@ -315,13 +351,15 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot)
 
 static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
+       Main *bmain= CTX_data_main(C);
        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;
        Object *obedit;
        int exitmode= 0;
-       char name[32];
+       char name[MAX_ID_NAME-2];
        
        /* Check context */
        if(base==NULL || base->object->type!=OB_MESH) {
@@ -330,12 +368,11 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
        }
        
        /* check input variables */
-       if(RNA_property_is_set(op->ptr, "filepath")) {
+       if(RNA_struct_property_is_set(op->ptr, "filepath")) {
                char path[FILE_MAX];
                
                RNA_string_get(op->ptr, "filepath", path);
-               ima= BKE_add_image_file(path, 
-                                                               scene ? scene->r.cfra : 1);
+               ima= BKE_add_image_file(path);
        }
        else {
                RNA_string_get(op->ptr, "name", name);
@@ -343,7 +380,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
        }
        
        if(!ima) {
-               BKE_report(op->reports, RPT_ERROR, "Not an Image.");
+               BKE_report(op->reports, RPT_ERROR, "Not an Image");
                return OPERATOR_CANCELLED;
        }
        
@@ -359,7 +396,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
        if(me->edit_mesh==NULL)
                return OPERATOR_CANCELLED;
        
-       ED_uvedit_assign_image(scene, obedit, ima, NULL);
+       ED_uvedit_assign_image(bmain, scene, obedit, ima, NULL);
 
        if(exitmode) {
                load_editMesh(scene, obedit);
@@ -368,6 +405,10 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
                me->edit_mesh= 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;
@@ -376,8 +417,8 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
 void MESH_OT_drop_named_image(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Assign Image to UV Texture";
-       ot->description= "Assigns Image to active UV layer, or creates a UV layer";
+       ot->name= "Assign Image to UV Map";
+       ot->description= "Assign Image to active UV Map, or create an UV Map";
        ot->idname= "MESH_OT_drop_named_image";
        
        /* api callbacks */
@@ -388,13 +429,13 @@ void MESH_OT_drop_named_image(wmOperatorType *ot)
        ot->flag= OPTYPE_UNDO;
        
        /* properties */
-       RNA_def_string(ot->srna, "name", "Image", 24, "Name", "Image name to assign.");
+       RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME-2, "Name", "Image name to assign");
        RNA_def_string(ot->srna, "filepath", "Path", FILE_MAX, "Filepath", "Path to image file");
 }
 
 static int uv_texture_remove_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+       Object *ob= ED_object_context(C);
        Mesh *me= ob->data;
 
        if(!ED_mesh_uv_texture_remove(C, ob, me))
@@ -406,8 +447,8 @@ static int uv_texture_remove_exec(bContext *C, wmOperator *UNUSED(op))
 void MESH_OT_uv_texture_remove(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Remove UV Texture";
-       ot->description= "Remove UV texture layer";
+       ot->name= "Remove UV Map";
+       ot->description= "Remove UV Map";
        ot->idname= "MESH_OT_uv_texture_remove";
        
        /* api callbacks */
@@ -423,7 +464,7 @@ void MESH_OT_uv_texture_remove(wmOperatorType *ot)
 static int vertex_color_add_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Scene *scene= CTX_data_scene(C);
-       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+       Object *ob= ED_object_context(C);
        Mesh *me= ob->data;
 
        if(!ED_mesh_color_add(C, scene, ob, me, NULL, TRUE))
@@ -449,7 +490,7 @@ void MESH_OT_vertex_color_add(wmOperatorType *ot)
 
 static int vertex_color_remove_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+       Object *ob= ED_object_context(C);
        Mesh *me= ob->data;
 
        if(!ED_mesh_color_remove(C, ob, me))
@@ -479,7 +520,7 @@ static int sticky_add_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Scene *scene= CTX_data_scene(C);
        View3D *v3d= CTX_wm_view3d(C);
-       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+       Object *ob= ED_object_context(C);
        Mesh *me= ob->data;
 
        /*if(me->msticky)
@@ -487,7 +528,7 @@ static int sticky_add_exec(bContext *C, wmOperator *UNUSED(op))
 
        RE_make_sticky(scene, v3d);
 
-       DAG_id_flush_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;
@@ -510,7 +551,7 @@ void MESH_OT_sticky_add(wmOperatorType *ot)
 
 static int sticky_remove_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+       Object *ob= ED_object_context(C);
        Mesh *me= ob->data;
 
        if(!me->msticky)
@@ -519,7 +560,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_flush_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;
@@ -542,81 +583,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_flush_update(&mesh->id, OB_RECALC_DATA);
+       DAG_id_tag_update(&mesh->id, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, mesh);
 }
 
@@ -725,7 +699,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) {
-               BKE_report(reports, RPT_ERROR, "Can't add geometry in edit mode.");
+               BKE_report(reports, RPT_ERROR, "Can't add geometry in edit mode");
                return;
        }
 
@@ -741,7 +715,7 @@ 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) {
-               BKE_report(reports, RPT_ERROR, "Can't add faces in edit mode.");
+               BKE_report(reports, RPT_ERROR, "Can't add faces in edit mode");
                return;
        }
 
@@ -751,7 +725,7 @@ void ED_mesh_faces_add(Mesh *mesh, ReportList *reports, int count)
 void ED_mesh_edges_add(Mesh *mesh, ReportList *reports, int count)
 {
        if(mesh->edit_mesh) {
-               BKE_report(reports, RPT_ERROR, "Can't add edges in edit mode.");
+               BKE_report(reports, RPT_ERROR, "Can't add edges in edit mode");
                return;
        }
 
@@ -761,7 +735,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) {
-               BKE_report(reports, RPT_ERROR, "Can't add vertices in edit mode.");
+               BKE_report(reports, RPT_ERROR, "Can't add vertices in edit mode");
                return;
        }