4 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
20 * The Original Code is Copyright (C) 2009 Blender Foundation.
21 * All rights reserved.
24 * Contributor(s): Blender Foundation
26 * ***** END GPL LICENSE BLOCK *****
32 #include "MEM_guardedalloc.h"
34 #include "DNA_customdata_types.h"
35 #include "DNA_mesh_types.h"
36 #include "DNA_meshdata_types.h"
37 #include "DNA_object_types.h"
38 #include "DNA_scene_types.h"
39 #include "DNA_windowmanager_types.h"
41 #include "BKE_context.h"
42 #include "BKE_customdata.h"
43 #include "BKE_depsgraph.h"
44 #include "BKE_displist.h"
45 #include "BKE_global.h"
48 #include "BLI_editVert.h"
50 #include "RNA_access.h"
51 #include "RNA_define.h"
57 #include "ED_object.h"
58 #include "ED_view3d.h"
60 #include "mesh_intern.h"
62 static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *layer)
65 CustomData *data= (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata;
66 void *actlayerdata, *rndlayerdata, *clonelayerdata, *masklayerdata, *layerdata=layer->data;
67 int type= layer->type;
68 int index= CustomData_get_layer_index(data, type);
69 int i, actindex, rndindex, cloneindex, maskindex;
71 /* ok, deleting a non-active layer needs to preserve the active layer indices.
72 to do this, we store a pointer to the .data member of both layer and the active layer,
73 (to detect if we're deleting the active layer or not), then use the active
74 layer data pointer to find where the active layer has ended up.
76 this is necassary because the deletion functions only support deleting the active
78 actlayerdata = data->layers[CustomData_get_active_layer_index(data, type)].data;
79 rndlayerdata = data->layers[CustomData_get_render_layer_index(data, type)].data;
80 clonelayerdata = data->layers[CustomData_get_clone_layer_index(data, type)].data;
81 masklayerdata = data->layers[CustomData_get_mask_layer_index(data, type)].data;
82 CustomData_set_layer_active(data, type, layer - &data->layers[index]);
85 EM_free_data_layer(me->edit_mesh, data, type);
88 CustomData_free_layer_active(data, type, me->totface);
89 mesh_update_customdata_pointers(me);
92 if(!CustomData_has_layer(data, type) && (type == CD_MCOL && (ob->mode & OB_MODE_VERTEX_PAINT)))
93 ED_object_toggle_modes(C, OB_MODE_VERTEX_PAINT);
95 /* reconstruct active layer */
96 if (actlayerdata != layerdata) {
98 actindex = CustomData_get_layer_index(data, type);
99 for (i=actindex; i<data->totlayer; i++) {
100 if (data->layers[i].data == actlayerdata) {
101 actindex = i - actindex;
107 CustomData_set_layer_active(data, type, actindex);
110 if (rndlayerdata != layerdata) {
112 rndindex = CustomData_get_layer_index(data, type);
113 for (i=rndindex; i<data->totlayer; i++) {
114 if (data->layers[i].data == rndlayerdata) {
115 rndindex = i - rndindex;
121 CustomData_set_layer_render(data, type, rndindex);
124 if (clonelayerdata != layerdata) {
126 cloneindex = CustomData_get_layer_index(data, type);
127 for (i=cloneindex; i<data->totlayer; i++) {
128 if (data->layers[i].data == clonelayerdata) {
129 cloneindex = i - cloneindex;
135 CustomData_set_layer_clone(data, type, cloneindex);
138 if (masklayerdata != layerdata) {
140 maskindex = CustomData_get_layer_index(data, type);
141 for (i=maskindex; i<data->totlayer; i++) {
142 if (data->layers[i].data == masklayerdata) {
143 maskindex = i - maskindex;
149 CustomData_set_layer_mask(data, type, maskindex);
153 /*********************** UV texture operators ************************/
155 static int uv_texture_add_exec(bContext *C, wmOperator *op)
157 Scene *scene= CTX_data_scene(C);
158 Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
163 if(!ob || ob->type!=OB_MESH)
164 return OPERATOR_CANCELLED;
168 if(scene->obedit == ob) {
171 layernum= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
172 if(layernum >= MAX_MTFACE)
173 return OPERATOR_CANCELLED;
175 EM_add_data_layer(em, &em->fdata, CD_MTFACE);
176 CustomData_set_layer_active(&em->fdata, CD_MTFACE, layernum);
179 layernum= CustomData_number_of_layers(&me->fdata, CD_MTFACE);
180 if(layernum >= MAX_MTFACE)
181 return OPERATOR_CANCELLED;
184 CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DUPLICATE, me->mtface, me->totface);
186 CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface);
188 CustomData_set_layer_active(&me->fdata, CD_MTFACE, layernum);
189 mesh_update_customdata_pointers(me);
192 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
193 WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
195 return OPERATOR_FINISHED;
198 void MESH_OT_uv_texture_add(wmOperatorType *ot)
201 ot->name= "Add UV Texture";
202 ot->description= "Add UV texture layer.";
203 ot->idname= "MESH_OT_uv_texture_add";
206 ot->exec= uv_texture_add_exec;
209 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
212 static int uv_texture_remove_exec(bContext *C, wmOperator *op)
214 Scene *scene= CTX_data_scene(C);
215 Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
217 CustomDataLayer *cdl;
220 if(!ob || ob->type!=OB_MESH)
221 return OPERATOR_CANCELLED;
224 index= CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
225 cdl= (index == -1)? NULL: &me->fdata.layers[index];
228 return OPERATOR_CANCELLED;
230 delete_customdata_layer(C, ob, cdl);
232 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
233 WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
235 return OPERATOR_FINISHED;
238 void MESH_OT_uv_texture_remove(wmOperatorType *ot)
241 ot->name= "Remove UV Texture";
242 ot->description= "Remove UV texture layer.";
243 ot->idname= "MESH_OT_uv_texture_remove";
246 ot->exec= uv_texture_remove_exec;
249 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
252 /*********************** vertex color operators ************************/
254 static int vertex_color_add_exec(bContext *C, wmOperator *op)
256 Scene *scene= CTX_data_scene(C);
257 Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
263 if(!ob || ob->type!=OB_MESH)
264 return OPERATOR_CANCELLED;
268 if(scene->obedit == ob) {
271 layernum= CustomData_number_of_layers(&em->fdata, CD_MCOL);
272 if(layernum >= MAX_MCOL)
273 return OPERATOR_CANCELLED;
275 EM_add_data_layer(em, &em->fdata, CD_MCOL);
276 CustomData_set_layer_active(&em->fdata, CD_MCOL, layernum);
279 layernum= CustomData_number_of_layers(&me->fdata, CD_MCOL);
280 if(layernum >= MAX_MCOL)
281 return OPERATOR_CANCELLED;
286 CustomData_add_layer(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mcol, me->totface);
288 CustomData_add_layer(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface);
290 CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum);
291 mesh_update_customdata_pointers(me);
294 shadeMeshMCol(scene, ob, me);
297 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
298 WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
300 return OPERATOR_FINISHED;
303 void MESH_OT_vertex_color_add(wmOperatorType *ot)
306 ot->name= "Add Vertex Color";
307 ot->description= "Add vertex color layer.";
308 ot->idname= "MESH_OT_vertex_color_add";
311 ot->exec= vertex_color_add_exec;
314 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
317 static int vertex_color_remove_exec(bContext *C, wmOperator *op)
319 Scene *scene= CTX_data_scene(C);
320 Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
322 CustomDataLayer *cdl;
325 if(!ob || ob->type!=OB_MESH)
326 return OPERATOR_CANCELLED;
329 index= CustomData_get_active_layer_index(&me->fdata, CD_MCOL);
330 cdl= (index == -1)? NULL: &me->fdata.layers[index];
333 return OPERATOR_CANCELLED;
335 delete_customdata_layer(C, ob, cdl);
337 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
338 WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
340 return OPERATOR_FINISHED;
343 void MESH_OT_vertex_color_remove(wmOperatorType *ot)
346 ot->name= "Remove Vertex Color";
347 ot->description= "Remove vertex color layer.";
348 ot->idname= "MESH_OT_vertex_color_remove";
351 ot->exec= vertex_color_remove_exec;
354 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
357 /*********************** sticky operators ************************/
359 static int sticky_add_exec(bContext *C, wmOperator *op)
361 Scene *scene= CTX_data_scene(C);
362 Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
365 if(!ob || ob->type!=OB_MESH)
366 return OPERATOR_CANCELLED;
371 return OPERATOR_CANCELLED;
373 // XXX RE_make_sticky();
375 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
376 WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
378 return OPERATOR_FINISHED;
381 void MESH_OT_sticky_add(wmOperatorType *ot)
384 ot->name= "Add Sticky";
385 ot->description= "Add sticky UV texture layer.";
386 ot->idname= "MESH_OT_sticky_add";
389 ot->exec= sticky_add_exec;
392 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
395 static int sticky_remove_exec(bContext *C, wmOperator *op)
397 Scene *scene= CTX_data_scene(C);
398 Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
401 if(!ob || ob->type!=OB_MESH)
402 return OPERATOR_CANCELLED;
407 return OPERATOR_CANCELLED;
409 CustomData_free_layer_active(&me->vdata, CD_MSTICKY, me->totvert);
412 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
413 WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
415 return OPERATOR_FINISHED;
418 void MESH_OT_sticky_remove(wmOperatorType *ot)
421 ot->name= "Remove Sticky";
422 ot->description= "Remove sticky UV texture layer.";
423 ot->idname= "MESH_OT_sticky_remove";
426 ot->exec= sticky_remove_exec;
429 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;