DAG_id_tag_update was being called with non object ID's and OB_RECALC_* flags which...
[blender.git] / source / blender / editors / mesh / mesh_data.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2009 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include <math.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "MEM_guardedalloc.h"
34
35 #include "DNA_material_types.h"
36 #include "DNA_meshdata_types.h"
37 #include "DNA_object_types.h"
38 #include "DNA_scene_types.h"
39 #include "DNA_view3d_types.h"
40
41 #include "BKE_context.h"
42 #include "BKE_depsgraph.h"
43 #include "BKE_displist.h"
44 #include "BKE_image.h"
45 #include "BKE_library.h"
46 #include "BKE_material.h"
47 #include "BKE_mesh.h"
48 #include "BKE_report.h"
49
50 #include "BLI_math.h"
51 #include "BLI_editVert.h"
52 #include "BLI_edgehash.h"
53
54 #include "RNA_access.h"
55 #include "RNA_define.h"
56
57 #include "WM_api.h"
58 #include "WM_types.h"
59
60 #include "ED_mesh.h"
61 #include "ED_object.h"
62 #include "ED_uvedit.h"
63 #include "ED_view3d.h"
64
65 #include "RE_render_ext.h"
66
67 #include "mesh_intern.h"
68
69 static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *layer)
70 {
71         Mesh *me = ob->data;
72         CustomData *data= (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata;
73         void *actlayerdata, *rndlayerdata, *clonelayerdata, *stencillayerdata, *layerdata=layer->data;
74         int type= layer->type;
75         int index= CustomData_get_layer_index(data, type);
76         int i, actindex, rndindex, cloneindex, stencilindex;
77         
78         /* ok, deleting a non-active layer needs to preserve the active layer indices.
79           to do this, we store a pointer to the .data member of both layer and the active layer,
80           (to detect if we're deleting the active layer or not), then use the active
81           layer data pointer to find where the active layer has ended up.
82           
83           this is necassary because the deletion functions only support deleting the active
84           layer. */
85         actlayerdata = data->layers[CustomData_get_active_layer_index(data, type)].data;
86         rndlayerdata = data->layers[CustomData_get_render_layer_index(data, type)].data;
87         clonelayerdata = data->layers[CustomData_get_clone_layer_index(data, type)].data;
88         stencillayerdata = data->layers[CustomData_get_stencil_layer_index(data, type)].data;
89         CustomData_set_layer_active(data, type, layer - &data->layers[index]);
90
91         if(me->edit_mesh) {
92                 EM_free_data_layer(me->edit_mesh, data, type);
93         }
94         else {
95                 CustomData_free_layer_active(data, type, me->totface);
96                 mesh_update_customdata_pointers(me);
97         }
98
99         if(!CustomData_has_layer(data, type) && (type == CD_MCOL && (ob->mode & OB_MODE_VERTEX_PAINT)))
100                 ED_object_toggle_modes(C, OB_MODE_VERTEX_PAINT);
101
102         /* reconstruct active layer */
103         if (actlayerdata != layerdata) {
104                 /* find index */
105                 actindex = CustomData_get_layer_index(data, type);
106                 for (i=actindex; i<data->totlayer; i++) {
107                         if (data->layers[i].data == actlayerdata) {
108                                 actindex = i - actindex;
109                                 break;
110                         }
111                 }
112                 
113                 /* set index */
114                 CustomData_set_layer_active(data, type, actindex);
115         }
116         
117         if (rndlayerdata != layerdata) {
118                 /* find index */
119                 rndindex = CustomData_get_layer_index(data, type);
120                 for (i=rndindex; i<data->totlayer; i++) {
121                         if (data->layers[i].data == rndlayerdata) {
122                                 rndindex = i - rndindex;
123                                 break;
124                         }
125                 }
126                 
127                 /* set index */
128                 CustomData_set_layer_render(data, type, rndindex);
129         }
130         
131         if (clonelayerdata != layerdata) {
132                 /* find index */
133                 cloneindex = CustomData_get_layer_index(data, type);
134                 for (i=cloneindex; i<data->totlayer; i++) {
135                         if (data->layers[i].data == clonelayerdata) {
136                                 cloneindex = i - cloneindex;
137                                 break;
138                         }
139                 }
140                 
141                 /* set index */
142                 CustomData_set_layer_clone(data, type, cloneindex);
143         }
144         
145         if (stencillayerdata != layerdata) {
146                 /* find index */
147                 stencilindex = CustomData_get_layer_index(data, type);
148                 for (i=stencilindex; i<data->totlayer; i++) {
149                         if (data->layers[i].data == stencillayerdata) {
150                                 stencilindex = i - stencilindex;
151                                 break;
152                         }
153                 }
154                 
155                 /* set index */
156                 CustomData_set_layer_stencil(data, type, stencilindex);
157         }
158 }
159
160 int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_set)
161 {
162         EditMesh *em;
163         int layernum;
164
165         if(me->edit_mesh) {
166                 em= me->edit_mesh;
167
168                 layernum= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
169                 if(layernum >= MAX_MTFACE)
170                         return 0;
171
172                 EM_add_data_layer(em, &em->fdata, CD_MTFACE, name);
173                 if(active_set || layernum==0)
174                         CustomData_set_layer_active(&em->fdata, CD_MTFACE, layernum);
175         }
176         else {
177                 layernum= CustomData_number_of_layers(&me->fdata, CD_MTFACE);
178                 if(layernum >= MAX_MTFACE)
179                         return 0;
180
181                 if(me->mtface)
182                         CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DUPLICATE, me->mtface, me->totface, name);
183                 else
184                         CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface, name);
185
186                 if(active_set || layernum==0)
187                         CustomData_set_layer_active(&me->fdata, CD_MTFACE, layernum);
188
189                 mesh_update_customdata_pointers(me);
190         }
191
192         DAG_id_tag_update(&me->id, 0);
193         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
194
195         return 1;
196 }
197
198 int ED_mesh_uv_texture_remove(bContext *C, Object *ob, Mesh *me)
199 {
200         CustomData *data= (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata;
201         CustomDataLayer *cdl;
202         int index;
203
204         index= CustomData_get_active_layer_index(data, CD_MTFACE);
205         cdl= (index == -1) ? NULL: &data->layers[index];
206
207         if(!cdl)
208                 return 0;
209
210         delete_customdata_layer(C, ob, cdl);
211         DAG_id_tag_update(&me->id, 0);
212         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
213
214         return 1;
215 }
216
217 int ED_mesh_color_add(bContext *C, Scene *scene, Object *ob, Mesh *me, const char *name, int active_set)
218 {
219         EditMesh *em;
220         MCol *mcol;
221         int layernum;
222
223         if(me->edit_mesh) {
224                 em= me->edit_mesh;
225
226                 layernum= CustomData_number_of_layers(&em->fdata, CD_MCOL);
227                 if(layernum >= MAX_MCOL)
228                         return 0;
229
230                 EM_add_data_layer(em, &em->fdata, CD_MCOL, name);
231                 if(active_set || layernum==0)
232                         CustomData_set_layer_active(&em->fdata, CD_MCOL, layernum);
233         }
234         else {
235                 layernum= CustomData_number_of_layers(&me->fdata, CD_MCOL);
236                 if(layernum >= MAX_MCOL)
237                         return 0;
238
239                 mcol= me->mcol;
240
241                 if(me->mcol)
242                         CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mcol, me->totface, name);
243                 else
244                         CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface, name);
245
246                 if(active_set || layernum==0)
247                         CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum);
248
249                 mesh_update_customdata_pointers(me);
250
251                 if(!mcol)
252                         shadeMeshMCol(scene, ob, me);
253         }
254
255         DAG_id_tag_update(&me->id, 0);
256         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
257
258         return 1;
259 }
260
261 int ED_mesh_color_remove(bContext *C, Object *ob, Mesh *me)
262 {
263         CustomData *data= (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata;
264         CustomDataLayer *cdl;
265         int index;
266
267          index= CustomData_get_active_layer_index(data, CD_MCOL);
268         cdl= (index == -1)? NULL: &data->layers[index];
269
270         if(!cdl)
271                 return 0;
272
273         delete_customdata_layer(C, ob, cdl);
274         DAG_id_tag_update(&me->id, 0);
275         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
276
277         return 1;
278 }
279
280 /*********************** UV texture operators ************************/
281
282 static int layers_poll(bContext *C)
283 {
284         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
285         ID *data= (ob)? ob->data: NULL;
286         return (ob && !ob->id.lib && ob->type==OB_MESH && data && !data->lib);
287 }
288
289 static int uv_texture_add_exec(bContext *C, wmOperator *UNUSED(op))
290 {
291         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
292         Mesh *me= ob->data;
293
294         if(!ED_mesh_uv_texture_add(C, me, NULL, TRUE))
295                 return OPERATOR_CANCELLED;
296
297         return OPERATOR_FINISHED;
298 }
299
300 void MESH_OT_uv_texture_add(wmOperatorType *ot)
301 {
302         /* identifiers */
303         ot->name= "Add UV Texture";
304         ot->description= "Add UV texture layer";
305         ot->idname= "MESH_OT_uv_texture_add";
306         
307         /* api callbacks */
308         ot->poll= layers_poll;
309         ot->exec= uv_texture_add_exec;
310
311         /* flags */
312         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
313 }
314
315 static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
316 {
317         Scene *scene= CTX_data_scene(C);
318         Base *base= ED_view3d_give_base_under_cursor(C, event->mval);
319         Image *ima= NULL;
320         Mesh *me;
321         Object *obedit;
322         int exitmode= 0;
323         char name[32];
324         
325         /* Check context */
326         if(base==NULL || base->object->type!=OB_MESH) {
327                 BKE_report(op->reports, RPT_ERROR, "Not an Object or Mesh");
328                 return OPERATOR_CANCELLED;
329         }
330         
331         /* check input variables */
332         if(RNA_property_is_set(op->ptr, "filepath")) {
333                 char path[FILE_MAX];
334                 
335                 RNA_string_get(op->ptr, "filepath", path);
336                 ima= BKE_add_image_file(path);
337         }
338         else {
339                 RNA_string_get(op->ptr, "name", name);
340                 ima= (Image *)find_id("IM", name);
341         }
342         
343         if(!ima) {
344                 BKE_report(op->reports, RPT_ERROR, "Not an Image.");
345                 return OPERATOR_CANCELLED;
346         }
347         
348         /* turn mesh in editmode */
349         /* BKE_mesh_get/end_editmesh: ED_uvedit_assign_image also calls this */
350
351         obedit= base->object;
352         me= obedit->data;
353         if(me->edit_mesh==NULL) {
354                 make_editMesh(scene, obedit);
355                 exitmode= 1;
356         }
357         if(me->edit_mesh==NULL)
358                 return OPERATOR_CANCELLED;
359         
360         ED_uvedit_assign_image(scene, obedit, ima, NULL);
361
362         if(exitmode) {
363                 load_editMesh(scene, obedit);
364                 free_editMesh(me->edit_mesh);
365                 MEM_freeN(me->edit_mesh);
366                 me->edit_mesh= NULL;
367         }
368
369         WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
370         
371         return OPERATOR_FINISHED;
372 }
373
374 void MESH_OT_drop_named_image(wmOperatorType *ot)
375 {
376         /* identifiers */
377         ot->name= "Assign Image to UV Texture";
378         ot->description= "Assigns Image to active UV layer, or creates a UV layer";
379         ot->idname= "MESH_OT_drop_named_image";
380         
381         /* api callbacks */
382         ot->poll= layers_poll;
383         ot->invoke= drop_named_image_invoke;
384         
385         /* flags */
386         ot->flag= OPTYPE_UNDO;
387         
388         /* properties */
389         RNA_def_string(ot->srna, "name", "Image", 24, "Name", "Image name to assign.");
390         RNA_def_string(ot->srna, "filepath", "Path", FILE_MAX, "Filepath", "Path to image file");
391 }
392
393 static int uv_texture_remove_exec(bContext *C, wmOperator *UNUSED(op))
394 {
395         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
396         Mesh *me= ob->data;
397
398         if(!ED_mesh_uv_texture_remove(C, ob, me))
399                 return OPERATOR_CANCELLED;
400
401         return OPERATOR_FINISHED;
402 }
403
404 void MESH_OT_uv_texture_remove(wmOperatorType *ot)
405 {
406         /* identifiers */
407         ot->name= "Remove UV Texture";
408         ot->description= "Remove UV texture layer";
409         ot->idname= "MESH_OT_uv_texture_remove";
410         
411         /* api callbacks */
412         ot->poll= layers_poll;
413         ot->exec= uv_texture_remove_exec;
414
415         /* flags */
416         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
417 }
418
419 /*********************** vertex color operators ************************/
420
421 static int vertex_color_add_exec(bContext *C, wmOperator *UNUSED(op))
422 {
423         Scene *scene= CTX_data_scene(C);
424         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
425         Mesh *me= ob->data;
426
427         if(!ED_mesh_color_add(C, scene, ob, me, NULL, TRUE))
428                 return OPERATOR_CANCELLED;
429
430         return OPERATOR_FINISHED;
431 }
432
433 void MESH_OT_vertex_color_add(wmOperatorType *ot)
434 {
435         /* identifiers */
436         ot->name= "Add Vertex Color";
437         ot->description= "Add vertex color layer";
438         ot->idname= "MESH_OT_vertex_color_add";
439         
440         /* api callbacks */
441         ot->poll= layers_poll;
442         ot->exec= vertex_color_add_exec;
443
444         /* flags */
445         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
446 }
447
448 static int vertex_color_remove_exec(bContext *C, wmOperator *UNUSED(op))
449 {
450         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
451         Mesh *me= ob->data;
452
453         if(!ED_mesh_color_remove(C, ob, me))
454                 return OPERATOR_CANCELLED;
455
456         return OPERATOR_FINISHED;
457 }
458
459 void MESH_OT_vertex_color_remove(wmOperatorType *ot)
460 {
461         /* identifiers */
462         ot->name= "Remove Vertex Color";
463         ot->description= "Remove vertex color layer";
464         ot->idname= "MESH_OT_vertex_color_remove";
465         
466         /* api callbacks */
467         ot->exec= vertex_color_remove_exec;
468         ot->poll= layers_poll;
469
470         /* flags */
471         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
472 }
473
474 /*********************** sticky operators ************************/
475
476 static int sticky_add_exec(bContext *C, wmOperator *UNUSED(op))
477 {
478         Scene *scene= CTX_data_scene(C);
479         View3D *v3d= CTX_wm_view3d(C);
480         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
481         Mesh *me= ob->data;
482
483         /*if(me->msticky)
484                 return OPERATOR_CANCELLED;*/
485
486         RE_make_sticky(scene, v3d);
487
488         DAG_id_tag_update(&me->id, 0);
489         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
490
491         return OPERATOR_FINISHED;
492 }
493
494 void MESH_OT_sticky_add(wmOperatorType *ot)
495 {
496         /* identifiers */
497         ot->name= "Add Sticky";
498         ot->description= "Add sticky UV texture layer";
499         ot->idname= "MESH_OT_sticky_add";
500         
501         /* api callbacks */
502         ot->poll= layers_poll;
503         ot->exec= sticky_add_exec;
504
505         /* flags */
506         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
507 }
508
509 static int sticky_remove_exec(bContext *C, wmOperator *UNUSED(op))
510 {
511         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
512         Mesh *me= ob->data;
513
514         if(!me->msticky)
515                 return OPERATOR_CANCELLED;
516
517         CustomData_free_layer_active(&me->vdata, CD_MSTICKY, me->totvert);
518         me->msticky= NULL;
519
520         DAG_id_tag_update(&me->id, 0);
521         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
522
523         return OPERATOR_FINISHED;
524 }
525
526 void MESH_OT_sticky_remove(wmOperatorType *ot)
527 {
528         /* identifiers */
529         ot->name= "Remove Sticky";
530         ot->description= "Remove sticky UV texture layer";
531         ot->idname= "MESH_OT_sticky_remove";
532         
533         /* api callbacks */
534         ot->poll= layers_poll;
535         ot->exec= sticky_remove_exec;
536
537         /* flags */
538         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
539 }
540
541 /************************** Add Geometry Layers *************************/
542
543 static void mesh_calc_edges(Mesh *mesh, int update)
544 {
545         CustomData edata;
546         EdgeHashIterator *ehi;
547         MFace *mf = mesh->mface;
548         MEdge *med, *med_orig;
549         EdgeHash *eh = BLI_edgehash_new();
550         int i, totedge, totface = mesh->totface;
551
552         if(mesh->totedge==0)
553                 update= 0;
554
555         if(update) {
556                 /* assume existing edges are valid
557                  * useful when adding more faces and generating edges from them */
558                 med= mesh->medge;
559                 for(i= 0; i<mesh->totedge; i++, med++)
560                         BLI_edgehash_insert(eh, med->v1, med->v2, med);
561         }
562
563         for (i = 0; i < totface; i++, mf++) {
564                 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
565                         BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
566                 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
567                         BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
568                 
569                 if (mf->v4) {
570                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
571                                 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
572                         if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
573                                 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
574                 } else {
575                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
576                                 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
577                 }
578         }
579
580         totedge = BLI_edgehash_size(eh);
581
582         /* write new edges into a temporary CustomData */
583         memset(&edata, 0, sizeof(edata));
584         CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
585
586         ehi = BLI_edgehashIterator_new(eh);
587         med = CustomData_get_layer(&edata, CD_MEDGE);
588         for(i = 0; !BLI_edgehashIterator_isDone(ehi);
589                 BLI_edgehashIterator_step(ehi), ++i, ++med) {
590
591                 if(update && (med_orig=BLI_edgehashIterator_getValue(ehi))) {
592                         *med= *med_orig; /* copy from the original */
593                 } else {
594                         BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
595                         med->flag = ME_EDGEDRAW|ME_EDGERENDER;
596                 }
597         }
598         BLI_edgehashIterator_free(ehi);
599
600         /* free old CustomData and assign new one */
601         CustomData_free(&mesh->edata, mesh->totedge);
602         mesh->edata = edata;
603         mesh->totedge = totedge;
604
605         mesh->medge = CustomData_get_layer(&mesh->edata, CD_MEDGE);
606
607         BLI_edgehash_free(eh, NULL);
608 }
609
610 void ED_mesh_update(Mesh *mesh, bContext *C, int calc_edges)
611 {
612         if(calc_edges || (mesh->totface && mesh->totedge == 0))
613                 mesh_calc_edges(mesh, calc_edges);
614
615         mesh_calc_normals(mesh->mvert, mesh->totvert, mesh->mface, mesh->totface, NULL);
616
617         DAG_id_tag_update(&mesh->id, 0);
618         WM_event_add_notifier(C, NC_GEOM|ND_DATA, mesh);
619 }
620
621 static void mesh_add_verts(Mesh *mesh, int len)
622 {
623         CustomData vdata;
624         MVert *mvert;
625         int i, totvert;
626
627         if(len == 0)
628                 return;
629
630         totvert= mesh->totvert + len;
631         CustomData_copy(&mesh->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert);
632         CustomData_copy_data(&mesh->vdata, &vdata, 0, 0, mesh->totvert);
633
634         if(!CustomData_has_layer(&vdata, CD_MVERT))
635                 CustomData_add_layer(&vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
636
637         CustomData_free(&mesh->vdata, mesh->totvert);
638         mesh->vdata= vdata;
639         mesh_update_customdata_pointers(mesh);
640
641         /* scan the input list and insert the new vertices */
642
643         mvert= &mesh->mvert[mesh->totvert];
644         for(i=0; i<len; i++, mvert++)
645                 mvert->flag |= SELECT;
646
647         /* set final vertex list size */
648         mesh->totvert= totvert;
649 }
650
651 void ED_mesh_transform(Mesh *me, float *mat)
652 {
653         int i;
654         MVert *mvert= me->mvert;
655
656         for(i= 0; i < me->totvert; i++, mvert++)
657                 mul_m4_v3((float (*)[4])mat, mvert->co);
658
659         mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
660 }
661
662 static void mesh_add_edges(Mesh *mesh, int len)
663 {
664         CustomData edata;
665         MEdge *medge;
666         int i, totedge;
667
668         if(len == 0)
669                 return;
670
671         totedge= mesh->totedge+len;
672
673         /* update customdata  */
674         CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge);
675         CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge);
676
677         if(!CustomData_has_layer(&edata, CD_MEDGE))
678                 CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
679
680         CustomData_free(&mesh->edata, mesh->totedge);
681         mesh->edata= edata;
682         mesh_update_customdata_pointers(mesh);
683
684         /* set default flags */
685         medge= &mesh->medge[mesh->totedge];
686         for(i=0; i<len; i++, medge++)
687                 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|SELECT;
688
689         mesh->totedge= totedge;
690 }
691
692 static void mesh_add_faces(Mesh *mesh, int len)
693 {
694         CustomData fdata;
695         MFace *mface;
696         int i, totface;
697
698         if(len == 0)
699                 return;
700
701         totface= mesh->totface + len;   /* new face count */
702
703         /* update customdata */
704         CustomData_copy(&mesh->fdata, &fdata, CD_MASK_MESH, CD_DEFAULT, totface);
705         CustomData_copy_data(&mesh->fdata, &fdata, 0, 0, mesh->totface);
706
707         if(!CustomData_has_layer(&fdata, CD_MFACE))
708                 CustomData_add_layer(&fdata, CD_MFACE, CD_CALLOC, NULL, totface);
709
710         CustomData_free(&mesh->fdata, mesh->totface);
711         mesh->fdata= fdata;
712         mesh_update_customdata_pointers(mesh);
713
714         /* set default flags */
715         mface= &mesh->mface[mesh->totface];
716         for(i=0; i<len; i++, mface++)
717                 mface->flag= ME_FACE_SEL;
718
719         mesh->totface= totface;
720 }
721
722 /*
723 void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, int faces)
724 {
725         if(mesh->edit_mesh) {
726                 BKE_report(reports, RPT_ERROR, "Can't add geometry in edit mode.");
727                 return;
728         }
729
730         if(verts)
731                 mesh_add_verts(mesh, verts);
732         if(edges)
733                 mesh_add_edges(mesh, edges);
734         if(faces)
735                 mesh_add_faces(mesh, faces);
736 }
737 */
738
739 void ED_mesh_faces_add(Mesh *mesh, ReportList *reports, int count)
740 {
741         if(mesh->edit_mesh) {
742                 BKE_report(reports, RPT_ERROR, "Can't add faces in edit mode.");
743                 return;
744         }
745
746         mesh_add_faces(mesh, count);
747 }
748
749 void ED_mesh_edges_add(Mesh *mesh, ReportList *reports, int count)
750 {
751         if(mesh->edit_mesh) {
752                 BKE_report(reports, RPT_ERROR, "Can't add edges in edit mode.");
753                 return;
754         }
755
756         mesh_add_edges(mesh, count);
757 }
758
759 void ED_mesh_vertices_add(Mesh *mesh, ReportList *reports, int count)
760 {
761         if(mesh->edit_mesh) {
762                 BKE_report(reports, RPT_ERROR, "Can't add vertices in edit mode.");
763                 return;
764         }
765
766         mesh_add_verts(mesh, count);
767 }
768
769 void ED_mesh_calc_normals(Mesh *me)
770 {
771         mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
772 }