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 
17 #pragma once
18 
19 /** \file
20  * \ingroup bke
21  */
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 struct CustomData;
28 struct CustomData_MeshMasks;
29 struct MVert;
30 struct MemArena;
31 struct Mesh;
32 
33 /* Generic ways to map some geometry elements from a source mesh to a dest one. */
34 
35 typedef struct MeshPairRemapItem {
36   int sources_num;
37   int *indices_src;   /* NULL if no source found. */
38   float *weights_src; /* NULL if no source found, else, always normalized! */
39   /* UNUSED (at the moment)*/
40   // float  hit_dist;     /* FLT_MAX if irrelevant or no source found. */
41   int island; /* For loops only. */
42 } MeshPairRemapItem;
43 
44 /* All mapping computing func return this. */
45 typedef struct MeshPairRemap {
46   int items_num;
47   MeshPairRemapItem *items; /* array, one item per dest element. */
48 
49   struct MemArena *mem; /* memory arena, internal use only. */
50 } MeshPairRemap;
51 
52 /* Helpers! */
53 void BKE_mesh_remap_init(MeshPairRemap *map, const int items_num);
54 void BKE_mesh_remap_free(MeshPairRemap *map);
55 
56 void BKE_mesh_remap_item_define_invalid(MeshPairRemap *map, const int index);
57 
58 /* TODO:
59  * Add other 'from/to' mapping sources, like e.g. using an UVMap, etc.
60  * https://blenderartists.org/t/619105
61  *
62  * We could also use similar topology mappings inside a same mesh
63  * (cf. Campbell's 'select face islands from similar topology' wip work).
64  * Also, users will have to check, whether we can get rid of some modes here,
65  * not sure all will be useful!
66  */
67 enum {
68   MREMAP_USE_VERT = 1 << 4,
69   MREMAP_USE_EDGE = 1 << 5,
70   MREMAP_USE_LOOP = 1 << 6,
71   MREMAP_USE_POLY = 1 << 7,
72 
73   MREMAP_USE_NEAREST = 1 << 8,
74   MREMAP_USE_NORPROJ = 1 << 9,
75   MREMAP_USE_INTERP = 1 << 10,
76   MREMAP_USE_NORMAL = 1 << 11,
77 
78   /* ***** Target's vertices ***** */
79   MREMAP_MODE_VERT = 1 << 24,
80   /* Nearest source vert. */
81   MREMAP_MODE_VERT_NEAREST = MREMAP_MODE_VERT | MREMAP_USE_VERT | MREMAP_USE_NEAREST,
82 
83   /* Nearest vertex of nearest edge. */
84   MREMAP_MODE_VERT_EDGE_NEAREST = MREMAP_MODE_VERT | MREMAP_USE_EDGE | MREMAP_USE_NEAREST,
85   /* This one uses two verts of selected edge (weighted interpolation). */
86   /* Nearest point on nearest edge. */
87   MREMAP_MODE_VERT_EDGEINTERP_NEAREST = MREMAP_MODE_VERT | MREMAP_USE_EDGE | MREMAP_USE_NEAREST |
88                                         MREMAP_USE_INTERP,
89 
90   /* Nearest vertex of nearest poly. */
91   MREMAP_MODE_VERT_POLY_NEAREST = MREMAP_MODE_VERT | MREMAP_USE_POLY | MREMAP_USE_NEAREST,
92   /* Those two use all verts of selected poly (weighted interpolation). */
93   /* Nearest point on nearest poly. */
94   MREMAP_MODE_VERT_POLYINTERP_NEAREST = MREMAP_MODE_VERT | MREMAP_USE_POLY | MREMAP_USE_NEAREST |
95                                         MREMAP_USE_INTERP,
96   /* Point on nearest face hit by ray from target vertex's normal. */
97   MREMAP_MODE_VERT_POLYINTERP_VNORPROJ = MREMAP_MODE_VERT | MREMAP_USE_POLY | MREMAP_USE_NORPROJ |
98                                          MREMAP_USE_INTERP,
99 
100   /* ***** Target's edges ***** */
101   MREMAP_MODE_EDGE = 1 << 25,
102 
103   /* Source edge which both vertices are nearest of dest ones. */
104   MREMAP_MODE_EDGE_VERT_NEAREST = MREMAP_MODE_EDGE | MREMAP_USE_VERT | MREMAP_USE_NEAREST,
105 
106   /* Nearest source edge (using mid-point). */
107   MREMAP_MODE_EDGE_NEAREST = MREMAP_MODE_EDGE | MREMAP_USE_EDGE | MREMAP_USE_NEAREST,
108 
109   /* Nearest edge of nearest poly (using mid-point). */
110   MREMAP_MODE_EDGE_POLY_NEAREST = MREMAP_MODE_EDGE | MREMAP_USE_POLY | MREMAP_USE_NEAREST,
111 
112   /* Cast a set of rays from along dest edge,
113    * interpolating its vertices' normals, and use hit source edges. */
114   MREMAP_MODE_EDGE_EDGEINTERP_VNORPROJ = MREMAP_MODE_EDGE | MREMAP_USE_VERT | MREMAP_USE_NORPROJ |
115                                          MREMAP_USE_INTERP,
116 
117   /* ***** Target's loops ***** */
118   /* Note: when islands are given to loop mapping func,
119    * all loops from the same destination face will always be mapped
120    * to loops of source faces within a same island, regardless of mapping mode. */
121   MREMAP_MODE_LOOP = 1 << 26,
122 
123   /* Best normal-matching loop from nearest vert. */
124   MREMAP_MODE_LOOP_NEAREST_LOOPNOR = MREMAP_MODE_LOOP | MREMAP_USE_LOOP | MREMAP_USE_VERT |
125                                      MREMAP_USE_NEAREST | MREMAP_USE_NORMAL,
126   /* Loop from best normal-matching poly from nearest vert. */
127   MREMAP_MODE_LOOP_NEAREST_POLYNOR = MREMAP_MODE_LOOP | MREMAP_USE_POLY | MREMAP_USE_VERT |
128                                      MREMAP_USE_NEAREST | MREMAP_USE_NORMAL,
129 
130   /* Loop from nearest vertex of nearest poly. */
131   MREMAP_MODE_LOOP_POLY_NEAREST = MREMAP_MODE_LOOP | MREMAP_USE_POLY | MREMAP_USE_NEAREST,
132   /* Those two use all verts of selected poly (weighted interpolation). */
133   /* Nearest point on nearest poly. */
134   MREMAP_MODE_LOOP_POLYINTERP_NEAREST = MREMAP_MODE_LOOP | MREMAP_USE_POLY | MREMAP_USE_NEAREST |
135                                         MREMAP_USE_INTERP,
136   /* Point on nearest face hit by ray from target loop's normal. */
137   MREMAP_MODE_LOOP_POLYINTERP_LNORPROJ = MREMAP_MODE_LOOP | MREMAP_USE_POLY | MREMAP_USE_NORPROJ |
138                                          MREMAP_USE_INTERP,
139 
140   /* ***** Target's polygons ***** */
141   MREMAP_MODE_POLY = 1 << 27,
142 
143   /* Nearest source poly. */
144   MREMAP_MODE_POLY_NEAREST = MREMAP_MODE_POLY | MREMAP_USE_POLY | MREMAP_USE_NEAREST,
145   /* Source poly from best normal-matching dest poly. */
146   MREMAP_MODE_POLY_NOR = MREMAP_MODE_POLY | MREMAP_USE_POLY | MREMAP_USE_NORMAL,
147 
148   /* Project dest poly onto source mesh using its normal,
149    * and use interpolation of all intersecting source polys. */
150   MREMAP_MODE_POLY_POLYINTERP_PNORPROJ = MREMAP_MODE_POLY | MREMAP_USE_POLY | MREMAP_USE_NORPROJ |
151                                          MREMAP_USE_INTERP,
152 
153   /* ***** Same topology, applies to all four elements types. ***** */
154   MREMAP_MODE_TOPOLOGY = MREMAP_MODE_VERT | MREMAP_MODE_EDGE | MREMAP_MODE_LOOP | MREMAP_MODE_POLY,
155 };
156 
157 void BKE_mesh_remap_calc_source_cddata_masks_from_map_modes(
158     const int vert_mode,
159     const int edge_mode,
160     const int loop_mode,
161     const int poly_mode,
162     struct CustomData_MeshMasks *cddata_mask);
163 
164 float BKE_mesh_remap_calc_difference_from_mesh(const struct SpaceTransform *space_transform,
165                                                const struct MVert *verts_dst,
166                                                const int numverts_dst,
167                                                struct Mesh *me_src);
168 
169 void BKE_mesh_remap_find_best_match_from_mesh(const struct MVert *verts_dst,
170                                               const int numverts_dst,
171                                               struct Mesh *me_src,
172                                               struct SpaceTransform *r_space_transform);
173 
174 void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
175                                          const struct SpaceTransform *space_transform,
176                                          const float max_dist,
177                                          const float ray_radius,
178                                          const struct MVert *verts_dst,
179                                          const int numverts_dst,
180                                          const bool dirty_nors_dst,
181                                          struct Mesh *me_src,
182                                          MeshPairRemap *r_map);
183 
184 void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
185                                          const struct SpaceTransform *space_transform,
186                                          const float max_dist,
187                                          const float ray_radius,
188                                          const struct MVert *verts_dst,
189                                          const int numverts_dst,
190                                          const struct MEdge *edges_dst,
191                                          const int numedges_dst,
192                                          const bool dirty_nors_dst,
193                                          struct Mesh *me_src,
194                                          MeshPairRemap *r_map);
195 
196 void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
197                                          const struct SpaceTransform *space_transform,
198                                          const float max_dist,
199                                          const float ray_radius,
200                                          struct MVert *verts_dst,
201                                          const int numverts_dst,
202                                          struct MEdge *edges_dst,
203                                          const int numedges_dst,
204                                          struct MLoop *loops_dst,
205                                          const int numloops_dst,
206                                          struct MPoly *polys_dst,
207                                          const int numpolys_dst,
208                                          struct CustomData *ldata_dst,
209                                          struct CustomData *pdata_dst,
210                                          const bool use_split_nors_dst,
211                                          const float split_angle_dst,
212                                          const bool dirty_nors_dst,
213                                          struct Mesh *me_src,
214                                          MeshRemapIslandsCalc gen_islands_src,
215                                          const float islands_precision_src,
216                                          struct MeshPairRemap *r_map);
217 
218 void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
219                                          const struct SpaceTransform *space_transform,
220                                          const float max_dist,
221                                          const float ray_radius,
222                                          struct MVert *verts_dst,
223                                          const int numverts_dst,
224                                          struct MLoop *loops_dst,
225                                          const int numloops_dst,
226                                          struct MPoly *polys_dst,
227                                          const int numpolys_dst,
228                                          struct CustomData *pdata_dst,
229                                          const bool dirty_nors_dst,
230                                          struct Mesh *me_src,
231                                          struct MeshPairRemap *r_map);
232 
233 #ifdef __cplusplus
234 }
235 #endif
236