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