1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2009 Blender Foundation.
17 * All rights reserved.
18 */
19
20 /** \file
21 * \ingroup RNA
22 */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26
27 #include "RNA_define.h"
28
29 #include "DNA_customdata_types.h"
30
31 #include "BLI_sys_types.h"
32
33 #include "BLI_utildefines.h"
34
35 #include "rna_internal.h" /* own include */
36
37 #ifdef RNA_RUNTIME
38
39 # include "DNA_mesh_types.h"
40
41 # include "BKE_mesh.h"
42 # include "BKE_mesh_mapping.h"
43 # include "BKE_mesh_runtime.h"
44 # include "BKE_mesh_tangent.h"
45 # include "ED_mesh.h"
46
rna_Mesh_unit_test_compare(struct Mesh * mesh,struct Mesh * mesh2,float threshold)47 static const char *rna_Mesh_unit_test_compare(struct Mesh *mesh,
48 struct Mesh *mesh2,
49 float threshold)
50 {
51 const char *ret = BKE_mesh_cmp(mesh, mesh2, threshold);
52
53 if (!ret) {
54 ret = "Same";
55 }
56
57 return ret;
58 }
59
rna_Mesh_create_normals_split(Mesh * mesh)60 static void rna_Mesh_create_normals_split(Mesh *mesh)
61 {
62 if (!CustomData_has_layer(&mesh->ldata, CD_NORMAL)) {
63 CustomData_add_layer(&mesh->ldata, CD_NORMAL, CD_CALLOC, NULL, mesh->totloop);
64 CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
65 }
66 }
67
rna_Mesh_free_normals_split(Mesh * mesh)68 static void rna_Mesh_free_normals_split(Mesh *mesh)
69 {
70 CustomData_free_layers(&mesh->ldata, CD_NORMAL, mesh->totloop);
71 }
72
rna_Mesh_calc_tangents(Mesh * mesh,ReportList * reports,const char * uvmap)73 static void rna_Mesh_calc_tangents(Mesh *mesh, ReportList *reports, const char *uvmap)
74 {
75 float(*r_looptangents)[4];
76
77 if (CustomData_has_layer(&mesh->ldata, CD_MLOOPTANGENT)) {
78 r_looptangents = CustomData_get_layer(&mesh->ldata, CD_MLOOPTANGENT);
79 memset(r_looptangents, 0, sizeof(float[4]) * mesh->totloop);
80 }
81 else {
82 r_looptangents = CustomData_add_layer(
83 &mesh->ldata, CD_MLOOPTANGENT, CD_CALLOC, NULL, mesh->totloop);
84 CustomData_set_layer_flag(&mesh->ldata, CD_MLOOPTANGENT, CD_FLAG_TEMPORARY);
85 }
86
87 /* Compute loop normals if needed. */
88 if (!CustomData_has_layer(&mesh->ldata, CD_NORMAL)) {
89 BKE_mesh_calc_normals_split(mesh);
90 }
91
92 BKE_mesh_calc_loop_tangent_single(mesh, uvmap, r_looptangents, reports);
93 }
94
rna_Mesh_free_tangents(Mesh * mesh)95 static void rna_Mesh_free_tangents(Mesh *mesh)
96 {
97 CustomData_free_layers(&mesh->ldata, CD_MLOOPTANGENT, mesh->totloop);
98 }
99
rna_Mesh_calc_looptri(Mesh * mesh)100 static void rna_Mesh_calc_looptri(Mesh *mesh)
101 {
102 BKE_mesh_runtime_looptri_ensure(mesh);
103 }
104
rna_Mesh_calc_smooth_groups(Mesh * mesh,bool use_bitflags,int * r_poly_group_len,int ** r_poly_group,int * r_group_total)105 static void rna_Mesh_calc_smooth_groups(
106 Mesh *mesh, bool use_bitflags, int *r_poly_group_len, int **r_poly_group, int *r_group_total)
107 {
108 *r_poly_group_len = mesh->totpoly;
109 *r_poly_group = BKE_mesh_calc_smoothgroups(mesh->medge,
110 mesh->totedge,
111 mesh->mpoly,
112 mesh->totpoly,
113 mesh->mloop,
114 mesh->totloop,
115 r_group_total,
116 use_bitflags);
117 }
118
rna_Mesh_normals_split_custom_do(Mesh * mesh,float (* custom_loopnors)[3],const bool use_vertices)119 static void rna_Mesh_normals_split_custom_do(Mesh *mesh,
120 float (*custom_loopnors)[3],
121 const bool use_vertices)
122 {
123 if (use_vertices) {
124 BKE_mesh_set_custom_normals_from_vertices(mesh, custom_loopnors);
125 }
126 else {
127 BKE_mesh_set_custom_normals(mesh, custom_loopnors);
128 }
129 }
130
rna_Mesh_normals_split_custom_set(Mesh * mesh,ReportList * reports,int normals_len,float * normals)131 static void rna_Mesh_normals_split_custom_set(Mesh *mesh,
132 ReportList *reports,
133 int normals_len,
134 float *normals)
135 {
136 float(*loopnors)[3] = (float(*)[3])normals;
137 const int numloops = mesh->totloop;
138
139 if (normals_len != numloops * 3) {
140 BKE_reportf(reports,
141 RPT_ERROR,
142 "Number of custom normals is not number of loops (%f / %d)",
143 (float)normals_len / 3.0f,
144 numloops);
145 return;
146 }
147
148 rna_Mesh_normals_split_custom_do(mesh, loopnors, false);
149
150 DEG_id_tag_update(&mesh->id, 0);
151 }
152
rna_Mesh_normals_split_custom_set_from_vertices(Mesh * mesh,ReportList * reports,int normals_len,float * normals)153 static void rna_Mesh_normals_split_custom_set_from_vertices(Mesh *mesh,
154 ReportList *reports,
155 int normals_len,
156 float *normals)
157 {
158 float(*vertnors)[3] = (float(*)[3])normals;
159 const int numverts = mesh->totvert;
160
161 if (normals_len != numverts * 3) {
162 BKE_reportf(reports,
163 RPT_ERROR,
164 "Number of custom normals is not number of vertices (%f / %d)",
165 (float)normals_len / 3.0f,
166 numverts);
167 return;
168 }
169
170 rna_Mesh_normals_split_custom_do(mesh, vertnors, true);
171
172 DEG_id_tag_update(&mesh->id, 0);
173 }
174
rna_Mesh_transform(Mesh * mesh,float * mat,bool shape_keys)175 static void rna_Mesh_transform(Mesh *mesh, float *mat, bool shape_keys)
176 {
177 BKE_mesh_transform(mesh, (float(*)[4])mat, shape_keys);
178
179 DEG_id_tag_update(&mesh->id, 0);
180 }
181
rna_Mesh_flip_normals(Mesh * mesh)182 static void rna_Mesh_flip_normals(Mesh *mesh)
183 {
184 BKE_mesh_polygons_flip(mesh->mpoly, mesh->mloop, &mesh->ldata, mesh->totpoly);
185 BKE_mesh_tessface_clear(mesh);
186 BKE_mesh_calc_normals(mesh);
187 BKE_mesh_runtime_clear_geometry(mesh);
188
189 DEG_id_tag_update(&mesh->id, 0);
190 }
191
rna_Mesh_split_faces(Mesh * mesh,bool free_loop_normals)192 static void rna_Mesh_split_faces(Mesh *mesh, bool free_loop_normals)
193 {
194 BKE_mesh_split_faces(mesh, free_loop_normals != 0);
195 }
196
rna_Mesh_update_gpu_tag(Mesh * mesh)197 static void rna_Mesh_update_gpu_tag(Mesh *mesh)
198 {
199 BKE_mesh_batch_cache_dirty_tag(mesh, BKE_MESH_BATCH_DIRTY_ALL);
200 }
201
rna_Mesh_count_selected_items(Mesh * mesh,int r_count[3])202 static void rna_Mesh_count_selected_items(Mesh *mesh, int r_count[3])
203 {
204 BKE_mesh_count_selected_items(mesh, r_count);
205 }
206
rna_Mesh_clear_geometry(Mesh * mesh)207 static void rna_Mesh_clear_geometry(Mesh *mesh)
208 {
209 BKE_mesh_clear_geometry(mesh);
210
211 DEG_id_tag_update(&mesh->id, ID_RECALC_GEOMETRY);
212 WM_main_add_notifier(NC_GEOM | ND_DATA, mesh);
213 }
214
215 #else
216
RNA_api_mesh(StructRNA * srna)217 void RNA_api_mesh(StructRNA *srna)
218 {
219 FunctionRNA *func;
220 PropertyRNA *parm;
221 const int normals_array_dim[] = {1, 3};
222
223 func = RNA_def_function(srna, "transform", "rna_Mesh_transform");
224 RNA_def_function_ui_description(func,
225 "Transform mesh vertices by a matrix "
226 "(Warning: inverts normals if matrix is negative)");
227 parm = RNA_def_float_matrix(func, "matrix", 4, 4, NULL, 0.0f, 0.0f, "", "Matrix", 0.0f, 0.0f);
228 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
229 RNA_def_boolean(func, "shape_keys", 0, "", "Transform Shape Keys");
230
231 func = RNA_def_function(srna, "flip_normals", "rna_Mesh_flip_normals");
232 RNA_def_function_ui_description(func,
233 "Invert winding of all polygons "
234 "(clears tessellation, does not handle custom normals)");
235
236 func = RNA_def_function(srna, "calc_normals", "BKE_mesh_calc_normals");
237 RNA_def_function_ui_description(func, "Calculate vertex normals");
238
239 func = RNA_def_function(srna, "create_normals_split", "rna_Mesh_create_normals_split");
240 RNA_def_function_ui_description(func, "Empty split vertex normals");
241
242 func = RNA_def_function(srna, "calc_normals_split", "BKE_mesh_calc_normals_split");
243 RNA_def_function_ui_description(func,
244 "Calculate split vertex normals, which preserve sharp edges");
245
246 func = RNA_def_function(srna, "free_normals_split", "rna_Mesh_free_normals_split");
247 RNA_def_function_ui_description(func, "Free split vertex normals");
248
249 func = RNA_def_function(srna, "split_faces", "rna_Mesh_split_faces");
250 RNA_def_function_ui_description(func, "Split faces based on the edge angle");
251 RNA_def_boolean(
252 func, "free_loop_normals", 1, "Free Loop Notmals", "Free loop normals custom data layer");
253
254 func = RNA_def_function(srna, "calc_tangents", "rna_Mesh_calc_tangents");
255 RNA_def_function_flag(func, FUNC_USE_REPORTS);
256 RNA_def_function_ui_description(
257 func,
258 "Compute tangents and bitangent signs, to be used together with the split normals "
259 "to get a complete tangent space for normal mapping "
260 "(split normals are also computed if not yet present)");
261 parm = RNA_def_string(func,
262 "uvmap",
263 NULL,
264 MAX_CUSTOMDATA_LAYER_NAME,
265 "",
266 "Name of the UV map to use for tangent space computation");
267
268 func = RNA_def_function(srna, "free_tangents", "rna_Mesh_free_tangents");
269 RNA_def_function_ui_description(func, "Free tangents");
270
271 func = RNA_def_function(srna, "calc_loop_triangles", "rna_Mesh_calc_looptri");
272 RNA_def_function_ui_description(func,
273 "Calculate loop triangle tessellation (supports editmode too)");
274
275 func = RNA_def_function(srna, "calc_smooth_groups", "rna_Mesh_calc_smooth_groups");
276 RNA_def_function_ui_description(func, "Calculate smooth groups from sharp edges");
277 RNA_def_boolean(
278 func, "use_bitflags", false, "", "Produce bitflags groups instead of simple numeric values");
279 /* return values */
280 parm = RNA_def_int_array(func, "poly_groups", 1, NULL, 0, 0, "", "Smooth Groups", 0, 0);
281 RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_OUTPUT);
282 parm = RNA_def_int(
283 func, "groups", 0, 0, INT_MAX, "groups", "Total number of groups", 0, INT_MAX);
284 RNA_def_parameter_flags(parm, 0, PARM_OUTPUT);
285
286 func = RNA_def_function(srna, "normals_split_custom_set", "rna_Mesh_normals_split_custom_set");
287 RNA_def_function_ui_description(func,
288 "Define custom split normals of this mesh "
289 "(use zero-vectors to keep auto ones)");
290 RNA_def_function_flag(func, FUNC_USE_REPORTS);
291 /* TODO, see how array size of 0 works, this shouldnt be used */
292 parm = RNA_def_float_array(func, "normals", 1, NULL, -1.0f, 1.0f, "", "Normals", 0.0f, 0.0f);
293 RNA_def_property_multi_array(parm, 2, normals_array_dim);
294 RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_REQUIRED);
295
296 func = RNA_def_function(srna,
297 "normals_split_custom_set_from_vertices",
298 "rna_Mesh_normals_split_custom_set_from_vertices");
299 RNA_def_function_ui_description(
300 func,
301 "Define custom split normals of this mesh, from vertices' normals "
302 "(use zero-vectors to keep auto ones)");
303 RNA_def_function_flag(func, FUNC_USE_REPORTS);
304 /* TODO, see how array size of 0 works, this shouldnt be used */
305 parm = RNA_def_float_array(func, "normals", 1, NULL, -1.0f, 1.0f, "", "Normals", 0.0f, 0.0f);
306 RNA_def_property_multi_array(parm, 2, normals_array_dim);
307 RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_REQUIRED);
308
309 func = RNA_def_function(srna, "update", "ED_mesh_update");
310 RNA_def_boolean(func, "calc_edges", 0, "Calculate Edges", "Force recalculation of edges");
311 RNA_def_boolean(func,
312 "calc_edges_loose",
313 0,
314 "Calculate Loose Edges",
315 "Calculate the loose state of each edge");
316 RNA_def_function_flag(func, FUNC_USE_CONTEXT);
317
318 RNA_def_function(srna, "update_gpu_tag", "rna_Mesh_update_gpu_tag");
319
320 func = RNA_def_function(srna, "unit_test_compare", "rna_Mesh_unit_test_compare");
321 RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh to compare to");
322 RNA_def_float_factor(func,
323 "threshold",
324 FLT_EPSILON * 60,
325 0.0f,
326 FLT_MAX,
327 "Threshold",
328 "Comparison tolerance threshold",
329 0.0f,
330 FLT_MAX);
331 /* return value */
332 parm = RNA_def_string(
333 func, "result", "nothing", 64, "Return value", "String description of result of comparison");
334 RNA_def_function_return(func, parm);
335
336 func = RNA_def_function(srna, "clear_geometry", "rna_Mesh_clear_geometry");
337 RNA_def_function_ui_description(
338 func,
339 "Remove all geometry from the mesh. Note that this does not free shape keys or materials");
340
341 func = RNA_def_function(srna, "validate", "BKE_mesh_validate");
342 RNA_def_function_ui_description(func,
343 "Validate geometry, return True when the mesh has had "
344 "invalid geometry corrected/removed");
345 RNA_def_boolean(func, "verbose", false, "Verbose", "Output information about the errors found");
346 RNA_def_boolean(func,
347 "clean_customdata",
348 true,
349 "Clean Custom Data",
350 "Remove temp/cached custom-data layers, like e.g. normals...");
351 parm = RNA_def_boolean(func, "result", 0, "Result", "");
352 RNA_def_function_return(func, parm);
353
354 func = RNA_def_function(srna, "validate_material_indices", "BKE_mesh_validate_material_indices");
355 RNA_def_function_ui_description(
356 func,
357 "Validate material indices of polygons, return True when the mesh has had "
358 "invalid indices corrected (to default 0)");
359 parm = RNA_def_boolean(func, "result", 0, "Result", "");
360 RNA_def_function_return(func, parm);
361
362 func = RNA_def_function(srna, "count_selected_items", "rna_Mesh_count_selected_items ");
363 RNA_def_function_ui_description(func, "Return the number of selected items (vert, edge, face)");
364 parm = RNA_def_int_vector(func, "result", 3, NULL, 0, INT_MAX, "Result", NULL, 0, INT_MAX);
365 RNA_def_function_output(func, parm);
366 }
367
368 #endif
369