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