Undo revision 23130 which was a merge with 2.5, a messy one because I did something...
[blender.git] / source / blender / makesrna / intern / rna_mesh_api.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 <stdlib.h>
30 #include <stdio.h>
31
32 #include "RNA_define.h"
33 #include "RNA_types.h"
34
35 #ifdef RNA_RUNTIME
36
37 #include "DNA_mesh_types.h"
38 #include "DNA_scene_types.h"
39
40 #include "BKE_customdata.h"
41 #include "BKE_depsgraph.h"
42 #include "BKE_DerivedMesh.h"
43 #include "BKE_main.h"
44 #include "BKE_mesh.h"
45 #include "BKE_material.h"
46
47 #include "DNA_mesh_types.h"
48 #include "DNA_scene_types.h"
49
50 #include "BLI_arithb.h"
51 #include "BLI_edgehash.h"
52
53 #include "WM_api.h"
54 #include "WM_types.h"
55
56 #include "MEM_guardedalloc.h"
57
58 static void rna_Mesh_calc_edges(Mesh *mesh)
59 {
60         CustomData edata;
61         EdgeHashIterator *ehi;
62         MFace *mf = mesh->mface;
63         MEdge *med;
64         EdgeHash *eh = BLI_edgehash_new();
65         int i, *index, totedge, totface = mesh->totface;
66
67         for (i = 0; i < totface; i++, mf++) {
68                 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
69                         BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
70                 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
71                         BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
72                 
73                 if (mf->v4) {
74                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
75                                 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
76                         if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
77                                 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
78                 } else {
79                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
80                                 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
81                 }
82         }
83
84         totedge = BLI_edgehash_size(eh);
85
86         /* write new edges into a temporary CustomData */
87         memset(&edata, 0, sizeof(edata));
88         CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
89
90         ehi = BLI_edgehashIterator_new(eh);
91         med = CustomData_get_layer(&edata, CD_MEDGE);
92         for(i = 0; !BLI_edgehashIterator_isDone(ehi);
93             BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
94                 BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
95
96                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
97         }
98         BLI_edgehashIterator_free(ehi);
99
100         /* free old CustomData and assign new one */
101         CustomData_free(&mesh->edata, mesh->totedge);
102         mesh->edata = edata;
103         mesh->totedge = totedge;
104
105         mesh->medge = CustomData_get_layer(&mesh->edata, CD_MEDGE);
106
107         BLI_edgehash_free(eh, NULL);
108 }
109
110 static void rna_Mesh_update(Mesh *mesh, bContext *C)
111 {
112         Main *bmain= CTX_data_main(C);
113         Object *ob;
114
115         if(mesh->totface && mesh->totedge == 0)
116                 rna_Mesh_calc_edges(mesh);
117
118         mesh_calc_normals(mesh->mvert, mesh->totvert, mesh->mface, mesh->totface, NULL);
119
120         for(ob=bmain->object.first; ob; ob=ob->id.next) {
121                 if(ob->data == mesh) {
122                         ob->recalc |= OB_RECALC_DATA;
123                         WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
124                 }
125         }
126 }
127
128 static void rna_Mesh_transform(Mesh *me, float *mat)
129 {
130
131         /* TODO: old API transform had recalc_normals option */
132         int i;
133         MVert *mvert= me->mvert;
134
135         for(i= 0; i < me->totvert; i++, mvert++) {
136                 Mat4MulVecfl((float (*)[4])mat, mvert->co);
137         }
138 }
139
140 static void rna_Mesh_add_verts(Mesh *mesh, int len)
141 {
142         CustomData vdata;
143         MVert *mvert;
144         int i, totvert;
145
146         if(len == 0)
147                 return;
148
149         totvert= mesh->totvert + len;
150         CustomData_copy(&mesh->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert);
151         CustomData_copy_data(&mesh->vdata, &vdata, 0, 0, mesh->totvert);
152
153         if(!CustomData_has_layer(&vdata, CD_MVERT))
154                 CustomData_add_layer(&vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
155
156         CustomData_free(&mesh->vdata, mesh->totvert);
157         mesh->vdata= vdata;
158         mesh_update_customdata_pointers(mesh);
159
160         /* scan the input list and insert the new vertices */
161
162         mvert= &mesh->mvert[mesh->totvert];
163         for(i=0; i<len; i++, mvert++)
164                 mvert->flag |= SELECT;
165
166         /* set final vertex list size */
167         mesh->totvert= totvert;
168 }
169
170 Mesh *rna_Mesh_create_copy(Mesh *me)
171 {
172         Mesh *ret= copy_mesh(me);
173         ret->id.us--;
174         
175         return ret;
176 }
177
178 static void rna_Mesh_add_edges(Mesh *mesh, int len)
179 {
180         CustomData edata;
181         MEdge *medge;
182         int i, totedge;
183
184         if(len == 0)
185                 return;
186
187         totedge= mesh->totedge+len;
188
189         /* update customdata  */
190         CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge);
191         CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge);
192
193         if(!CustomData_has_layer(&edata, CD_MEDGE))
194                 CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
195
196         CustomData_free(&mesh->edata, mesh->totedge);
197         mesh->edata= edata;
198         mesh_update_customdata_pointers(mesh);
199
200         /* set default flags */
201         medge= &mesh->medge[mesh->totedge];
202         for(i=0; i<len; i++, medge++)
203                 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|SELECT;
204
205         mesh->totedge= totedge;
206 }
207
208 static void rna_Mesh_add_faces(Mesh *mesh, int len)
209 {
210         CustomData fdata;
211         MFace *mface;
212         int i, totface;
213
214         if(len == 0)
215                 return;
216
217         totface= mesh->totface + len;   /* new face count */
218
219         /* update customdata */
220         CustomData_copy(&mesh->fdata, &fdata, CD_MASK_MESH, CD_DEFAULT, totface);
221         CustomData_copy_data(&mesh->fdata, &fdata, 0, 0, mesh->totface);
222
223         if(!CustomData_has_layer(&fdata, CD_MFACE))
224                 CustomData_add_layer(&fdata, CD_MFACE, CD_CALLOC, NULL, totface);
225
226         CustomData_free(&mesh->fdata, mesh->totface);
227         mesh->fdata= fdata;
228         mesh_update_customdata_pointers(mesh);
229
230         /* set default flags */
231         mface= &mesh->mface[mesh->totface];
232         for(i=0; i<len; i++, mface++)
233                 mface->flag= SELECT;
234
235         mesh->totface= totface;
236 }
237
238 /*
239 static void rna_Mesh_add_faces(Mesh *mesh)
240 {
241 }
242 */
243
244 static void rna_Mesh_add_geometry(Mesh *mesh, int verts, int edges, int faces)
245 {
246         if(verts)
247                 rna_Mesh_add_verts(mesh, verts);
248         if(edges)
249                 rna_Mesh_add_edges(mesh, edges);
250         if(faces)
251                 rna_Mesh_add_faces(mesh, faces);
252 }
253
254 static void rna_Mesh_add_uv_texture(Mesh *me)
255 {
256         me->mtface= CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface);
257 }
258
259 static void rna_Mesh_calc_normals(Mesh *me)
260 {
261         mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
262 }
263
264 static void rna_Mesh_add_material(Mesh *me, Material *ma)
265 {
266         int i;
267         int totcol = me->totcol + 1;
268         Material **mat;
269
270         /* don't add if mesh already has it */
271         for (i = 0; i < me->totcol; i++)
272                 if (me->mat[i] == ma)
273                         return;
274
275         mat= MEM_callocN(sizeof(void*) * totcol, "newmatar");
276
277         if (me->totcol) memcpy(mat, me->mat, sizeof(void*) * me->totcol);
278         if (me->mat) MEM_freeN(me->mat);
279
280         me->mat = mat;
281         me->mat[me->totcol++] = ma;
282         ma->id.us++;
283
284         test_object_materials((ID*)me);
285 }
286
287 #else
288
289 void RNA_api_mesh(StructRNA *srna)
290 {
291         FunctionRNA *func;
292         PropertyRNA *parm;
293
294         func= RNA_def_function(srna, "transform", "rna_Mesh_transform");
295         RNA_def_function_ui_description(func, "Transform mesh vertices by a matrix.");
296         parm= RNA_def_float_matrix(func, "matrix", 16, NULL, 0.0f, 0.0f, "", "Matrix.", 0.0f, 0.0f);
297         RNA_def_property_flag(parm, PROP_REQUIRED);
298
299         func= RNA_def_function(srna, "add_geometry", "rna_Mesh_add_geometry");
300         parm= RNA_def_int(func, "verts", 0, 0, INT_MAX, "Number", "Number of vertices to add.", 0, INT_MAX);
301         RNA_def_property_flag(parm, PROP_REQUIRED);
302         parm= RNA_def_int(func, "edges", 0, 0, INT_MAX, "Number", "Number of edges to add.", 0, INT_MAX);
303         RNA_def_property_flag(parm, PROP_REQUIRED);
304         parm= RNA_def_int(func, "faces", 0, 0, INT_MAX, "Number", "Number of faces to add.", 0, INT_MAX);
305         RNA_def_property_flag(parm, PROP_REQUIRED);
306
307         func= RNA_def_function(srna, "create_copy", "rna_Mesh_create_copy");
308         RNA_def_function_ui_description(func, "Create a copy of this Mesh datablock.");
309         parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh, remove it if it is only used for export.");
310         RNA_def_function_return(func, parm);
311
312         func= RNA_def_function(srna, "add_uv_texture", "rna_Mesh_add_uv_texture");
313         RNA_def_function_ui_description(func, "Add a UV texture layer to Mesh.");
314
315         func= RNA_def_function(srna, "calc_normals", "rna_Mesh_calc_normals");
316         RNA_def_function_ui_description(func, "Calculate vertex normals.");
317
318         func= RNA_def_function(srna, "update", "rna_Mesh_update");
319         RNA_def_function_flag(func, FUNC_USE_CONTEXT);
320
321         func= RNA_def_function(srna, "add_material", "rna_Mesh_add_material");
322         RNA_def_function_ui_description(func, "Add a new material to Mesh.");
323         parm= RNA_def_pointer(func, "material", "Material", "", "Material to add.");
324         RNA_def_property_flag(parm, PROP_REQUIRED);
325 }
326
327 #endif
328