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