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