Merge branch 'master' of git@git.blender.org:blender.git into blender2.8
[blender.git] / source / blender / makesrna / intern / rna_mesh_utils.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Andrew Wiggin
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/makesrna/intern/rna_mesh_utils.h
24  *  \ingroup RNA
25  */
26  
27 #ifndef __RNA_MESH_UTILS_H__
28 #define __RNA_MESH_UTILS_H__
29
30 /* Macros to help reduce code clutter in rna_mesh.c */
31
32 /* Define the accessors for a basic CustomDataLayer collection */
33 #define DEFINE_CUSTOMDATA_LAYER_COLLECTION(collection_name, customdata_type, layer_type)        \
34         /* check */                                                                                 \
35         static int rna_##collection_name##_check(                                                   \
36                 CollectionPropertyIterator *UNUSED(iter), void *data)                               \
37         {                                                                                           \
38                 CustomDataLayer *layer = (CustomDataLayer *)data;                                       \
39                 return (layer->type != layer_type);                                                     \
40         }                                                                                           \
41         /* begin */                                                                                 \
42         static void rna_Mesh_##collection_name##s_begin(CollectionPropertyIterator *iter,           \
43                                                         PointerRNA *ptr)                            \
44         {                                                                                           \
45                 CustomData *data = rna_mesh_##customdata_type(ptr);                                     \
46                 if (data) {                                                                             \
47                         rna_iterator_array_begin(iter,                                                      \
48                                                  (void *)data->layers, sizeof(CustomDataLayer),             \
49                                                  data->totlayer, 0,                                         \
50                                                  rna_##collection_name##_check);                            \
51                 }                                                                                       \
52                 else {                                                                                  \
53                         rna_iterator_array_begin(iter, NULL, 0, 0, 0, NULL);                                \
54                 }                                                                                       \
55         }                                                                                           \
56         /* length */                                                                                \
57         static int rna_Mesh_##collection_name##s_length(PointerRNA *ptr)                            \
58         {                                                                                           \
59                 CustomData *data = rna_mesh_##customdata_type(ptr);                                     \
60                 return data ? CustomData_number_of_layers(data, layer_type) : 0;                        \
61         }                                                                                           \
62         /* index range */                                                                           \
63         static void rna_Mesh_##collection_name##_index_range(                                       \
64                 PointerRNA *ptr, int *min, int *max,                                                \
65                 int *UNUSED(softmin), int *UNUSED(softmax))                                         \
66         {                                                                                           \
67                 CustomData *data = rna_mesh_##customdata_type(ptr);                                     \
68                 *min = 0;                                                                               \
69                 *max = data ? CustomData_number_of_layers(data, layer_type) - 1 : 0;                    \
70                 *max = MAX2(0, *max);                                                                   \
71         }
72
73 /* Define the accessors for special CustomDataLayers in the collection
74  * (active, render, clone, stencil, etc) */
75 #define DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(collection_name, customdata_type,         \
76                                                           layer_type, active_type, layer_rna_type)  \
77                                                                                                     \
78         static PointerRNA rna_Mesh_##collection_name##_##active_type##_get(PointerRNA *ptr)         \
79         {                                                                                           \
80                 CustomData *data = rna_mesh_##customdata_type(ptr);                                     \
81                 CustomDataLayer *layer;                                                                 \
82                 if (data) {                                                                             \
83                         int index = CustomData_get_##active_type##_layer_index(data, layer_type);           \
84                         layer = (index == -1) ? NULL : &data->layers[index];                                \
85                 }                                                                                       \
86                 else {                                                                                  \
87                         layer = NULL;                                                                       \
88                         }                                                                                   \
89                 return rna_pointer_inherit_refine(ptr, &RNA_##layer_rna_type, layer);                   \
90         }                                                                                           \
91                                                                                                     \
92         static void rna_Mesh_##collection_name##_##active_type##_set(PointerRNA *ptr,               \
93                                                                      PointerRNA value)              \
94         {                                                                                           \
95                 Mesh *me = rna_mesh(ptr);                                                               \
96                 CustomData *data = rna_mesh_##customdata_type(ptr);                                     \
97                 int a;                                                                                  \
98                 if (data) {                                                                             \
99                         CustomDataLayer *layer;                                                             \
100                         int layer_index = CustomData_get_layer_index(data, layer_type);                     \
101                         for (layer = data->layers + layer_index, a = 0; layer_index + a < data->totlayer; layer++, a++) { \
102                                 if (value.data == layer) {                                                      \
103                                         CustomData_set_layer_##active_type(data, layer_type, a);                    \
104                                         BKE_mesh_update_customdata_pointers(me, true);                              \
105                                         return;                                                                     \
106                                 }                                                                               \
107                         }                                                                                   \
108                 }                                                                                       \
109         }                                                                                           \
110                                                                                                     \
111         static int rna_Mesh_##collection_name##_##active_type##_index_get(PointerRNA *ptr)          \
112         {                                                                                           \
113                 CustomData *data = rna_mesh_##customdata_type(ptr);                                     \
114                 if (data) {                                                                             \
115                         return CustomData_get_##active_type##_layer(data, layer_type);                      \
116                 }                                                                                       \
117                 else {                                                                                  \
118                         return 0;                                                                           \
119                 }                                                                                       \
120         }                                                                                           \
121                                                                                                     \
122         static void rna_Mesh_##collection_name##_##active_type##_index_set(PointerRNA *ptr, int value) \
123         {                                                                                           \
124                 Mesh *me = rna_mesh(ptr);                                                               \
125                 CustomData *data = rna_mesh_##customdata_type(ptr);                                     \
126                 if (data) {                                                                             \
127                         CustomData_set_layer_##active_type(data, layer_type, value);                        \
128                         BKE_mesh_update_customdata_pointers(me, true);                                      \
129                 }                                                                                       \
130         }
131
132 #endif /* __RNA_MESH_UTILS_H__ */