synched with trunk at revision 34793
[blender.git] / source / blender / editors / mesh / mesh_data.c
index 94a7dbebb9caafd52509243739bb2db975fac4dd..d1c6ff4c4aee822688e840793fb7a28665a7e32f 100644 (file)
@@ -15,7 +15,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2009 Blender Foundation.
  * All rights reserved.
 
 #include "MEM_guardedalloc.h"
 
-#include "DNA_customdata_types.h"
 #include "DNA_material_types.h"
-#include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
-#include "DNA_windowmanager_types.h"
+#include "DNA_view3d_types.h"
 
 #include "BKE_context.h"
-#include "BKE_customdata.h"
 #include "BKE_depsgraph.h"
 #include "BKE_displist.h"
-#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_library.h"
 #include "BKE_material.h"
 #include "BKE_mesh.h"
 #include "BKE_report.h"
 
-#include "BLI_arithb.h"
+#include "BLI_math.h"
 #include "BLI_editVert.h"
 #include "BLI_edgehash.h"
 
 
 #include "ED_mesh.h"
 #include "ED_object.h"
+#include "ED_uvedit.h"
 #include "ED_view3d.h"
 
+#include "RE_render_ext.h"
+
 #include "mesh_intern.h"
 
 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;
-       void *actlayerdata, *rndlayerdata, *clonelayerdata, *masklayerdata, *layerdata=layer->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, maskindex;
+       int i, actindex, rndindex, cloneindex, stencilindex;
        
        /* 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,
@@ -84,7 +85,7 @@ static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *la
        actlayerdata = data->layers[CustomData_get_active_layer_index(data, type)].data;
        rndlayerdata = data->layers[CustomData_get_render_layer_index(data, type)].data;
        clonelayerdata = data->layers[CustomData_get_clone_layer_index(data, type)].data;
-       masklayerdata = data->layers[CustomData_get_mask_layer_index(data, type)].data;
+       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) {
@@ -141,22 +142,22 @@ static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *la
                CustomData_set_layer_clone(data, type, cloneindex);
        }
        
-       if (masklayerdata != layerdata) {
+       if (stencillayerdata != layerdata) {
                /* find index */
-               maskindex = CustomData_get_layer_index(data, type);
-               for (i=maskindex; i<data->totlayer; i++) {
-                       if (data->layers[i].data == masklayerdata) {
-                               maskindex = i - maskindex;
+               stencilindex = CustomData_get_layer_index(data, type);
+               for (i=stencilindex; i<data->totlayer; i++) {
+                       if (data->layers[i].data == stencillayerdata) {
+                               stencilindex = i - stencilindex;
                                break;
                        }
                }
                
                /* set index */
-               CustomData_set_layer_mask(data, type, maskindex);
+               CustomData_set_layer_stencil(data, type, stencilindex);
        }
 }
 
-int ED_mesh_uv_texture_add(bContext *C, Scene *scene, Object *ob, Mesh *me)
+int ED_mesh_uv_texture_add(bContext *C, Scene *scene, Object *ob, Mesh *me, const char *name, int active_set)
 {
        EditMesh *em;
        int layernum;
@@ -166,22 +167,25 @@ int ED_mesh_uv_texture_add(bContext *C, Scene *scene, Object *ob, Mesh *me)
 
                layernum= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
                if(layernum >= MAX_MTFACE)
-                       return OPERATOR_CANCELLED;
+                       return 0;
 
-               EM_add_data_layer(em, &em->fdata, CD_MTFACE);
-               CustomData_set_layer_active(&em->fdata, CD_MTFACE, layernum);
+               EM_add_data_layer(em, &em->fdata, CD_MTFACE, name);
+               if(active_set || layernum==0)
+                       CustomData_set_layer_active(&em->fdata, CD_MTFACE, layernum);
        }
        else {
                layernum= CustomData_number_of_layers(&me->fdata, CD_MTFACE);
                if(layernum >= MAX_MTFACE)
-                       return OPERATOR_CANCELLED;
+                       return 0;
 
                if(me->mtface)
-                       CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DUPLICATE, me->mtface, me->totface);
+                       CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DUPLICATE, me->mtface, me->totface, name);
                else
-                       CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface);
+                       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);
 
-               CustomData_set_layer_active(&me->fdata, CD_MTFACE, layernum);
                mesh_update_customdata_pointers(me);
        }
 
@@ -193,11 +197,12 @@ int ED_mesh_uv_texture_add(bContext *C, Scene *scene, Object *ob, Mesh *me)
 
 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;
        int index;
 
-       index= CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
-       cdl= (index == -1)? NULL: &me->fdata.layers[index];
+       index= CustomData_get_active_layer_index(data, CD_MTFACE);
+       cdl= (index == -1) ? NULL: &data->layers[index];
 
        if(!cdl)
                return 0;
@@ -209,7 +214,7 @@ int ED_mesh_uv_texture_remove(bContext *C, Object *ob, Mesh *me)
        return 1;
 }
 
-int ED_mesh_color_add(bContext *C, Scene *scene, 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;
@@ -222,8 +227,9 @@ int ED_mesh_color_add(bContext *C, Scene *scene, Object *ob, Mesh *me)
                if(layernum >= MAX_MCOL)
                        return 0;
 
-               EM_add_data_layer(em, &em->fdata, CD_MCOL);
-               CustomData_set_layer_active(&em->fdata, CD_MCOL, layernum);
+               EM_add_data_layer(em, &em->fdata, CD_MCOL, name);
+               if(active_set || layernum==0)
+                       CustomData_set_layer_active(&em->fdata, CD_MCOL, layernum);
        }
        else {
                layernum= CustomData_number_of_layers(&me->fdata, CD_MCOL);
@@ -233,11 +239,13 @@ int ED_mesh_color_add(bContext *C, Scene *scene, Object *ob, Mesh *me)
                mcol= me->mcol;
 
                if(me->mcol)
-                       CustomData_add_layer(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mcol, me->totface);
+                       CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mcol, me->totface, name);
                else
-                       CustomData_add_layer(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface);
+                       CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface, name);
+
+               if(active_set || layernum==0)
+                       CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum);
 
-               CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum);
                mesh_update_customdata_pointers(me);
 
                if(!mcol)
@@ -252,11 +260,12 @@ int ED_mesh_color_add(bContext *C, Scene *scene, Object *ob, Mesh *me)
 
 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(&me->fdata, CD_MCOL);
-       cdl= (index == -1)? NULL: &me->fdata.layers[index];
+        index= CustomData_get_active_layer_index(data, CD_MCOL);
+       cdl= (index == -1)? NULL: &data->layers[index];
 
        if(!cdl)
                return 0;
@@ -283,7 +292,7 @@ static int uv_texture_add_exec(bContext *C, wmOperator *op)
        Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
        Mesh *me= ob->data;
 
-       if(!ED_mesh_uv_texture_add(C, scene, ob, me))
+       if(!ED_mesh_uv_texture_add(C, scene, ob, me, NULL, TRUE))
                return OPERATOR_CANCELLED;
 
        return OPERATOR_FINISHED;
@@ -293,7 +302,7 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Add UV Texture";
-       ot->description= "Add UV texture layer.";
+       ot->description= "Add UV texture layer";
        ot->idname= "MESH_OT_uv_texture_add";
        
        /* api callbacks */
@@ -304,6 +313,85 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       Scene *scene= CTX_data_scene(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];
+       
+       /* Check context */
+       if(base==NULL || base->object->type!=OB_MESH) {
+               BKE_report(op->reports, RPT_ERROR, "Not an Object or Mesh");
+               return OPERATOR_CANCELLED;
+       }
+       
+       /* check input variables */
+       if(RNA_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);
+       }
+       else {
+               RNA_string_get(op->ptr, "name", name);
+               ima= (Image *)find_id("IM", name);
+       }
+       
+       if(!ima) {
+               BKE_report(op->reports, RPT_ERROR, "Not an Image.");
+               return OPERATOR_CANCELLED;
+       }
+       
+       /* turn mesh in editmode */
+       /* BKE_mesh_get/end_editmesh: ED_uvedit_assign_image also calls this */
+
+       obedit= base->object;
+       me= obedit->data;
+       if(me->edit_mesh==NULL) {
+               make_editMesh(scene, obedit);
+               exitmode= 1;
+       }
+       if(me->edit_mesh==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;
+       }
+
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
+       
+       return OPERATOR_FINISHED;
+}
+
+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->idname= "MESH_OT_drop_named_image";
+       
+       /* api callbacks */
+       ot->poll= layers_poll;
+       ot->invoke= drop_named_image_invoke;
+       
+       /* flags */
+       ot->flag= OPTYPE_UNDO;
+       
+       /* properties */
+       RNA_def_string(ot->srna, "name", "Image", 24, "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 *op)
 {
        Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
@@ -319,7 +407,7 @@ void MESH_OT_uv_texture_remove(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Remove UV Texture";
-       ot->description= "Remove UV texture layer.";
+       ot->description= "Remove UV texture layer";
        ot->idname= "MESH_OT_uv_texture_remove";
        
        /* api callbacks */
@@ -338,7 +426,7 @@ static int vertex_color_add_exec(bContext *C, wmOperator *op)
        Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
        Mesh *me= ob->data;
 
-       if(!ED_mesh_color_add(C, scene, ob, me))
+       if(!ED_mesh_color_add(C, scene, ob, me, NULL, TRUE))
                return OPERATOR_CANCELLED;
 
        return OPERATOR_FINISHED;
@@ -348,7 +436,7 @@ void MESH_OT_vertex_color_add(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Add Vertex Color";
-       ot->description= "Add vertex color layer.";
+       ot->description= "Add vertex color layer";
        ot->idname= "MESH_OT_vertex_color_add";
        
        /* api callbacks */
@@ -374,7 +462,7 @@ void MESH_OT_vertex_color_remove(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Remove Vertex Color";
-       ot->description= "Remove vertex color layer.";
+       ot->description= "Remove vertex color layer";
        ot->idname= "MESH_OT_vertex_color_remove";
        
        /* api callbacks */
@@ -389,13 +477,15 @@ void MESH_OT_vertex_color_remove(wmOperatorType *ot)
 
 static int sticky_add_exec(bContext *C, wmOperator *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;
        Mesh *me= ob->data;
 
-       if(me->msticky)
-               return OPERATOR_CANCELLED;
+       /*if(me->msticky)
+               return OPERATOR_CANCELLED;*/
 
-       // XXX RE_make_sticky();
+       RE_make_sticky(scene, v3d);
 
        DAG_id_flush_update(&me->id, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
@@ -407,7 +497,7 @@ void MESH_OT_sticky_add(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Add Sticky";
-       ot->description= "Add sticky UV texture layer.";
+       ot->description= "Add sticky UV texture layer";
        ot->idname= "MESH_OT_sticky_add";
        
        /* api callbacks */
@@ -439,7 +529,7 @@ void MESH_OT_sticky_remove(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Remove Sticky";
-       ot->description= "Remove sticky UV texture layer.";
+       ot->description= "Remove sticky UV texture layer";
        ot->idname= "MESH_OT_sticky_remove";
        
        /* api callbacks */
@@ -459,7 +549,7 @@ static void mesh_calc_edges(Mesh *mesh, int update)
        MFace *mf = mesh->mface;
        MEdge *med, *med_orig;
        EdgeHash *eh = BLI_edgehash_new();
-       int i, *index, totedge, totface = mesh->totface;
+       int i, totedge, totface = mesh->totface;
 
        if(mesh->totedge==0)
                update= 0;
@@ -498,7 +588,7 @@ static void mesh_calc_edges(Mesh *mesh, int update)
        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, ++index) {
+               BLI_edgehashIterator_step(ehi), ++i, ++med) {
 
                if(update && (med_orig=BLI_edgehashIterator_getValue(ehi))) {
                        *med= *med_orig; /* copy from the original */
@@ -566,7 +656,7 @@ void ED_mesh_transform(Mesh *me, float *mat)
        MVert *mvert= me->mvert;
 
        for(i= 0; i < me->totvert; i++, mvert++)
-               Mat4MulVecfl((float (*)[4])mat, mvert->co);
+               mul_m4_v3((float (*)[4])mat, mvert->co);
 
        mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
 }
@@ -626,11 +716,12 @@ static void mesh_add_faces(Mesh *mesh, int len)
        /* set default flags */
        mface= &mesh->mface[mesh->totface];
        for(i=0; i<len; i++, mface++)
-               mface->flag= SELECT;
+               mface->flag= ME_FACE_SEL;
 
        mesh->totface= totface;
 }
 
+/*
 void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, int faces)
 {
        if(mesh->edit_mesh) {
@@ -645,32 +736,39 @@ void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges,
        if(faces)
                mesh_add_faces(mesh, faces);
 }
+*/
 
-void ED_mesh_calc_normals(Mesh *me)
+void ED_mesh_faces_add(Mesh *mesh, ReportList *reports, int count)
 {
-       mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
+       if(mesh->edit_mesh) {
+               BKE_report(reports, RPT_ERROR, "Can't add faces in edit mode.");
+               return;
+       }
+
+       mesh_add_faces(mesh, count);
 }
 
-void ED_mesh_material_add(Mesh *me, Material *ma)
+void ED_mesh_edges_add(Mesh *mesh, ReportList *reports, int count)
 {
-       int i;
-       int totcol = me->totcol + 1;
-       Material **mat;
-
-       /* don't add if mesh already has it */
-       for(i = 0; i < me->totcol; i++)
-               if(me->mat[i] == ma)
-                       return;
-
-       mat= MEM_callocN(sizeof(void*)*totcol, "newmatar");
+       if(mesh->edit_mesh) {
+               BKE_report(reports, RPT_ERROR, "Can't add edges in edit mode.");
+               return;
+       }
 
-       if(me->totcol) memcpy(mat, me->mat, sizeof(void*) * me->totcol);
-       if(me->mat) MEM_freeN(me->mat);
+       mesh_add_edges(mesh, count);
+}
 
-       me->mat = mat;
-       me->mat[me->totcol++] = ma;
-       ma->id.us++;
+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.");
+               return;
+       }
 
-       test_object_materials((ID*)me);
+       mesh_add_verts(mesh, count);
 }
 
+void ED_mesh_calc_normals(Mesh *me)
+{
+       mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
+}