fix [#30457] Smooth normals wrongly exported to wavefront
[blender.git] / source / blender / editors / mesh / mesh_data.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2009 Blender Foundation.
19  * All rights reserved.
20  *
21  * 
22  * Contributor(s): Blender Foundation
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/editors/mesh/mesh_data.c
28  *  \ingroup edmesh
29  */
30
31
32 #include <math.h>
33 #include <stdlib.h>
34 #include <string.h>
35
36 #include "MEM_guardedalloc.h"
37
38 #include "DNA_material_types.h"
39 #include "DNA_mesh_types.h"
40 #include "DNA_meshdata_types.h"
41 #include "DNA_object_types.h"
42 #include "DNA_scene_types.h"
43 #include "DNA_view3d_types.h"
44
45 #include "BLI_utildefines.h"
46 #include "BLI_array.h"
47 #include "BLI_math.h"
48 #include "BLI_edgehash.h"
49 #include "BLI_utildefines.h"
50
51 #include "BKE_context.h"
52 #include "BKE_depsgraph.h"
53 #include "BKE_displist.h"
54 #include "BKE_image.h"
55 #include "BKE_library.h"
56 #include "BKE_main.h"
57 #include "BKE_material.h"
58 #include "BKE_mesh.h"
59 #include "BKE_report.h"
60 #include "BKE_tessmesh.h"
61
62 #include "RNA_access.h"
63 #include "RNA_define.h"
64
65 #include "WM_api.h"
66 #include "WM_types.h"
67
68 #include "ED_mesh.h"
69 #include "ED_object.h"
70 #include "ED_uvedit.h"
71 #include "ED_view3d.h"
72
73 #include "RE_render_ext.h"
74
75 #include "mesh_intern.h"
76
77 #define GET_CD_DATA(me, data) (me->edit_btmesh ? &me->edit_btmesh->bm->data : &me->data)
78 static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *layer)
79 {
80         Mesh *me = ob->data;
81         CustomData *data;
82         void *actlayerdata, *rndlayerdata, *clonelayerdata, *stencillayerdata, *layerdata=layer->data;
83         int type= layer->type;
84         int index;
85         int i, actindex, rndindex, cloneindex, stencilindex, tot;
86         
87         if (layer->type == CD_MLOOPCOL || layer->type == CD_MLOOPUV) {
88                 data = (me->edit_btmesh)? &me->edit_btmesh->bm->ldata: &me->ldata;
89                 tot = me->totloop;
90         } else {
91                 data = (me->edit_btmesh)? &me->edit_btmesh->bm->pdata: &me->pdata;
92                 tot = me->totpoly;
93         }
94         
95         index = CustomData_get_layer_index(data, type);
96
97         /* ok, deleting a non-active layer needs to preserve the active layer indices.
98          * to do this, we store a pointer to the .data member of both layer and the active layer,
99          * (to detect if we're deleting the active layer or not), then use the active
100          * layer data pointer to find where the active layer has ended up.
101          *
102          * this is necessary because the deletion functions only support deleting the active
103          * layer. */
104         actlayerdata = data->layers[CustomData_get_active_layer_index(data, type)].data;
105         rndlayerdata = data->layers[CustomData_get_render_layer_index(data, type)].data;
106         clonelayerdata = data->layers[CustomData_get_clone_layer_index(data, type)].data;
107         stencillayerdata = data->layers[CustomData_get_stencil_layer_index(data, type)].data;
108         CustomData_set_layer_active(data, type, layer - &data->layers[index]);
109
110         if(me->edit_btmesh) {
111                 BM_data_layer_free(me->edit_btmesh->bm, data, type);
112         }
113         else {
114                 CustomData_free_layer_active(data, type, tot);
115                 mesh_update_customdata_pointers(me, TRUE);
116         }
117
118         if(!CustomData_has_layer(data, type) && (type == CD_MLOOPCOL && (ob->mode & OB_MODE_VERTEX_PAINT)))
119                 ED_object_toggle_modes(C, OB_MODE_VERTEX_PAINT);
120
121         /* reconstruct active layer */
122         if (actlayerdata != layerdata) {
123                 /* find index */
124                 actindex = CustomData_get_layer_index(data, type);
125                 for (i=actindex; i<data->totlayer; i++) {
126                         if (data->layers[i].data == actlayerdata) {
127                                 actindex = i - actindex;
128                                 break;
129                         }
130                 }
131                 
132                 /* set index */
133                 CustomData_set_layer_active(data, type, actindex);
134         }
135         
136         if (rndlayerdata != layerdata) {
137                 /* find index */
138                 rndindex = CustomData_get_layer_index(data, type);
139                 for (i=rndindex; i<data->totlayer; i++) {
140                         if (data->layers[i].data == rndlayerdata) {
141                                 rndindex = i - rndindex;
142                                 break;
143                         }
144                 }
145                 
146                 /* set index */
147                 CustomData_set_layer_render(data, type, rndindex);
148         }
149         
150         if (clonelayerdata != layerdata) {
151                 /* find index */
152                 cloneindex = CustomData_get_layer_index(data, type);
153                 for (i=cloneindex; i<data->totlayer; i++) {
154                         if (data->layers[i].data == clonelayerdata) {
155                                 cloneindex = i - cloneindex;
156                                 break;
157                         }
158                 }
159                 
160                 /* set index */
161                 CustomData_set_layer_clone(data, type, cloneindex);
162         }
163         
164         if (stencillayerdata != layerdata) {
165                 /* find index */
166                 stencilindex = CustomData_get_layer_index(data, type);
167                 for (i=stencilindex; i<data->totlayer; i++) {
168                         if (data->layers[i].data == stencillayerdata) {
169                                 stencilindex = i - stencilindex;
170                                 break;
171                         }
172                 }
173                 
174                 /* set index */
175                 CustomData_set_layer_stencil(data, type, stencilindex);
176         }
177 }
178
179 static void copy_editface_active_customdata(BMEditMesh *em, int type, int index)
180 {
181 #if 1 /*BMESH_TODO*/
182         (void)em;
183         (void)type;
184         (void)index;
185 #else
186         EditFace *efa;
187         int n= CustomData_get_active_layer(&em->fdata, type);
188
189         for(efa= em->faces.first; efa; efa= efa->next) {
190                 void *data= CustomData_em_get_n(&em->fdata, efa->data, type, n);
191                 CustomData_em_set_n(&em->fdata, efa->data, type, index, data);
192         }
193 #endif
194 }
195
196 int ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me)
197 {
198         BMEditMesh *em= me->edit_btmesh;
199         MLoopUV *luv;
200         BLI_array_declare(polylengths);
201         int *polylengths = NULL;
202         BLI_array_declare(uvs);
203         float **uvs = NULL;
204         float **fuvs = NULL;
205         int i, j;
206
207         if (em) {
208                 /* Collect BMesh UVs */
209
210                 BMFace *efa;
211                 BMLoop *l;
212                 BMIter iter, liter;
213
214                 BLI_assert(CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV));
215
216                 BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
217                         if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
218                                 continue;
219
220                         i = 0;
221                         BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
222                                 luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
223                                 BLI_array_append(uvs, luv->uv);
224                                 i++;
225                         }
226
227                         BLI_array_append(polylengths, efa->len);
228                 }
229         }
230         else {
231                 /* Collect Mesh UVs */
232
233                 MPoly *mp;
234
235                 BLI_assert(CustomData_has_layer(&me->ldata, CD_MLOOPUV));
236
237                 for (j = 0; j < me->totpoly; j++) {
238                         mp = &me->mpoly[j];
239
240                         for (i = 0; i < mp->totloop; i++) {
241                                 luv = &me->mloopuv[mp->loopstart + i];
242                                 BLI_array_append(uvs, luv->uv);
243                         }
244
245                         BLI_array_append(polylengths, mp->totloop);
246                 }
247         }
248
249         fuvs = uvs;
250         for (j = 0; j < BLI_array_count(polylengths); j++) {
251                 int len = polylengths[j];
252
253                 if (len == 3) {
254                         fuvs[0][0] = 0.0;
255                         fuvs[0][1] = 0.0;
256                         
257                         fuvs[1][0] = 1.0;
258                         fuvs[1][1] = 0.0;
259
260                         fuvs[2][0] = 1.0;
261                         fuvs[2][1] = 1.0;
262                 } else if (len == 4) {
263                         fuvs[0][0] = 0.0;
264                         fuvs[0][1] = 0.0;
265                         
266                         fuvs[1][0] = 1.0;
267                         fuvs[1][1] = 0.0;
268
269                         fuvs[2][0] = 1.0;
270                         fuvs[2][1] = 1.0;
271
272                         fuvs[3][0] = 0.0;
273                         fuvs[3][1] = 1.0;
274                   /*make sure we ignore 2-sided faces*/
275                 } else if (len > 2) {
276                         float fac = 0.0f, dfac = 1.0f / (float)len;
277
278                         dfac *= M_PI*2;
279
280                         for (i = 0; i < len; i++) {
281                                 fuvs[i][0] = 0.5f * sin(fac) + 0.5f;
282                                 fuvs[i][1] = 0.5f * cos(fac) + 0.5f;
283
284                                 fac += dfac;
285                         }
286                 }
287
288                 fuvs += len;
289         }
290
291         /* BMESH_TODO: Copy poly UVs onto CD_MTFACE layer for tesselated faces */
292
293         BLI_array_free(uvs);
294         BLI_array_free(polylengths);
295
296         DAG_id_tag_update(&me->id, 0);
297         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
298
299         return 1;
300 }
301
302 int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_set)
303 {
304         BMEditMesh *em;
305         int layernum;
306
307         if (me->edit_btmesh) {
308                 em= me->edit_btmesh;
309
310                 layernum = CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY);
311                 if (layernum >= MAX_MTFACE)
312                         return -1;
313
314                 BM_data_layer_add(em->bm, &em->bm->pdata, CD_MTEXPOLY);
315                 CustomData_set_layer_active(&em->bm->pdata, CD_MTEXPOLY, layernum);
316                 CustomData_set_layer_name(&em->bm->pdata, CD_MTEXPOLY, layernum, name);
317
318                 /* copy data from active UV */
319                 if (layernum)
320                         copy_editface_active_customdata(em, CD_MTFACE, layernum);
321
322                 if (active_set || layernum == 0) {
323                         CustomData_set_layer_active(&em->bm->pdata, CD_MTEXPOLY, layernum);
324                 }
325
326                 BM_data_layer_add(em->bm, &em->bm->ldata, CD_MLOOPUV);
327                 CustomData_set_layer_name(&em->bm->ldata, CD_MLOOPUV, layernum, name);
328                 
329                 CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPUV, layernum);
330                 if(active_set || layernum == 0) {
331                         CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPUV, layernum);
332                 }
333         }
334         else {
335                 layernum = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
336                 if (layernum >= MAX_MTFACE)
337                         return -1;
338
339                 if (me->mtpoly) {
340                         CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DUPLICATE, me->mtpoly, me->totpoly, name);
341                         CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DUPLICATE, me->mloopuv, me->totloop, name);
342                         CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DUPLICATE, me->mtface, me->totface, name);
343                 } else {
344                         CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, name);
345                         CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, name);
346                         CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface, name);
347                 }
348                 
349                 if (active_set || layernum == 0) {
350                         CustomData_set_layer_active(&me->pdata, CD_MTEXPOLY, layernum);
351                         CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, layernum);
352
353                         CustomData_set_layer_active(&me->fdata, CD_MTFACE, layernum);
354                 }
355
356                 mesh_update_customdata_pointers(me, TRUE);
357         }
358
359         ED_mesh_uv_loop_reset(C, me);
360
361         DAG_id_tag_update(&me->id, 0);
362         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
363
364         return layernum;
365 }
366
367 int ED_mesh_uv_texture_remove(bContext *C, Object *ob, Mesh *me)
368 {
369         CustomData *pdata = GET_CD_DATA(me, pdata), *ldata = GET_CD_DATA(me, ldata);
370         CustomDataLayer *cdlp, *cdlu;
371         int index;
372
373         index= CustomData_get_active_layer_index(pdata, CD_MTEXPOLY);
374         cdlp= (index == -1)? NULL: &pdata->layers[index];
375
376         index= CustomData_get_active_layer_index(ldata, CD_MLOOPUV);
377         cdlu= (index == -1)? NULL: &ldata->layers[index];
378         
379         if (!cdlp || !cdlu)
380                 return 0;
381
382         delete_customdata_layer(C, ob, cdlp);
383         delete_customdata_layer(C, ob, cdlu);
384         
385         DAG_id_tag_update(&me->id, 0);
386         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
387
388         return 1;
389 }
390
391 int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mesh *me, const char *name, int active_set)
392 {
393         BMEditMesh *em;
394         int layernum;
395
396         if (me->edit_btmesh) {
397                 em= me->edit_btmesh;
398
399                 layernum= CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPCOL);
400                 if (layernum >= MAX_MCOL) {
401                         return -1;
402                 }
403
404                 BM_data_layer_add(em->bm, &em->bm->pdata, CD_MLOOPCOL);
405                 CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPCOL, layernum);
406
407                 /* copy data from active vertex color layer */
408                 if (layernum) {
409                         copy_editface_active_customdata(em, CD_MCOL, layernum);
410                 }
411
412                 if (active_set || layernum == 0) {
413                         CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPCOL, layernum);
414                 }
415         }
416         else {
417                 layernum= CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL);
418                 if (layernum >= CD_MLOOPCOL) {
419                         return -1;
420                 }
421
422                 if(me->mloopcol) {
423                         CustomData_add_layer_named(&me->ldata, CD_MLOOPCOL, CD_DUPLICATE, me->mloopcol, me->totloop, name);
424                         CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mloopcol, me->totface, name);
425                 }
426                 else {
427                         CustomData_add_layer_named(&me->ldata, CD_MLOOPCOL, CD_DEFAULT, NULL, me->totloop, name);
428                         CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface, name);
429                 }
430
431                 if(active_set || layernum==0) {
432                         CustomData_set_layer_active(&me->ldata, CD_MLOOPCOL, layernum);
433                         CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum);
434                 }
435
436                 mesh_update_customdata_pointers(me, TRUE);
437         }
438
439         DAG_id_tag_update(&me->id, 0);
440         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
441
442         return layernum;
443 }
444
445 int ED_mesh_color_remove(bContext *C, Object *ob, Mesh *me)
446 {
447         CustomDataLayer *cdl;
448         int index;
449
450         index= CustomData_get_active_layer_index(&me->ldata, CD_MLOOPCOL);
451         cdl= (index == -1)? NULL: &me->ldata.layers[index];
452
453         if(!cdl)
454                 return 0;
455
456         delete_customdata_layer(C, ob, cdl);
457         DAG_id_tag_update(&me->id, 0);
458         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
459
460         return 1;
461 }
462
463 int ED_mesh_color_remove_named(bContext *C, Object *ob, Mesh *me, const char *name)
464 {
465         CustomDataLayer *cdl;
466         int index;
467
468         index= CustomData_get_named_layer_index(&me->ldata, CD_MLOOPCOL, name);
469         cdl= (index == -1)? NULL: &me->ldata.layers[index];
470
471         if(!cdl)
472                 return 0;
473
474         delete_customdata_layer(C, ob, cdl);
475         DAG_id_tag_update(&me->id, 0);
476         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
477
478         return 1;
479 }
480
481 /*********************** UV texture operators ************************/
482
483 static int layers_poll(bContext *C)
484 {
485         Object *ob= ED_object_context(C);
486         ID *data= (ob)? ob->data: NULL;
487         return (ob && !ob->id.lib && ob->type==OB_MESH && data && !data->lib);
488 }
489
490 static int uv_texture_add_exec(bContext *C, wmOperator *UNUSED(op))
491 {
492         Object *ob= ED_object_context(C);
493         Mesh *me= ob->data;
494
495         if(ED_mesh_uv_texture_add(C, me, NULL, TRUE) == -1)
496                 return OPERATOR_CANCELLED;
497
498         return OPERATOR_FINISHED;
499 }
500
501 void MESH_OT_uv_texture_add(wmOperatorType *ot)
502 {
503         /* identifiers */
504         ot->name= "Add UV Map";
505         ot->description= "Add UV Map";
506         ot->idname= "MESH_OT_uv_texture_add";
507         
508         /* api callbacks */
509         ot->poll= layers_poll;
510         ot->exec= uv_texture_add_exec;
511
512         /* flags */
513         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
514 }
515
516 static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
517 {
518         Main *bmain= CTX_data_main(C);
519         Scene *scene= CTX_data_scene(C);
520         View3D *v3d= CTX_wm_view3d(C);
521         Base *base= ED_view3d_give_base_under_cursor(C, event->mval);
522         Image *ima= NULL;
523         Mesh *me;
524         Object *obedit;
525         int exitmode= 0;
526         char name[MAX_ID_NAME-2];
527         
528         /* Check context */
529         if(base==NULL || base->object->type!=OB_MESH) {
530                 BKE_report(op->reports, RPT_ERROR, "Not an Object or Mesh");
531                 return OPERATOR_CANCELLED;
532         }
533         
534         /* check input variables */
535         if(RNA_struct_property_is_set(op->ptr, "filepath")) {
536                 char path[FILE_MAX];
537                 
538                 RNA_string_get(op->ptr, "filepath", path);
539                 ima= BKE_add_image_file(path);
540         }
541         else {
542                 RNA_string_get(op->ptr, "name", name);
543                 ima= (Image *)find_id("IM", name);
544         }
545         
546         if(!ima) {
547                 BKE_report(op->reports, RPT_ERROR, "Not an Image");
548                 return OPERATOR_CANCELLED;
549         }
550         
551         /* put mesh in editmode */
552
553         obedit= base->object;
554         me= obedit->data;
555         if(me->edit_btmesh==NULL) {
556                 EDBM_MakeEditBMesh(scene->toolsettings, scene, obedit);
557                 exitmode= 1;
558         }
559         if(me->edit_btmesh==NULL)
560                 return OPERATOR_CANCELLED;
561         
562         ED_uvedit_assign_image(bmain, scene, obedit, ima, NULL);
563
564         if(exitmode) {
565                 EDBM_LoadEditBMesh(scene, obedit);
566                 EDBM_FreeEditBMesh(me->edit_btmesh);
567                 MEM_freeN(me->edit_btmesh);
568                 me->edit_btmesh= NULL;
569
570                 /* load_editMesh free's pointers used by CustomData layers which might be used by DerivedMesh too,
571                  * so signal to re-create DerivedMesh here (sergey) */
572                 DAG_id_tag_update(&me->id, 0);
573         }
574
575         /* dummie drop support; ensure view shows a result :) */
576         if(v3d)
577                 v3d->flag2 |= V3D_SOLID_TEX;
578         
579         WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
580         
581         return OPERATOR_FINISHED;
582 }
583
584 void MESH_OT_drop_named_image(wmOperatorType *ot)
585 {
586         /* identifiers */
587         ot->name= "Assign Image to UV Map";
588         ot->description= "Assign Image to active UV Map, or create an UV Map";
589         ot->idname= "MESH_OT_drop_named_image";
590         
591         /* api callbacks */
592         ot->poll= layers_poll;
593         ot->invoke= drop_named_image_invoke;
594         
595         /* flags */
596         ot->flag= OPTYPE_UNDO;
597         
598         /* properties */
599         RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME-2, "Name", "Image name to assign");
600         RNA_def_string(ot->srna, "filepath", "Path", FILE_MAX, "Filepath", "Path to image file");
601 }
602
603 static int uv_texture_remove_exec(bContext *C, wmOperator *UNUSED(op))
604 {
605         Object *ob= ED_object_context(C);
606         Mesh *me= ob->data;
607
608         if(!ED_mesh_uv_texture_remove(C, ob, me))
609                 return OPERATOR_CANCELLED;
610
611         return OPERATOR_FINISHED;
612 }
613
614 void MESH_OT_uv_texture_remove(wmOperatorType *ot)
615 {
616         /* identifiers */
617         ot->name= "Remove UV Map";
618         ot->description= "Remove UV Map";
619         ot->idname= "MESH_OT_uv_texture_remove";
620         
621         /* api callbacks */
622         ot->poll= layers_poll;
623         ot->exec= uv_texture_remove_exec;
624
625         /* flags */
626         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
627 }
628
629 /*********************** vertex color operators ************************/
630
631 static int vertex_color_add_exec(bContext *C, wmOperator *UNUSED(op))
632 {
633         Scene *scene= CTX_data_scene(C);
634         Object *ob= ED_object_context(C);
635         Mesh *me= ob->data;
636
637         if(ED_mesh_color_add(C, scene, ob, me, NULL, TRUE) == -1)
638                 return OPERATOR_CANCELLED;
639
640         return OPERATOR_FINISHED;
641 }
642
643 void MESH_OT_vertex_color_add(wmOperatorType *ot)
644 {
645         /* identifiers */
646         ot->name= "Add Vertex Color";
647         ot->description= "Add vertex color layer";
648         ot->idname= "MESH_OT_vertex_color_add";
649         
650         /* api callbacks */
651         ot->poll= layers_poll;
652         ot->exec= vertex_color_add_exec;
653
654         /* flags */
655         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
656 }
657
658 static int vertex_color_remove_exec(bContext *C, wmOperator *UNUSED(op))
659 {
660         Object *ob= ED_object_context(C);
661         Mesh *me= ob->data;
662
663         if(!ED_mesh_color_remove(C, ob, me))
664                 return OPERATOR_CANCELLED;
665
666         return OPERATOR_FINISHED;
667 }
668
669 void MESH_OT_vertex_color_remove(wmOperatorType *ot)
670 {
671         /* identifiers */
672         ot->name= "Remove Vertex Color";
673         ot->description= "Remove vertex color layer";
674         ot->idname= "MESH_OT_vertex_color_remove";
675         
676         /* api callbacks */
677         ot->exec= vertex_color_remove_exec;
678         ot->poll= layers_poll;
679
680         /* flags */
681         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
682 }
683
684 /*********************** sticky operators ************************/
685
686 static int sticky_add_exec(bContext *C, wmOperator *UNUSED(op))
687 {
688         Scene *scene= CTX_data_scene(C);
689         View3D *v3d= CTX_wm_view3d(C);
690         Object *ob= ED_object_context(C);
691         Mesh *me= ob->data;
692
693         /* why is this commented out? */
694 #if 0
695         if(me->msticky)
696                 return OPERATOR_CANCELLED;
697 #endif
698
699         RE_make_sticky(scene, v3d);
700
701         DAG_id_tag_update(&me->id, 0);
702         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
703
704         return OPERATOR_FINISHED;
705 }
706
707 void MESH_OT_sticky_add(wmOperatorType *ot)
708 {
709         /* identifiers */
710         ot->name= "Add Sticky";
711         ot->description= "Add sticky UV texture layer";
712         ot->idname= "MESH_OT_sticky_add";
713         
714         /* api callbacks */
715         ot->poll= layers_poll;
716         ot->exec= sticky_add_exec;
717
718         /* flags */
719         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
720 }
721
722 static int sticky_remove_exec(bContext *C, wmOperator *UNUSED(op))
723 {
724         Object *ob= ED_object_context(C);
725         Mesh *me= ob->data;
726
727         if(!me->msticky)
728                 return OPERATOR_CANCELLED;
729
730         CustomData_free_layer_active(&me->vdata, CD_MSTICKY, me->totvert);
731         me->msticky= NULL;
732
733         DAG_id_tag_update(&me->id, 0);
734         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
735
736         return OPERATOR_FINISHED;
737 }
738
739 void MESH_OT_sticky_remove(wmOperatorType *ot)
740 {
741         /* identifiers */
742         ot->name= "Remove Sticky";
743         ot->description= "Remove sticky UV texture layer";
744         ot->idname= "MESH_OT_sticky_remove";
745         
746         /* api callbacks */
747         ot->poll= layers_poll;
748         ot->exec= sticky_remove_exec;
749
750         /* flags */
751         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
752 }
753
754 /************************** Add Geometry Layers *************************/
755
756 void ED_mesh_update(Mesh *mesh, bContext *C, int calc_edges, int calc_tessface)
757 {
758         int *polyindex = NULL;
759         float (*face_nors)[3];
760
761         if(mesh->totface > 0 && mesh->totpoly == 0) {
762                 convert_mfaces_to_mpolys(mesh);
763
764                 /* would only be converting back again, dont bother */
765                 calc_tessface = FALSE;
766
767                 /* it also happens that converting the faces calculates edges, skip this */
768                 calc_edges = FALSE;
769         }
770
771         if(calc_edges || (mesh->totpoly && mesh->totedge == 0))
772                 BKE_mesh_calc_edges(mesh, calc_edges);
773
774         if (calc_tessface) {
775                 BKE_mesh_tessface_calc(mesh);
776         }
777         else {
778                 /* default state is not to have tessface's so make sure this is the case */
779                 BKE_mesh_tessface_clear(mesh);
780         }
781
782         /* note on this if/else - looks like these layers are not needed
783          * so rather then add poly-index layer and calculate normals for it
784          * calculate normals only for the mvert's. - campbell */
785 #ifdef USE_BMESH_MPOLY_NORMALS
786         polyindex = CustomData_get_layer(&mesh->fdata, CD_POLYINDEX);
787         /* add a normals layer for tesselated faces, a tessface normal will
788          * contain the normal of the poly the face was tesselated from. */
789         face_nors = CustomData_add_layer(&mesh->fdata, CD_NORMAL, CD_CALLOC, NULL, mesh->totface);
790
791         mesh_calc_normals_mapping_ex(mesh->mvert, mesh->totvert,
792                                      mesh->mloop, mesh->mpoly,
793                                      mesh->totloop, mesh->totpoly,
794                                      NULL /* polyNors_r */,
795                                      mesh->mface, mesh->totface,
796                                      polyindex, face_nors, FALSE);
797 #else
798         mesh_calc_normals(mesh->mvert, mesh->totvert,
799                           mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly,
800                           NULL);
801         (void)polyindex;
802         (void)face_nors;
803 #endif
804
805         DAG_id_tag_update(&mesh->id, 0);
806         WM_event_add_notifier(C, NC_GEOM|ND_DATA, mesh);
807 }
808
809 static void mesh_add_verts(Mesh *mesh, int len)
810 {
811         CustomData vdata;
812         MVert *mvert;
813         int i, totvert;
814
815         if(len == 0)
816                 return;
817
818         totvert= mesh->totvert + len;
819         CustomData_copy(&mesh->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert);
820         CustomData_copy_data(&mesh->vdata, &vdata, 0, 0, mesh->totvert);
821
822         if(!CustomData_has_layer(&vdata, CD_MVERT))
823                 CustomData_add_layer(&vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
824
825         CustomData_free(&mesh->vdata, mesh->totvert);
826         mesh->vdata= vdata;
827         mesh_update_customdata_pointers(mesh, FALSE);
828
829         /* scan the input list and insert the new vertices */
830
831         mvert= &mesh->mvert[mesh->totvert];
832         for(i=0; i<len; i++, mvert++)
833                 mvert->flag |= SELECT;
834
835         /* set final vertex list size */
836         mesh->totvert= totvert;
837 }
838
839 void ED_mesh_transform(Mesh *me, float *mat)
840 {
841         int i;
842         MVert *mvert= me->mvert;
843
844         for(i= 0; i < me->totvert; i++, mvert++)
845                 mul_m4_v3((float (*)[4])mat, mvert->co);
846
847         mesh_calc_normals_mapping(me->mvert, me->totvert, me->mloop, me->mpoly, me->totloop, me->totpoly, NULL, NULL, 0, NULL, NULL);
848 }
849
850 static void mesh_add_edges(Mesh *mesh, int len)
851 {
852         CustomData edata;
853         MEdge *medge;
854         int i, totedge;
855
856         if(len == 0)
857                 return;
858
859         totedge= mesh->totedge+len;
860
861         /* update customdata  */
862         CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge);
863         CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge);
864
865         if(!CustomData_has_layer(&edata, CD_MEDGE))
866                 CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
867
868         CustomData_free(&mesh->edata, mesh->totedge);
869         mesh->edata= edata;
870         mesh_update_customdata_pointers(mesh, FALSE); /* new edges dont change tessellation */
871
872         /* set default flags */
873         medge= &mesh->medge[mesh->totedge];
874         for(i=0; i<len; i++, medge++)
875                 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|SELECT;
876
877         mesh->totedge= totedge;
878 }
879
880 static void mesh_add_faces(Mesh *mesh, int len)
881 {
882         CustomData fdata;
883         MFace *mface;
884         int i, totface;
885
886         if(len == 0)
887                 return;
888
889         totface= mesh->totface + len;   /* new face count */
890
891         /* update customdata */
892         CustomData_copy(&mesh->fdata, &fdata, CD_MASK_MESH, CD_DEFAULT, totface);
893         CustomData_copy_data(&mesh->fdata, &fdata, 0, 0, mesh->totface);
894
895         if(!CustomData_has_layer(&fdata, CD_MFACE))
896                 CustomData_add_layer(&fdata, CD_MFACE, CD_CALLOC, NULL, totface);
897
898         CustomData_free(&mesh->fdata, mesh->totface);
899         mesh->fdata= fdata;
900         mesh_update_customdata_pointers(mesh, TRUE);
901
902         /* set default flags */
903         mface= &mesh->mface[mesh->totface];
904         for(i=0; i<len; i++, mface++)
905                 mface->flag= ME_FACE_SEL;
906
907         mesh->totface= totface;
908 }
909
910 static void mesh_add_loops(Mesh *mesh, int len)
911 {
912         CustomData ldata;
913         int totloop;
914
915         if(len == 0)
916                 return;
917
918         totloop= mesh->totloop + len;   /* new face count */
919
920         /* update customdata */
921         CustomData_copy(&mesh->ldata, &ldata, CD_MASK_MESH, CD_DEFAULT, totloop);
922         CustomData_copy_data(&mesh->ldata, &ldata, 0, 0, mesh->totloop);
923
924         if(!CustomData_has_layer(&ldata, CD_MLOOP))
925                 CustomData_add_layer(&ldata, CD_MLOOP, CD_CALLOC, NULL, totloop);
926
927         CustomData_free(&mesh->ldata, mesh->totloop);
928         mesh->ldata= ldata;
929         mesh_update_customdata_pointers(mesh, TRUE);
930
931         mesh->totloop= totloop;
932 }
933
934 static void mesh_add_polys(Mesh *mesh, int len)
935 {
936         CustomData pdata;
937         MPoly *mpoly;
938         int i, totpoly;
939
940         if(len == 0)
941                 return;
942
943         totpoly= mesh->totpoly + len;   /* new face count */
944
945         /* update customdata */
946         CustomData_copy(&mesh->pdata, &pdata, CD_MASK_MESH, CD_DEFAULT, totpoly);
947         CustomData_copy_data(&mesh->pdata, &pdata, 0, 0, mesh->totpoly);
948
949         if(!CustomData_has_layer(&pdata, CD_MPOLY))
950                 CustomData_add_layer(&pdata, CD_MPOLY, CD_CALLOC, NULL, totpoly);
951
952         CustomData_free(&mesh->pdata, mesh->totpoly);
953         mesh->pdata= pdata;
954         mesh_update_customdata_pointers(mesh, TRUE);
955
956         /* set default flags */
957         mpoly= &mesh->mpoly[mesh->totpoly];
958         for(i=0; i<len; i++, mpoly++)
959                 mpoly->flag= ME_FACE_SEL;
960
961         mesh->totpoly= totpoly;
962 }
963
964 static void mesh_remove_verts(Mesh *mesh, int len)
965 {
966         int totvert;
967
968         if(len == 0)
969                 return;
970
971         totvert= mesh->totvert - len;
972         CustomData_free_elem(&mesh->vdata, totvert, len);
973
974         /* set final vertex list size */
975         mesh->totvert= totvert;
976 }
977
978 static void mesh_remove_edges(Mesh *mesh, int len)
979 {
980         int totedge;
981
982         if(len == 0)
983                 return;
984
985         totedge= mesh->totedge - len;
986         CustomData_free_elem(&mesh->edata, totedge, len);
987
988         mesh->totedge= totedge;
989 }
990
991 static void mesh_remove_faces(Mesh *mesh, int len)
992 {
993         int totface;
994
995         if(len == 0)
996                 return;
997
998         totface= mesh->totface - len;   /* new face count */
999         CustomData_free_elem(&mesh->fdata, totface, len);
1000
1001         mesh->totface= totface;
1002 }
1003
1004 #if 0
1005 void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, int faces)
1006 {
1007         if(mesh->edit_btmesh) {
1008                 BKE_report(reports, RPT_ERROR, "Can't add geometry in edit mode");
1009                 return;
1010         }
1011
1012         if(verts)
1013                 mesh_add_verts(mesh, verts);
1014         if(edges)
1015                 mesh_add_edges(mesh, edges);
1016         if(faces)
1017                 mesh_add_faces(mesh, faces);
1018 }
1019 #endif
1020
1021 void ED_mesh_faces_add(Mesh *mesh, ReportList *reports, int count)
1022 {
1023         if(mesh->edit_btmesh) {
1024                 BKE_report(reports, RPT_ERROR, "Can't add faces in edit mode");
1025                 return;
1026         }
1027
1028         mesh_add_faces(mesh, count);
1029 }
1030
1031 void ED_mesh_edges_add(Mesh *mesh, ReportList *reports, int count)
1032 {
1033         if(mesh->edit_btmesh) {
1034                 BKE_report(reports, RPT_ERROR, "Can't add edges in edit mode");
1035                         return;
1036         }
1037
1038         mesh_add_edges(mesh, count);
1039 }
1040
1041 void ED_mesh_vertices_add(Mesh *mesh, ReportList *reports, int count)
1042 {
1043         if(mesh->edit_btmesh) {
1044                 BKE_report(reports, RPT_ERROR, "Can't add vertices in edit mode");
1045                 return;
1046         }
1047
1048         mesh_add_verts(mesh, count);
1049 }
1050
1051 void ED_mesh_faces_remove(Mesh *mesh, ReportList *reports, int count)
1052 {
1053         if(mesh->edit_btmesh) {
1054                 BKE_report(reports, RPT_ERROR, "Can't remove faces in edit mode");
1055                 return;
1056         }
1057         else if(count > mesh->totface) {
1058                 BKE_report(reports, RPT_ERROR, "Can't remove more faces than the mesh contains");
1059                 return;
1060         }
1061
1062         mesh_remove_faces(mesh, count);
1063 }
1064
1065 void ED_mesh_edges_remove(Mesh *mesh, ReportList *reports, int count)
1066 {
1067         if(mesh->edit_btmesh) {
1068                 BKE_report(reports, RPT_ERROR, "Can't remove edges in edit mode");
1069                 return;
1070         }
1071         else if(count > mesh->totedge) {
1072                 BKE_report(reports, RPT_ERROR, "Can't remove more edges than the mesh contains");
1073                 return;
1074         }
1075
1076         mesh_remove_edges(mesh, count);
1077 }
1078
1079 void ED_mesh_vertices_remove(Mesh *mesh, ReportList *reports, int count)
1080 {
1081         if(mesh->edit_btmesh) {
1082                 BKE_report(reports, RPT_ERROR, "Can't remove vertices in edit mode");
1083                 return;
1084         }
1085         else if(count > mesh->totvert) {
1086                 BKE_report(reports, RPT_ERROR, "Can't remove more vertices than the mesh contains");
1087                 return;
1088         }
1089
1090         mesh_remove_verts(mesh, count);
1091 }
1092
1093 void ED_mesh_loops_add(Mesh *mesh, ReportList *reports, int count)
1094 {
1095         if(mesh->edit_btmesh) {
1096                 BKE_report(reports, RPT_ERROR, "Can't add loops in edit mode.");
1097                         return;
1098         }
1099
1100         mesh_add_loops(mesh, count);
1101 }
1102
1103 void ED_mesh_polys_add(Mesh *mesh, ReportList *reports, int count)
1104 {
1105         if(mesh->edit_btmesh) {
1106                 BKE_report(reports, RPT_ERROR, "Can't add polys in edit mode.");
1107                 return;
1108         }
1109
1110         mesh_add_polys(mesh, count);
1111 }
1112
1113 void ED_mesh_calc_normals(Mesh *mesh)
1114 {
1115 #ifdef USE_BMESH_MPOLY_NORMALS
1116         mesh_calc_normals_mapping_ex(mesh->mvert, mesh->totvert,
1117                                      mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly,
1118                                      NULL, NULL, 0, NULL, NULL, FALSE);
1119 #else
1120         mesh_calc_normals(mesh->mvert, mesh->totvert,
1121                           mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly,
1122                           NULL);
1123 #endif
1124 }