Blender V4.3
rna_mesh.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cstdlib>
10
11#include "MEM_guardedalloc.h"
12
13#include "DNA_material_types.h"
14#include "DNA_mesh_types.h"
15#include "DNA_meshdata_types.h"
16#include "DNA_object_types.h"
17
18#include "BLI_math_base.h"
19#include "BLI_math_geom.h"
20#include "BLI_math_rotation.h"
21#include "BLI_string_utf8.h"
22#include "BLI_utildefines.h"
23
24#include "BKE_attribute.hh"
25#include "BKE_editmesh.hh"
26#include "BKE_mesh_types.hh"
27
28#include "RNA_access.hh"
29#include "RNA_define.hh"
30#include "RNA_enum_types.hh"
31#include "RNA_types.hh"
32
33#include "rna_internal.hh"
34
35#include "WM_types.hh"
36
38 {BMO_DELIM_NORMAL, "NORMAL", 0, "Normal", "Delimit by face directions"},
39 {BMO_DELIM_MATERIAL, "MATERIAL", 0, "Material", "Delimit by face material"},
40 {BMO_DELIM_SEAM, "SEAM", 0, "Seam", "Delimit by edge seams"},
41 {BMO_DELIM_SHARP, "SHARP", 0, "Sharp", "Delimit by sharp edges"},
42 {BMO_DELIM_UV, "UV", 0, "UVs", "Delimit by UV coordinates"},
43 {0, nullptr, 0, nullptr, nullptr},
44};
45
47 {REMESH_VOXEL, "VOXEL", 0, "Voxel", "Use the voxel remesher"},
48 {REMESH_QUAD, "QUAD", 0, "Quad", "Use the quad remesher"},
49 {0, nullptr, 0, nullptr, nullptr},
50};
51
52#ifdef RNA_RUNTIME
53
54# include <fmt/format.h>
55
56# include "DNA_scene_types.h"
57
58# include "BLI_math_vector.h"
59
60# include "BKE_attribute.hh"
61# include "BKE_customdata.hh"
62# include "BKE_main.hh"
63# include "BKE_mesh.hh"
64# include "BKE_mesh_runtime.hh"
65# include "BKE_report.hh"
66
67# include "DEG_depsgraph.hh"
68
69# include "ED_mesh.hh" /* XXX Bad level call */
70
71# include "WM_api.hh"
72
73# include "rna_mesh_utils.hh"
74
75/* -------------------------------------------------------------------- */
79static Mesh *rna_mesh(const PointerRNA *ptr)
80{
81 Mesh *mesh = (Mesh *)ptr->owner_id;
82 return mesh;
83}
84
85static CustomData *rna_mesh_vdata_helper(Mesh *mesh)
86{
87 return (mesh->runtime->edit_mesh) ? &mesh->runtime->edit_mesh->bm->vdata : &mesh->vert_data;
88}
89
90static CustomData *rna_mesh_ldata_helper(Mesh *mesh)
91{
92 return (mesh->runtime->edit_mesh) ? &mesh->runtime->edit_mesh->bm->ldata : &mesh->corner_data;
93}
94
95static CustomData *rna_mesh_vdata(const PointerRNA *ptr)
96{
97 Mesh *mesh = rna_mesh(ptr);
98 return rna_mesh_vdata_helper(mesh);
99}
100static CustomData *rna_mesh_ldata(const PointerRNA *ptr)
101{
102 Mesh *mesh = rna_mesh(ptr);
103 return rna_mesh_ldata_helper(mesh);
104}
105
108/* -------------------------------------------------------------------- */
112static void rna_cd_layer_name_set(CustomData *cdata, CustomDataLayer *cdl, const char *value)
113{
114 STRNCPY_UTF8(cdl->name, value);
115 CustomData_set_layer_unique_name(cdata, cdl - cdata->layers);
116}
117
118static void rna_MeshVertexLayer_name_set(PointerRNA *ptr, const char *value)
119{
121
122 if (CD_TYPE_AS_MASK(layer->type) & CD_MASK_PROP_ALL) {
124 BKE_attribute_rename(owner, layer->name, value, nullptr);
125 }
126 else {
127 rna_cd_layer_name_set(rna_mesh_vdata(ptr), layer, value);
128 }
129}
130# if 0
131static void rna_MeshEdgeLayer_name_set(PointerRNA *ptr, const char *value)
132{
134
135 if (CD_TYPE_AS_MASK(layer->type) & CD_MASK_PROP_ALL) {
137 BKE_attribute_rename(owner, layer->name, value, nullptr);
138 }
139 else {
140 rna_cd_layer_name_set(rna_mesh_edata(ptr), layer, value);
141 }
142}
143# endif
144static void rna_MeshLoopLayer_name_set(PointerRNA *ptr, const char *value)
145{
147
148 if (CD_TYPE_AS_MASK(layer->type) & CD_MASK_PROP_ALL) {
150 BKE_attribute_rename(owner, layer->name, value, nullptr);
151 }
152 else {
153 rna_cd_layer_name_set(rna_mesh_ldata(ptr), layer, value);
154 }
155}
156
157static bool rna_Mesh_has_custom_normals_get(PointerRNA *ptr)
158{
159 Mesh *mesh = static_cast<Mesh *>(ptr->data);
161}
162
165/* -------------------------------------------------------------------- */
180static void rna_Mesh_update_data_legacy_deg_tag_all(Main * /*bmain*/,
181 Scene * /*scene*/,
183{
184 ID *id = ptr->owner_id;
185 if (id->us <= 0) { /* See note in section heading. */
186 return;
187 }
188
189 DEG_id_tag_update(id, 0);
191}
192
193static void rna_Mesh_update_geom_and_params(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr)
194{
195 ID *id = ptr->owner_id;
196 if (id->us <= 0) { /* See note in section heading. */
197 return;
198 }
199
202}
203
204static void rna_Mesh_update_data_edit_weight(Main *bmain, Scene *scene, PointerRNA *ptr)
205{
207
208 rna_Mesh_update_data_legacy_deg_tag_all(bmain, scene, ptr);
209}
210
211static void rna_Mesh_update_data_edit_active_color(Main *bmain, Scene *scene, PointerRNA *ptr)
212{
214
215 rna_Mesh_update_data_legacy_deg_tag_all(bmain, scene, ptr);
216}
217static void rna_Mesh_update_select(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr)
218{
219 ID *id = ptr->owner_id;
220 if (id->us <= 0) { /* See note in section heading. */
221 return;
222 }
223
225}
226
227void rna_Mesh_update_draw(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr)
228{
229 ID *id = ptr->owner_id;
230 if (id->us <= 0) { /* See note in section heading. */
231 return;
232 }
233
235}
236
237static void rna_Mesh_update_bone_selection_mode(Main *bmain, Scene *scene, PointerRNA *ptr)
238{
239 Mesh *mesh = static_cast<Mesh *>(ptr->data);
240 mesh->editflag &= ~ME_EDIT_PAINT_VERT_SEL;
241 mesh->editflag &= ~ME_EDIT_PAINT_FACE_SEL;
242
244
245 rna_Mesh_update_draw(bmain, scene, ptr);
246}
247
248static void rna_Mesh_update_vertmask(Main *bmain, Scene *scene, PointerRNA *ptr)
249{
250 Mesh *mesh = static_cast<Mesh *>(ptr->data);
251 if ((mesh->editflag & ME_EDIT_PAINT_VERT_SEL) && (mesh->editflag & ME_EDIT_PAINT_FACE_SEL)) {
252 mesh->editflag &= ~ME_EDIT_PAINT_FACE_SEL;
253 }
254
256
257 rna_Mesh_update_draw(bmain, scene, ptr);
258}
259
260static void rna_Mesh_update_facemask(Main *bmain, Scene *scene, PointerRNA *ptr)
261{
262 Mesh *mesh = static_cast<Mesh *>(ptr->data);
263 if ((mesh->editflag & ME_EDIT_PAINT_VERT_SEL) && (mesh->editflag & ME_EDIT_PAINT_FACE_SEL)) {
264 mesh->editflag &= ~ME_EDIT_PAINT_VERT_SEL;
265 }
266
268
269 rna_Mesh_update_draw(bmain, scene, ptr);
270}
271
272static void rna_Mesh_update_positions_tag(Main *bmain, Scene *scene, PointerRNA *ptr)
273{
274 rna_Mesh_update_data_legacy_deg_tag_all(bmain, scene, ptr);
275}
276
279/* -------------------------------------------------------------------- */
283static int rna_MeshVertex_index_get(PointerRNA *ptr)
284{
285 const Mesh *mesh = rna_mesh(ptr);
286 const blender::float3 *position = static_cast<const blender::float3 *>(ptr->data);
287 const int index = int(position - mesh->vert_positions().data());
288 BLI_assert(index >= 0);
289 BLI_assert(index < mesh->verts_num);
290 return index;
291}
292
293static int rna_MeshEdge_index_get(PointerRNA *ptr)
294{
295 using namespace blender;
296 const Mesh *mesh = rna_mesh(ptr);
297 const blender::int2 *edge = static_cast<const blender::int2 *>(ptr->data);
298 const blender::int2 *edges = static_cast<const blender::int2 *>(
299 CustomData_get_layer_named(&mesh->edge_data, CD_PROP_INT32_2D, ".edge_verts"));
300 const int index = int(edge - edges);
301 BLI_assert(index >= 0);
302 BLI_assert(index < mesh->edges_num);
303 return index;
304}
305
306static int rna_MeshPolygon_index_get(PointerRNA *ptr)
307{
308 const Mesh *mesh = rna_mesh(ptr);
309 const int *face_offset = static_cast<const int *>(ptr->data);
310 const int index = int(face_offset - mesh->face_offsets().data());
311 BLI_assert(index >= 0);
312 BLI_assert(index < mesh->faces_num);
313 return index;
314}
315
316static int rna_MeshLoop_index_get(PointerRNA *ptr)
317{
318 const Mesh *mesh = rna_mesh(ptr);
319 const int *corner_vert = static_cast<const int *>(ptr->data);
320 const int index = int(corner_vert - mesh->corner_verts().data());
321 BLI_assert(index >= 0);
322 BLI_assert(index < mesh->corners_num);
323 return index;
324}
325
326static int rna_MeshLoopTriangle_index_get(PointerRNA *ptr)
327{
328 const Mesh *mesh = rna_mesh(ptr);
329 const blender::int3 *tri = static_cast<const blender::int3 *>(ptr->data);
330 const int index = int(tri - mesh->corner_tris().data());
331 BLI_assert(index >= 0);
333 return index;
334}
335
336static int rna_MeshLoopTriangle_polygon_index_get(PointerRNA *ptr)
337{
338 const Mesh *mesh = rna_mesh(ptr);
339 const int index = rna_MeshLoopTriangle_index_get(ptr);
340 return mesh->corner_tri_faces()[index];
341}
342
343static void rna_Mesh_loop_triangles_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
344{
345 const Mesh *mesh = rna_mesh(ptr);
346 const blender::Span<blender::int3> corner_tris = mesh->corner_tris();
348 const_cast<blender::int3 *>(corner_tris.data()),
349 sizeof(blender::int3),
350 corner_tris.size(),
351 false,
352 nullptr);
353}
354
355static int rna_Mesh_loop_triangles_length(PointerRNA *ptr)
356{
357 const Mesh *mesh = rna_mesh(ptr);
359}
360
361bool rna_Mesh_loop_triangles_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
362{
363 const Mesh *mesh = rna_mesh(ptr);
364 if (index < 0 || index >= BKE_mesh_runtime_corner_tris_len(mesh)) {
365 return false;
366 }
367 /* Casting away const is okay because this RNA type doesn't allow changing the value. */
368 r_ptr->owner_id = (ID *)&mesh->id;
369 r_ptr->type = &RNA_MeshLoopTriangle;
370 r_ptr->data = const_cast<blender::int3 *>(&mesh->corner_tris()[index]);
371 return true;
372}
373
374static void rna_Mesh_loop_triangle_polygons_begin(CollectionPropertyIterator *iter,
376{
377 const Mesh *mesh = rna_mesh(ptr);
379 const_cast<int *>(mesh->corner_tri_faces().data()),
380 sizeof(int),
382 false,
383 nullptr);
384}
385
386bool rna_Mesh_loop_triangle_polygons_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
387{
388 const Mesh *mesh = rna_mesh(ptr);
389 if (index < 0 || index >= BKE_mesh_runtime_corner_tris_len(mesh)) {
390 return false;
391 }
392 /* Casting away const is okay because this RNA type doesn't allow changing the value. */
393 r_ptr->owner_id = (ID *)&mesh->id;
394 r_ptr->type = &RNA_ReadOnlyInteger;
395 r_ptr->data = const_cast<int *>(&mesh->corner_tri_faces()[index]);
396 return true;
397}
398
399static void rna_MeshVertex_co_get(PointerRNA *ptr, float *value)
400{
401 copy_v3_v3(value, (const float *)ptr->data);
402}
403
404static void rna_MeshVertex_co_set(PointerRNA *ptr, const float *value)
405{
406 copy_v3_v3((float *)ptr->data, value);
407 Mesh *mesh = rna_mesh(ptr);
408 mesh->tag_positions_changed();
409}
410
411static void rna_MeshVertex_normal_get(PointerRNA *ptr, float *value)
412{
413 Mesh *mesh = rna_mesh(ptr);
414 const blender::Span<blender::float3> vert_normals = mesh->vert_normals();
415 const int index = rna_MeshVertex_index_get(ptr);
416 copy_v3_v3(value, vert_normals[index]);
417}
418
419static bool rna_MeshVertex_hide_get(PointerRNA *ptr)
420{
421 const Mesh *mesh = rna_mesh(ptr);
422 const bool *hide_vert = static_cast<const bool *>(
423 CustomData_get_layer_named(&mesh->vert_data, CD_PROP_BOOL, ".hide_vert"));
424 const int index = rna_MeshVertex_index_get(ptr);
425 return hide_vert == nullptr ? false : hide_vert[index];
426}
427
428static void rna_MeshVertex_hide_set(PointerRNA *ptr, bool value)
429{
430 Mesh *mesh = rna_mesh(ptr);
431 bool *hide_vert = static_cast<bool *>(CustomData_get_layer_named_for_write(
432 &mesh->vert_data, CD_PROP_BOOL, ".hide_vert", mesh->verts_num));
433 if (!hide_vert) {
434 if (!value) {
435 /* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */
436 return;
437 }
438 hide_vert = static_cast<bool *>(CustomData_add_layer_named(
439 &mesh->vert_data, CD_PROP_BOOL, CD_SET_DEFAULT, mesh->verts_num, ".hide_vert"));
440 }
441 const int index = rna_MeshVertex_index_get(ptr);
442 hide_vert[index] = value;
443}
444
445static bool rna_MeshVertex_select_get(PointerRNA *ptr)
446{
447 const Mesh *mesh = rna_mesh(ptr);
448 const bool *select_vert = static_cast<const bool *>(
449 CustomData_get_layer_named(&mesh->vert_data, CD_PROP_BOOL, ".select_vert"));
450 const int index = rna_MeshVertex_index_get(ptr);
451 return select_vert == nullptr ? false : select_vert[index];
452}
453
454static void rna_MeshVertex_select_set(PointerRNA *ptr, bool value)
455{
456 Mesh *mesh = rna_mesh(ptr);
457 bool *select_vert = static_cast<bool *>(CustomData_get_layer_named_for_write(
458 &mesh->vert_data, CD_PROP_BOOL, ".select_vert", mesh->verts_num));
459 if (!select_vert) {
460 if (!value) {
461 /* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */
462 return;
463 }
464 select_vert = static_cast<bool *>(CustomData_add_layer_named(
465 &mesh->vert_data, CD_PROP_BOOL, CD_SET_DEFAULT, mesh->verts_num, ".select_vert"));
466 }
467 const int index = rna_MeshVertex_index_get(ptr);
468 select_vert[index] = value;
469}
470
471static int rna_MeshLoop_vertex_index_get(PointerRNA *ptr)
472{
473 return *(int *)ptr->data;
474}
475
476static void rna_MeshLoop_vertex_index_set(PointerRNA *ptr, int value)
477{
478 *(int *)ptr->data = value;
479}
480
481static int rna_MeshLoop_edge_index_get(PointerRNA *ptr)
482{
483 const Mesh *mesh = rna_mesh(ptr);
484 const int index = rna_MeshLoop_index_get(ptr);
485 return mesh->corner_edges()[index];
486}
487
488static void rna_MeshLoop_edge_index_set(PointerRNA *ptr, int value)
489{
490 Mesh *mesh = rna_mesh(ptr);
491 const int index = rna_MeshLoop_index_get(ptr);
492 mesh->corner_edges_for_write()[index] = value;
493}
494
495static void rna_MeshLoop_normal_get(PointerRNA *ptr, float *values)
496{
497 Mesh *mesh = rna_mesh(ptr);
498 const int index = rna_MeshLoop_index_get(ptr);
499 copy_v3_v3(values, mesh->corner_normals()[index]);
500}
501
502static void rna_MeshLoop_tangent_get(PointerRNA *ptr, float *values)
503{
504 Mesh *mesh = rna_mesh(ptr);
505 const int index = rna_MeshLoop_index_get(ptr);
506 const float(*layer)[4] = static_cast<const float(*)[4]>(
507 CustomData_get_layer(&mesh->corner_data, CD_MLOOPTANGENT));
508
509 if (!layer) {
510 zero_v3(values);
511 }
512 else {
513 copy_v3_v3(values, (const float *)(layer + index));
514 }
515}
516
517static float rna_MeshLoop_bitangent_sign_get(PointerRNA *ptr)
518{
519 Mesh *mesh = rna_mesh(ptr);
520 const int index = rna_MeshLoop_index_get(ptr);
521 const float(*vec)[4] = static_cast<const float(*)[4]>(
522 CustomData_get_layer(&mesh->corner_data, CD_MLOOPTANGENT));
523
524 return (vec) ? vec[index][3] : 0.0f;
525}
526
527static void rna_MeshLoop_bitangent_get(PointerRNA *ptr, float *values)
528{
529 Mesh *mesh = rna_mesh(ptr);
530 const int index = rna_MeshLoop_index_get(ptr);
531 const float(*vec)[4] = static_cast<const float(*)[4]>(
532 CustomData_get_layer(&mesh->corner_data, CD_MLOOPTANGENT));
533
534 if (vec) {
535 cross_v3_v3v3(values, mesh->corner_normals()[index], vec[index]);
536 mul_v3_fl(values, vec[index][3]);
537 }
538 else {
539 zero_v3(values);
540 }
541}
542
543static void rna_MeshPolygon_normal_get(PointerRNA *ptr, float *values)
544{
545 using namespace blender;
546 Mesh *mesh = rna_mesh(ptr);
547 const int poly_start = *((const int *)ptr->data);
548 const int poly_size = *(((const int *)ptr->data) + 1) - poly_start;
549 const Span<int> face_verts = mesh->corner_verts().slice(poly_start, poly_size);
550 const float3 result = bke::mesh::face_normal_calc(mesh->vert_positions(), face_verts);
551 copy_v3_v3(values, result);
552}
553
554static bool rna_MeshPolygon_hide_get(PointerRNA *ptr)
555{
556 const Mesh *mesh = rna_mesh(ptr);
557 const bool *hide_poly = static_cast<const bool *>(
558 CustomData_get_layer_named(&mesh->face_data, CD_PROP_BOOL, ".hide_poly"));
559 const int index = rna_MeshPolygon_index_get(ptr);
560 return hide_poly == nullptr ? false : hide_poly[index];
561}
562
563static void rna_MeshPolygon_hide_set(PointerRNA *ptr, bool value)
564{
565 Mesh *mesh = rna_mesh(ptr);
566 bool *hide_poly = static_cast<bool *>(CustomData_get_layer_named_for_write(
567 &mesh->face_data, CD_PROP_BOOL, ".hide_poly", mesh->faces_num));
568 if (!hide_poly) {
569 if (!value) {
570 /* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */
571 return;
572 }
573 hide_poly = static_cast<bool *>(CustomData_add_layer_named(
574 &mesh->face_data, CD_PROP_BOOL, CD_SET_DEFAULT, mesh->faces_num, ".hide_poly"));
575 }
576 const int index = rna_MeshPolygon_index_get(ptr);
577 hide_poly[index] = value;
578}
579
580static bool rna_MeshPolygon_use_smooth_get(PointerRNA *ptr)
581{
582 const Mesh *mesh = rna_mesh(ptr);
583 const bool *sharp_faces = static_cast<const bool *>(
584 CustomData_get_layer_named(&mesh->face_data, CD_PROP_BOOL, "sharp_face"));
585 const int index = rna_MeshPolygon_index_get(ptr);
586 return !(sharp_faces && sharp_faces[index]);
587}
588
589static void rna_MeshPolygon_use_smooth_set(PointerRNA *ptr, bool value)
590{
591 Mesh *mesh = rna_mesh(ptr);
592 bool *sharp_faces = static_cast<bool *>(CustomData_get_layer_named_for_write(
593 &mesh->face_data, CD_PROP_BOOL, "sharp_face", mesh->faces_num));
594 if (!sharp_faces) {
595 if (value) {
596 /* Skip adding layer if the value is the same as the default. */
597 return;
598 }
599 sharp_faces = static_cast<bool *>(CustomData_add_layer_named(
600 &mesh->face_data, CD_PROP_BOOL, CD_SET_DEFAULT, mesh->faces_num, "sharp_face"));
601 }
602 const int index = rna_MeshPolygon_index_get(ptr);
603 if (value == sharp_faces[index]) {
604 sharp_faces[index] = !value;
605 mesh->tag_sharpness_changed();
606 }
607}
608
609static bool rna_MeshPolygon_select_get(PointerRNA *ptr)
610{
611 const Mesh *mesh = rna_mesh(ptr);
612 const bool *select_poly = static_cast<const bool *>(
613 CustomData_get_layer_named(&mesh->face_data, CD_PROP_BOOL, ".select_poly"));
614 const int index = rna_MeshPolygon_index_get(ptr);
615 return select_poly == nullptr ? false : select_poly[index];
616}
617
618static void rna_MeshPolygon_select_set(PointerRNA *ptr, bool value)
619{
620 Mesh *mesh = rna_mesh(ptr);
621 bool *select_poly = static_cast<bool *>(CustomData_get_layer_named_for_write(
622 &mesh->face_data, CD_PROP_BOOL, ".select_poly", mesh->faces_num));
623 if (!select_poly) {
624 if (!value) {
625 /* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */
626 return;
627 }
628 select_poly = static_cast<bool *>(CustomData_add_layer_named(
629 &mesh->face_data, CD_PROP_BOOL, CD_SET_DEFAULT, mesh->faces_num, ".select_poly"));
630 }
631 const int index = rna_MeshPolygon_index_get(ptr);
632 select_poly[index] = value;
633}
634
635static int rna_MeshPolygon_material_index_get(PointerRNA *ptr)
636{
637 using namespace blender;
638 const Mesh *mesh = rna_mesh(ptr);
639 const bke::AttributeAccessor attributes = mesh->attributes();
640 const VArray material_index = *attributes.lookup_or_default<int>(
641 "material_index", bke::AttrDomain::Face, 0);
642 return material_index[rna_MeshPolygon_index_get(ptr)];
643}
644
645static void rna_MeshPolygon_material_index_set(PointerRNA *ptr, int value)
646{
647 using namespace blender;
648 Mesh *mesh = rna_mesh(ptr);
649 bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
650 bke::AttributeWriter material_index = attributes.lookup_or_add_for_write<int>(
651 "material_index", bke::AttrDomain::Face);
652 material_index.varray.set(rna_MeshPolygon_index_get(ptr), max_ii(0, value));
653 material_index.finish();
654}
655
656static void rna_MeshPolygon_center_get(PointerRNA *ptr, float *values)
657{
658 using namespace blender;
659 Mesh *mesh = rna_mesh(ptr);
660 const int poly_start = *((const int *)ptr->data);
661 const int poly_size = *(((const int *)ptr->data) + 1) - poly_start;
662 const Span<int> face_verts = mesh->corner_verts().slice(poly_start, poly_size);
663 const float3 result = bke::mesh::face_center_calc(mesh->vert_positions(), face_verts);
664 copy_v3_v3(values, result);
665}
666
667static float rna_MeshPolygon_area_get(PointerRNA *ptr)
668{
669 using namespace blender;
670 Mesh *mesh = (Mesh *)ptr->owner_id;
671 const int poly_start = *((const int *)ptr->data);
672 const int poly_size = *(((const int *)ptr->data) + 1) - poly_start;
673 const Span<int> face_verts = mesh->corner_verts().slice(poly_start, poly_size);
674 return bke::mesh::face_area_calc(mesh->vert_positions(), face_verts);
675}
676
677static void rna_MeshPolygon_flip(ID *id, MIntProperty *poly_offset_p)
678{
679 using namespace blender;
680 Mesh *mesh = (Mesh *)id;
681 const int index = reinterpret_cast<int *>(poly_offset_p) - mesh->faces().data().data();
682 bke::mesh_flip_faces(*mesh, IndexMask(IndexRange(index, 1)));
685}
686
687static void rna_MeshLoopTriangle_verts_get(PointerRNA *ptr, int *values)
688{
689 Mesh *mesh = rna_mesh(ptr);
690 const blender::Span<int> corner_verts = mesh->corner_verts();
692 values[0] = corner_verts[tri[0]];
693 values[1] = corner_verts[tri[1]];
694 values[2] = corner_verts[tri[2]];
695}
696
697static void rna_MeshLoopTriangle_normal_get(PointerRNA *ptr, float *values)
698{
699 Mesh *mesh = rna_mesh(ptr);
701 const blender::Span<blender::float3> positions = mesh->vert_positions();
702 const blender::Span<int> corner_verts = mesh->corner_verts();
703 const int v1 = corner_verts[tri[0]];
704 const int v2 = corner_verts[tri[1]];
705 const int v3 = corner_verts[tri[2]];
706
707 normal_tri_v3(values, positions[v1], positions[v2], positions[v3]);
708}
709
710static void rna_MeshLoopTriangle_split_normals_get(PointerRNA *ptr, float *values)
711{
712 Mesh *mesh = rna_mesh(ptr);
713 const blender::Span<blender::float3> corner_normals = mesh->corner_normals();
714 const blender::int3 tri = *(const blender::int3 *)ptr->data;
715 copy_v3_v3(values + 0, corner_normals[tri[0]]);
716 copy_v3_v3(values + 3, corner_normals[tri[1]]);
717 copy_v3_v3(values + 6, corner_normals[tri[2]]);
718}
719
720static float rna_MeshLoopTriangle_area_get(PointerRNA *ptr)
721{
722 Mesh *mesh = rna_mesh(ptr);
724 const blender::Span<blender::float3> positions = mesh->vert_positions();
725 const blender::Span<int> corner_verts = mesh->corner_verts();
726 const int v1 = corner_verts[tri[0]];
727 const int v2 = corner_verts[tri[1]];
728 const int v3 = corner_verts[tri[2]];
729 return area_tri_v3(positions[v1], positions[v2], positions[v3]);
730}
731
732static void rna_MeshLoopColor_color_get(PointerRNA *ptr, float *values)
733{
734 MLoopCol *mlcol = (MLoopCol *)ptr->data;
735
736 values[0] = mlcol->r / 255.0f;
737 values[1] = mlcol->g / 255.0f;
738 values[2] = mlcol->b / 255.0f;
739 values[3] = mlcol->a / 255.0f;
740}
741
742static void rna_MeshLoopColor_color_set(PointerRNA *ptr, const float *values)
743{
744 MLoopCol *mlcol = (MLoopCol *)ptr->data;
745
746 mlcol->r = round_fl_to_uchar_clamp(values[0] * 255.0f);
747 mlcol->g = round_fl_to_uchar_clamp(values[1] * 255.0f);
748 mlcol->b = round_fl_to_uchar_clamp(values[2] * 255.0f);
749 mlcol->a = round_fl_to_uchar_clamp(values[3] * 255.0f);
750}
751
752static int rna_Mesh_texspace_editable(const PointerRNA *ptr, const char ** /*r_info*/)
753{
754 Mesh *mesh = (Mesh *)ptr->data;
755 return (mesh->texspace_flag & ME_TEXSPACE_FLAG_AUTO) ? PropertyFlag(0) : PROP_EDITABLE;
756}
757
758static void rna_Mesh_texspace_size_get(PointerRNA *ptr, float values[3])
759{
760 Mesh *mesh = (Mesh *)ptr->data;
761
763
764 copy_v3_v3(values, mesh->texspace_size);
765}
766
767static void rna_Mesh_texspace_location_get(PointerRNA *ptr, float values[3])
768{
769 Mesh *mesh = (Mesh *)ptr->data;
770
772
773 copy_v3_v3(values, mesh->texspace_location);
774}
775
776static void rna_MeshVertex_groups_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
777{
778 Mesh *mesh = rna_mesh(ptr);
779 MDeformVert *dverts = mesh->deform_verts_for_write().data();
780 if (dverts) {
781 const int index = rna_MeshVertex_index_get(ptr);
782 MDeformVert *dvert = &dverts[index];
783
784 rna_iterator_array_begin(iter, dvert->dw, sizeof(MDeformWeight), dvert->totweight, 0, nullptr);
785 }
786 else {
787 rna_iterator_array_begin(iter, nullptr, 0, 0, 0, nullptr);
788 }
789}
790
791static void rna_MeshVertex_undeformed_co_get(PointerRNA *ptr, float values[3])
792{
793 Mesh *mesh = rna_mesh(ptr);
794 const float *position = (const float *)ptr->data;
795 const float(*orco)[3] = static_cast<const float(*)[3]>(
796 CustomData_get_layer(&mesh->vert_data, CD_ORCO));
797
798 if (orco) {
799 const int index = rna_MeshVertex_index_get(ptr);
800 /* orco is normalized to 0..1, we do inverse to match the vertex position */
801 float texspace_location[3], texspace_size[3];
802
804 mesh->texcomesh ? mesh->texcomesh : mesh, texspace_location, texspace_size);
805 madd_v3_v3v3v3(values, texspace_location, orco[index], texspace_size);
806 }
807 else {
808 copy_v3_v3(values, position);
809 }
810}
811
812static int rna_CustomDataLayer_active_get(PointerRNA *ptr, CustomData *data, int type, bool render)
813{
814 int n = ((CustomDataLayer *)ptr->data) - data->layers;
815
816 if (render) {
817 return (n == CustomData_get_render_layer_index(data, eCustomDataType(type)));
818 }
819 else {
820 return (n == CustomData_get_active_layer_index(data, eCustomDataType(type)));
821 }
822}
823
824static int rna_CustomDataLayer_clone_get(PointerRNA *ptr, CustomData *data, int type)
825{
826 int n = ((CustomDataLayer *)ptr->data) - data->layers;
827
828 return (n == CustomData_get_clone_layer_index(data, eCustomDataType(type)));
829}
830
831static void rna_CustomDataLayer_active_set(
832 PointerRNA *ptr, CustomData *data, int value, int type, int render)
833{
834 Mesh *mesh = (Mesh *)ptr->owner_id;
835 int n = (((CustomDataLayer *)ptr->data) - data->layers) -
837
838 if (value == 0) {
839 return;
840 }
841
842 if (render) {
844 }
845 else {
847 }
848
850}
851
852static void rna_CustomDataLayer_clone_set(PointerRNA *ptr, CustomData *data, int value, int type)
853{
854 int n = ((CustomDataLayer *)ptr->data) - data->layers;
855
856 if (value == 0) {
857 return;
858 }
859
861}
862
863static bool rna_MEdge_freestyle_edge_mark_get(PointerRNA *ptr)
864{
865 const Mesh *mesh = rna_mesh(ptr);
866 const int index = rna_MeshEdge_index_get(ptr);
867 const FreestyleEdge *fed = static_cast<const FreestyleEdge *>(
868 CustomData_get_layer(&mesh->edge_data, CD_FREESTYLE_EDGE));
869
870 return fed && (fed[index].flag & FREESTYLE_EDGE_MARK) != 0;
871}
872
873static void rna_MEdge_freestyle_edge_mark_set(PointerRNA *ptr, bool value)
874{
875 Mesh *mesh = rna_mesh(ptr);
876 const int index = rna_MeshEdge_index_get(ptr);
877 FreestyleEdge *fed = static_cast<FreestyleEdge *>(
878 CustomData_get_layer_for_write(&mesh->edge_data, CD_FREESTYLE_EDGE, mesh->edges_num));
879
880 if (!fed) {
881 fed = static_cast<FreestyleEdge *>(CustomData_add_layer(
882 &mesh->edge_data, CD_FREESTYLE_EDGE, CD_SET_DEFAULT, mesh->edges_num));
883 }
884 if (value) {
885 fed[index].flag |= FREESTYLE_EDGE_MARK;
886 }
887 else {
888 fed[index].flag &= ~FREESTYLE_EDGE_MARK;
889 }
890}
891
892static bool rna_MPoly_freestyle_face_mark_get(PointerRNA *ptr)
893{
894 const Mesh *mesh = rna_mesh(ptr);
895 const int index = rna_MeshPolygon_index_get(ptr);
896 const FreestyleFace *ffa = static_cast<const FreestyleFace *>(
897 CustomData_get_layer(&mesh->face_data, CD_FREESTYLE_FACE));
898
899 return ffa && (ffa[index].flag & FREESTYLE_FACE_MARK) != 0;
900}
901
902static void rna_MPoly_freestyle_face_mark_set(PointerRNA *ptr, bool value)
903{
904 Mesh *mesh = rna_mesh(ptr);
905 const int index = rna_MeshPolygon_index_get(ptr);
906 FreestyleFace *ffa = static_cast<FreestyleFace *>(
907 CustomData_get_layer_for_write(&mesh->face_data, CD_FREESTYLE_FACE, mesh->faces_num));
908
909 if (!ffa) {
910 ffa = static_cast<FreestyleFace *>(CustomData_add_layer(
911 &mesh->face_data, CD_FREESTYLE_FACE, CD_SET_DEFAULT, mesh->faces_num));
912 }
913 if (value) {
914 ffa[index].flag |= FREESTYLE_FACE_MARK;
915 }
916 else {
917 ffa[index].flag &= ~FREESTYLE_FACE_MARK;
918 }
919}
920
921/* uv_layers */
922
925 uv_layer, ldata, CD_PROP_FLOAT2, active, MeshUVLoopLayer)
927 uv_layer, ldata, CD_PROP_FLOAT2, clone, MeshUVLoopLayer)
929 uv_layer, ldata, CD_PROP_FLOAT2, stencil, MeshUVLoopLayer)
931 uv_layer, ldata, CD_PROP_FLOAT2, render, MeshUVLoopLayer)
932
933/* MeshUVLoopLayer */
934
935static std::optional<std::string> rna_MeshUVLoopLayer_path(const PointerRNA *ptr)
936{
937 const CustomDataLayer *cdl = static_cast<const CustomDataLayer *>(ptr->data);
938 char name_esc[sizeof(cdl->name) * 2];
939 BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
940 return fmt::format("uv_layers[\"{}\"]", name_esc);
941}
942
943static void rna_MeshUVLoopLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
944{
945 Mesh *mesh = rna_mesh(ptr);
947 const int length = (mesh->runtime->edit_mesh) ? 0 : mesh->corners_num;
949 rna_iterator_array_begin(iter, layer->data, sizeof(float[2]), length, 0, nullptr);
950}
951
952static int rna_MeshUVLoopLayer_data_length(PointerRNA *ptr)
953{
954 Mesh *mesh = rna_mesh(ptr);
955 return (mesh->runtime->edit_mesh) ? 0 : mesh->corners_num;
956}
957
958static MBoolProperty *MeshUVLoopLayer_get_bool_layer(Mesh *mesh, char const *name)
959{
961 &mesh->corner_data, CD_PROP_BOOL, name, mesh->corners_num);
962 if (layer == nullptr) {
964 &mesh->corner_data, CD_PROP_BOOL, CD_SET_DEFAULT, mesh->corners_num, name);
965 }
966
967 BLI_assert(layer);
968
969 return (MBoolProperty *)layer;
970}
971
972static void bool_layer_begin(CollectionPropertyIterator *iter,
974 const char *(*layername_func)(const char *uv_name, char *name))
975{
976 char bool_layer_name[MAX_CUSTOMDATA_LAYER_NAME];
977 Mesh *mesh = rna_mesh(ptr);
979 layername_func(layer->name, bool_layer_name);
980
982 MeshUVLoopLayer_get_bool_layer(mesh, bool_layer_name),
983 sizeof(MBoolProperty),
984 (mesh->runtime->edit_mesh) ? 0 : mesh->corners_num,
985 0,
986 nullptr);
987}
988
989static bool bool_layer_lookup_int(PointerRNA *ptr,
990 int index,
991 PointerRNA *r_ptr,
992 const char *(*layername_func)(const char *uv_name, char *name))
993{
994 char bool_layer_name[MAX_CUSTOMDATA_LAYER_NAME];
995 Mesh *mesh = rna_mesh(ptr);
996 if (mesh->runtime->edit_mesh || index < 0 || index >= mesh->corners_num) {
997 return 0;
998 }
1000 layername_func(layer->name, bool_layer_name);
1001
1002 r_ptr->owner_id = &mesh->id;
1003 r_ptr->type = &RNA_BoolAttributeValue;
1004 r_ptr->data = MeshUVLoopLayer_get_bool_layer(mesh, bool_layer_name) + index;
1005 return 1;
1006}
1007
1008/* Collection accessors for vert_select. */
1009static void rna_MeshUVLoopLayer_vert_select_begin(CollectionPropertyIterator *iter,
1010 PointerRNA *ptr)
1011{
1012 bool_layer_begin(iter, ptr, BKE_uv_map_vert_select_name_get);
1013}
1014
1015static bool rna_MeshUVLoopLayer_vert_select_lookup_int(PointerRNA *ptr,
1016 int index,
1017 PointerRNA *r_ptr)
1018{
1019 return bool_layer_lookup_int(ptr, index, r_ptr, BKE_uv_map_vert_select_name_get);
1020}
1021
1022/* Collection accessors for edge_select. */
1023static void rna_MeshUVLoopLayer_edge_select_begin(CollectionPropertyIterator *iter,
1024 PointerRNA *ptr)
1025{
1026 bool_layer_begin(iter, ptr, BKE_uv_map_edge_select_name_get);
1027}
1028
1029static bool rna_MeshUVLoopLayer_edge_select_lookup_int(PointerRNA *ptr,
1030 int index,
1031 PointerRNA *r_ptr)
1032{
1033 return bool_layer_lookup_int(ptr, index, r_ptr, BKE_uv_map_edge_select_name_get);
1034}
1035
1036/* Collection accessors for pin. */
1037static void rna_MeshUVLoopLayer_pin_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1038{
1039 bool_layer_begin(iter, ptr, BKE_uv_map_pin_name_get);
1040}
1041
1042static bool rna_MeshUVLoopLayer_pin_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
1043{
1044 return bool_layer_lookup_int(ptr, index, r_ptr, BKE_uv_map_pin_name_get);
1045}
1046
1047static void rna_MeshUVLoopLayer_uv_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1048{
1049 Mesh *mesh = rna_mesh(ptr);
1051
1053 layer->data,
1054 sizeof(float[2]),
1055 (mesh->runtime->edit_mesh) ? 0 : mesh->corners_num,
1056 0,
1057 nullptr);
1058}
1059
1060bool rna_MeshUVLoopLayer_uv_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
1061{
1062 Mesh *mesh = rna_mesh(ptr);
1063 if (mesh->runtime->edit_mesh || index < 0 || index >= mesh->corners_num) {
1064 return 0;
1065 }
1067
1068 r_ptr->owner_id = &mesh->id;
1069 r_ptr->type = &RNA_Float2AttributeValue;
1070 r_ptr->data = (float *)layer->data + 2 * index;
1071 return 1;
1072}
1073
1074static bool rna_MeshUVLoopLayer_active_render_get(PointerRNA *ptr)
1075{
1076 return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_PROP_FLOAT2, 1);
1077}
1078
1079static bool rna_MeshUVLoopLayer_active_get(PointerRNA *ptr)
1080{
1081 return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_PROP_FLOAT2, 0);
1082}
1083
1084static bool rna_MeshUVLoopLayer_clone_get(PointerRNA *ptr)
1085{
1086 return rna_CustomDataLayer_clone_get(ptr, rna_mesh_ldata(ptr), CD_PROP_FLOAT2);
1087}
1088
1089static void rna_MeshUVLoopLayer_active_render_set(PointerRNA *ptr, bool value)
1090{
1091 rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_PROP_FLOAT2, 1);
1092}
1093
1094static void rna_MeshUVLoopLayer_active_set(PointerRNA *ptr, bool value)
1095{
1096 rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_PROP_FLOAT2, 0);
1097}
1098
1099static void rna_MeshUVLoopLayer_clone_set(PointerRNA *ptr, bool value)
1100{
1101 rna_CustomDataLayer_clone_set(ptr, rna_mesh_ldata(ptr), value, CD_PROP_FLOAT2);
1102}
1103
1104/* vertex_color_layers */
1105
1107
1108static PointerRNA rna_Mesh_vertex_color_active_get(PointerRNA *ptr)
1109{
1110 Mesh *mesh = (Mesh *)ptr->data;
1113 owner, mesh->active_color_attribute, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_CORNER);
1114 return rna_pointer_inherit_refine(ptr, &RNA_MeshLoopColorLayer, layer);
1115}
1116
1117static void rna_Mesh_vertex_color_active_set(PointerRNA *ptr,
1118 const PointerRNA value,
1119 ReportList * /*reports*/)
1120{
1121 Mesh *mesh = (Mesh *)ptr->data;
1122 CustomDataLayer *layer = (CustomDataLayer *)value.data;
1123
1124 if (!layer) {
1125 return;
1126 }
1127
1128 BKE_id_attributes_active_color_set(&mesh->id, layer->name);
1129}
1130
1131static int rna_Mesh_vertex_color_active_index_get(PointerRNA *ptr)
1132{
1133 Mesh *mesh = (Mesh *)ptr->data;
1136 owner, mesh->active_color_attribute, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_CORNER);
1137 if (!layer) {
1138 return 0;
1139 }
1140 CustomData *ldata = rna_mesh_ldata(ptr);
1141 return layer - ldata->layers + CustomData_get_layer_index(ldata, CD_PROP_BYTE_COLOR);
1142}
1143
1144static void rna_Mesh_vertex_color_active_index_set(PointerRNA *ptr, int value)
1145{
1146 Mesh *mesh = (Mesh *)ptr->data;
1147 CustomData *ldata = rna_mesh_ldata(ptr);
1148
1149 if (value < 0 || value >= CustomData_number_of_layers(ldata, CD_PROP_BYTE_COLOR)) {
1150 fprintf(stderr, "Invalid loop byte attribute index %d\n", value);
1151 return;
1152 }
1153
1155 value;
1156
1157 BKE_id_attributes_active_color_set(&mesh->id, layer->name);
1158}
1159
1160static void rna_MeshLoopColorLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1161{
1162 Mesh *mesh = rna_mesh(ptr);
1165 layer->data,
1166 sizeof(MLoopCol),
1167 (mesh->runtime->edit_mesh) ? 0 : mesh->corners_num,
1168 0,
1169 nullptr);
1170}
1171
1172static int rna_MeshLoopColorLayer_data_length(PointerRNA *ptr)
1173{
1174 Mesh *mesh = rna_mesh(ptr);
1175 return (mesh->runtime->edit_mesh) ? 0 : mesh->corners_num;
1176}
1177
1178static bool rna_mesh_color_active_render_get(PointerRNA *ptr)
1179{
1180 const Mesh *mesh = rna_mesh(ptr);
1181 const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data;
1182 return mesh->default_color_attribute && STREQ(mesh->default_color_attribute, layer->name);
1183}
1184
1185static bool rna_mesh_color_active_get(PointerRNA *ptr)
1186{
1187 const Mesh *mesh = rna_mesh(ptr);
1188 const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data;
1189 return mesh->active_color_attribute && STREQ(mesh->active_color_attribute, layer->name);
1190}
1191
1192static void rna_mesh_color_active_render_set(PointerRNA *ptr, bool value)
1193{
1194 if (value == false) {
1195 return;
1196 }
1197 Mesh *mesh = (Mesh *)ptr->owner_id;
1199 BKE_id_attributes_default_color_set(&mesh->id, layer->name);
1200}
1201
1202static void rna_mesh_color_active_set(PointerRNA *ptr, bool value)
1203{
1204 if (value == false) {
1205 return;
1206 }
1207 Mesh *mesh = (Mesh *)ptr->owner_id;
1209
1210 BKE_id_attributes_active_color_set(&mesh->id, layer->name);
1211}
1212
1213/* Skin vertices */
1215
1216static std::optional<std::string> rna_MeshSkinVertexLayer_path(const PointerRNA *ptr)
1217{
1218 const CustomDataLayer *cdl = static_cast<const CustomDataLayer *>(ptr->data);
1219 char name_esc[sizeof(cdl->name) * 2];
1220 BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
1221 return fmt::format("skin_vertices[\"{}\"]", name_esc);
1222}
1223
1224static std::optional<std::string> rna_VertCustomData_data_path(const PointerRNA *ptr,
1225 const char *collection,
1226 int type);
1227static std::optional<std::string> rna_MeshSkinVertex_path(const PointerRNA *ptr)
1228{
1229 return rna_VertCustomData_data_path(ptr, "skin_vertices", CD_MVERT_SKIN);
1230}
1231
1232static void rna_MeshSkinVertexLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1233{
1234 Mesh *mesh = rna_mesh(ptr);
1237 layer->data,
1238 sizeof(MVertSkin),
1239 (mesh->runtime->edit_mesh) ? 0 : mesh->verts_num,
1240 0,
1241 nullptr);
1242}
1243
1244static int rna_MeshSkinVertexLayer_data_length(PointerRNA *ptr)
1245{
1246 Mesh *mesh = rna_mesh(ptr);
1247 return (mesh->runtime->edit_mesh) ? 0 : mesh->verts_num;
1248}
1249
1250/* End skin vertices */
1251
1252/* poly.vertices - this is faked loop access for convenience */
1253static int rna_MeshPoly_vertices_get_length(const PointerRNA *ptr,
1254 int length[RNA_MAX_ARRAY_DIMENSION])
1255{
1256 const int *poly_offset_p = static_cast<const int *>(ptr->data);
1257 const int poly_start = *poly_offset_p;
1258 const int poly_size = *(poly_offset_p + 1) - poly_start;
1259 /* NOTE: raw access uses dummy item, this _could_ crash,
1260 * watch out for this, #MFace uses it but it can't work here. */
1261 return (length[0] = poly_size);
1262}
1263
1264static void rna_MeshPoly_vertices_get(PointerRNA *ptr, int *values)
1265{
1266 const Mesh *mesh = rna_mesh(ptr);
1267 const int *poly_offset_p = static_cast<const int *>(ptr->data);
1268 const int poly_start = *poly_offset_p;
1269 const int poly_size = *(poly_offset_p + 1) - poly_start;
1270 memcpy(values, &mesh->corner_verts()[poly_start], sizeof(int) * poly_size);
1271}
1272
1273static int rna_MeshPolygon_loop_total_get(PointerRNA *ptr)
1274{
1275 const int *data = static_cast<const int *>(ptr->data);
1276 return *(data + 1) - *data;
1277}
1278
1279static void rna_MeshPoly_vertices_set(PointerRNA *ptr, const int *values)
1280{
1281 Mesh *mesh = rna_mesh(ptr);
1282 const int *poly_offset_p = static_cast<const int *>(ptr->data);
1283 const int poly_start = *poly_offset_p;
1284 const int poly_size = *(poly_offset_p + 1) - poly_start;
1285 memcpy(&mesh->corner_verts_for_write()[poly_start], values, sizeof(int) * poly_size);
1286}
1287
1288/* disabling, some importers don't know the total material count when assigning materials */
1289# if 0
1290static void rna_MeshPoly_material_index_range(
1291 PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
1292{
1293 Mesh *mesh = rna_mesh(ptr);
1294 *min = 0;
1295 *max = max_ii(0, mesh->totcol - 1);
1296}
1297# endif
1298
1299static bool rna_MeshEdge_hide_get(PointerRNA *ptr)
1300{
1301 const Mesh *mesh = rna_mesh(ptr);
1302 const bool *hide_edge = static_cast<const bool *>(
1303 CustomData_get_layer_named(&mesh->edge_data, CD_PROP_BOOL, ".hide_edge"));
1304 const int index = rna_MeshEdge_index_get(ptr);
1305 return hide_edge == nullptr ? false : hide_edge[index];
1306}
1307
1308static void rna_MeshEdge_hide_set(PointerRNA *ptr, bool value)
1309{
1310 Mesh *mesh = rna_mesh(ptr);
1311 bool *hide_edge = static_cast<bool *>(CustomData_get_layer_named_for_write(
1312 &mesh->edge_data, CD_PROP_BOOL, ".hide_edge", mesh->edges_num));
1313 if (!hide_edge) {
1314 if (!value) {
1315 /* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */
1316 return;
1317 }
1318 hide_edge = static_cast<bool *>(CustomData_add_layer_named(
1319 &mesh->edge_data, CD_PROP_BOOL, CD_SET_DEFAULT, mesh->edges_num, ".hide_edge"));
1320 }
1321 const int index = rna_MeshEdge_index_get(ptr);
1322 hide_edge[index] = value;
1323}
1324
1325static bool rna_MeshEdge_select_get(PointerRNA *ptr)
1326{
1327 const Mesh *mesh = rna_mesh(ptr);
1328 const bool *select_edge = static_cast<const bool *>(
1329 CustomData_get_layer_named(&mesh->edge_data, CD_PROP_BOOL, ".select_edge"));
1330 const int index = rna_MeshEdge_index_get(ptr);
1331 return select_edge == nullptr ? false : select_edge[index];
1332}
1333
1334static void rna_MeshEdge_select_set(PointerRNA *ptr, bool value)
1335{
1336 Mesh *mesh = rna_mesh(ptr);
1337 bool *select_edge = static_cast<bool *>(CustomData_get_layer_named_for_write(
1338 &mesh->edge_data, CD_PROP_BOOL, ".select_edge", mesh->edges_num));
1339 if (!select_edge) {
1340 if (!value) {
1341 /* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */
1342 return;
1343 }
1344 select_edge = static_cast<bool *>(CustomData_add_layer_named(
1345 &mesh->edge_data, CD_PROP_BOOL, CD_SET_DEFAULT, mesh->edges_num, ".select_edge"));
1346 }
1347 const int index = rna_MeshEdge_index_get(ptr);
1348 select_edge[index] = value;
1349}
1350
1351static bool rna_MeshEdge_use_edge_sharp_get(PointerRNA *ptr)
1352{
1353 const Mesh *mesh = rna_mesh(ptr);
1354 const bool *sharp_edge = static_cast<const bool *>(
1355 CustomData_get_layer_named(&mesh->edge_data, CD_PROP_BOOL, "sharp_edge"));
1356 const int index = rna_MeshEdge_index_get(ptr);
1357 return sharp_edge == nullptr ? false : sharp_edge[index];
1358}
1359
1360static void rna_MeshEdge_use_edge_sharp_set(PointerRNA *ptr, bool value)
1361{
1362 Mesh *mesh = rna_mesh(ptr);
1363 bool *sharp_edge = static_cast<bool *>(CustomData_get_layer_named_for_write(
1364 &mesh->edge_data, CD_PROP_BOOL, "sharp_edge", mesh->edges_num));
1365 if (!sharp_edge) {
1366 if (!value) {
1367 /* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */
1368 return;
1369 }
1370 sharp_edge = static_cast<bool *>(CustomData_add_layer_named(
1371 &mesh->edge_data, CD_PROP_BOOL, CD_SET_DEFAULT, mesh->edges_num, "sharp_edge"));
1372 }
1373 const int index = rna_MeshEdge_index_get(ptr);
1374 if (value != sharp_edge[index]) {
1375 sharp_edge[index] = value;
1376 mesh->tag_sharpness_changed();
1377 }
1378}
1379
1380static bool rna_MeshEdge_use_seam_get(PointerRNA *ptr)
1381{
1382 const Mesh *mesh = rna_mesh(ptr);
1383 const bool *seam_edge = static_cast<const bool *>(
1384 CustomData_get_layer_named(&mesh->edge_data, CD_PROP_BOOL, ".uv_seam"));
1385 const int index = rna_MeshEdge_index_get(ptr);
1386 return seam_edge == nullptr ? false : seam_edge[index];
1387}
1388
1389static void rna_MeshEdge_use_seam_set(PointerRNA *ptr, bool value)
1390{
1391 Mesh *mesh = rna_mesh(ptr);
1392 bool *seam_edge = static_cast<bool *>(CustomData_get_layer_named_for_write(
1393 &mesh->edge_data, CD_PROP_BOOL, ".uv_seam", mesh->edges_num));
1394 if (!seam_edge) {
1395 if (!value) {
1396 /* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */
1397 return;
1398 }
1399 seam_edge = static_cast<bool *>(CustomData_add_layer_named(
1400 &mesh->edge_data, CD_PROP_BOOL, CD_SET_DEFAULT, mesh->edges_num, ".uv_seam"));
1401 }
1402 const int index = rna_MeshEdge_index_get(ptr);
1403 seam_edge[index] = value;
1404}
1405
1406static bool rna_MeshEdge_is_loose_get(PointerRNA *ptr)
1407{
1408 const Mesh *mesh = rna_mesh(ptr);
1409 const int index = rna_MeshEdge_index_get(ptr);
1410 const blender::bke::LooseEdgeCache &loose_edges = mesh->loose_edges();
1411 return loose_edges.count > 0 && loose_edges.is_loose_bits[index];
1412}
1413
1414static int rna_MeshLoopTriangle_material_index_get(PointerRNA *ptr)
1415{
1416 using namespace blender;
1417 const Mesh *mesh = rna_mesh(ptr);
1418 const bke::AttributeAccessor attributes = mesh->attributes();
1419 const VArray material_indices = *attributes.lookup_or_default<int>(
1420 "material_index", bke::AttrDomain::Face, 0);
1421 return material_indices[rna_MeshLoopTriangle_polygon_index_get(ptr)];
1422}
1423
1424static bool rna_MeshLoopTriangle_use_smooth_get(PointerRNA *ptr)
1425{
1426 const Mesh *mesh = rna_mesh(ptr);
1427 const int face_i = rna_MeshLoopTriangle_polygon_index_get(ptr);
1428 const bool *sharp_faces = static_cast<const bool *>(
1429 CustomData_get_layer_named(&mesh->face_data, CD_PROP_BOOL, "sharp_face"));
1430 return !(sharp_faces && sharp_faces[face_i]);
1431}
1432
1433/* path construction */
1434
1435static std::optional<std::string> rna_VertexGroupElement_path(const PointerRNA *ptr)
1436{
1437 const Mesh *mesh = rna_mesh(ptr); /* XXX not always! */
1438 const MDeformWeight *dw = (MDeformWeight *)ptr->data;
1439 const MDeformVert *dvert = mesh->deform_verts().data();
1440 int a, b;
1441
1442 for (a = 0; a < mesh->verts_num; a++, dvert++) {
1443 for (b = 0; b < dvert->totweight; b++) {
1444 if (dw == &dvert->dw[b]) {
1445 return fmt::format("vertices[{}].groups[{}]", a, b);
1446 }
1447 }
1448 }
1449
1450 return std::nullopt;
1451}
1452
1453static std::optional<std::string> rna_MeshPolygon_path(const PointerRNA *ptr)
1454{
1455 return fmt::format("polygons[{}]", rna_MeshPolygon_index_get(const_cast<PointerRNA *>(ptr)));
1456}
1457
1458static std::optional<std::string> rna_MeshLoopTriangle_path(const PointerRNA *ptr)
1459{
1460 const int index = rna_MeshLoopTriangle_index_get(const_cast<PointerRNA *>(ptr));
1461 return fmt::format("loop_triangles[{}]", index);
1462}
1463
1464static std::optional<std::string> rna_MeshEdge_path(const PointerRNA *ptr)
1465{
1466 return fmt::format("edges[{}]", rna_MeshEdge_index_get(const_cast<PointerRNA *>(ptr)));
1467}
1468
1469static std::optional<std::string> rna_MeshLoop_path(const PointerRNA *ptr)
1470{
1471 return fmt::format("loops[{}]", rna_MeshLoop_index_get(const_cast<PointerRNA *>(ptr)));
1472}
1473
1474static std::optional<std::string> rna_MeshVertex_path(const PointerRNA *ptr)
1475{
1476 return fmt::format("vertices[{}]", rna_MeshVertex_index_get(const_cast<PointerRNA *>(ptr)));
1477}
1478
1479static std::optional<std::string> rna_VertCustomData_data_path(const PointerRNA *ptr,
1480 const char *collection,
1481 int type)
1482{
1483 const CustomDataLayer *cdl;
1484 const Mesh *mesh = rna_mesh(ptr);
1485 const CustomData *vdata = rna_mesh_vdata(ptr);
1486 int a, b, totvert = (mesh->runtime->edit_mesh) ? 0 : mesh->verts_num;
1487
1488 for (cdl = vdata->layers, a = 0; a < vdata->totlayer; cdl++, a++) {
1489 if (cdl->type == type) {
1490 b = ((char *)ptr->data - ((char *)cdl->data)) / CustomData_sizeof(eCustomDataType(type));
1491 if (b >= 0 && b < totvert) {
1492 char name_esc[sizeof(cdl->name) * 2];
1493 BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
1494 return fmt::format("{}[\"{}\"].data[{}]", collection, name_esc, b);
1495 }
1496 }
1497 }
1498
1499 return std::nullopt;
1500}
1501
1502static std::optional<std::string> rna_LoopCustomData_data_path(const PointerRNA *ptr,
1503 const char *collection,
1504 int type)
1505{
1506 const CustomDataLayer *cdl;
1507 const Mesh *mesh = rna_mesh(ptr);
1508 const CustomData *ldata = rna_mesh_ldata(ptr);
1509 int a, b, totloop = (mesh->runtime->edit_mesh) ? 0 : mesh->corners_num;
1510
1511 for (cdl = ldata->layers, a = 0; a < ldata->totlayer; cdl++, a++) {
1512 if (cdl->type == type) {
1513 b = ((char *)ptr->data - ((char *)cdl->data)) / CustomData_sizeof(eCustomDataType(type));
1514 if (b >= 0 && b < totloop) {
1515 char name_esc[sizeof(cdl->name) * 2];
1516 BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
1517 return fmt::format("{}[\"{}\"].data[{}]", collection, name_esc, b);
1518 }
1519 }
1520 }
1521
1522 return std::nullopt;
1523}
1524
1525static void rna_Mesh_vertices_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1526{
1527 Mesh *mesh = rna_mesh(ptr);
1529 mesh->vert_positions_for_write().data(),
1530 sizeof(blender::float3),
1531 mesh->verts_num,
1532 false,
1533 nullptr);
1534}
1535static int rna_Mesh_vertices_length(PointerRNA *ptr)
1536{
1537 const Mesh *mesh = rna_mesh(ptr);
1538 return mesh->verts_num;
1539}
1540bool rna_Mesh_vertices_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
1541{
1542 Mesh *mesh = rna_mesh(ptr);
1543 if (index < 0 || index >= mesh->verts_num) {
1544 return false;
1545 }
1546 r_ptr->owner_id = &mesh->id;
1547 r_ptr->type = &RNA_MeshVertex;
1548 r_ptr->data = &mesh->vert_positions_for_write()[index];
1549 return true;
1550}
1551
1552static void rna_Mesh_edges_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1553{
1554 using namespace blender;
1555 Mesh *mesh = rna_mesh(ptr);
1557 &mesh->edge_data, CD_PROP_INT32_2D, ".edge_verts", mesh->edges_num));
1558 rna_iterator_array_begin(iter, edges, sizeof(blender::int2), mesh->edges_num, false, nullptr);
1559}
1560static int rna_Mesh_edges_length(PointerRNA *ptr)
1561{
1562 const Mesh *mesh = rna_mesh(ptr);
1563 return mesh->edges_num;
1564}
1565bool rna_Mesh_edges_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
1566{
1567 using namespace blender;
1568 Mesh *mesh = rna_mesh(ptr);
1569 if (index < 0 || index >= mesh->edges_num) {
1570 return false;
1571 }
1573 &mesh->edge_data, CD_PROP_INT32_2D, ".edge_verts", mesh->edges_num));
1574 r_ptr->owner_id = &mesh->id;
1575 r_ptr->type = &RNA_MeshEdge;
1576 r_ptr->data = &edges[index];
1577 return true;
1578}
1579
1580static void rna_Mesh_polygons_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1581{
1582 Mesh *mesh = rna_mesh(ptr);
1584 iter, mesh->face_offsets_for_write().data(), sizeof(int), mesh->faces_num, false, nullptr);
1585}
1586static int rna_Mesh_polygons_length(PointerRNA *ptr)
1587{
1588 const Mesh *mesh = rna_mesh(ptr);
1589 return mesh->faces_num;
1590}
1591bool rna_Mesh_polygons_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
1592{
1593 Mesh *mesh = rna_mesh(ptr);
1594 if (index < 0 || index >= mesh->faces_num) {
1595 return false;
1596 }
1597 r_ptr->owner_id = &mesh->id;
1598 r_ptr->type = &RNA_MeshPolygon;
1599 r_ptr->data = &mesh->face_offsets_for_write()[index];
1600 return true;
1601}
1602
1603static void rna_Mesh_loops_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1604{
1605 Mesh *mesh = rna_mesh(ptr);
1607 iter, mesh->corner_verts_for_write().data(), sizeof(int), mesh->corners_num, false, nullptr);
1608}
1609static int rna_Mesh_loops_length(PointerRNA *ptr)
1610{
1611 const Mesh *mesh = rna_mesh(ptr);
1612 return mesh->corners_num;
1613}
1614bool rna_Mesh_loops_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
1615{
1616 Mesh *mesh = rna_mesh(ptr);
1617 if (index < 0 || index >= mesh->corners_num) {
1618 return false;
1619 }
1620 r_ptr->owner_id = &mesh->id;
1621 r_ptr->type = &RNA_MeshLoop;
1622 r_ptr->data = &mesh->corner_verts_for_write()[index];
1623 return true;
1624}
1625
1626static int rna_Mesh_normals_domain_get(PointerRNA *ptr)
1627{
1628 return int(rna_mesh(ptr)->normals_domain());
1629}
1630
1631static void rna_Mesh_vertex_normals_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1632{
1633 const Mesh *mesh = rna_mesh(ptr);
1634 const blender::Span<blender::float3> normals = mesh->vert_normals();
1636 const_cast<blender::float3 *>(normals.data()),
1637 sizeof(blender::float3),
1638 normals.size(),
1639 false,
1640 nullptr);
1641}
1642
1643static int rna_Mesh_vertex_normals_length(PointerRNA *ptr)
1644{
1645 const Mesh *mesh = rna_mesh(ptr);
1646 return mesh->verts_num;
1647}
1648
1649bool rna_Mesh_vertex_normals_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
1650{
1651 const Mesh *mesh = rna_mesh(ptr);
1652 if (index < 0 || index >= mesh->verts_num) {
1653 return false;
1654 }
1655 /* Casting away const is okay because this RNA type doesn't allow changing the value. */
1656 r_ptr->owner_id = (ID *)&mesh->id;
1657 r_ptr->type = &RNA_MeshNormalValue;
1658 r_ptr->data = const_cast<blender::float3 *>(&mesh->vert_normals()[index]);
1659 return true;
1660}
1661
1662static void rna_Mesh_poly_normals_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1663{
1664 const Mesh *mesh = rna_mesh(ptr);
1665 const blender::Span<blender::float3> normals = mesh->face_normals();
1667 const_cast<blender::float3 *>(normals.data()),
1668 sizeof(blender::float3),
1669 normals.size(),
1670 false,
1671 nullptr);
1672}
1673
1674static int rna_Mesh_poly_normals_length(PointerRNA *ptr)
1675{
1676 const Mesh *mesh = rna_mesh(ptr);
1677 return mesh->faces_num;
1678}
1679
1680bool rna_Mesh_poly_normals_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
1681{
1682 const Mesh *mesh = rna_mesh(ptr);
1683 if (index < 0 || index >= mesh->faces_num) {
1684 return false;
1685 }
1686 /* Casting away const is okay because this RNA type doesn't allow changing the value. */
1687 r_ptr->owner_id = (ID *)&mesh->id;
1688 r_ptr->type = &RNA_MeshNormalValue;
1689 r_ptr->data = const_cast<blender::float3 *>(&mesh->face_normals()[index]);
1690 return true;
1691}
1692
1693static void rna_Mesh_corner_normals_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1694{
1695 const Mesh *mesh = rna_mesh(ptr);
1696 const blender::Span<blender::float3> normals = mesh->corner_normals();
1697 if (normals.is_empty()) {
1698 iter->valid = false;
1699 return;
1700 }
1702 iter, (void *)normals.data(), sizeof(float[3]), mesh->corners_num, false, nullptr);
1703}
1704
1705static int rna_Mesh_corner_normals_length(PointerRNA *ptr)
1706{
1707 const Mesh *mesh = rna_mesh(ptr);
1708 return mesh->corners_num;
1709}
1710
1711bool rna_Mesh_corner_normals_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
1712{
1713 const Mesh *mesh = rna_mesh(ptr);
1714 const blender::Span<blender::float3> normals = mesh->corner_normals();
1715 if (index < 0 || index >= mesh->corners_num || normals.is_empty()) {
1716 return false;
1717 }
1718 /* Casting away const is okay because this RNA type doesn't allow changing the value. */
1719 r_ptr->owner_id = (ID *)&mesh->id;
1720 r_ptr->type = &RNA_MeshNormalValue;
1721 r_ptr->data = (float *)&normals[index];
1722 return true;
1723}
1724
1725static std::optional<std::string> rna_MeshUVLoop_path(const PointerRNA *ptr)
1726{
1727 return rna_LoopCustomData_data_path(ptr, "uv_layers", CD_PROP_FLOAT2);
1728}
1729/* The rna_MeshUVLoop_*_get/set() functions get passed a pointer to
1730 * the (float2) uv attribute. This is for historical reasons because
1731 * the api used to wrap MLoopUV, which contained the uv and all the selection
1732 * pin states in a single struct. But since that struct no longer exists and
1733 * we still can use only a single pointer to access these, we need to look up
1734 * the original attribute layer and the index of the uv in it to be able to
1735 * find the associated bool layers. So we scan the available foat2 layers
1736 * to find into which layer the pointer we got passed points. */
1737static bool get_uv_index_and_layer(const PointerRNA *ptr,
1738 int *r_uv_map_index,
1739 int *r_index_in_attribute)
1740{
1741 const Mesh *mesh = rna_mesh(ptr);
1742 const blender::float2 *uv_coord = static_cast<const blender::float2 *>(ptr->data);
1743
1744 /* We don't know from which attribute the RNA pointer is from, so we need to scan them all. */
1745 const int uv_layers_num = CustomData_number_of_layers(&mesh->corner_data, CD_PROP_FLOAT2);
1746 for (int layer_i = 0; layer_i < uv_layers_num; layer_i++) {
1747 const blender::float2 *layer_data = static_cast<const blender::float2 *>(
1748 CustomData_get_layer_n(&mesh->corner_data, CD_PROP_FLOAT2, layer_i));
1749 const ptrdiff_t index = uv_coord - layer_data;
1750 if (index >= 0 && index < mesh->corners_num) {
1751 *r_uv_map_index = layer_i;
1752 *r_index_in_attribute = index;
1753 return true;
1754 }
1755 }
1756 /* This can happen if the Customdata arrays were re-allocated between obtaining the
1757 * Python object and accessing it. */
1758 return false;
1759}
1760
1761static bool rna_MeshUVLoop_select_get(PointerRNA *ptr)
1762{
1763 const Mesh *mesh = rna_mesh(ptr);
1764 int uv_map_index;
1765 int loop_index;
1766 const bool *select = nullptr;
1767 if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) {
1768 select = ED_mesh_uv_map_vert_select_layer_get(mesh, uv_map_index);
1769 }
1770 return select ? select[loop_index] : false;
1771}
1772
1773static void rna_MeshUVLoop_select_set(PointerRNA *ptr, const bool value)
1774{
1775 Mesh *mesh = rna_mesh(ptr);
1776 int uv_map_index;
1777 int loop_index;
1778 if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) {
1779 bool *select = ED_mesh_uv_map_vert_select_layer_ensure(mesh, uv_map_index);
1780 select[loop_index] = value;
1781 }
1782}
1783
1784static bool rna_MeshUVLoop_select_edge_get(PointerRNA *ptr)
1785{
1786 const Mesh *mesh = rna_mesh(ptr);
1787 int uv_map_index;
1788 int loop_index;
1789 const bool *select_edge = nullptr;
1790 if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) {
1791 select_edge = ED_mesh_uv_map_edge_select_layer_get(mesh, uv_map_index);
1792 }
1793 return select_edge ? select_edge[loop_index] : false;
1794}
1795
1796static void rna_MeshUVLoop_select_edge_set(PointerRNA *ptr, const bool value)
1797{
1798 Mesh *mesh = rna_mesh(ptr);
1799 int uv_map_index;
1800 int loop_index;
1801 if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) {
1802 bool *select_edge = ED_mesh_uv_map_edge_select_layer_ensure(mesh, uv_map_index);
1803 select_edge[loop_index] = value;
1804 }
1805}
1806
1807static bool rna_MeshUVLoop_pin_uv_get(PointerRNA *ptr)
1808{
1809 const Mesh *mesh = rna_mesh(ptr);
1810 int uv_map_index;
1811 int loop_index;
1812 const bool *pin_uv = nullptr;
1813 if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) {
1814 pin_uv = ED_mesh_uv_map_pin_layer_get(mesh, uv_map_index);
1815 }
1816 return pin_uv ? pin_uv[loop_index] : false;
1817}
1818
1819static void rna_MeshUVLoop_pin_uv_set(PointerRNA *ptr, const bool value)
1820{
1821 Mesh *mesh = rna_mesh(ptr);
1822 int uv_map_index;
1823 int loop_index;
1824 if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) {
1825 bool *pin_uv = ED_mesh_uv_map_pin_layer_ensure(mesh, uv_map_index);
1826 pin_uv[loop_index] = value;
1827 }
1828}
1829
1830static void rna_MeshUVLoop_uv_get(PointerRNA *ptr, float *value)
1831{
1832 copy_v2_v2(value, static_cast<const float *>(ptr->data));
1833}
1834
1835static void rna_MeshUVLoop_uv_set(PointerRNA *ptr, const float *value)
1836{
1837 copy_v2_v2(static_cast<float *>(ptr->data), value);
1838}
1839
1840static std::optional<std::string> rna_MeshLoopColorLayer_path(const PointerRNA *ptr)
1841{
1842 const CustomDataLayer *cdl = static_cast<const CustomDataLayer *>(ptr->data);
1843 char name_esc[sizeof(cdl->name) * 2];
1844 BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
1845 return fmt::format("vertex_colors[\"{}\"]", name_esc);
1846}
1847
1848static std::optional<std::string> rna_MeshColor_path(const PointerRNA *ptr)
1849{
1850 return rna_LoopCustomData_data_path(ptr, "vertex_colors", CD_PROP_BYTE_COLOR);
1851}
1852
1853/***************************************/
1854
1855static int rna_Mesh_tot_vert_get(PointerRNA *ptr)
1856{
1857 Mesh *mesh = rna_mesh(ptr);
1858 return mesh->runtime->edit_mesh ? mesh->runtime->edit_mesh->bm->totvertsel : 0;
1859}
1860static int rna_Mesh_tot_edge_get(PointerRNA *ptr)
1861{
1862 Mesh *mesh = rna_mesh(ptr);
1863 return mesh->runtime->edit_mesh ? mesh->runtime->edit_mesh->bm->totedgesel : 0;
1864}
1865static int rna_Mesh_tot_face_get(PointerRNA *ptr)
1866{
1867 Mesh *mesh = rna_mesh(ptr);
1868 return mesh->runtime->edit_mesh ? mesh->runtime->edit_mesh->bm->totfacesel : 0;
1869}
1870
1871static PointerRNA rna_Mesh_vertex_color_new(Mesh *mesh,
1872 ReportList *reports,
1873 const char *name,
1874 const bool do_init)
1875{
1876 CustomData *ldata;
1877 CustomDataLayer *cdl = nullptr;
1878 int index = ED_mesh_color_add(mesh, name, false, do_init, reports);
1879
1880 if (index != -1) {
1881 ldata = rna_mesh_ldata_helper(mesh);
1882 cdl = &ldata->layers[CustomData_get_layer_index_n(ldata, CD_PROP_BYTE_COLOR, index)];
1883
1884 if (!mesh->active_color_attribute) {
1885 mesh->active_color_attribute = BLI_strdup(cdl->name);
1886 }
1887 if (!mesh->default_color_attribute) {
1888 mesh->default_color_attribute = BLI_strdup(cdl->name);
1889 }
1890 }
1891
1892 PointerRNA ptr = RNA_pointer_create(&mesh->id, &RNA_MeshLoopColorLayer, cdl);
1893 return ptr;
1894}
1895
1896static void rna_Mesh_vertex_color_remove(Mesh *mesh, ReportList *reports, CustomDataLayer *layer)
1897{
1898 AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
1899 BKE_attribute_remove(owner, layer->name, reports);
1900}
1901
1902static PointerRNA rna_Mesh_uv_layers_new(Mesh *mesh,
1903 ReportList *reports,
1904 const char *name,
1905 const bool do_init)
1906{
1907 CustomData *ldata;
1908 CustomDataLayer *cdl = nullptr;
1909 int index = ED_mesh_uv_add(mesh, name, false, do_init, reports);
1910
1911 if (index != -1) {
1912 ldata = rna_mesh_ldata_helper(mesh);
1913 cdl = &ldata->layers[CustomData_get_layer_index_n(ldata, CD_PROP_FLOAT2, index)];
1914 }
1915
1916 PointerRNA ptr = RNA_pointer_create(&mesh->id, &RNA_MeshUVLoopLayer, cdl);
1917 return ptr;
1918}
1919
1920static void rna_Mesh_uv_layers_remove(Mesh *mesh, ReportList *reports, CustomDataLayer *layer)
1921{
1922 using namespace blender;
1923 AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
1924 if (!BKE_attribute_find(owner, layer->name, CD_PROP_FLOAT2, bke::AttrDomain::Corner)) {
1925 BKE_reportf(reports, RPT_ERROR, "UV map '%s' not found", layer->name);
1926 return;
1927 }
1928 BKE_attribute_remove(owner, layer->name, reports);
1929}
1930
1931static bool rna_Mesh_is_editmode_get(PointerRNA *ptr)
1932{
1933 Mesh *mesh = rna_mesh(ptr);
1934 return (mesh->runtime->edit_mesh != nullptr);
1935}
1936
1937static bool rna_Mesh_materials_override_apply(Main *bmain,
1938 RNAPropertyOverrideApplyContext &rnaapply_ctx)
1939{
1940 PointerRNA *ptr_dst = &rnaapply_ctx.ptr_dst;
1941 PropertyRNA *prop_dst = rnaapply_ctx.prop_dst;
1942 PointerRNA *ptr_item_dst = &rnaapply_ctx.ptr_item_dst;
1943 PointerRNA *ptr_item_src = &rnaapply_ctx.ptr_item_src;
1945
1947 "Unsupported RNA override operation on collections' objects");
1948 UNUSED_VARS_NDEBUG(opop);
1949
1950 Mesh *mesh_dst = (Mesh *)ptr_dst->owner_id;
1951
1952 if (ptr_item_dst->type == nullptr || ptr_item_src->type == nullptr) {
1953 // BLI_assert_msg(0, "invalid source or destination material.");
1954 return false;
1955 }
1956
1957 Material *mat_dst = static_cast<Material *>(ptr_item_dst->data);
1958 Material *mat_src = static_cast<Material *>(ptr_item_src->data);
1959
1960 if (mat_src == mat_dst) {
1961 return true;
1962 }
1963
1964 bool is_modified = false;
1965 for (int i = 0; i < mesh_dst->totcol; i++) {
1966 if (mesh_dst->mat[i] == mat_dst) {
1967 id_us_min(&mat_dst->id);
1968 mesh_dst->mat[i] = mat_src;
1969 id_us_plus(&mat_src->id);
1970 is_modified = true;
1971 }
1972 }
1973
1974 if (is_modified) {
1975 RNA_property_update_main(bmain, nullptr, ptr_dst, prop_dst);
1976 }
1977
1978 return true;
1979}
1980
1983#else
1984
1985/* -------------------------------------------------------------------- */
1990{
1991 StructRNA *srna;
1992 PropertyRNA *prop;
1993
1994 srna = RNA_def_struct(brna, "VertexGroupElement", nullptr);
1995 RNA_def_struct_sdna(srna, "MDeformWeight");
1996 RNA_def_struct_path_func(srna, "rna_VertexGroupElement_path");
1998 srna, "Vertex Group Element", "Weight value of a vertex in a vertex group");
1999 RNA_def_struct_ui_icon(srna, ICON_GROUP_VERTEX);
2000
2001 /* we can't point to actual group, it is in the object and so
2002 * there is no unique group to point to, hence the index */
2003 prop = RNA_def_property(srna, "group", PROP_INT, PROP_UNSIGNED);
2004 RNA_def_property_int_sdna(prop, nullptr, "def_nr");
2006 RNA_def_property_ui_text(prop, "Group Index", "");
2007 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2008
2009 prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_NONE);
2010 RNA_def_property_range(prop, 0.0f, 1.0f);
2011 RNA_def_property_ui_text(prop, "Weight", "Vertex Weight");
2012 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_edit_weight");
2013}
2014
2015static void rna_def_mvert(BlenderRNA *brna)
2016{
2017 StructRNA *srna;
2018 PropertyRNA *prop;
2019
2020 srna = RNA_def_struct(brna, "MeshVertex", nullptr);
2021 RNA_def_struct_ui_text(srna, "Mesh Vertex", "Vertex in a Mesh data-block");
2022 RNA_def_struct_path_func(srna, "rna_MeshVertex_path");
2023 RNA_def_struct_ui_icon(srna, ICON_VERTEXSEL);
2024
2025 prop = RNA_def_property(srna, "co", PROP_FLOAT, PROP_TRANSLATION);
2026 RNA_def_property_array(prop, 3);
2027 RNA_def_property_float_funcs(prop, "rna_MeshVertex_co_get", "rna_MeshVertex_co_set", nullptr);
2028 RNA_def_property_ui_text(prop, "Position", "");
2029 RNA_def_property_update(prop, 0, "rna_Mesh_update_positions_tag");
2030
2031 prop = RNA_def_property(srna, "normal", PROP_FLOAT, PROP_DIRECTION);
2032 RNA_def_property_array(prop, 3);
2034 RNA_def_property_float_funcs(prop, "rna_MeshVertex_normal_get", nullptr, nullptr);
2035 RNA_def_property_ui_text(prop, "Normal", "Vertex Normal");
2036
2037 prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
2038 RNA_def_property_boolean_funcs(prop, "rna_MeshVertex_select_get", "rna_MeshVertex_select_set");
2039 RNA_def_property_ui_text(prop, "Select", "");
2040 RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
2041
2042 prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
2043 RNA_def_property_ui_text(prop, "Hide", "");
2044 RNA_def_property_boolean_funcs(prop, "rna_MeshVertex_hide_get", "rna_MeshVertex_hide_set");
2045 RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
2046
2047 prop = RNA_def_property(srna, "groups", PROP_COLLECTION, PROP_NONE);
2049 "rna_MeshVertex_groups_begin",
2050 "rna_iterator_array_next",
2051 "rna_iterator_array_end",
2052 "rna_iterator_array_get",
2053 nullptr,
2054 nullptr,
2055 nullptr,
2056 nullptr);
2057 RNA_def_property_struct_type(prop, "VertexGroupElement");
2059 prop, "Groups", "Weights for the vertex groups this vertex is member of");
2060
2061 prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED);
2063 RNA_def_property_int_funcs(prop, "rna_MeshVertex_index_get", nullptr, nullptr);
2064 RNA_def_property_ui_text(prop, "Index", "Index of this vertex");
2065
2066 prop = RNA_def_property(srna, "undeformed_co", PROP_FLOAT, PROP_TRANSLATION);
2067 RNA_def_property_array(prop, 3);
2069 prop,
2070 "Undeformed Location",
2071 "For meshes with modifiers applied, the coordinate of the vertex with no deforming "
2072 "modifiers applied, as used for generated texture coordinates");
2073 RNA_def_property_float_funcs(prop, "rna_MeshVertex_undeformed_co_get", nullptr, nullptr);
2075}
2076
2077static void rna_def_medge(BlenderRNA *brna)
2078{
2079 StructRNA *srna;
2080 PropertyRNA *prop;
2081
2082 srna = RNA_def_struct(brna, "MeshEdge", nullptr);
2083 RNA_def_struct_sdna(srna, "vec2i");
2084 RNA_def_struct_ui_text(srna, "Mesh Edge", "Edge in a Mesh data-block");
2085 RNA_def_struct_path_func(srna, "rna_MeshEdge_path");
2086 RNA_def_struct_ui_icon(srna, ICON_EDGESEL);
2087
2088 prop = RNA_def_property(srna, "vertices", PROP_INT, PROP_UNSIGNED);
2089 RNA_def_property_int_sdna(prop, nullptr, "x");
2090 RNA_def_property_array(prop, 2);
2091 RNA_def_property_ui_text(prop, "Vertices", "Vertex indices");
2092 /* XXX allows creating invalid meshes */
2093
2094 prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
2095 RNA_def_property_boolean_funcs(prop, "rna_MeshEdge_select_get", "rna_MeshEdge_select_set");
2096 RNA_def_property_ui_text(prop, "Select", "");
2097 RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
2098
2099 prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
2100 RNA_def_property_ui_text(prop, "Hide", "");
2101 RNA_def_property_boolean_funcs(prop, "rna_MeshEdge_hide_get", "rna_MeshEdge_hide_set");
2102 RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
2103
2104 prop = RNA_def_property(srna, "use_seam", PROP_BOOLEAN, PROP_NONE);
2105 RNA_def_property_boolean_funcs(prop, "rna_MeshEdge_use_seam_get", "rna_MeshEdge_use_seam_set");
2106 RNA_def_property_ui_text(prop, "Seam", "Seam edge for UV unwrapping");
2107 RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
2108
2109 prop = RNA_def_property(srna, "use_edge_sharp", PROP_BOOLEAN, PROP_NONE);
2111 prop, "rna_MeshEdge_use_edge_sharp_get", "rna_MeshEdge_use_edge_sharp_set");
2112 RNA_def_property_ui_text(prop, "Sharp", "Sharp edge for shading");
2113 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2114
2115 prop = RNA_def_property(srna, "is_loose", PROP_BOOLEAN, PROP_NONE);
2117 RNA_def_property_boolean_funcs(prop, "rna_MeshEdge_is_loose_get", nullptr);
2118 RNA_def_property_ui_text(prop, "Loose", "Edge is not connected to any faces");
2119
2120 prop = RNA_def_property(srna, "use_freestyle_mark", PROP_BOOLEAN, PROP_NONE);
2122 prop, "rna_MEdge_freestyle_edge_mark_get", "rna_MEdge_freestyle_edge_mark_set");
2123 RNA_def_property_ui_text(prop, "Freestyle Edge Mark", "Edge mark for Freestyle line rendering");
2124 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2125
2126 prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED);
2128 RNA_def_property_int_funcs(prop, "rna_MeshEdge_index_get", nullptr, nullptr);
2129 RNA_def_property_ui_text(prop, "Index", "Index of this edge");
2130}
2131
2133{
2134 StructRNA *srna;
2135 PropertyRNA *prop;
2136 const int splitnor_dim[] = {3, 3};
2137
2138 srna = RNA_def_struct(brna, "MeshLoopTriangle", nullptr);
2139 RNA_def_struct_sdna(srna, "vec3i");
2140 RNA_def_struct_ui_text(srna, "Mesh Loop Triangle", "Tessellated triangle in a Mesh data-block");
2141 RNA_def_struct_path_func(srna, "rna_MeshLoopTriangle_path");
2142 RNA_def_struct_ui_icon(srna, ICON_FACESEL);
2143
2144 prop = RNA_def_property(srna, "vertices", PROP_INT, PROP_UNSIGNED);
2145 RNA_def_property_array(prop, 3);
2146 RNA_def_property_int_funcs(prop, "rna_MeshLoopTriangle_verts_get", nullptr, nullptr);
2147 RNA_def_property_ui_text(prop, "Vertices", "Indices of triangle vertices");
2149
2150 prop = RNA_def_property(srna, "loops", PROP_INT, PROP_UNSIGNED);
2151 RNA_def_property_int_sdna(prop, nullptr, "x");
2152 RNA_def_property_array(prop, 3);
2153 RNA_def_property_ui_text(prop, "Loops", "Indices of mesh loops that make up the triangle");
2155
2156 prop = RNA_def_property(srna, "polygon_index", PROP_INT, PROP_UNSIGNED);
2157 RNA_def_property_int_funcs(prop, "rna_MeshLoopTriangle_polygon_index_get", nullptr, nullptr);
2158 RNA_def_property_ui_text(prop, "Polygon", "Index of mesh face that the triangle is a part of");
2160
2161 prop = RNA_def_property(srna, "normal", PROP_FLOAT, PROP_DIRECTION);
2162 RNA_def_property_array(prop, 3);
2163 RNA_def_property_range(prop, -1.0f, 1.0f);
2165 RNA_def_property_float_funcs(prop, "rna_MeshLoopTriangle_normal_get", nullptr, nullptr);
2167 prop, "Triangle Normal", "Local space unit length normal vector for this triangle");
2168
2169 prop = RNA_def_property(srna, "split_normals", PROP_FLOAT, PROP_DIRECTION);
2170 RNA_def_property_multi_array(prop, 2, splitnor_dim);
2171 RNA_def_property_range(prop, -1.0f, 1.0f);
2173 RNA_def_property_float_funcs(prop, "rna_MeshLoopTriangle_split_normals_get", nullptr, nullptr);
2175 prop,
2176 "Split Normals",
2177 "Local space unit length split normal vectors of the face corners of this triangle");
2178
2179 prop = RNA_def_property(srna, "area", PROP_FLOAT, PROP_UNSIGNED);
2181 RNA_def_property_float_funcs(prop, "rna_MeshLoopTriangle_area_get", nullptr, nullptr);
2182 RNA_def_property_ui_text(prop, "Triangle Area", "Area of this triangle");
2183
2184 prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED);
2186 RNA_def_property_int_funcs(prop, "rna_MeshLoopTriangle_index_get", nullptr, nullptr);
2187 RNA_def_property_ui_text(prop, "Index", "Index of this loop triangle");
2188
2189 prop = RNA_def_property(srna, "material_index", PROP_INT, PROP_UNSIGNED);
2191 RNA_def_property_int_funcs(prop, "rna_MeshLoopTriangle_material_index_get", nullptr, nullptr);
2192 RNA_def_property_ui_text(prop, "Material Index", "Material slot index of this triangle");
2193
2194 prop = RNA_def_property(srna, "use_smooth", PROP_BOOLEAN, PROP_NONE);
2196 RNA_def_property_boolean_funcs(prop, "rna_MeshLoopTriangle_use_smooth_get", nullptr);
2197 RNA_def_property_ui_text(prop, "Smooth", "");
2198}
2199
2200static void rna_def_mloop(BlenderRNA *brna)
2201{
2202 StructRNA *srna;
2203 PropertyRNA *prop;
2204
2205 srna = RNA_def_struct(brna, "MeshLoop", nullptr);
2206 RNA_def_struct_ui_text(srna, "Mesh Loop", "Loop in a Mesh data-block");
2207 RNA_def_struct_path_func(srna, "rna_MeshLoop_path");
2208 RNA_def_struct_ui_icon(srna, ICON_EDGESEL);
2209
2210 prop = RNA_def_property(srna, "vertex_index", PROP_INT, PROP_UNSIGNED);
2212 prop, "rna_MeshLoop_vertex_index_get", "rna_MeshLoop_vertex_index_set", nullptr);
2213 RNA_def_property_ui_text(prop, "Vertex", "Vertex index");
2214
2215 prop = RNA_def_property(srna, "edge_index", PROP_INT, PROP_UNSIGNED);
2217 prop, "rna_MeshLoop_edge_index_get", "rna_MeshLoop_edge_index_set", nullptr);
2218 RNA_def_property_ui_text(prop, "Edge", "Edge index");
2219
2220 prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED);
2222 RNA_def_property_int_funcs(prop, "rna_MeshLoop_index_get", nullptr, nullptr);
2223 RNA_def_property_ui_text(prop, "Index", "Index of this loop");
2224
2225 prop = RNA_def_property(srna, "normal", PROP_FLOAT, PROP_DIRECTION);
2227 RNA_def_property_array(prop, 3);
2228 RNA_def_property_range(prop, -1.0f, 1.0f);
2229 RNA_def_property_float_funcs(prop, "rna_MeshLoop_normal_get", nullptr, nullptr);
2231 "Normal",
2232 "The normal direction of the face corner, taking into account sharp "
2233 "faces, sharp edges, and custom normal data");
2234
2235 prop = RNA_def_property(srna, "tangent", PROP_FLOAT, PROP_DIRECTION);
2236 RNA_def_property_array(prop, 3);
2237 RNA_def_property_range(prop, -1.0f, 1.0f);
2239 RNA_def_property_float_funcs(prop, "rna_MeshLoop_tangent_get", nullptr, nullptr);
2241 "Tangent",
2242 "Local space unit length tangent vector of this vertex for this face "
2243 "(must be computed beforehand using calc_tangents)");
2244
2245 prop = RNA_def_property(srna, "bitangent_sign", PROP_FLOAT, PROP_NONE);
2246 RNA_def_property_range(prop, -1.0f, 1.0f);
2248 RNA_def_property_float_funcs(prop, "rna_MeshLoop_bitangent_sign_get", nullptr, nullptr);
2250 prop,
2251 "Bitangent Sign",
2252 "Sign of the bitangent vector of this vertex for this face (must be computed "
2253 "beforehand using calc_tangents, bitangent = bitangent_sign * cross(normal, tangent))");
2254
2255 prop = RNA_def_property(srna, "bitangent", PROP_FLOAT, PROP_DIRECTION);
2256 RNA_def_property_array(prop, 3);
2257 RNA_def_property_range(prop, -1.0f, 1.0f);
2259 RNA_def_property_float_funcs(prop, "rna_MeshLoop_bitangent_get", nullptr, nullptr);
2261 prop,
2262 "Bitangent",
2263 "Bitangent vector of this vertex for this face (must be computed beforehand using "
2264 "calc_tangents, use it only if really needed, slower access than bitangent_sign)");
2265}
2266
2268{
2269 StructRNA *srna;
2270 PropertyRNA *prop;
2271 FunctionRNA *func;
2272
2273 srna = RNA_def_struct(brna, "MeshPolygon", nullptr);
2274 RNA_def_struct_sdna(srna, "MIntProperty");
2275 RNA_def_struct_ui_text(srna, "Mesh Polygon", "Polygon in a Mesh data-block");
2276 RNA_def_struct_path_func(srna, "rna_MeshPolygon_path");
2277 RNA_def_struct_ui_icon(srna, ICON_FACESEL);
2278
2279 /* Faked, actually access to loop vertex values, don't this way because manually setting up
2280 * vertex/edge per loop is very low level.
2281 * Instead we setup face sizes, assign indices, then calc edges automatic when creating
2282 * meshes from rna/py. */
2283 prop = RNA_def_property(srna, "vertices", PROP_INT, PROP_UNSIGNED);
2284 /* Eek, this is still used in some cases but in fact we don't want to use it at all here. */
2285 RNA_def_property_array(prop, 3);
2287 RNA_def_property_dynamic_array_funcs(prop, "rna_MeshPoly_vertices_get_length");
2289 prop, "rna_MeshPoly_vertices_get", "rna_MeshPoly_vertices_set", nullptr);
2290 RNA_def_property_ui_text(prop, "Vertices", "Vertex indices");
2291
2292 /* these are both very low level access */
2293 prop = RNA_def_property(srna, "loop_start", PROP_INT, PROP_UNSIGNED);
2294 RNA_def_property_int_sdna(prop, nullptr, "i");
2295 RNA_def_property_ui_text(prop, "Loop Start", "Index of the first loop of this face");
2296 /* also low level */
2297 prop = RNA_def_property(srna, "loop_total", PROP_INT, PROP_UNSIGNED);
2299 RNA_def_property_int_funcs(prop, "rna_MeshPolygon_loop_total_get", nullptr, nullptr);
2300 RNA_def_property_ui_text(prop, "Loop Total", "Number of loops used by this face");
2301
2302 prop = RNA_def_property(srna, "material_index", PROP_INT, PROP_UNSIGNED);
2304 prop, "rna_MeshPolygon_material_index_get", "rna_MeshPolygon_material_index_set", nullptr);
2305 RNA_def_property_ui_text(prop, "Material Index", "Material slot index of this face");
2306# if 0
2307 RNA_def_property_int_funcs(prop, nullptr, nullptr, "rna_MeshPoly_material_index_range");
2308# endif
2309 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2310
2311 prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
2312 RNA_def_property_boolean_funcs(prop, "rna_MeshPolygon_select_get", "rna_MeshPolygon_select_set");
2313 RNA_def_property_ui_text(prop, "Select", "");
2314 RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
2315
2316 prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
2317 RNA_def_property_ui_text(prop, "Hide", "");
2318 RNA_def_property_boolean_funcs(prop, "rna_MeshPolygon_hide_get", "rna_MeshPolygon_hide_set");
2319 RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
2320
2321 prop = RNA_def_property(srna, "use_smooth", PROP_BOOLEAN, PROP_NONE);
2323 prop, "rna_MeshPolygon_use_smooth_get", "rna_MeshPolygon_use_smooth_set");
2324 RNA_def_property_ui_text(prop, "Smooth", "");
2325 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2326
2327 prop = RNA_def_property(srna, "use_freestyle_mark", PROP_BOOLEAN, PROP_NONE);
2329 prop, "rna_MPoly_freestyle_face_mark_get", "rna_MPoly_freestyle_face_mark_set");
2330 RNA_def_property_ui_text(prop, "Freestyle Face Mark", "Face mark for Freestyle line rendering");
2331 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2332
2333 prop = RNA_def_property(srna, "normal", PROP_FLOAT, PROP_DIRECTION);
2334 RNA_def_property_array(prop, 3);
2335 RNA_def_property_range(prop, -1.0f, 1.0f);
2337 RNA_def_property_float_funcs(prop, "rna_MeshPolygon_normal_get", nullptr, nullptr);
2339 prop, "Polygon Normal", "Local space unit length normal vector for this face");
2340
2341 prop = RNA_def_property(srna, "center", PROP_FLOAT, PROP_XYZ);
2342 RNA_def_property_array(prop, 3);
2344 RNA_def_property_float_funcs(prop, "rna_MeshPolygon_center_get", nullptr, nullptr);
2345 RNA_def_property_ui_text(prop, "Polygon Center", "Center of this face");
2346
2347 prop = RNA_def_property(srna, "area", PROP_FLOAT, PROP_UNSIGNED);
2349 RNA_def_property_float_funcs(prop, "rna_MeshPolygon_area_get", nullptr, nullptr);
2350 RNA_def_property_ui_text(prop, "Polygon Area", "Read only area of this face");
2351
2352 prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED);
2354 RNA_def_property_int_funcs(prop, "rna_MeshPolygon_index_get", nullptr, nullptr);
2355 RNA_def_property_ui_text(prop, "Index", "Index of this face");
2356
2357 func = RNA_def_function(srna, "flip", "rna_MeshPolygon_flip");
2359 RNA_def_function_ui_description(func, "Invert winding of this face (flip its normal)");
2360}
2361
2362/* mesh.loop_uvs */
2363static void rna_def_mloopuv(BlenderRNA *brna)
2364{
2365 StructRNA *srna;
2366 PropertyRNA *prop;
2367
2368 srna = RNA_def_struct(brna, "MeshUVLoopLayer", nullptr);
2369 RNA_def_struct_sdna(srna, "CustomDataLayer");
2370 RNA_def_struct_path_func(srna, "rna_MeshUVLoopLayer_path");
2371
2372 prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
2373 RNA_def_property_struct_type(prop, "MeshUVLoop");
2375 prop,
2376 "MeshUVLoop (Deprecated)",
2377 "Deprecated, use 'uv', 'vertex_select', 'edge_select' or 'pin' properties instead");
2380 "rna_MeshUVLoopLayer_data_begin",
2381 "rna_iterator_array_next",
2382 "rna_iterator_array_end",
2383 "rna_iterator_array_get",
2384 "rna_MeshUVLoopLayer_data_length",
2385 nullptr,
2386 nullptr,
2387 nullptr);
2388
2389 prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
2390 RNA_def_struct_name_property(srna, prop);
2391 RNA_def_property_string_funcs(prop, nullptr, nullptr, "rna_MeshLoopLayer_name_set");
2393 RNA_def_property_ui_text(prop, "Name", "Name of UV map");
2394 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2395
2396 prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
2398 prop, "rna_MeshUVLoopLayer_active_get", "rna_MeshUVLoopLayer_active_set");
2399 RNA_def_property_ui_text(prop, "Active", "Set the map as active for display and editing");
2400 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2401
2402 prop = RNA_def_property(srna, "active_render", PROP_BOOLEAN, PROP_NONE);
2403 RNA_def_property_boolean_sdna(prop, nullptr, "active_rnd", 0);
2405 prop, "rna_MeshUVLoopLayer_active_render_get", "rna_MeshUVLoopLayer_active_render_set");
2406 RNA_def_property_ui_text(prop, "Active Render", "Set the UV map as active for rendering");
2407 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2408
2409 prop = RNA_def_property(srna, "active_clone", PROP_BOOLEAN, PROP_NONE);
2410 RNA_def_property_boolean_sdna(prop, nullptr, "active_clone", 0);
2412 prop, "rna_MeshUVLoopLayer_clone_get", "rna_MeshUVLoopLayer_clone_set");
2413 RNA_def_property_ui_text(prop, "Active Clone", "Set the map as active for cloning");
2414 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2415
2416 prop = RNA_def_property(srna, "uv", PROP_COLLECTION, PROP_NONE);
2417 RNA_def_property_struct_type(prop, "Float2AttributeValue");
2418 RNA_def_property_ui_text(prop, "UV", "UV coordinates on face corners");
2421 "rna_MeshUVLoopLayer_uv_begin",
2422 "rna_iterator_array_next",
2423 "rna_iterator_array_end",
2424 "rna_iterator_array_get",
2425 "rna_MeshUVLoopLayer_data_length",
2426 "rna_MeshUVLoopLayer_uv_lookup_int",
2427 nullptr,
2428 nullptr);
2429
2430 prop = RNA_def_property(srna, "vertex_selection", PROP_COLLECTION, PROP_NONE);
2431 RNA_def_property_struct_type(prop, "BoolAttributeValue");
2433 prop, "UV Vertex Selection", "Selection state of the face corner the UV editor");
2436 "rna_MeshUVLoopLayer_vert_select_begin",
2437 "rna_iterator_array_next",
2438 "rna_iterator_array_end",
2439 "rna_iterator_array_get",
2440 "rna_MeshUVLoopLayer_data_length",
2441 "rna_MeshUVLoopLayer_vert_select_lookup_int",
2442 nullptr,
2443 nullptr);
2444
2445 prop = RNA_def_property(srna, "edge_selection", PROP_COLLECTION, PROP_NONE);
2446 RNA_def_property_struct_type(prop, "BoolAttributeValue");
2448 prop, "UV Edge Selection", "Selection state of the edge in the UV editor");
2451 "rna_MeshUVLoopLayer_edge_select_begin",
2452 "rna_iterator_array_next",
2453 "rna_iterator_array_end",
2454 "rna_iterator_array_get",
2455 "rna_MeshUVLoopLayer_data_length",
2456 "rna_MeshUVLoopLayer_edge_select_lookup_int",
2457 nullptr,
2458 nullptr);
2459
2460 prop = RNA_def_property(srna, "pin", PROP_COLLECTION, PROP_NONE);
2461 RNA_def_property_struct_type(prop, "BoolAttributeValue");
2462 RNA_def_property_ui_text(prop, "UV Pin", "UV pinned state in the UV editor");
2465 "rna_MeshUVLoopLayer_pin_begin",
2466 "rna_iterator_array_next",
2467 "rna_iterator_array_end",
2468 "rna_iterator_array_get",
2469 "rna_MeshUVLoopLayer_data_length",
2470 "rna_MeshUVLoopLayer_pin_lookup_int",
2471 nullptr,
2472 nullptr);
2473
2474 srna = RNA_def_struct(brna, "MeshUVLoop", nullptr);
2476 srna, "Mesh UV Layer", "(Deprecated) Layer of UV coordinates in a Mesh data-block");
2477 RNA_def_struct_path_func(srna, "rna_MeshUVLoop_path");
2478
2479 prop = RNA_def_property(srna, "uv", PROP_FLOAT, PROP_XYZ);
2480 RNA_def_property_array(prop, 2);
2481 RNA_def_property_float_funcs(prop, "rna_MeshUVLoop_uv_get", "rna_MeshUVLoop_uv_set", nullptr);
2482 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2483
2484 prop = RNA_def_property(srna, "pin_uv", PROP_BOOLEAN, PROP_NONE);
2485 RNA_def_property_boolean_funcs(prop, "rna_MeshUVLoop_pin_uv_get", "rna_MeshUVLoop_pin_uv_set");
2486 RNA_def_property_ui_text(prop, "UV Pinned", "");
2487
2488 prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
2489 RNA_def_property_boolean_funcs(prop, "rna_MeshUVLoop_select_get", "rna_MeshUVLoop_select_set");
2490 RNA_def_property_ui_text(prop, "UV Select", "");
2491
2492 prop = RNA_def_property(srna, "select_edge", PROP_BOOLEAN, PROP_NONE);
2494 prop, "rna_MeshUVLoop_select_edge_get", "rna_MeshUVLoop_select_edge_set");
2495 RNA_def_property_ui_text(prop, "UV Edge Select", "");
2496}
2497
2499{
2500 StructRNA *srna;
2501 PropertyRNA *prop;
2502
2503 srna = RNA_def_struct(brna, "MeshLoopColorLayer", nullptr);
2505 srna, "Mesh Vertex Color Layer", "Layer of vertex colors in a Mesh data-block");
2506 RNA_def_struct_sdna(srna, "CustomDataLayer");
2507 RNA_def_struct_path_func(srna, "rna_MeshLoopColorLayer_path");
2508 RNA_def_struct_ui_icon(srna, ICON_GROUP_VCOL);
2509
2510 prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
2511 RNA_def_struct_name_property(srna, prop);
2512 RNA_def_property_string_funcs(prop, nullptr, nullptr, "rna_MeshLoopLayer_name_set");
2514 RNA_def_property_ui_text(prop, "Name", "Name of Vertex color layer");
2515 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2516
2517 prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
2518 RNA_def_property_boolean_funcs(prop, "rna_mesh_color_active_get", "rna_mesh_color_active_set");
2519 RNA_def_property_ui_text(prop, "Active", "Sets the layer as active for display and editing");
2520 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2521
2522 prop = RNA_def_property(srna, "active_render", PROP_BOOLEAN, PROP_NONE);
2523 RNA_def_property_boolean_sdna(prop, nullptr, "active_rnd", 0);
2525 prop, "rna_mesh_color_active_render_get", "rna_mesh_color_active_render_set");
2526 RNA_def_property_ui_text(prop, "Active Render", "Sets the layer as active for rendering");
2527 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2528
2529 prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
2530 RNA_def_property_struct_type(prop, "MeshLoopColor");
2531 RNA_def_property_ui_text(prop, "Data", "");
2534 "rna_MeshLoopColorLayer_data_begin",
2535 "rna_iterator_array_next",
2536 "rna_iterator_array_end",
2537 "rna_iterator_array_get",
2538 "rna_MeshLoopColorLayer_data_length",
2539 nullptr,
2540 nullptr,
2541 nullptr);
2542
2543 srna = RNA_def_struct(brna, "MeshLoopColor", nullptr);
2544 RNA_def_struct_sdna(srna, "MLoopCol");
2545 RNA_def_struct_ui_text(srna, "Mesh Vertex Color", "Vertex loop colors in a Mesh");
2546 RNA_def_struct_path_func(srna, "rna_MeshColor_path");
2547
2548 prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
2549 RNA_def_property_array(prop, 4);
2550 RNA_def_property_range(prop, 0.0f, 1.0f);
2552 prop, "rna_MeshLoopColor_color_get", "rna_MeshLoopColor_color_set", nullptr);
2553 RNA_def_property_ui_text(prop, "Color", "Color in sRGB color space");
2554 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2555}
2556
2557void rna_def_texmat_common(StructRNA *srna, const char *texspace_editable)
2558{
2559 PropertyRNA *prop;
2560
2561 /* texture space */
2562 prop = RNA_def_property(srna, "auto_texspace", PROP_BOOLEAN, PROP_NONE);
2563 RNA_def_property_boolean_sdna(prop, nullptr, "texspace_flag", ME_TEXSPACE_FLAG_AUTO);
2565 prop,
2566 "Auto Texture Space",
2567 "Adjust active object's texture space automatically when transforming object");
2568
2569 prop = RNA_def_property(srna, "texspace_location", PROP_FLOAT, PROP_TRANSLATION);
2570 RNA_def_property_float_sdna(prop, nullptr, "texspace_location");
2571 RNA_def_property_ui_text(prop, "Texture Space Location", "Texture space location");
2572 RNA_def_property_float_funcs(prop, "rna_Mesh_texspace_location_get", nullptr, nullptr);
2573 RNA_def_property_editable_func(prop, texspace_editable);
2574 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2575
2576 prop = RNA_def_property(srna, "texspace_size", PROP_FLOAT, PROP_XYZ);
2577 RNA_def_property_float_sdna(prop, nullptr, "texspace_size");
2579 RNA_def_property_ui_text(prop, "Texture Space Size", "Texture space size");
2580 RNA_def_property_float_funcs(prop, "rna_Mesh_texspace_size_get", nullptr, nullptr);
2581 RNA_def_property_editable_func(prop, texspace_editable);
2582 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2583
2584 /* materials */
2585 prop = RNA_def_property(srna, "materials", PROP_COLLECTION, PROP_NONE);
2586 RNA_def_property_collection_sdna(prop, nullptr, "mat", "totcol");
2587 RNA_def_property_struct_type(prop, "Material");
2588 RNA_def_property_ui_text(prop, "Materials", "");
2589 RNA_def_property_srna(prop, "IDMaterials"); /* see rna_ID.cc */
2591 RNA_def_property_override_funcs(prop, nullptr, nullptr, "rna_Mesh_materials_override_apply");
2593 nullptr,
2594 nullptr,
2595 nullptr,
2596 nullptr,
2597 nullptr,
2598 nullptr,
2599 nullptr,
2600 "rna_IDMaterials_assign_int");
2601}
2602
2603/* scene.objects */
2604/* mesh.vertices */
2606{
2607 StructRNA *srna;
2608 // PropertyRNA *prop;
2609
2610 FunctionRNA *func;
2611 PropertyRNA *parm;
2612
2613 RNA_def_property_srna(cprop, "MeshVertices");
2614 srna = RNA_def_struct(brna, "MeshVertices", nullptr);
2615 RNA_def_struct_sdna(srna, "Mesh");
2616 RNA_def_struct_ui_text(srna, "Mesh Vertices", "Collection of mesh vertices");
2617
2618 func = RNA_def_function(srna, "add", "ED_mesh_verts_add");
2620 parm = RNA_def_int(
2621 func, "count", 0, 0, INT_MAX, "Count", "Number of vertices to add", 0, INT_MAX);
2623# if 0 /* BMESH_TODO Remove until BMesh merge */
2624 func = RNA_def_function(srna, "remove", "ED_mesh_verts_remove");
2626 RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of vertices to remove", 0, INT_MAX);
2627# endif
2628}
2629
2630/* mesh.edges */
2632{
2633 StructRNA *srna;
2634 // PropertyRNA *prop;
2635
2636 FunctionRNA *func;
2637 PropertyRNA *parm;
2638
2639 RNA_def_property_srna(cprop, "MeshEdges");
2640 srna = RNA_def_struct(brna, "MeshEdges", nullptr);
2641 RNA_def_struct_sdna(srna, "Mesh");
2642 RNA_def_struct_ui_text(srna, "Mesh Edges", "Collection of mesh edges");
2643
2644 func = RNA_def_function(srna, "add", "ED_mesh_edges_add");
2646 parm = RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of edges to add", 0, INT_MAX);
2648# if 0 /* BMESH_TODO Remove until BMesh merge */
2649 func = RNA_def_function(srna, "remove", "ED_mesh_edges_remove");
2651 RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of edges to remove", 0, INT_MAX);
2652# endif
2653}
2654
2655/* mesh.loop_triangles */
2657{
2658 StructRNA *srna;
2659
2660 RNA_def_property_srna(cprop, "MeshLoopTriangles");
2661 srna = RNA_def_struct(brna, "MeshLoopTriangles", nullptr);
2662 RNA_def_struct_sdna(srna, "Mesh");
2664 srna, "Mesh Loop Triangles", "Tessellation of mesh polygons into triangles");
2665}
2666
2667/* mesh.loops */
2669{
2670 StructRNA *srna;
2671
2672 // PropertyRNA *prop;
2673
2674 FunctionRNA *func;
2675 PropertyRNA *parm;
2676
2677 RNA_def_property_srna(cprop, "MeshLoops");
2678 srna = RNA_def_struct(brna, "MeshLoops", nullptr);
2679 RNA_def_struct_sdna(srna, "Mesh");
2680 RNA_def_struct_ui_text(srna, "Mesh Loops", "Collection of mesh loops");
2681
2682 func = RNA_def_function(srna, "add", "ED_mesh_loops_add");
2684 parm = RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of loops to add", 0, INT_MAX);
2686}
2687
2688/* mesh.polygons */
2690{
2691 StructRNA *srna;
2692
2693 PropertyRNA *prop;
2694
2695 FunctionRNA *func;
2696 PropertyRNA *parm;
2697
2698 RNA_def_property_srna(cprop, "MeshPolygons");
2699 srna = RNA_def_struct(brna, "MeshPolygons", nullptr);
2700 RNA_def_struct_sdna(srna, "Mesh");
2701 RNA_def_struct_ui_text(srna, "Mesh Polygons", "Collection of mesh polygons");
2702
2703 prop = RNA_def_property(srna, "active", PROP_INT, PROP_NONE);
2704 RNA_def_property_int_sdna(prop, nullptr, "act_face");
2705 RNA_def_property_ui_text(prop, "Active Polygon", "The active face for this mesh");
2706
2707 func = RNA_def_function(srna, "add", "ED_mesh_faces_add");
2709 parm = RNA_def_int(
2710 func, "count", 0, 0, INT_MAX, "Count", "Number of polygons to add", 0, INT_MAX);
2712}
2713
2714/* Defines a read-only vector type since normals can not be modified manually. */
2716{
2717 StructRNA *srna = RNA_def_struct(brna, "MeshNormalValue", nullptr);
2718 RNA_def_struct_sdna(srna, "vec3f");
2719 RNA_def_struct_ui_text(srna, "Mesh Normal Vector", "Vector in a mesh normal array");
2720
2721 PropertyRNA *prop = RNA_def_property(srna, "vector", PROP_FLOAT, PROP_DIRECTION);
2722 RNA_def_property_ui_text(prop, "Vector", "3D vector");
2723 RNA_def_property_float_sdna(prop, nullptr, "x");
2724 RNA_def_property_array(prop, 3);
2726}
2727
2729{
2730 StructRNA *srna;
2731 PropertyRNA *prop;
2732
2733 FunctionRNA *func;
2734 PropertyRNA *parm;
2735
2736 RNA_def_property_srna(cprop, "LoopColors");
2737 srna = RNA_def_struct(brna, "LoopColors", nullptr);
2738 RNA_def_struct_sdna(srna, "Mesh");
2739 RNA_def_struct_ui_text(srna, "Loop Colors", "Collection of vertex colors");
2740
2741 func = RNA_def_function(srna, "new", "rna_Mesh_vertex_color_new");
2742 RNA_def_function_ui_description(func, "Add a vertex color layer to Mesh");
2744 RNA_def_string(func, "name", "Col", 0, "", "Vertex color name");
2745 RNA_def_boolean(func,
2746 "do_init",
2747 true,
2748 "",
2749 "Whether new layer's data should be initialized by copying current active one");
2750 parm = RNA_def_pointer(func, "layer", "MeshLoopColorLayer", "", "The newly created layer");
2752 RNA_def_function_return(func, parm);
2753
2754 func = RNA_def_function(srna, "remove", "rna_Mesh_vertex_color_remove");
2755 RNA_def_function_ui_description(func, "Remove a vertex color layer");
2757 parm = RNA_def_pointer(func, "layer", "MeshLoopColorLayer", "", "The layer to remove");
2760
2761 prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
2762 RNA_def_property_struct_type(prop, "MeshLoopColorLayer");
2764 "rna_Mesh_vertex_color_active_get",
2765 "rna_Mesh_vertex_color_active_set",
2766 nullptr,
2767 nullptr);
2769 RNA_def_property_ui_text(prop, "Active Vertex Color Layer", "Active vertex color layer");
2770 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_edit_active_color");
2771
2772 prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
2774 "rna_Mesh_vertex_color_active_index_get",
2775 "rna_Mesh_vertex_color_active_index_set",
2776 "rna_Mesh_vertex_color_index_range");
2777 RNA_def_property_ui_text(prop, "Active Vertex Color Index", "Active vertex color index");
2778 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_edit_active_color");
2779}
2780
2781static void rna_def_uv_layers(BlenderRNA *brna, PropertyRNA *cprop)
2782{
2783 StructRNA *srna;
2784 PropertyRNA *prop;
2785
2786 FunctionRNA *func;
2787 PropertyRNA *parm;
2788
2789 RNA_def_property_srna(cprop, "UVLoopLayers");
2790 srna = RNA_def_struct(brna, "UVLoopLayers", nullptr);
2791 RNA_def_struct_sdna(srna, "Mesh");
2792 RNA_def_struct_ui_text(srna, "UV Map Layers", "Collection of UV map layers");
2793
2794 func = RNA_def_function(srna, "new", "rna_Mesh_uv_layers_new");
2796 RNA_def_function_ui_description(func, "Add a UV map layer to Mesh");
2797 RNA_def_string(func, "name", "UVMap", 0, "", "UV map name");
2798 RNA_def_boolean(func,
2799 "do_init",
2800 true,
2801 "",
2802 "Whether new layer's data should be initialized by copying current active one, "
2803 "or if none is active, with a default UVmap");
2804 parm = RNA_def_pointer(func, "layer", "MeshUVLoopLayer", "", "The newly created layer");
2806 RNA_def_function_return(func, parm);
2807
2808 func = RNA_def_function(srna, "remove", "rna_Mesh_uv_layers_remove");
2809 RNA_def_function_ui_description(func, "Remove a vertex color layer");
2811 parm = RNA_def_pointer(func, "layer", "MeshUVLoopLayer", "", "The layer to remove");
2813
2814 prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
2815 RNA_def_property_struct_type(prop, "MeshUVLoopLayer");
2817 prop, "rna_Mesh_uv_layer_active_get", "rna_Mesh_uv_layer_active_set", nullptr, nullptr);
2819 RNA_def_property_ui_text(prop, "Active UV Map Layer", "Active UV Map layer");
2820 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2821
2822 prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
2824 "rna_Mesh_uv_layer_active_index_get",
2825 "rna_Mesh_uv_layer_active_index_set",
2826 "rna_Mesh_uv_layer_index_range");
2827 RNA_def_property_ui_text(prop, "Active UV Map Index", "Active UV map index");
2828 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2829}
2830
2831static void rna_def_skin_vertices(BlenderRNA *brna, PropertyRNA * /*cprop*/)
2832{
2833 StructRNA *srna;
2834 PropertyRNA *prop;
2835
2836 srna = RNA_def_struct(brna, "MeshSkinVertexLayer", nullptr);
2838 srna, "Mesh Skin Vertex Layer", "Per-vertex skin data for use with the Skin modifier");
2839 RNA_def_struct_sdna(srna, "CustomDataLayer");
2840 RNA_def_struct_path_func(srna, "rna_MeshSkinVertexLayer_path");
2841
2842 prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
2843 RNA_def_struct_name_property(srna, prop);
2844 RNA_def_property_string_funcs(prop, nullptr, nullptr, "rna_MeshVertexLayer_name_set");
2846 RNA_def_property_ui_text(prop, "Name", "Name of skin layer");
2847 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2848
2849 prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
2850 RNA_def_property_struct_type(prop, "MeshSkinVertex");
2851 RNA_def_property_ui_text(prop, "Data", "");
2854 "rna_MeshSkinVertexLayer_data_begin",
2855 "rna_iterator_array_next",
2856 "rna_iterator_array_end",
2857 "rna_iterator_array_get",
2858 "rna_MeshSkinVertexLayer_data_length",
2859 nullptr,
2860 nullptr,
2861 nullptr);
2862
2863 /* SkinVertex struct */
2864 srna = RNA_def_struct(brna, "MeshSkinVertex", nullptr);
2865 RNA_def_struct_sdna(srna, "MVertSkin");
2867 srna, "Skin Vertex", "Per-vertex skin data for use with the Skin modifier");
2868 RNA_def_struct_path_func(srna, "rna_MeshSkinVertex_path");
2869
2870 prop = RNA_def_property(srna, "radius", PROP_FLOAT, PROP_UNSIGNED);
2871 RNA_def_property_array(prop, 2);
2872 RNA_def_property_ui_range(prop, 0.001, 100.0, 1, 3);
2873 RNA_def_property_ui_text(prop, "Radius", "Radius of the skin");
2874 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2875
2876 /* Flags */
2877
2878 prop = RNA_def_property(srna, "use_root", PROP_BOOLEAN, PROP_NONE);
2879 RNA_def_property_boolean_sdna(prop, nullptr, "flag", MVERT_SKIN_ROOT);
2881 "Root",
2882 "Vertex is a root for rotation calculations and armature generation, "
2883 "setting this flag does not clear other roots in the same mesh island");
2884 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2885
2886 prop = RNA_def_property(srna, "use_loose", PROP_BOOLEAN, PROP_NONE);
2887 RNA_def_property_boolean_sdna(prop, nullptr, "flag", MVERT_SKIN_LOOSE);
2889 prop, "Loose", "If vertex has multiple adjacent edges, it is hulled to them directly");
2890 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
2891}
2892
2894{
2895 StructRNA *srna = RNA_def_struct(brna, "ReadOnlyInteger", nullptr);
2896 RNA_def_struct_sdna(srna, "MIntProperty");
2897 RNA_def_struct_ui_text(srna, "Read-only Integer", "");
2898
2899 PropertyRNA *prop = RNA_def_property(srna, "value", PROP_INT, PROP_NONE);
2900 RNA_def_property_ui_text(prop, "Value", "");
2901 RNA_def_property_int_sdna(prop, nullptr, "i");
2903}
2904
2905static void rna_def_mesh(BlenderRNA *brna)
2906{
2907 StructRNA *srna;
2908 PropertyRNA *prop;
2909
2910 srna = RNA_def_struct(brna, "Mesh", "ID");
2911 RNA_def_struct_ui_text(srna, "Mesh", "Mesh data-block defining geometric surfaces");
2912 RNA_def_struct_ui_icon(srna, ICON_MESH_DATA);
2913
2914 prop = RNA_def_property(srna, "vertices", PROP_COLLECTION, PROP_NONE);
2916 "rna_Mesh_vertices_begin",
2917 "rna_iterator_array_next",
2918 "rna_iterator_array_end",
2919 "rna_iterator_array_get",
2920 "rna_Mesh_vertices_length",
2921 "rna_Mesh_vertices_lookup_int",
2922 nullptr,
2923 nullptr);
2924 RNA_def_property_struct_type(prop, "MeshVertex");
2926 RNA_def_property_ui_text(prop, "Vertices", "Vertices of the mesh");
2927 rna_def_mesh_vertices(brna, prop);
2928
2929 prop = RNA_def_property(srna, "edges", PROP_COLLECTION, PROP_NONE);
2931 "rna_Mesh_edges_begin",
2932 "rna_iterator_array_next",
2933 "rna_iterator_array_end",
2934 "rna_iterator_array_get",
2935 "rna_Mesh_edges_length",
2936 "rna_Mesh_edges_lookup_int",
2937 nullptr,
2938 nullptr);
2939 RNA_def_property_struct_type(prop, "MeshEdge");
2941 RNA_def_property_ui_text(prop, "Edges", "Edges of the mesh");
2942 rna_def_mesh_edges(brna, prop);
2943
2944 prop = RNA_def_property(srna, "loops", PROP_COLLECTION, PROP_NONE);
2946 "rna_Mesh_loops_begin",
2947 "rna_iterator_array_next",
2948 "rna_iterator_array_end",
2949 "rna_iterator_array_get",
2950 "rna_Mesh_loops_length",
2951 "rna_Mesh_loops_lookup_int",
2952 nullptr,
2953 nullptr);
2954 RNA_def_property_struct_type(prop, "MeshLoop");
2956 RNA_def_property_ui_text(prop, "Loops", "Loops of the mesh (face corners)");
2957 rna_def_mesh_loops(brna, prop);
2958
2959 prop = RNA_def_property(srna, "polygons", PROP_COLLECTION, PROP_NONE);
2961 "rna_Mesh_polygons_begin",
2962 "rna_iterator_array_next",
2963 "rna_iterator_array_end",
2964 "rna_iterator_array_get",
2965 "rna_Mesh_polygons_length",
2966 "rna_Mesh_polygons_lookup_int",
2967 nullptr,
2968 nullptr);
2969 RNA_def_property_struct_type(prop, "MeshPolygon");
2971 RNA_def_property_ui_text(prop, "Polygons", "Polygons of the mesh");
2972 rna_def_mesh_polygons(brna, prop);
2973
2975
2976 static const EnumPropertyItem normal_domain_items[] = {
2977 {int(blender::bke::MeshNormalDomain::Point), "POINT", 0, "Point", ""},
2978 {int(blender::bke::MeshNormalDomain::Face), "FACE", 0, "Face", ""},
2979 {int(blender::bke::MeshNormalDomain::Corner), "CORNER", 0, "Corner", ""},
2980 {0, nullptr, 0, nullptr, nullptr},
2981 };
2982
2983 prop = RNA_def_property(srna, "normals_domain", PROP_ENUM, PROP_NONE);
2984 RNA_def_property_enum_items(prop, normal_domain_items);
2986 prop,
2987 "Normal Domain",
2988 "The attribute domain that gives enough information to represent the mesh's normals");
2990 RNA_def_property_enum_funcs(prop, "rna_Mesh_normals_domain_get", nullptr, nullptr);
2991
2992 prop = RNA_def_property(srna, "vertex_normals", PROP_COLLECTION, PROP_NONE);
2993 RNA_def_property_struct_type(prop, "MeshNormalValue");
2996 "Vertex Normals",
2997 "The normal direction of each vertex, defined as the average of the "
2998 "surrounding face normals");
3000 "rna_Mesh_vertex_normals_begin",
3001 "rna_iterator_array_next",
3002 "rna_iterator_array_end",
3003 "rna_iterator_array_get",
3004 "rna_Mesh_vertex_normals_length",
3005 "rna_Mesh_vertex_normals_lookup_int",
3006 nullptr,
3007 nullptr);
3008
3009 prop = RNA_def_property(srna, "polygon_normals", PROP_COLLECTION, PROP_NONE);
3010 RNA_def_property_struct_type(prop, "MeshNormalValue");
3013 "Polygon Normals",
3014 "The normal direction of each face, defined by the winding order "
3015 "and position of its vertices");
3017 "rna_Mesh_poly_normals_begin",
3018 "rna_iterator_array_next",
3019 "rna_iterator_array_end",
3020 "rna_iterator_array_get",
3021 "rna_Mesh_poly_normals_length",
3022 "rna_Mesh_poly_normals_lookup_int",
3023 nullptr,
3024 nullptr);
3025
3026 prop = RNA_def_property(srna, "corner_normals", PROP_COLLECTION, PROP_NONE);
3027 RNA_def_property_struct_type(prop, "MeshNormalValue");
3030 prop,
3031 "Corner Normals",
3032 "The \"slit\" normal direction of each face corner, influenced by vertex normals, "
3033 "sharp faces, sharp edges, and custom normals. May be empty.");
3035 "rna_Mesh_corner_normals_begin",
3036 "rna_iterator_array_next",
3037 "rna_iterator_array_end",
3038 "rna_iterator_array_get",
3039 "rna_Mesh_corner_normals_length",
3040 "rna_Mesh_corner_normals_lookup_int",
3041 nullptr,
3042 nullptr);
3043
3044 prop = RNA_def_property(srna, "loop_triangles", PROP_COLLECTION, PROP_NONE);
3046 "rna_Mesh_loop_triangles_begin",
3047 "rna_iterator_array_next",
3048 "rna_iterator_array_end",
3049 "rna_iterator_array_get",
3050 "rna_Mesh_loop_triangles_length",
3051 "rna_Mesh_loop_triangles_lookup_int",
3052 nullptr,
3053 nullptr);
3054 RNA_def_property_struct_type(prop, "MeshLoopTriangle");
3056 RNA_def_property_ui_text(prop, "Loop Triangles", "Tessellation of mesh polygons into triangles");
3057 rna_def_mesh_looptris(brna, prop);
3058
3060
3061 prop = RNA_def_property(srna, "loop_triangle_polygons", PROP_COLLECTION, PROP_NONE);
3063 "rna_Mesh_loop_triangle_polygons_begin",
3064 "rna_iterator_array_next",
3065 "rna_iterator_array_end",
3066 "rna_iterator_array_get",
3067 "rna_Mesh_loop_triangles_length",
3068 "rna_Mesh_loop_triangle_polygons_lookup_int",
3069 nullptr,
3070 nullptr);
3071 RNA_def_property_struct_type(prop, "ReadOnlyInteger");
3074 RNA_def_property_ui_text(prop, "Triangle Faces", "The face index for each loop triangle");
3075
3076 /* TODO: should this be allowed to be itself? */
3077 prop = RNA_def_property(srna, "texture_mesh", PROP_POINTER, PROP_NONE);
3078 RNA_def_property_pointer_sdna(prop, nullptr, "texcomesh");
3082 prop,
3083 "Texture Mesh",
3084 "Use another mesh for texture indices (vertex indices must be aligned)");
3085
3086 /* UV loop layers */
3087 prop = RNA_def_property(srna, "uv_layers", PROP_COLLECTION, PROP_NONE);
3088 RNA_def_property_collection_sdna(prop, nullptr, "corner_data.layers", "corner_data.totlayer");
3090 "rna_Mesh_uv_layers_begin",
3091 nullptr,
3092 nullptr,
3093 nullptr,
3094 "rna_Mesh_uv_layers_length",
3095 nullptr,
3096 nullptr,
3097 nullptr);
3098 RNA_def_property_struct_type(prop, "MeshUVLoopLayer");
3100 RNA_def_property_ui_text(prop, "UV Loop Layers", "All UV loop layers");
3101 rna_def_uv_layers(brna, prop);
3102
3103 prop = RNA_def_property(srna, "uv_layer_clone", PROP_POINTER, PROP_NONE);
3104 RNA_def_property_struct_type(prop, "MeshUVLoopLayer");
3106 prop, "rna_Mesh_uv_layer_clone_get", "rna_Mesh_uv_layer_clone_set", nullptr, nullptr);
3110 prop, "Clone UV Loop Layer", "UV loop layer to be used as cloning source");
3111
3112 prop = RNA_def_property(srna, "uv_layer_clone_index", PROP_INT, PROP_UNSIGNED);
3114 "rna_Mesh_uv_layer_clone_index_get",
3115 "rna_Mesh_uv_layer_clone_index_set",
3116 "rna_Mesh_uv_layer_index_range");
3117 RNA_def_property_ui_text(prop, "Clone UV Loop Layer Index", "Clone UV loop layer index");
3118
3119 prop = RNA_def_property(srna, "uv_layer_stencil", PROP_POINTER, PROP_NONE);
3120 RNA_def_property_struct_type(prop, "MeshUVLoopLayer");
3122 prop, "rna_Mesh_uv_layer_stencil_get", "rna_Mesh_uv_layer_stencil_set", nullptr, nullptr);
3125 RNA_def_property_ui_text(prop, "Mask UV Loop Layer", "UV loop layer to mask the painted area");
3126
3127 prop = RNA_def_property(srna, "uv_layer_stencil_index", PROP_INT, PROP_UNSIGNED);
3129 "rna_Mesh_uv_layer_stencil_index_get",
3130 "rna_Mesh_uv_layer_stencil_index_set",
3131 "rna_Mesh_uv_layer_index_range");
3132 RNA_def_property_ui_text(prop, "Mask UV Loop Layer Index", "Mask UV loop layer index");
3133 RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
3134
3135 /* Vertex colors */
3136
3137 prop = RNA_def_property(srna, "vertex_colors", PROP_COLLECTION, PROP_NONE);
3138 RNA_def_property_collection_sdna(prop, nullptr, "corner_data.layers", "corner_data.totlayer");
3140 "rna_Mesh_vertex_colors_begin",
3141 nullptr,
3142 nullptr,
3143 nullptr,
3144 "rna_Mesh_vertex_colors_length",
3145 nullptr,
3146 nullptr,
3147 nullptr);
3148 RNA_def_property_struct_type(prop, "MeshLoopColorLayer");
3151 prop,
3152 "Vertex Colors",
3153 "Legacy vertex color layers. Deprecated, use color attributes instead.");
3154 rna_def_loop_colors(brna, prop);
3155
3156 /* Skin vertices */
3157 prop = RNA_def_property(srna, "skin_vertices", PROP_COLLECTION, PROP_NONE);
3158 RNA_def_property_collection_sdna(prop, nullptr, "vert_data.layers", "vert_data.totlayer");
3160 "rna_Mesh_skin_vertices_begin",
3161 nullptr,
3162 nullptr,
3163 nullptr,
3164 "rna_Mesh_skin_vertices_length",
3165 nullptr,
3166 nullptr,
3167 nullptr);
3168 RNA_def_property_struct_type(prop, "MeshSkinVertexLayer");
3170 RNA_def_property_ui_text(prop, "Skin Vertices", "All skin vertices");
3171 rna_def_skin_vertices(brna, prop);
3172 /* End skin vertices */
3173
3174 /* Attributes */
3176
3177 /* Remesh */
3178 prop = RNA_def_property(srna, "remesh_voxel_size", PROP_FLOAT, PROP_DISTANCE);
3179 RNA_def_property_float_sdna(prop, nullptr, "remesh_voxel_size");
3180 RNA_def_property_range(prop, 0.0001f, FLT_MAX);
3181 RNA_def_property_ui_range(prop, 0.0001f, FLT_MAX, 0.01, 4);
3183 "Voxel Size",
3184 "Size of the voxel in object space used for volume evaluation. Lower "
3185 "values preserve finer details.");
3186 RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
3188
3189 prop = RNA_def_property(srna, "remesh_voxel_adaptivity", PROP_FLOAT, PROP_DISTANCE);
3190 RNA_def_property_float_sdna(prop, nullptr, "remesh_voxel_adaptivity");
3191 RNA_def_property_range(prop, 0.0f, 1.0f);
3192 RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.01, 4);
3194 prop,
3195 "Adaptivity",
3196 "Reduces the final face count by simplifying geometry where detail is not needed, "
3197 "generating triangles. A value greater than 0 disables Fix Poles.");
3198 RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
3200
3201 prop = RNA_def_property(srna, "use_remesh_fix_poles", PROP_BOOLEAN, PROP_NONE);
3202 RNA_def_property_boolean_sdna(prop, nullptr, "flag", ME_REMESH_FIX_POLES);
3203 RNA_def_property_ui_text(prop, "Fix Poles", "Produces fewer poles and a better topology flow");
3204 RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
3206
3207 prop = RNA_def_property(srna, "use_remesh_preserve_volume", PROP_BOOLEAN, PROP_NONE);
3210 prop,
3211 "Preserve Volume",
3212 "Projects the mesh to preserve the volume and details of the original mesh");
3213 RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
3215
3216 prop = RNA_def_property(srna, "use_remesh_preserve_attributes", PROP_BOOLEAN, PROP_NONE);
3218 RNA_def_property_ui_text(prop, "Preserve Attributes", "Transfer all attributes to the new mesh");
3219 RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
3221
3222 prop = RNA_def_property(srna, "remesh_mode", PROP_ENUM, PROP_NONE);
3223 RNA_def_property_enum_sdna(prop, nullptr, "remesh_mode");
3225 RNA_def_property_ui_text(prop, "Remesh Mode", "");
3226 RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
3228
3229 /* End remesh */
3230
3231 /* Symmetry */
3232 prop = RNA_def_property(srna, "use_mirror_x", PROP_BOOLEAN, PROP_NONE);
3233 RNA_def_property_boolean_sdna(prop, nullptr, "symmetry", ME_SYMMETRY_X);
3234 RNA_def_property_ui_text(prop, "X", "Enable symmetry in the X axis");
3235 RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
3236
3237 prop = RNA_def_property(srna, "use_mirror_y", PROP_BOOLEAN, PROP_NONE);
3238 RNA_def_property_boolean_sdna(prop, nullptr, "symmetry", ME_SYMMETRY_Y);
3239 RNA_def_property_ui_text(prop, "Y", "Enable symmetry in the Y axis");
3240 RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
3241
3242 prop = RNA_def_property(srna, "use_mirror_z", PROP_BOOLEAN, PROP_NONE);
3243 RNA_def_property_boolean_sdna(prop, nullptr, "symmetry", ME_SYMMETRY_Z);
3244 RNA_def_property_ui_text(prop, "Z", "Enable symmetry in the Z axis");
3245 RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
3246
3247 prop = RNA_def_property(srna, "use_mirror_vertex_groups", PROP_BOOLEAN, PROP_NONE);
3250 "Mirror Vertex Groups",
3251 "Mirror the left/right vertex groups when painting. The symmetry axis "
3252 "is determined by the symmetry settings.");
3253 RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
3254 /* End Symmetry */
3255
3257 prop = RNA_def_property(srna, "has_custom_normals", PROP_BOOLEAN, PROP_NONE);
3258 RNA_def_property_boolean_sdna(prop, nullptr, "", 0);
3261 prop, "Has Custom Normals", "True if there are custom split normals data in this mesh");
3262 RNA_def_property_boolean_funcs(prop, "rna_Mesh_has_custom_normals_get", nullptr);
3264
3265 prop = RNA_def_property(srna, "texco_mesh", PROP_POINTER, PROP_NONE);
3266 RNA_def_property_pointer_sdna(prop, nullptr, "texcomesh");
3270 prop, "Texture Space Mesh", "Derive texture coordinates from another mesh");
3271
3272 prop = RNA_def_property(srna, "shape_keys", PROP_POINTER, PROP_NONE);
3273 RNA_def_property_pointer_sdna(prop, nullptr, "key");
3276 RNA_def_property_ui_text(prop, "Shape Keys", "");
3277
3278 /* texture space */
3279 prop = RNA_def_property(srna, "use_auto_texspace", PROP_BOOLEAN, PROP_NONE);
3280 RNA_def_property_boolean_sdna(prop, nullptr, "texspace_flag", ME_TEXSPACE_FLAG_AUTO);
3282 prop,
3283 "Auto Texture Space",
3284 "Adjust active object's texture space automatically when transforming object");
3285 RNA_def_property_update(prop, 0, "rna_Mesh_update_geom_and_params");
3286
3287# if 0
3288 prop = RNA_def_property(srna, "texspace_location", PROP_FLOAT, PROP_TRANSLATION);
3289 RNA_def_property_array(prop, 3);
3290 RNA_def_property_ui_text(prop, "Texture Space Location", "Texture space location");
3291 RNA_def_property_editable_func(prop, "rna_Mesh_texspace_editable");
3293 prop, "rna_Mesh_texspace_location_get", "rna_Mesh_texspace_location_set", nullptr);
3294 RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
3295# endif
3296
3297 /* editflag */
3298 prop = RNA_def_property(srna, "use_mirror_topology", PROP_BOOLEAN, PROP_NONE);
3299 RNA_def_property_boolean_sdna(prop, nullptr, "editflag", ME_EDIT_MIRROR_TOPO);
3301 "Topology Mirror",
3302 "Use topology based mirroring "
3303 "(for when both sides of mesh have matching, unique topology)");
3304
3305 prop = RNA_def_property(srna, "use_paint_bone_selection", PROP_BOOLEAN, PROP_NONE);
3307 prop, nullptr, "editflag", ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL);
3308 RNA_def_property_ui_text(prop, "Bone Selection", "Bone selection during painting");
3309 RNA_def_property_ui_icon(prop, ICON_BONE_DATA, 0);
3310 RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_Mesh_update_bone_selection_mode");
3311
3312 prop = RNA_def_property(srna, "use_paint_mask", PROP_BOOLEAN, PROP_NONE);
3313 RNA_def_property_boolean_sdna(prop, nullptr, "editflag", ME_EDIT_PAINT_FACE_SEL);
3314 RNA_def_property_ui_text(prop, "Paint Mask", "Face selection masking for painting");
3315 RNA_def_property_ui_icon(prop, ICON_FACESEL, 0);
3316 RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_Mesh_update_facemask");
3317
3318 prop = RNA_def_property(srna, "use_paint_mask_vertex", PROP_BOOLEAN, PROP_NONE);
3319 RNA_def_property_boolean_sdna(prop, nullptr, "editflag", ME_EDIT_PAINT_VERT_SEL);
3320 RNA_def_property_ui_text(prop, "Vertex Selection", "Vertex selection masking for painting");
3321 RNA_def_property_ui_icon(prop, ICON_VERTEXSEL, 0);
3322 RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_Mesh_update_vertmask");
3323
3324 /* readonly editmesh info - use for extrude menu */
3325 prop = RNA_def_property(srna, "total_vert_sel", PROP_INT, PROP_UNSIGNED);
3326 RNA_def_property_int_funcs(prop, "rna_Mesh_tot_vert_get", nullptr, nullptr);
3327 RNA_def_property_ui_text(prop, "Selected Vertex Total", "Selected vertex count in editmode");
3329
3330 prop = RNA_def_property(srna, "total_edge_sel", PROP_INT, PROP_UNSIGNED);
3331 RNA_def_property_int_funcs(prop, "rna_Mesh_tot_edge_get", nullptr, nullptr);
3332 RNA_def_property_ui_text(prop, "Selected Edge Total", "Selected edge count in editmode");
3334
3335 prop = RNA_def_property(srna, "total_face_sel", PROP_INT, PROP_UNSIGNED);
3336 RNA_def_property_int_funcs(prop, "rna_Mesh_tot_face_get", nullptr, nullptr);
3337 RNA_def_property_ui_text(prop, "Selected Face Total", "Selected face count in editmode");
3339
3340 prop = RNA_def_property(srna, "is_editmode", PROP_BOOLEAN, PROP_NONE);
3341 RNA_def_property_boolean_funcs(prop, "rna_Mesh_is_editmode_get", nullptr);
3343 RNA_def_property_ui_text(prop, "Is Editmode", "True when used in editmode");
3344
3345 /* pointers */
3347 rna_def_texmat_common(srna, "rna_Mesh_texspace_editable");
3348
3349 RNA_api_mesh(srna);
3350}
3351
3353{
3354 rna_def_mesh(brna);
3355 rna_def_mvert(brna);
3356 rna_def_mvert_group(brna);
3357 rna_def_medge(brna);
3358 rna_def_mlooptri(brna);
3359 rna_def_mloop(brna);
3360 rna_def_mpolygon(brna);
3361 rna_def_mloopuv(brna);
3362 rna_def_mloopcol(brna);
3363}
3364
3365#endif
3366
struct CustomDataLayer * BKE_attribute_search_for_write(AttributeOwner &owner, const char *name, eCustomDataMask type, AttrDomainMask domain_mask)
Definition attribute.cc:669
void BKE_id_attributes_default_color_set(struct ID *id, const char *name)
Definition attribute.cc:994
void BKE_id_attributes_active_color_set(struct ID *id, const char *name)
Definition attribute.cc:965
@ ATTR_DOMAIN_MASK_CORNER
struct CustomDataLayer * BKE_attribute_find(const AttributeOwner &owner, const char *name, eCustomDataType type, blender::bke::AttrDomain domain)
bool BKE_attribute_rename(AttributeOwner &owner, const char *old_name, const char *new_name, struct ReportList *reports)
Definition attribute.cc:253
bool BKE_attribute_remove(AttributeOwner &owner, const char *name, struct ReportList *reports)
Definition attribute.cc:501
const char * BKE_uv_map_pin_name_get(const char *uv_map_name, char *buffer)
const char * BKE_uv_map_vert_select_name_get(const char *uv_map_name, char *buffer)
const char * BKE_uv_map_edge_select_name_get(const char *uv_map_name, char *buffer)
const struct CustomDataLayer * BKE_attribute_search(const AttributeOwner &owner, const char *name, eCustomDataMask type, AttrDomainMask domain_mask)
Definition attribute.cc:636
CustomData interface, see also DNA_customdata_types.h.
int CustomData_sizeof(eCustomDataType type)
void * CustomData_get_layer_named_for_write(CustomData *data, eCustomDataType type, blender::StringRef name, int totelem)
int CustomData_get_layer_index_n(const CustomData *data, eCustomDataType type, int n)
const void * CustomData_get_layer_n(const CustomData *data, eCustomDataType type, int n)
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
@ CD_SET_DEFAULT
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void * CustomData_add_layer_named(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem, blender::StringRef name)
void CustomData_set_layer_render(CustomData *data, eCustomDataType type, int n)
int CustomData_get_layer_index(const CustomData *data, eCustomDataType type)
void CustomData_set_layer_clone_index(CustomData *data, eCustomDataType type, int n)
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
void CustomData_set_layer_unique_name(CustomData *data, int index)
void CustomData_ensure_data_is_mutable(CustomDataLayer *layer, int totelem)
void * CustomData_add_layer(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem)
int CustomData_get_active_layer_index(const CustomData *data, eCustomDataType type)
int CustomData_number_of_layers(const CustomData *data, eCustomDataType type)
#define CD_TYPE_AS_MASK(_type)
int CustomData_get_render_layer_index(const CustomData *data, eCustomDataType type)
void CustomData_set_layer_active(CustomData *data, eCustomDataType type, int n)
int CustomData_get_clone_layer_index(const CustomData *data, eCustomDataType type)
void id_us_plus(ID *id)
Definition lib_id.cc:351
void id_us_min(ID *id)
Definition lib_id.cc:359
void BKE_mesh_batch_cache_dirty_tag(Mesh *mesh, eMeshBatchDirtyMode mode)
void BKE_mesh_tessface_clear(Mesh *mesh)
bool BKE_mesh_has_custom_loop_normals(Mesh *mesh)
void BKE_mesh_texspace_ensure(Mesh *mesh)
void BKE_mesh_texspace_get(Mesh *mesh, float r_texspace_location[3], float r_texspace_size[3])
@ BKE_MESH_BATCH_DIRTY_ALL
Definition BKE_mesh.h:38
void BKE_mesh_runtime_clear_geometry(Mesh *mesh)
int BKE_mesh_runtime_corner_tris_len(const Mesh *mesh)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
MINLINE int max_ii(int a, int b)
MINLINE unsigned char round_fl_to_uchar_clamp(float a)
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
Definition math_geom.cc:98
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
Definition math_geom.cc:39
MINLINE void madd_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void zero_v3(float r[3])
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.c:40
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define STRNCPY_UTF8(dst, src)
#define UNUSED_VARS_NDEBUG(...)
#define STREQ(a, b)
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_PARAMETERS
Definition DNA_ID.h:1105
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
@ LIBOVERRIDE_OP_REPLACE
Definition DNA_ID.h:229
#define MAX_CUSTOMDATA_LAYER_NAME
#define CD_MASK_PROP_BYTE_COLOR
#define CD_MASK_PROP_ALL
@ CD_PROP_BYTE_COLOR
@ CD_MLOOPTANGENT
@ CD_MVERT_SKIN
@ CD_PROP_INT32_2D
@ CD_PROP_FLOAT2
@ CD_FREESTYLE_EDGE
@ CD_FREESTYLE_FACE
#define MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX
@ ME_REMESH_REPROJECT_ATTRIBUTES
@ ME_REMESH_REPROJECT_VOLUME
@ ME_REMESH_FIX_POLES
@ ME_SYMMETRY_X
@ ME_SYMMETRY_Y
@ ME_SYMMETRY_Z
@ ME_EDIT_MIRROR_VERTEX_GROUPS
@ ME_EDIT_PAINT_VERT_SEL
@ ME_EDIT_PAINT_FACE_SEL
@ ME_EDIT_MIRROR_TOPO
@ ME_TEXSPACE_FLAG_AUTO
@ REMESH_QUAD
@ REMESH_VOXEL
@ FREESTYLE_FACE_MARK
@ MVERT_SKIN_LOOSE
@ MVERT_SKIN_ROOT
@ FREESTYLE_EDGE_MARK
Object is a sort of wrapper for general info.
bool * ED_mesh_uv_map_edge_select_layer_ensure(Mesh *mesh, int uv_index)
Definition mesh_data.cc:348
int ED_mesh_uv_add(Mesh *mesh, const char *name, bool active_set, bool do_init, ReportList *reports)
Definition mesh_data.cc:221
int ED_mesh_color_add(Mesh *mesh, const char *name, bool active_set, bool do_init, ReportList *reports)
Definition mesh_data.cc:381
const bool * ED_mesh_uv_map_vert_select_layer_get(const Mesh *mesh, int uv_index)
Definition mesh_data.cc:301
bool * ED_mesh_uv_map_vert_select_layer_ensure(Mesh *mesh, int uv_index)
Definition mesh_data.cc:341
const bool * ED_mesh_uv_map_pin_layer_get(const Mesh *mesh, int uv_index)
Definition mesh_data.cc:321
bool * ED_mesh_uv_map_pin_layer_ensure(Mesh *mesh, int uv_index)
Definition mesh_data.cc:355
const bool * ED_mesh_uv_map_edge_select_layer_get(const Mesh *mesh, int uv_index)
Definition mesh_data.cc:309
Read Guarded memory(de)allocation.
#define RNA_MAX_ARRAY_DIMENSION
Definition RNA_define.hh:26
@ PARM_RNAPTR
Definition RNA_types.hh:399
@ PARM_REQUIRED
Definition RNA_types.hh:397
@ FUNC_USE_REPORTS
Definition RNA_types.hh:680
@ FUNC_USE_SELF_ID
Definition RNA_types.hh:667
@ PROP_FLOAT
Definition RNA_types.hh:67
@ PROP_BOOLEAN
Definition RNA_types.hh:65
@ PROP_ENUM
Definition RNA_types.hh:69
@ PROP_INT
Definition RNA_types.hh:66
@ PROP_STRING
Definition RNA_types.hh:68
@ PROP_POINTER
Definition RNA_types.hh:70
@ PROP_COLLECTION
Definition RNA_types.hh:71
@ PROPOVERRIDE_OVERRIDABLE_LIBRARY
Definition RNA_types.hh:355
@ PROPOVERRIDE_IGNORE
Definition RNA_types.hh:375
PropertyFlag
Definition RNA_types.hh:201
@ PROP_THICK_WRAP
Definition RNA_types.hh:312
@ PROP_DYNAMIC
Definition RNA_types.hh:317
@ PROP_PROPORTIONAL
Definition RNA_types.hh:250
@ PROP_NEVER_UNLINK
Definition RNA_types.hh:273
@ PROP_EDITABLE
Definition RNA_types.hh:207
@ PROP_NEVER_NULL
Definition RNA_types.hh:266
@ PROP_NO_DEG_UPDATE
Definition RNA_types.hh:328
@ PROP_PTR_NO_OWNERSHIP
Definition RNA_types.hh:284
@ PROP_ID_SELF_CHECK
Definition RNA_types.hh:259
@ PROP_DIRECTION
Definition RNA_types.hh:165
@ PROP_XYZ
Definition RNA_types.hh:172
@ PROP_DISTANCE
Definition RNA_types.hh:159
@ PROP_COLOR
Definition RNA_types.hh:163
@ PROP_NONE
Definition RNA_types.hh:136
@ PROP_TRANSLATION
Definition RNA_types.hh:164
@ PROP_UNSIGNED
Definition RNA_types.hh:152
#define NC_GEOM
Definition WM_types.hh:360
#define ND_DATA
Definition WM_types.hh:475
#define ND_SELECT
Definition WM_types.hh:474
#define ND_SPACE_VIEW3D
Definition WM_types.hh:494
#define NC_SPACE
Definition WM_types.hh:359
@ BMO_DELIM_NORMAL
@ BMO_DELIM_MATERIAL
@ BMO_DELIM_SEAM
@ BMO_DELIM_SHARP
@ BMO_DELIM_UV
ATTR_WARN_UNUSED_RESULT const BMVert * v2
static AttributeOwner from_id(ID *id)
Definition attribute.cc:43
constexpr Span slice(int64_t start, int64_t size) const
Definition BLI_span.hh:138
constexpr const T * data() const
Definition BLI_span.hh:216
constexpr int64_t size() const
Definition BLI_span.hh:253
local_group_size(16, 16) .push_constant(Type b
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
ccl_device_inline float4 select(const int4 mask, const float4 a, const float4 b)
void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int itemsize, int length, bool free_ptr, IteratorSkipFunc skip)
void RNA_property_update_main(Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
PointerRNA rna_pointer_inherit_refine(const PointerRNA *ptr, StructRNA *type, void *data)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
void rna_def_animdata_common(StructRNA *srna)
void rna_def_attributes_common(StructRNA *srna, const AttributeOwnerType type)
void RNA_def_struct_name_property(StructRNA *srna, PropertyRNA *prop)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, const char *propname)
void RNA_def_struct_path_func(StructRNA *srna, const char *path)
void RNA_def_property_boolean_sdna(PropertyRNA *prop, const char *structname, const char *propname, int64_t bit)
void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set)
void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret)
void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
void RNA_define_verify_sdna(bool verify)
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
void RNA_def_property_ui_icon(PropertyRNA *prop, int icon, int consecutive)
void RNA_def_property_srna(PropertyRNA *prop, const char *type)
void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, const char *next, const char *end, const char *get, const char *length, const char *lookupint, const char *lookupstring, const char *assignint)
void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *description)
void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set)
void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength)
void RNA_def_property_multi_array(PropertyRNA *prop, int dimension, const int length[])
void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item)
void RNA_def_struct_sdna(StructRNA *srna, const char *structname)
FunctionRNA * RNA_def_function(StructRNA *srna, const char *identifier, const char *call)
void RNA_def_property_array(PropertyRNA *prop, int length)
void RNA_def_property_range(PropertyRNA *prop, double min, double max)
PropertyRNA * RNA_def_pointer(StructOrFunctionRNA *cont_, const char *identifier, const char *type, const char *ui_name, const char *ui_description)
void RNA_def_property_string_maxlength(PropertyRNA *prop, int maxlength)
void RNA_def_property_struct_type(PropertyRNA *prop, const char *type)
void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, const char *propname, const char *lengthpropname)
void RNA_def_function_ui_description(FunctionRNA *func, const char *description)
void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *func)
PropertyRNA * RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set, const char *item)
void RNA_def_property_editable_func(PropertyRNA *prop, const char *editable)
StructRNA * RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from)
void RNA_def_function_flag(FunctionRNA *func, int flag)
void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set, const char *type_fn, const char *poll)
void RNA_def_property_enum_sdna(PropertyRNA *prop, const char *structname, const char *propname)
void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
void RNA_def_struct_ui_icon(StructRNA *srna, int icon)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_override_funcs(PropertyRNA *prop, const char *diff, const char *store, const char *apply)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, const char *propname)
void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, int precision)
void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const char *propname)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
void RNA_def_property_boolean_negative_sdna(PropertyRNA *prop, const char *structname, const char *propname, int64_t booleanbit)
void RNA_def_property_override_flag(PropertyRNA *prop, PropertyOverrideFlag flag)
void RNA_def_parameter_flags(PropertyRNA *prop, PropertyFlag flag_property, ParameterFlag flag_parameter)
void RNA_api_mesh(StructRNA *srna)
void rna_Mesh_update_draw(Main *bmain, Scene *scene, PointerRNA *ptr)
void rna_def_texmat_common(StructRNA *srna, const char *texspace_editable)
Definition rna_mesh.cc:2557
static void rna_def_mesh_edges(BlenderRNA *brna, PropertyRNA *cprop)
Definition rna_mesh.cc:2631
static void rna_def_mvert(BlenderRNA *brna)
Definition rna_mesh.cc:2015
static void rna_def_mloopuv(BlenderRNA *brna)
Definition rna_mesh.cc:2363
static void rna_def_mlooptri(BlenderRNA *brna)
Definition rna_mesh.cc:2132
static void rna_def_uv_layers(BlenderRNA *brna, PropertyRNA *cprop)
Definition rna_mesh.cc:2781
static void rna_def_normal_layer_value(BlenderRNA *brna)
Definition rna_mesh.cc:2715
static void rna_def_mpolygon(BlenderRNA *brna)
Definition rna_mesh.cc:2267
static void rna_def_mesh_looptris(BlenderRNA *brna, PropertyRNA *cprop)
Definition rna_mesh.cc:2656
static void rna_def_mesh_vertices(BlenderRNA *brna, PropertyRNA *cprop)
Definition rna_mesh.cc:2605
static void rna_def_mesh_polygons(BlenderRNA *brna, PropertyRNA *cprop)
Definition rna_mesh.cc:2689
static void rna_def_skin_vertices(BlenderRNA *brna, PropertyRNA *)
Definition rna_mesh.cc:2831
static void rna_def_mloopcol(BlenderRNA *brna)
Definition rna_mesh.cc:2498
void RNA_def_mesh(BlenderRNA *brna)
Definition rna_mesh.cc:3352
static void rna_def_loop_colors(BlenderRNA *brna, PropertyRNA *cprop)
Definition rna_mesh.cc:2728
static void rna_def_looptri_poly_value(BlenderRNA *brna)
Definition rna_mesh.cc:2893
const EnumPropertyItem rna_enum_mesh_delimit_mode_items[]
Definition rna_mesh.cc:37
static void rna_def_mesh(BlenderRNA *brna)
Definition rna_mesh.cc:2905
static void rna_def_mvert_group(BlenderRNA *brna)
Definition rna_mesh.cc:1989
static const EnumPropertyItem rna_enum_mesh_remesh_mode_items[]
Definition rna_mesh.cc:46
static void rna_def_medge(BlenderRNA *brna)
Definition rna_mesh.cc:2077
static void rna_def_mloop(BlenderRNA *brna)
Definition rna_mesh.cc:2200
static void rna_def_mesh_loops(BlenderRNA *brna, PropertyRNA *cprop)
Definition rna_mesh.cc:2668
#define DEFINE_CUSTOMDATA_LAYER_COLLECTION(collection_name, customdata_type, layer_type)
#define DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(collection_name, customdata_type, layer_type, active_type, layer_rna_type)
#define min(a, b)
Definition sort.c:32
#define FLT_MAX
Definition stdcycles.h:14
CustomDataLayer * layers
Definition DNA_ID.h:413
struct MDeformWeight * dw
char editflag
ID * owner_id
Definition RNA_types.hh:40
StructRNA * type
Definition RNA_types.hh:41
void * data
Definition RNA_types.hh:42
IDOverrideLibraryPropertyOperation * liboverride_operation
blender::BitVector is_loose_bits
void WM_main_add_notifier(uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4126