RNA
[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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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_customdata_types.h"
36 #include "DNA_material_types.h"
37 #include "DNA_mesh_types.h"
38 #include "DNA_meshdata_types.h"
39 #include "DNA_object_types.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_windowmanager_types.h"
42
43 #include "BKE_context.h"
44 #include "BKE_customdata.h"
45 #include "BKE_depsgraph.h"
46 #include "BKE_displist.h"
47 #include "BKE_global.h"
48 #include "BKE_material.h"
49 #include "BKE_mesh.h"
50 #include "BKE_report.h"
51
52 #include "BLI_arithb.h"
53 #include "BLI_editVert.h"
54 #include "BLI_edgehash.h"
55
56 #include "RNA_access.h"
57 #include "RNA_define.h"
58
59 #include "WM_api.h"
60 #include "WM_types.h"
61
62 #include "ED_mesh.h"
63 #include "ED_object.h"
64 #include "ED_view3d.h"
65
66 #include "mesh_intern.h"
67
68 static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *layer)
69 {
70         Mesh *me = ob->data;
71         CustomData *data= (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata;
72         void *actlayerdata, *rndlayerdata, *clonelayerdata, *masklayerdata, *layerdata=layer->data;
73         int type= layer->type;
74         int index= CustomData_get_layer_index(data, type);
75         int i, actindex, rndindex, cloneindex, maskindex;
76         
77         /* ok, deleting a non-active layer needs to preserve the active layer indices.
78           to do this, we store a pointer to the .data member of both layer and the active layer,
79           (to detect if we're deleting the active layer or not), then use the active
80           layer data pointer to find where the active layer has ended up.
81           
82           this is necassary because the deletion functions only support deleting the active
83           layer. */
84         actlayerdata = data->layers[CustomData_get_active_layer_index(data, type)].data;
85         rndlayerdata = data->layers[CustomData_get_render_layer_index(data, type)].data;
86         clonelayerdata = data->layers[CustomData_get_clone_layer_index(data, type)].data;
87         masklayerdata = data->layers[CustomData_get_mask_layer_index(data, type)].data;
88         CustomData_set_layer_active(data, type, layer - &data->layers[index]);
89
90         if(me->edit_mesh) {
91                 EM_free_data_layer(me->edit_mesh, data, type);
92         }
93         else {
94                 CustomData_free_layer_active(data, type, me->totface);
95                 mesh_update_customdata_pointers(me);
96         }
97
98         if(!CustomData_has_layer(data, type) && (type == CD_MCOL && (ob->mode & OB_MODE_VERTEX_PAINT)))
99                 ED_object_toggle_modes(C, OB_MODE_VERTEX_PAINT);
100
101         /* reconstruct active layer */
102         if (actlayerdata != layerdata) {
103                 /* find index */
104                 actindex = CustomData_get_layer_index(data, type);
105                 for (i=actindex; i<data->totlayer; i++) {
106                         if (data->layers[i].data == actlayerdata) {
107                                 actindex = i - actindex;
108                                 break;
109                         }
110                 }
111                 
112                 /* set index */
113                 CustomData_set_layer_active(data, type, actindex);
114         }
115         
116         if (rndlayerdata != layerdata) {
117                 /* find index */
118                 rndindex = CustomData_get_layer_index(data, type);
119                 for (i=rndindex; i<data->totlayer; i++) {
120                         if (data->layers[i].data == rndlayerdata) {
121                                 rndindex = i - rndindex;
122                                 break;
123                         }
124                 }
125                 
126                 /* set index */
127                 CustomData_set_layer_render(data, type, rndindex);
128         }
129         
130         if (clonelayerdata != layerdata) {
131                 /* find index */
132                 cloneindex = CustomData_get_layer_index(data, type);
133                 for (i=cloneindex; i<data->totlayer; i++) {
134                         if (data->layers[i].data == clonelayerdata) {
135                                 cloneindex = i - cloneindex;
136                                 break;
137                         }
138                 }
139                 
140                 /* set index */
141                 CustomData_set_layer_clone(data, type, cloneindex);
142         }
143         
144         if (masklayerdata != layerdata) {
145                 /* find index */
146                 maskindex = CustomData_get_layer_index(data, type);
147                 for (i=maskindex; i<data->totlayer; i++) {
148                         if (data->layers[i].data == masklayerdata) {
149                                 maskindex = i - maskindex;
150                                 break;
151                         }
152                 }
153                 
154                 /* set index */
155                 CustomData_set_layer_mask(data, type, maskindex);
156         }
157 }
158
159 int ED_mesh_uv_texture_add(bContext *C, Scene *scene, Object *ob, Mesh *me)
160 {
161         EditMesh *em;
162         MCol *mcol;
163         int layernum;
164
165         if(me->edit_mesh) {
166                 em= me->edit_mesh;
167
168                 layernum= CustomData_number_of_layers(&em->fdata, CD_MCOL);
169                 if(layernum >= MAX_MCOL)
170                         return 0;
171
172                 EM_add_data_layer(em, &em->fdata, CD_MCOL);
173                 CustomData_set_layer_active(&em->fdata, CD_MCOL, layernum);
174         }
175         else {
176                 layernum= CustomData_number_of_layers(&me->fdata, CD_MCOL);
177                 if(layernum >= MAX_MCOL)
178                         return 0;
179
180                 mcol= me->mcol;
181
182                 if(me->mcol)
183                         CustomData_add_layer(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mcol, me->totface);
184                 else
185                         CustomData_add_layer(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface);
186
187                 CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum);
188                 mesh_update_customdata_pointers(me);
189
190                 if(!mcol && ob)
191                         shadeMeshMCol(scene, ob, me);
192         }
193
194         DAG_id_flush_update(&me->id, OB_RECALC_DATA);
195         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
196
197         return 1;
198 }
199
200 int ED_mesh_uv_texture_remove(bContext *C, Object *ob, Mesh *me)
201 {
202         CustomDataLayer *cdl;
203         int index;
204
205         index= CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
206         cdl= (index == -1)? NULL: &me->fdata.layers[index];
207
208         if(!cdl)
209                 return 0;
210
211         delete_customdata_layer(C, ob, cdl);
212         DAG_id_flush_update(&me->id, OB_RECALC_DATA);
213         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
214
215         return 1;
216 }
217
218 int ED_mesh_color_add(bContext *C, Scene *scene, Object *ob, Mesh *me)
219 {
220         EditMesh *em;
221         MCol *mcol;
222         int layernum;
223
224         if(me->edit_mesh) {
225                 em= me->edit_mesh;
226
227                 layernum= CustomData_number_of_layers(&em->fdata, CD_MCOL);
228                 if(layernum >= MAX_MCOL)
229                         return 0;
230
231                 EM_add_data_layer(em, &em->fdata, CD_MCOL);
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(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mcol, me->totface);
243                 else
244                         CustomData_add_layer(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface);
245
246                 CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum);
247                 mesh_update_customdata_pointers(me);
248
249                 if(!mcol)
250                         shadeMeshMCol(scene, ob, me);
251         }
252
253         DAG_id_flush_update(&me->id, OB_RECALC_DATA);
254         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
255
256         return 1;
257 }
258
259 int ED_mesh_color_remove(bContext *C, Object *ob, Mesh *me)
260 {
261         CustomDataLayer *cdl;
262         int index;
263
264         index= CustomData_get_active_layer_index(&me->fdata, CD_MCOL);
265         cdl= (index == -1)? NULL: &me->fdata.layers[index];
266
267         if(!cdl)
268                 return 0;
269
270         delete_customdata_layer(C, ob, cdl);
271         DAG_id_flush_update(&me->id, OB_RECALC_DATA);
272         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
273
274         return 1;
275 }
276
277 /*********************** UV texture operators ************************/
278
279 static int layers_poll(bContext *C)
280 {
281         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
282         ID *data= (ob)? ob->data: NULL;
283         return (ob && !ob->id.lib && ob->type==OB_MESH && data && !data->lib);
284 }
285
286 static int uv_texture_add_exec(bContext *C, wmOperator *op)
287 {
288         Scene *scene= CTX_data_scene(C);
289         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
290         Mesh *me= ob->data;
291
292         if(!ED_mesh_uv_texture_add(C, scene, ob, me))
293                 return OPERATOR_CANCELLED;
294
295         return OPERATOR_FINISHED;
296 }
297
298 void MESH_OT_uv_texture_add(wmOperatorType *ot)
299 {
300         /* identifiers */
301         ot->name= "Add UV Texture";
302         ot->description= "Add UV texture layer.";
303         ot->idname= "MESH_OT_uv_texture_add";
304         
305         /* api callbacks */
306         ot->poll= layers_poll;
307         ot->exec= uv_texture_add_exec;
308
309         /* flags */
310         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
311 }
312
313 static int uv_texture_remove_exec(bContext *C, wmOperator *op)
314 {
315         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
316         Mesh *me= ob->data;
317
318         if(!ED_mesh_uv_texture_remove(C, ob, me))
319                 return OPERATOR_CANCELLED;
320
321         return OPERATOR_FINISHED;
322 }
323
324 void MESH_OT_uv_texture_remove(wmOperatorType *ot)
325 {
326         /* identifiers */
327         ot->name= "Remove UV Texture";
328         ot->description= "Remove UV texture layer.";
329         ot->idname= "MESH_OT_uv_texture_remove";
330         
331         /* api callbacks */
332         ot->poll= layers_poll;
333         ot->exec= uv_texture_remove_exec;
334
335         /* flags */
336         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
337 }
338
339 /*********************** vertex color operators ************************/
340
341 static int vertex_color_add_exec(bContext *C, wmOperator *op)
342 {
343         Scene *scene= CTX_data_scene(C);
344         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
345         Mesh *me= ob->data;
346
347         if(!ED_mesh_color_add(C, scene, ob, me))
348                 return OPERATOR_CANCELLED;
349
350         return OPERATOR_FINISHED;
351 }
352
353 void MESH_OT_vertex_color_add(wmOperatorType *ot)
354 {
355         /* identifiers */
356         ot->name= "Add Vertex Color";
357         ot->description= "Add vertex color layer.";
358         ot->idname= "MESH_OT_vertex_color_add";
359         
360         /* api callbacks */
361         ot->poll= layers_poll;
362         ot->exec= vertex_color_add_exec;
363
364         /* flags */
365         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
366 }
367
368 static int vertex_color_remove_exec(bContext *C, wmOperator *op)
369 {
370         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
371         Mesh *me= ob->data;
372
373         if(!ED_mesh_color_remove(C, ob, me))
374                 return OPERATOR_CANCELLED;
375
376         return OPERATOR_FINISHED;
377 }
378
379 void MESH_OT_vertex_color_remove(wmOperatorType *ot)
380 {
381         /* identifiers */
382         ot->name= "Remove Vertex Color";
383         ot->description= "Remove vertex color layer.";
384         ot->idname= "MESH_OT_vertex_color_remove";
385         
386         /* api callbacks */
387         ot->exec= vertex_color_remove_exec;
388         ot->poll= layers_poll;
389
390         /* flags */
391         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
392 }
393
394 /*********************** sticky operators ************************/
395
396 static int sticky_add_exec(bContext *C, wmOperator *op)
397 {
398         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
399         Mesh *me= ob->data;
400
401         if(me->msticky)
402                 return OPERATOR_CANCELLED;
403
404         // XXX RE_make_sticky();
405
406         DAG_id_flush_update(&me->id, OB_RECALC_DATA);
407         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
408
409         return OPERATOR_FINISHED;
410 }
411
412 void MESH_OT_sticky_add(wmOperatorType *ot)
413 {
414         /* identifiers */
415         ot->name= "Add Sticky";
416         ot->description= "Add sticky UV texture layer.";
417         ot->idname= "MESH_OT_sticky_add";
418         
419         /* api callbacks */
420         ot->poll= layers_poll;
421         ot->exec= sticky_add_exec;
422
423         /* flags */
424         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
425 }
426
427 static int sticky_remove_exec(bContext *C, wmOperator *op)
428 {
429         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
430         Mesh *me= ob->data;
431
432         if(!me->msticky)
433                 return OPERATOR_CANCELLED;
434
435         CustomData_free_layer_active(&me->vdata, CD_MSTICKY, me->totvert);
436         me->msticky= NULL;
437
438         DAG_id_flush_update(&me->id, OB_RECALC_DATA);
439         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
440
441         return OPERATOR_FINISHED;
442 }
443
444 void MESH_OT_sticky_remove(wmOperatorType *ot)
445 {
446         /* identifiers */
447         ot->name= "Remove Sticky";
448         ot->description= "Remove sticky UV texture layer.";
449         ot->idname= "MESH_OT_sticky_remove";
450         
451         /* api callbacks */
452         ot->poll= layers_poll;
453         ot->exec= sticky_remove_exec;
454
455         /* flags */
456         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
457 }
458
459 /************************** Add Geometry Layers *************************/
460
461 static void mesh_calc_edges(Mesh *mesh)
462 {
463         CustomData edata;
464         EdgeHashIterator *ehi;
465         MFace *mf = mesh->mface;
466         MEdge *med;
467         EdgeHash *eh = BLI_edgehash_new();
468         int i, *index, totedge, totface = mesh->totface;
469
470         for (i = 0; i < totface; i++, mf++) {
471                 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
472                         BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
473                 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
474                         BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
475                 
476                 if (mf->v4) {
477                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
478                                 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
479                         if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
480                                 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
481                 } else {
482                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
483                                 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
484                 }
485         }
486
487         totedge = BLI_edgehash_size(eh);
488
489         /* write new edges into a temporary CustomData */
490         memset(&edata, 0, sizeof(edata));
491         CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
492
493         ehi = BLI_edgehashIterator_new(eh);
494         med = CustomData_get_layer(&edata, CD_MEDGE);
495         for(i = 0; !BLI_edgehashIterator_isDone(ehi);
496             BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
497                 BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
498
499                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
500         }
501         BLI_edgehashIterator_free(ehi);
502
503         /* free old CustomData and assign new one */
504         CustomData_free(&mesh->edata, mesh->totedge);
505         mesh->edata = edata;
506         mesh->totedge = totedge;
507
508         mesh->medge = CustomData_get_layer(&mesh->edata, CD_MEDGE);
509
510         BLI_edgehash_free(eh, NULL);
511 }
512
513 void ED_mesh_update(Mesh *mesh, bContext *C)
514 {
515         if(mesh->totface && mesh->totedge == 0)
516                 mesh_calc_edges(mesh);
517
518         mesh_calc_normals(mesh->mvert, mesh->totvert, mesh->mface, mesh->totface, NULL);
519
520         DAG_id_flush_update(&mesh->id, OB_RECALC_DATA);
521         WM_event_add_notifier(C, NC_GEOM|ND_DATA, mesh);
522 }
523
524 static void mesh_add_verts(Mesh *mesh, int len)
525 {
526         CustomData vdata;
527         MVert *mvert;
528         int i, totvert;
529
530         if(len == 0)
531                 return;
532
533         totvert= mesh->totvert + len;
534         CustomData_copy(&mesh->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert);
535         CustomData_copy_data(&mesh->vdata, &vdata, 0, 0, mesh->totvert);
536
537         if(!CustomData_has_layer(&vdata, CD_MVERT))
538                 CustomData_add_layer(&vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
539
540         CustomData_free(&mesh->vdata, mesh->totvert);
541         mesh->vdata= vdata;
542         mesh_update_customdata_pointers(mesh);
543
544         /* scan the input list and insert the new vertices */
545
546         mvert= &mesh->mvert[mesh->totvert];
547         for(i=0; i<len; i++, mvert++)
548                 mvert->flag |= SELECT;
549
550         /* set final vertex list size */
551         mesh->totvert= totvert;
552 }
553
554 void ED_mesh_transform(Mesh *me, float *mat)
555 {
556         int i;
557         MVert *mvert= me->mvert;
558
559         for(i= 0; i < me->totvert; i++, mvert++)
560                 Mat4MulVecfl((float (*)[4])mat, mvert->co);
561
562         mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
563 }
564
565 static void mesh_add_edges(Mesh *mesh, int len)
566 {
567         CustomData edata;
568         MEdge *medge;
569         int i, totedge;
570
571         if(len == 0)
572                 return;
573
574         totedge= mesh->totedge+len;
575
576         /* update customdata  */
577         CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge);
578         CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge);
579
580         if(!CustomData_has_layer(&edata, CD_MEDGE))
581                 CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
582
583         CustomData_free(&mesh->edata, mesh->totedge);
584         mesh->edata= edata;
585         mesh_update_customdata_pointers(mesh);
586
587         /* set default flags */
588         medge= &mesh->medge[mesh->totedge];
589         for(i=0; i<len; i++, medge++)
590                 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|SELECT;
591
592         mesh->totedge= totedge;
593 }
594
595 static void mesh_add_faces(Mesh *mesh, int len)
596 {
597         CustomData fdata;
598         MFace *mface;
599         int i, totface;
600
601         if(len == 0)
602                 return;
603
604         totface= mesh->totface + len;   /* new face count */
605
606         /* update customdata */
607         CustomData_copy(&mesh->fdata, &fdata, CD_MASK_MESH, CD_DEFAULT, totface);
608         CustomData_copy_data(&mesh->fdata, &fdata, 0, 0, mesh->totface);
609
610         if(!CustomData_has_layer(&fdata, CD_MFACE))
611                 CustomData_add_layer(&fdata, CD_MFACE, CD_CALLOC, NULL, totface);
612
613         CustomData_free(&mesh->fdata, mesh->totface);
614         mesh->fdata= fdata;
615         mesh_update_customdata_pointers(mesh);
616
617         /* set default flags */
618         mface= &mesh->mface[mesh->totface];
619         for(i=0; i<len; i++, mface++)
620                 mface->flag= SELECT;
621
622         mesh->totface= totface;
623 }
624
625 void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, int faces)
626 {
627         if(mesh->edit_mesh) {
628                 BKE_report(reports, RPT_ERROR, "Can't add geometry in edit mode.");
629                 return;
630         }
631
632         if(verts)
633                 mesh_add_verts(mesh, verts);
634         if(edges)
635                 mesh_add_edges(mesh, edges);
636         if(faces)
637                 mesh_add_faces(mesh, faces);
638 }
639
640 void ED_mesh_calc_normals(Mesh *me)
641 {
642         mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
643 }
644
645 void ED_mesh_material_add(Mesh *me, Material *ma)
646 {
647         int i;
648         int totcol = me->totcol + 1;
649         Material **mat;
650
651         /* don't add if mesh already has it */
652         for(i = 0; i < me->totcol; i++)
653                 if(me->mat[i] == ma)
654                         return;
655
656         mat= MEM_callocN(sizeof(void*)*totcol, "newmatar");
657
658         if(me->totcol) memcpy(mat, me->mat, sizeof(void*) * me->totcol);
659         if(me->mat) MEM_freeN(me->mat);
660
661         me->mat = mat;
662         me->mat[me->totcol++] = ma;
663         ma->id.us++;
664
665         test_object_materials((ID*)me);
666 }
667