d17ee49ca0c78f8200ef55cddc6dbf8986a0ee54
[blender.git] / source / blender / blenkernel / intern / subdiv_converter_mesh.c
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  * The Original Code is Copyright (C) 2018 by Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Sergey Sharybin.
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/blenkernel/intern/subdiv_converter_mesh.c
27  *  \ingroup bke
28  */
29
30 #include "subdiv_converter.h"
31
32 #include <string.h>
33
34 #include "DNA_mesh_types.h"
35 #include "DNA_meshdata_types.h"
36
37 #include "BLI_utildefines.h"
38 #include "BLI_bitmap.h"
39 #include "BLI_math_vector.h"
40
41 #include "BKE_customdata.h"
42 #include "BKE_mesh_mapping.h"
43 #include "BKE_subdiv.h"
44
45 #include "MEM_guardedalloc.h"
46
47 #include "opensubdiv_capi.h"
48 #include "opensubdiv_converter_capi.h"
49
50 typedef struct ConverterStorage {
51         SubdivSettings settings;
52         const Mesh *mesh;
53         /* Indexed by loop index, value denotes index of face-varying vertex
54          * which corresponds to the UV coordinate.
55          */
56         int *loop_uv_indices;
57         int num_uv_coordinates;
58         /* Indexed by coarse mesh elements, gives index of corresponding element
59          * with ignoring all non-manifold entities.
60          *
61          * NOTE: This isn't strictly speaking manifold, this is more like non-loose
62          * geometry index. As in, index of element as if there were no loose edges
63          * or vertices in the mesh.
64          */
65         int *manifold_vertex_index;
66         /* Indexed by vertex index from mesh, corresponds to whether this vertex has
67          * infinite sharpness due to non-manifol topology.
68          */
69         BLI_bitmap *infinite_sharp_vertices_map;
70         /* Reverse mapping to above. */
71         int *manifold_vertex_index_reverse;
72         int *manifold_edge_index_reverse;
73         /* Number of non-loose elements. */
74         int num_manifold_vertices;
75         int num_manifold_edges;
76 } ConverterStorage;
77
78 static OpenSubdiv_SchemeType get_scheme_type(
79         const OpenSubdiv_Converter *converter)
80 {
81         ConverterStorage *storage = converter->user_data;
82         if (storage->settings.is_simple) {
83                 return OSD_SCHEME_BILINEAR;
84         }
85         else {
86                 return OSD_SCHEME_CATMARK;
87         }
88 }
89
90 static OpenSubdiv_FVarLinearInterpolation get_fvar_linear_interpolation(
91         const OpenSubdiv_Converter *converter)
92 {
93         ConverterStorage *storage = converter->user_data;
94         return BKE_subdiv_converter_fvar_linear_from_settings(&storage->settings);
95 }
96
97 static bool specifies_full_topology(
98         const OpenSubdiv_Converter *UNUSED(converter))
99 {
100         return false;
101 }
102
103 static int get_num_faces(const OpenSubdiv_Converter *converter)
104 {
105         ConverterStorage *storage = converter->user_data;
106         return storage->mesh->totpoly;
107 }
108
109 static int get_num_edges(const OpenSubdiv_Converter *converter)
110 {
111         ConverterStorage *storage = converter->user_data;
112         return storage->num_manifold_edges;
113 }
114
115 static int get_num_vertices(const OpenSubdiv_Converter *converter)
116 {
117         ConverterStorage *storage = converter->user_data;
118         return storage->num_manifold_vertices;
119 }
120
121 static int get_num_face_vertices(const OpenSubdiv_Converter *converter,
122                                  int manifold_face_index)
123 {
124         ConverterStorage *storage = converter->user_data;
125         return storage->mesh->mpoly[manifold_face_index].totloop;
126 }
127
128 static void get_face_vertices(const OpenSubdiv_Converter *converter,
129                               int manifold_face_index,
130                               int *manifold_face_vertices)
131 {
132         ConverterStorage *storage = converter->user_data;
133         const MPoly *poly = &storage->mesh->mpoly[manifold_face_index];
134         const MLoop *mloop = storage->mesh->mloop;
135         for (int corner = 0; corner < poly->totloop; corner++) {
136                 manifold_face_vertices[corner] = storage->manifold_vertex_index[
137                         mloop[poly->loopstart + corner].v];
138         }
139 }
140
141 static void get_edge_vertices(const OpenSubdiv_Converter *converter,
142                               int manifold_edge_index,
143                               int *manifold_edge_vertices)
144 {
145         ConverterStorage *storage = converter->user_data;
146         const int edge_index =
147                 storage->manifold_edge_index_reverse[manifold_edge_index];
148         const MEdge *edge = &storage->mesh->medge[edge_index];
149         manifold_edge_vertices[0] = storage->manifold_vertex_index[edge->v1];
150         manifold_edge_vertices[1] = storage->manifold_vertex_index[edge->v2];
151 }
152
153 static float get_edge_sharpness(const OpenSubdiv_Converter *converter,
154                                 int manifold_edge_index)
155 {
156         ConverterStorage *storage = converter->user_data;
157         const int edge_index =
158                 storage->manifold_edge_index_reverse[manifold_edge_index];
159         const MEdge *medge = storage->mesh->medge;
160         const float edge_crease =  (float)medge[edge_index].crease / 255.0f;
161         return edge_crease * edge_crease * 10.0f;
162 }
163
164
165 static bool is_infinite_sharp_vertex(const OpenSubdiv_Converter *converter,
166                                      int manifold_vertex_index)
167 {
168         ConverterStorage *storage = converter->user_data;
169         const int vertex_index =
170                 storage->manifold_vertex_index_reverse[manifold_vertex_index];
171         return BLI_BITMAP_TEST_BOOL(storage->infinite_sharp_vertices_map,
172                                     vertex_index);
173 }
174
175 static float get_vertex_sharpness(const OpenSubdiv_Converter *UNUSED(converter),
176                                   int UNUSED(manifold_vertex_index))
177 {
178         return 0.0f;
179 }
180
181 static int get_num_uv_layers(const OpenSubdiv_Converter *converter)
182 {
183         ConverterStorage *storage = converter->user_data;
184         const Mesh *mesh = storage->mesh;
185         return CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV);
186 }
187
188 static void precalc_uv_layer(const OpenSubdiv_Converter *converter,
189                              const int layer_index)
190 {
191         ConverterStorage *storage = converter->user_data;
192         const Mesh *mesh = storage->mesh;
193         const MPoly *mpoly = mesh->mpoly;
194         const MLoop *mloop = mesh->mloop;
195         const MLoopUV *mloopuv = CustomData_get_layer_n(
196                 &mesh->ldata, CD_MLOOPUV, layer_index);
197         const int num_poly = mesh->totpoly;
198         const int num_vert = mesh->totvert;
199         const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT};
200         /* Initialize memory required for the operations. */
201         if (storage->loop_uv_indices == NULL) {
202                 storage->loop_uv_indices = MEM_malloc_arrayN(
203                         mesh->totloop, sizeof(int), "loop uv vertex index");
204         }
205         UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(
206                 mpoly, mloop, mloopuv,
207                 num_poly, num_vert,
208                 limit,
209                 false, true);
210         /* NOTE: First UV vertex is supposed to be always marked as separate. */
211         storage->num_uv_coordinates = -1;
212         for (int vertex_index = 0; vertex_index < num_vert; ++vertex_index) {
213                 const UvMapVert *uv_vert = BKE_mesh_uv_vert_map_get_vert(uv_vert_map,
214                                                                          vertex_index);
215                 while (uv_vert != NULL) {
216                         if (uv_vert->separate) {
217                                 storage->num_uv_coordinates++;
218                         }
219                         const MPoly *mp = &mpoly[uv_vert->poly_index];
220                         const int global_loop_index = mp->loopstart +
221                                                       uv_vert->loop_of_poly_index;
222                         storage->loop_uv_indices[global_loop_index] =
223                                 storage->num_uv_coordinates;
224                         uv_vert = uv_vert->next;
225                 }
226         }
227         /* So far this value was used as a 0-based index, actual number of UV
228          * vertices is 1 more.
229          */
230         storage->num_uv_coordinates += 1;
231         BKE_mesh_uv_vert_map_free(uv_vert_map);
232 }
233
234 static void finish_uv_layer(const OpenSubdiv_Converter *UNUSED(converter))
235 {
236 }
237
238 static int get_num_uvs(const OpenSubdiv_Converter *converter)
239 {
240         ConverterStorage *storage = converter->user_data;
241         return storage->num_uv_coordinates;
242 }
243
244 static int get_face_corner_uv_index(const OpenSubdiv_Converter *converter,
245                                     const int face_index,
246                                     const int corner)
247 {
248         ConverterStorage *storage = converter->user_data;
249         const MPoly *mp = &storage->mesh->mpoly[face_index];
250         return storage->loop_uv_indices[mp->loopstart + corner];
251 }
252
253 static void free_user_data(const OpenSubdiv_Converter *converter)
254 {
255         ConverterStorage *user_data = converter->user_data;
256         MEM_SAFE_FREE(user_data->loop_uv_indices);
257         MEM_freeN(user_data->manifold_vertex_index);
258         MEM_freeN(user_data->infinite_sharp_vertices_map);
259         MEM_freeN(user_data->manifold_vertex_index_reverse);
260         MEM_freeN(user_data->manifold_edge_index_reverse);
261         MEM_freeN(user_data);
262 }
263
264 static void init_functions(OpenSubdiv_Converter *converter)
265 {
266         converter->getSchemeType = get_scheme_type;
267         converter->getFVarLinearInterpolation = get_fvar_linear_interpolation;
268         converter->specifiesFullTopology = specifies_full_topology;
269
270         converter->getNumFaces = get_num_faces;
271         converter->getNumEdges = get_num_edges;
272         converter->getNumVertices = get_num_vertices;
273
274         converter->getNumFaceVertices = get_num_face_vertices;
275         converter->getFaceVertices = get_face_vertices;
276         converter->getFaceEdges = NULL;
277
278         converter->getEdgeVertices = get_edge_vertices;
279         converter->getNumEdgeFaces = NULL;
280         converter->getEdgeFaces = NULL;
281         converter->getEdgeSharpness = get_edge_sharpness;
282
283         converter->getNumVertexEdges = NULL;
284         converter->getVertexEdges = NULL;
285         converter->getNumVertexFaces = NULL;
286         converter->getVertexFaces = NULL;
287         converter->isInfiniteSharpVertex = is_infinite_sharp_vertex;
288         converter->getVertexSharpness = get_vertex_sharpness;
289
290         converter->getNumUVLayers = get_num_uv_layers;
291         converter->precalcUVLayer = precalc_uv_layer;
292         converter->finishUVLayer = finish_uv_layer;
293         converter->getNumUVCoordinates = get_num_uvs;
294         converter->getFaceCornerUVIndex = get_face_corner_uv_index;
295
296         converter->freeUserData = free_user_data;
297 }
298
299 static void initialize_manifold_index_array(const BLI_bitmap *used_map,
300                                             const int num_elements,
301                                             int **indices_r,
302                                             int **indices_reverse_r,
303                                             int *num_manifold_elements_r)
304 {
305         int *indices = NULL;
306         if (indices_r != NULL) {
307                 indices = MEM_malloc_arrayN(
308                 num_elements, sizeof(int), "manifold indices");
309         }
310         int *indices_reverse = NULL;
311         if (indices_reverse_r != NULL) {
312                 indices_reverse = MEM_malloc_arrayN(
313                 num_elements, sizeof(int), "manifold indices reverse");
314         }
315         int offset = 0;
316         for (int i = 0; i < num_elements; i++) {
317                 if (BLI_BITMAP_TEST_BOOL(used_map, i)) {
318                         if (indices != NULL) {
319                                 indices[i] = i - offset;
320                         }
321                         if (indices_reverse != NULL) {
322                                 indices_reverse[i - offset] = i;
323                         }
324                 }
325                 else {
326                         if (indices != NULL) {
327                                 indices[i] = -1;
328                         }
329                         offset++;
330                 }
331         }
332         if (indices_r != NULL) {
333                 *indices_r = indices;
334         }
335         if (indices_reverse_r != NULL) {
336                 *indices_reverse_r = indices_reverse;
337         }
338         *num_manifold_elements_r = num_elements - offset;
339 }
340
341 static void initialize_manifold_indices(ConverterStorage *storage)
342 {
343         const Mesh *mesh = storage->mesh;
344         const MEdge *medge = mesh->medge;
345         const MLoop *mloop = mesh->mloop;
346         const MPoly *mpoly = mesh->mpoly;
347         /* Set bits of elements which are not loose. */
348         BLI_bitmap *vert_used_map = BLI_BITMAP_NEW(mesh->totvert, "vert used map");
349         BLI_bitmap *edge_used_map = BLI_BITMAP_NEW(mesh->totedge, "edge used map");
350         for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) {
351                 const MPoly *poly = &mpoly[poly_index];
352                 for (int corner = 0; corner < poly->totloop; corner++) {
353                         const MLoop *loop = &mloop[poly->loopstart + corner];
354                         BLI_BITMAP_ENABLE(vert_used_map, loop->v);
355                         BLI_BITMAP_ENABLE(edge_used_map, loop->e);
356                 }
357         }
358         initialize_manifold_index_array(vert_used_map,
359                                         mesh->totvert,
360                                         &storage->manifold_vertex_index,
361                                         &storage->manifold_vertex_index_reverse,
362                                         &storage->num_manifold_vertices);
363         initialize_manifold_index_array(edge_used_map,
364                                         mesh->totedge,
365                                         NULL,
366                                         &storage->manifold_edge_index_reverse,
367                                         &storage->num_manifold_edges);
368         /* Initialize infinite sharp mapping. */
369         storage->infinite_sharp_vertices_map =
370                 BLI_BITMAP_NEW(mesh->totvert, "vert used map");
371         for (int edge_index = 0; edge_index < mesh->totedge; edge_index++) {
372                 if (!BLI_BITMAP_TEST_BOOL(edge_used_map, edge_index)) {
373                         const MEdge *edge = &medge[edge_index];
374                         BLI_BITMAP_ENABLE(storage->infinite_sharp_vertices_map, edge->v1);
375                         BLI_BITMAP_ENABLE(storage->infinite_sharp_vertices_map, edge->v2);
376                 }
377         }
378         /* Free working variables. */
379         MEM_freeN(vert_used_map);
380         MEM_freeN(edge_used_map);
381 }
382
383 static void init_user_data(OpenSubdiv_Converter *converter,
384                            const SubdivSettings *settings,
385                            const Mesh *mesh)
386 {
387         ConverterStorage *user_data =
388                  MEM_mallocN(sizeof(ConverterStorage), __func__);
389         user_data->settings = *settings;
390         user_data->mesh = mesh;
391         user_data->loop_uv_indices = NULL;
392         initialize_manifold_indices(user_data);
393         converter->user_data = user_data;
394 }
395
396 void BKE_subdiv_converter_init_for_mesh(struct OpenSubdiv_Converter *converter,
397                                         const SubdivSettings *settings,
398                                         const Mesh *mesh)
399 {
400         init_functions(converter);
401         init_user_data(converter, settings, mesh);
402 }