1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 #pragma once
20 
21 /** \file
22  * \ingroup bke
23  */
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 struct MEdge;
30 struct MLoop;
31 struct MLoopTri;
32 struct MLoopUV;
33 struct MPoly;
34 struct MVert;
35 
36 /* map from uv vertex to face (for select linked, stitch, uv suburf) */
37 
38 /* UvVertMap */
39 #define STD_UV_CONNECT_LIMIT 0.0001f
40 
41 typedef struct UvVertMap {
42   struct UvMapVert **vert;
43   struct UvMapVert *buf;
44 } UvVertMap;
45 
46 typedef struct UvMapVert {
47   struct UvMapVert *next;
48   unsigned int poly_index;
49   unsigned short loop_of_poly_index;
50   bool separate;
51 } UvMapVert;
52 
53 /* UvElement stores per uv information so that we can quickly access information for a uv.
54  * it is actually an improved UvMapVert, including an island and a direct pointer to the face
55  * to avoid initializing face arrays */
56 typedef struct UvElement {
57   /* Next UvElement corresponding to same vertex */
58   struct UvElement *next;
59   /* Face the element belongs to */
60   struct BMLoop *l;
61   /* index in loop. */
62   unsigned short loop_of_poly_index;
63   /* Whether this element is the first of coincident elements */
64   bool separate;
65   /* general use flag */
66   unsigned char flag;
67   /* If generating element map with island sorting, this stores the island index */
68   unsigned int island;
69 } UvElement;
70 
71 /* UvElementMap is a container for UvElements of a mesh. It stores some UvElements belonging to the
72  * same uv island in sequence and the number of uvs per island so it is possible to access all uvs
73  * belonging to an island directly by iterating through the buffer.
74  */
75 typedef struct UvElementMap {
76   /* address UvElements by their vertex */
77   struct UvElement **vert;
78   /* UvElement Store */
79   struct UvElement *buf;
80   /* Total number of UVs in the layer. Useful to know */
81   int totalUVs;
82   /* Number of Islands in the mesh */
83   int totalIslands;
84   /* Stores the starting index in buf where each island begins */
85   int *islandIndices;
86 } UvElementMap;
87 
88 #define INVALID_ISLAND ((unsigned int)-1)
89 
90 /* Connectivity data */
91 typedef struct MeshElemMap {
92   int *indices;
93   int count;
94 } MeshElemMap;
95 
96 /* mapping */
97 UvVertMap *BKE_mesh_uv_vert_map_create(const struct MPoly *mpoly,
98                                        const struct MLoop *mloop,
99                                        const struct MLoopUV *mloopuv,
100                                        unsigned int totpoly,
101                                        unsigned int totvert,
102                                        const float limit[2],
103                                        const bool selected,
104                                        const bool use_winding);
105 UvMapVert *BKE_mesh_uv_vert_map_get_vert(UvVertMap *vmap, unsigned int v);
106 void BKE_mesh_uv_vert_map_free(UvVertMap *vmap);
107 
108 void BKE_mesh_vert_poly_map_create(MeshElemMap **r_map,
109                                    int **r_mem,
110                                    const struct MPoly *mpoly,
111                                    const struct MLoop *mloop,
112                                    int totvert,
113                                    int totpoly,
114                                    int totloop);
115 void BKE_mesh_vert_loop_map_create(MeshElemMap **r_map,
116                                    int **r_mem,
117                                    const struct MPoly *mpoly,
118                                    const struct MLoop *mloop,
119                                    int totvert,
120                                    int totpoly,
121                                    int totloop);
122 void BKE_mesh_vert_looptri_map_create(MeshElemMap **r_map,
123                                       int **r_mem,
124                                       const struct MVert *mvert,
125                                       const int totvert,
126                                       const struct MLoopTri *mlooptri,
127                                       const int totlooptri,
128                                       const struct MLoop *mloop,
129                                       const int totloop);
130 void BKE_mesh_vert_edge_map_create(
131     MeshElemMap **r_map, int **r_mem, const struct MEdge *medge, int totvert, int totedge);
132 void BKE_mesh_vert_edge_vert_map_create(
133     MeshElemMap **r_map, int **r_mem, const struct MEdge *medge, int totvert, int totedge);
134 void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map,
135                                    int **r_mem,
136                                    const struct MEdge *medge,
137                                    const int totedge,
138                                    const struct MPoly *mpoly,
139                                    const int totpoly,
140                                    const struct MLoop *mloop,
141                                    const int totloop);
142 void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map,
143                                    int **r_mem,
144                                    const struct MEdge *medge,
145                                    const int totedge,
146                                    const struct MPoly *mpoly,
147                                    const int totpoly,
148                                    const struct MLoop *mloop,
149                                    const int totloop);
150 void BKE_mesh_origindex_map_create(MeshElemMap **r_map,
151                                    int **r_mem,
152                                    const int totsource,
153                                    const int *final_origindex,
154                                    const int totfinal);
155 void BKE_mesh_origindex_map_create_looptri(MeshElemMap **r_map,
156                                            int **r_mem,
157                                            const struct MPoly *mpoly,
158                                            const int mpoly_num,
159                                            const struct MLoopTri *looptri,
160                                            const int looptri_num);
161 
162 /* islands */
163 
164 /* Loop islands data helpers. */
165 enum {
166   MISLAND_TYPE_NONE = 0,
167   MISLAND_TYPE_VERT = 1,
168   MISLAND_TYPE_EDGE = 2,
169   MISLAND_TYPE_POLY = 3,
170   MISLAND_TYPE_LOOP = 4,
171 };
172 
173 typedef struct MeshIslandStore {
174   short item_type;     /* MISLAND_TYPE_... */
175   short island_type;   /* MISLAND_TYPE_... */
176   short innercut_type; /* MISLAND_TYPE_... */
177 
178   int items_to_islands_num;
179   int *items_to_islands; /* map the item to the island index */
180 
181   int islands_num;
182   size_t islands_num_alloc;
183   struct MeshElemMap **islands;   /* Array of pointers, one item per island. */
184   struct MeshElemMap **innercuts; /* Array of pointers, one item per island. */
185 
186   struct MemArena *mem; /* Memory arena, internal use only. */
187 } MeshIslandStore;
188 
189 void BKE_mesh_loop_islands_init(MeshIslandStore *island_store,
190                                 const short item_type,
191                                 const int items_num,
192                                 const short island_type,
193                                 const short innercut_type);
194 void BKE_mesh_loop_islands_clear(MeshIslandStore *island_store);
195 void BKE_mesh_loop_islands_free(MeshIslandStore *island_store);
196 void BKE_mesh_loop_islands_add(MeshIslandStore *island_store,
197                                const int item_num,
198                                const int *items_indices,
199                                const int num_island_items,
200                                int *island_item_indices,
201                                const int num_innercut_items,
202                                int *innercut_item_indices);
203 
204 typedef bool (*MeshRemapIslandsCalc)(struct MVert *verts,
205                                      const int totvert,
206                                      struct MEdge *edges,
207                                      const int totedge,
208                                      struct MPoly *polys,
209                                      const int totpoly,
210                                      struct MLoop *loops,
211                                      const int totloop,
212                                      struct MeshIslandStore *r_island_store);
213 
214 /* Above vert/UV mapping stuff does not do what we need here, but does things we do not need here.
215  * So better keep them separated for now, I think.
216  */
217 bool BKE_mesh_calc_islands_loop_poly_edgeseam(struct MVert *verts,
218                                               const int totvert,
219                                               struct MEdge *edges,
220                                               const int totedge,
221                                               struct MPoly *polys,
222                                               const int totpoly,
223                                               struct MLoop *loops,
224                                               const int totloop,
225                                               MeshIslandStore *r_island_store);
226 
227 bool BKE_mesh_calc_islands_loop_poly_uvmap(struct MVert *verts,
228                                            const int totvert,
229                                            struct MEdge *edges,
230                                            const int totedge,
231                                            struct MPoly *polys,
232                                            const int totpoly,
233                                            struct MLoop *loops,
234                                            const int totloop,
235                                            const struct MLoopUV *luvs,
236                                            MeshIslandStore *r_island_store);
237 
238 int *BKE_mesh_calc_smoothgroups(const struct MEdge *medge,
239                                 const int totedge,
240                                 const struct MPoly *mpoly,
241                                 const int totpoly,
242                                 const struct MLoop *mloop,
243                                 const int totloop,
244                                 int *r_totgroup,
245                                 const bool use_bitflags);
246 
247 /* use on looptri vertex values */
248 #define BKE_MESH_TESSTRI_VINDEX_ORDER(_tri, _v) \
249   ((CHECK_TYPE_ANY( \
250         _tri, unsigned int *, int *, int[3], const unsigned int *, const int *, const int[3]), \
251     CHECK_TYPE_ANY(_v, unsigned int, const unsigned int, int, const int)), \
252    (((_tri)[0] == _v) ? 0 : ((_tri)[1] == _v) ? 1 : ((_tri)[2] == _v) ? 2 : -1))
253 
254 #ifdef __cplusplus
255 }
256 #endif
257