OpenSubdiv: Properly respect Subdivide UVs option
[blender.git] / source / blender / blenkernel / intern / CCGSubSurf_opensubdiv.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  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
22  *  \ingroup bke
23  */
24
25 #ifdef WITH_OPENSUBDIV
26
27 #include "MEM_guardedalloc.h"
28 #include "BLI_sys_types.h" // for intptr_t support
29
30 #include "BLI_utildefines.h" /* for BLI_assert */
31 #include "BLI_listbase.h"
32 #include "BLI_math.h"
33 #include "BLI_threads.h"
34
35 #include "CCGSubSurf.h"
36 #include "CCGSubSurf_intern.h"
37
38 #include "BKE_DerivedMesh.h"
39 #include "BKE_subsurf.h"
40
41 #include "DNA_userdef_types.h"
42
43 #include "opensubdiv_capi.h"
44 #include "opensubdiv_converter_capi.h"
45
46 #include "GL/glew.h"
47 #include "GPU_extensions.h"
48
49 #define OSD_LOG if (false) printf
50
51 static bool compare_ccg_derivedmesh_topology(CCGSubSurf *ss, DerivedMesh *dm)
52 {
53         const int num_verts = dm->getNumVerts(dm);
54         const int num_edges = dm->getNumEdges(dm);
55         const int num_polys = dm->getNumPolys(dm);
56         const MEdge *medge = dm->getEdgeArray(dm);
57         const MLoop *mloop = dm->getLoopArray(dm);
58         const MPoly *mpoly = dm->getPolyArray(dm);
59
60         /* Quick preliminary tests based on the number of verts and facces. */
61         {
62                 if (num_verts != ss->vMap->numEntries ||
63                     num_edges != ss->eMap->numEntries ||
64                     num_polys != ss->fMap->numEntries)
65                 {
66                         return false;
67                 }
68         }
69
70         /* Rather slow check for faces topology change. */
71         {
72                 CCGFaceIterator ccg_face_iter;
73                 for (ccgSubSurf_initFaceIterator(ss, &ccg_face_iter);
74                      !ccgFaceIterator_isStopped(&ccg_face_iter);
75                      ccgFaceIterator_next(&ccg_face_iter))
76                 {
77                         /*const*/ CCGFace *ccg_face = ccgFaceIterator_getCurrent(&ccg_face_iter);
78                         const int poly_index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ccg_face));
79                         const MPoly *mp = &mpoly[poly_index];
80                         int corner;
81                         if (ccg_face->numVerts != mp->totloop) {
82                                 return false;
83                         }
84                         for (corner = 0; corner < ccg_face->numVerts; corner++) {
85                                 /*const*/ CCGVert *ccg_vert = FACE_getVerts(ccg_face)[corner];
86                                 const int vert_index = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ccg_vert));
87                                 if (vert_index != mloop[mp->loopstart + corner].v) {
88                                         return false;
89                                 }
90                         }
91                 }
92         }
93
94         /* Check for edge topology change. */
95         {
96                 CCGEdgeIterator ccg_edge_iter;
97                 for (ccgSubSurf_initEdgeIterator(ss, &ccg_edge_iter);
98                      !ccgEdgeIterator_isStopped(&ccg_edge_iter);
99                      ccgEdgeIterator_next(&ccg_edge_iter))
100                 {
101                         /* const */ CCGEdge *ccg_edge = ccgEdgeIterator_getCurrent(&ccg_edge_iter);
102                         /* const */ CCGVert *ccg_vert1 = ccg_edge->v0;
103                         /* const */ CCGVert *ccg_vert2 = ccg_edge->v1;
104                         const int ccg_vert1_index = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ccg_vert1));
105                         const int ccg_vert2_index = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ccg_vert2));
106                         const int edge_index = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ccg_edge));
107                         const MEdge *me = &medge[edge_index];
108                         if (me->v1 != ccg_vert1_index || me->v2 != ccg_vert2_index) {
109                                 return false;
110                         }
111                 }
112         }
113
114         /* TODO(sergey): Crease topology changes detection. */
115         {
116                 CCGEdgeIterator ccg_edge_iter;
117                 for (ccgSubSurf_initEdgeIterator(ss, &ccg_edge_iter);
118                      !ccgEdgeIterator_isStopped(&ccg_edge_iter);
119                      ccgEdgeIterator_next(&ccg_edge_iter))
120                 {
121                         /* const */ CCGEdge *ccg_edge = ccgEdgeIterator_getCurrent(&ccg_edge_iter);
122                         const int edge_index = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ccg_edge));
123                         if (ccg_edge->crease != medge[edge_index].crease) {
124                                 return false;
125                         }
126                 }
127         }
128
129         return true;
130 }
131
132 static bool compare_osd_derivedmesh_topology(CCGSubSurf *ss, DerivedMesh *dm)
133 {
134         const OpenSubdiv_TopologyRefinerDescr *topology_refiner;
135         OpenSubdiv_Converter converter;
136         bool result;
137         if (ss->osd_mesh == NULL && ss->osd_topology_refiner == NULL) {
138                 return true;
139         }
140         /* TODO(sergey): De-duplicate with topology counter at the bottom of
141          * the file.
142          */
143         if (ss->osd_topology_refiner != NULL) {
144                 topology_refiner = ss->osd_topology_refiner;
145         }
146         else {
147                 topology_refiner = openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh);
148         }
149         ccgSubSurf_converter_setup_from_derivedmesh(ss, dm, &converter);
150         result = openSubdiv_topologyRefnerCompareConverter(topology_refiner,
151                                                            &converter);
152         ccgSubSurf_converter_free(&converter);
153         return result;
154 }
155
156 static bool opensubdiv_is_topology_changed(CCGSubSurf *ss, DerivedMesh *dm)
157 {
158         if (ss->osd_compute != U.opensubdiv_compute_type) {
159                 return true;
160         }
161         if (ss->osd_topology_refiner != NULL) {
162                 int levels = openSubdiv_topologyRefinerGetSubdivLevel(
163                         ss->osd_topology_refiner);
164                 BLI_assert(ss->osd_mesh_invalid == true);
165                 if (levels != ss->subdivLevels) {
166                         return true;
167                 }
168         }
169         if (ss->osd_mesh != NULL && ss->osd_mesh_invalid == false) {
170                 const OpenSubdiv_TopologyRefinerDescr *topology_refiner =
171                         openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh);
172                 int levels = openSubdiv_topologyRefinerGetSubdivLevel(topology_refiner);
173                 BLI_assert(ss->osd_topology_refiner == NULL);
174                 if (levels != ss->subdivLevels) {
175                         return true;
176                 }
177         }
178         if (ss->skip_grids == false) {
179                 return compare_ccg_derivedmesh_topology(ss, dm) == false;
180         }
181         else {
182                 return compare_osd_derivedmesh_topology(ss, dm) == false;
183         }
184         return false;
185 }
186
187 void ccgSubSurf_checkTopologyChanged(CCGSubSurf *ss, DerivedMesh *dm)
188 {
189         if (opensubdiv_is_topology_changed(ss, dm)) {
190                 /* ** Make sure both GPU and CPU backends are properly reset. ** */
191
192                 ss->osd_coarse_coords_invalid = true;
193
194                 /* Reset GPU part. */
195                 ss->osd_mesh_invalid = true;
196                 if (ss->osd_topology_refiner != NULL) {
197                         openSubdiv_deleteTopologyRefinerDescr(ss->osd_topology_refiner);
198                         ss->osd_topology_refiner = NULL;
199                 }
200
201                 /* Reste CPU side. */
202                 if (ss->osd_evaluator != NULL) {
203                         openSubdiv_deleteEvaluatorDescr(ss->osd_evaluator);
204                         ss->osd_evaluator = NULL;
205                 }
206         }
207 }
208
209 static void ccgSubSurf__updateGLMeshCoords(CCGSubSurf *ss)
210 {
211         BLI_assert(ss->meshIFC.numLayers == 3);
212         openSubdiv_osdGLMeshUpdateVertexBuffer(ss->osd_mesh,
213                                                (float *) ss->osd_coarse_coords,
214                                                0,
215                                                ss->osd_num_coarse_coords);
216 }
217
218 bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss,
219                               bool use_osd_glsl,
220                               int active_uv_index)
221 {
222         int compute_type;
223
224         switch (U.opensubdiv_compute_type) {
225 #define CHECK_COMPUTE_TYPE(type) \
226                 case USER_OPENSUBDIV_COMPUTE_ ## type: \
227                         compute_type = OPENSUBDIV_EVALUATOR_ ## type; \
228                         break;
229                 CHECK_COMPUTE_TYPE(CPU)
230                 CHECK_COMPUTE_TYPE(OPENMP)
231                 CHECK_COMPUTE_TYPE(OPENCL)
232                 CHECK_COMPUTE_TYPE(CUDA)
233                 CHECK_COMPUTE_TYPE(GLSL_TRANSFORM_FEEDBACK)
234                 CHECK_COMPUTE_TYPE(GLSL_COMPUTE)
235 #undef CHECK_COMPUTE_TYPE
236         }
237
238         if (ss->osd_vao == 0) {
239                 glGenVertexArrays(1, &ss->osd_vao);
240         }
241
242         if (ss->osd_mesh_invalid) {
243                 if (ss->osd_mesh != NULL) {
244                         ccgSubSurf__delete_osdGLMesh(ss->osd_mesh);
245                         ss->osd_mesh = NULL;
246                 }
247                 ss->osd_mesh_invalid = false;
248         }
249
250         if (ss->osd_mesh == NULL) {
251                 if (ss->osd_topology_refiner == NULL) {
252                         /* Happens with empty meshes. */
253                         /* TODO(sergey): Add assert that mesh is indeed empty. */
254                         return false;
255                 }
256
257                 ss->osd_mesh = openSubdiv_createOsdGLMeshFromTopologyRefiner(
258                         ss->osd_topology_refiner,
259                         compute_type,
260                         ss->subdivLevels);
261                 ss->osd_topology_refiner = NULL;
262
263                 if (UNLIKELY(ss->osd_mesh == NULL)) {
264                         /* Most likely compute device is not available. */
265                         return false;
266                 }
267
268                 ccgSubSurf__updateGLMeshCoords(ss);
269                 openSubdiv_osdGLMeshRefine(ss->osd_mesh);
270                 openSubdiv_osdGLMeshSynchronize(ss->osd_mesh);
271                 ss->osd_coarse_coords_invalid = false;
272
273                 glBindVertexArray(ss->osd_vao);
274                 glBindBuffer(GL_ARRAY_BUFFER,
275                              openSubdiv_getOsdGLMeshVertexBuffer(ss->osd_mesh));
276
277                 glEnableVertexAttribArray(0);
278                 glEnableVertexAttribArray(1);
279                 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
280                                       sizeof(GLfloat) * 6, 0);
281                 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,
282                                       sizeof(GLfloat) * 6, (float *)12);
283
284                 glBindBuffer(GL_ARRAY_BUFFER, 0);
285         }
286         else if (ss->osd_coarse_coords_invalid) {
287                 ccgSubSurf__updateGLMeshCoords(ss);
288                 openSubdiv_osdGLMeshRefine(ss->osd_mesh);
289                 openSubdiv_osdGLMeshSynchronize(ss->osd_mesh);
290                 ss->osd_coarse_coords_invalid = false;
291         }
292
293         openSubdiv_osdGLMeshDisplayPrepare(use_osd_glsl, active_uv_index);
294
295         return true;
296 }
297
298 void ccgSubSurf_drawGLMesh(CCGSubSurf *ss, bool fill_quads,
299                            int start_partition, int num_partitions)
300 {
301         if (LIKELY(ss->osd_mesh != NULL)) {
302                 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
303                              openSubdiv_getOsdGLMeshPatchIndexBuffer(ss->osd_mesh));
304
305                 openSubdiv_osdGLMeshBindVertexBuffer(ss->osd_mesh);
306                 glBindVertexArray(ss->osd_vao);
307                 openSubdiv_osdGLMeshDisplay(ss->osd_mesh, fill_quads,
308                                             start_partition, num_partitions);
309                 glBindVertexArray(0);
310                 glBindBuffer(GL_ARRAY_BUFFER, 0);
311                 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
312         }
313 }
314
315 int ccgSubSurf_getNumGLMeshBaseFaces(CCGSubSurf *ss)
316 {
317         const OpenSubdiv_TopologyRefinerDescr *topology_refiner;
318         if (ss->osd_topology_refiner != NULL) {
319                 topology_refiner = ss->osd_topology_refiner;
320         }
321         else if (ss->osd_mesh != NULL) {
322                 topology_refiner = openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh);
323         }
324         else {
325                 return 0;
326         }
327         return openSubdiv_topologyRefinerGetNumFaces(topology_refiner);
328 }
329
330 /* Get number of vertices in base faces in a particular GL mesh. */
331 int ccgSubSurf_getNumGLMeshBaseFaceVerts(CCGSubSurf *ss, int face)
332 {
333         const OpenSubdiv_TopologyRefinerDescr *topology_refiner;
334         if (ss->osd_topology_refiner != NULL) {
335                 topology_refiner = ss->osd_topology_refiner;
336         }
337         else if (ss->osd_mesh != NULL) {
338                 topology_refiner = openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh);
339         }
340         else {
341                 return 0;
342         }
343         return openSubdiv_topologyRefinerGetNumFaceVerts(topology_refiner, face);
344 }
345
346 void ccgSubSurf_setSkipGrids(CCGSubSurf *ss, bool skip_grids)
347 {
348         ss->skip_grids = skip_grids;
349 }
350
351 bool ccgSubSurf_needGrids(CCGSubSurf *ss)
352 {
353         return ss->skip_grids == false;
354 }
355
356 BLI_INLINE void ccgSubSurf__mapGridToFace(int S, float grid_u, float grid_v,
357                                           float *face_u, float *face_v)
358 {
359         float u, v;
360
361         /* - Each grid covers half of the face along the edges.
362          * - Grid's (0, 0) starts from the middle of the face.
363          */
364         u = 0.5f - 0.5f * grid_u;
365         v = 0.5f - 0.5f * grid_v;
366
367         if (S == 0) {
368                 *face_u = v;
369                 *face_v = u;
370         }
371         else if (S == 1) {
372                 *face_u = 1.0f - u;
373                 *face_v = v;
374         }
375         else if (S == 2) {
376                 *face_u = 1.0f - v;
377                 *face_v = 1.0f - u;
378         }
379         else {
380                 *face_u = u;
381                 *face_v = 1.0f - v;
382         }
383 }
384
385 BLI_INLINE void ccgSubSurf__mapEdgeToFace(int S,
386                                           int edge_segment,
387                                           bool inverse_edge,
388                                           int edgeSize,
389                                           float *face_u, float *face_v)
390 {
391         int t = inverse_edge ? edgeSize - edge_segment - 1 : edge_segment;
392         if (S == 0) {
393                 *face_u = (float) t / (edgeSize - 1);
394                 *face_v = 0.0f;
395         }
396         else if (S == 1) {
397                 *face_u = 1.0f;
398                 *face_v = (float) t / (edgeSize - 1);
399         }
400         else if (S == 2) {
401                 *face_u = 1.0f - (float) t / (edgeSize - 1);
402                 *face_v = 1.0f;
403         }
404         else {
405                 *face_u = 0.0f;
406                 *face_v = 1.0f - (float) t / (edgeSize - 1);
407         }
408 }
409
410 void ccgSubSurf_evaluatorSetFVarUV(CCGSubSurf *ss,
411                                    DerivedMesh *dm,
412                                    int layer_index)
413 {
414         MPoly *mpoly = dm->getPolyArray(dm);
415         MLoopUV *mloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, layer_index);
416         int num_polys = dm->getNumPolys(dm);
417         int index, poly;
418         BLI_assert(ss->osd_evaluator != NULL);
419         for (poly = 0, index = 0; poly < num_polys; poly++) {
420                 int loop;
421                 MPoly *mp = &mpoly[poly];
422                 for (loop = 0; loop < mp->totloop; loop++, index++) {
423                         MLoopUV *mluv = &mloopuv[loop + mp->loopstart];
424                         (void)mluv;
425                         /* TODO(sergey): Send mluv->uv to the evaluator's face varying
426                          * buffer.
427                          */
428                 }
429         }
430         (void)ss;
431 }
432
433 void ccgSubSurf_evaluatorFVarUV(CCGSubSurf *ss,
434                                 int face_index, int S,
435                                 float grid_u, float grid_v,
436                                 float uv[2])
437 {
438         float face_u, face_v;
439         ccgSubSurf__mapGridToFace(S,
440                                   grid_u, grid_v,
441                                   &face_u, &face_v);
442         (void)ss;
443         (void)face_index;
444         /* TODO(sergey): Evaluate face varying coordinate. */
445         zero_v2(uv);
446 }
447
448 static bool opensubdiv_createEvaluator(CCGSubSurf *ss)
449 {
450         OpenSubdiv_Converter converter;
451         OpenSubdiv_TopologyRefinerDescr *topology_refiner;
452         if (ss->fMap->numEntries == 0) {
453                 /* OpenSubdiv doesn't support meshes without faces. */
454                 return false;
455         }
456         ccgSubSurf_converter_setup_from_ccg(ss, &converter);
457         topology_refiner = openSubdiv_createTopologyRefinerDescr(&converter);
458         ccgSubSurf_converter_free(&converter);
459         ss->osd_evaluator =
460                 openSubdiv_createEvaluatorDescr(topology_refiner,
461                                                 ss->subdivLevels);
462         if (ss->osd_evaluator == NULL) {
463                 BLI_assert(!"OpenSubdiv initialization failed, should not happen.");
464                 return false;
465         }
466         return true;
467 }
468
469 static bool opensubdiv_ensureEvaluator(CCGSubSurf *ss)
470 {
471         if (ss->osd_evaluator == NULL) {
472                 OSD_LOG("Allocating new evaluator, %d verts\n", ss->vMap->numEntries);
473                 opensubdiv_createEvaluator(ss);
474         }
475         return ss->osd_evaluator != NULL;
476 }
477
478 static void opensubdiv_updateEvaluatorCoarsePositions(CCGSubSurf *ss)
479 {
480         float (*positions)[3];
481         int vertDataSize = ss->meshIFC.vertDataSize;
482         int num_basis_verts = ss->vMap->numEntries;
483         int i;
484
485         /* TODO(sergey): Avoid allocation on every update. We could either update
486          * coordinates in chunks of 1K vertices (which will only use stack memory)
487          * or do some callback magic for OSD evaluator can invoke it and fill in
488          * buffer directly.
489          */
490         if (ss->meshIFC.numLayers == 3) {
491                 /* If all the components are to be initialized, no need to memset the
492                  * new memory block.
493                  */
494                 positions = MEM_mallocN(3 * sizeof(float) * num_basis_verts,
495                                         "OpenSubdiv coarse points");
496         }
497         else {
498                 /* Calloc in order to have z component initialized to 0 for Uvs */
499                 positions = MEM_callocN(3 * sizeof(float) * num_basis_verts,
500                                         "OpenSubdiv coarse points");
501         }
502 #pragma omp parallel for
503         for (i = 0; i < ss->vMap->curSize; i++) {
504                 CCGVert *v = (CCGVert *) ss->vMap->buckets[i];
505                 for (; v; v = v->next) {
506                         float *co = VERT_getCo(v, 0);
507                         BLI_assert(v->osd_index < ss->vMap->numEntries);
508                         VertDataCopy(positions[v->osd_index], co, ss);
509                         OSD_LOG("Point %d has value %f %f %f\n",
510                                 v->osd_index,
511                                 positions[v->osd_index][0],
512                                 positions[v->osd_index][1],
513                                 positions[v->osd_index][2]);
514                 }
515         }
516
517         openSubdiv_setEvaluatorCoarsePositions(ss->osd_evaluator,
518                                                (float *)positions,
519                                                0,
520                                                num_basis_verts);
521
522         MEM_freeN(positions);
523 }
524
525 static void opensubdiv_evaluateQuadFaceGrids(CCGSubSurf *ss,
526                                              CCGFace *face,
527                                              const int osd_face_index)
528 {
529         int normalDataOffset = ss->normalDataOffset;
530         int subdivLevels = ss->subdivLevels;
531         int gridSize = ccg_gridsize(subdivLevels);
532         int edgeSize = ccg_edgesize(subdivLevels);
533         int vertDataSize = ss->meshIFC.vertDataSize;
534         int S;
535         bool do_normals = ss->meshIFC.numLayers == 3;
536
537 #pragma omp parallel for
538         for (S = 0; S < face->numVerts; S++) {
539                 int x, y, k;
540                 CCGEdge *edge = NULL;
541                 bool inverse_edge;
542
543                 for (x = 0; x < gridSize; x++) {
544                         for (y = 0; y < gridSize; y++) {
545                                 float *co = FACE_getIFCo(face, subdivLevels, S, x, y);
546                                 float *no = FACE_getIFNo(face, subdivLevels, S, x, y);
547                                 float grid_u = (float) x / (gridSize - 1),
548                                       grid_v = (float) y / (gridSize - 1);
549                                 float face_u, face_v;
550                                 float P[3], dPdu[3], dPdv[3];
551
552                                 ccgSubSurf__mapGridToFace(S, grid_u, grid_v, &face_u, &face_v);
553
554                                 /* TODO(sergey): Need proper port. */
555                                 openSubdiv_evaluateLimit(ss->osd_evaluator, osd_face_index,
556                                                          face_u, face_v,
557                                                          P,
558                                                          do_normals ? dPdu : NULL,
559                                                          do_normals ? dPdv : NULL);
560
561                                 OSD_LOG("face=%d, corner=%d, grid_u=%f, grid_v=%f, face_u=%f, face_v=%f, P=(%f, %f, %f)\n",
562                                         osd_face_index, S, grid_u, grid_v, face_u, face_v, P[0], P[1], P[2]);
563
564                                 VertDataCopy(co, P, ss);
565                                 if (do_normals) {
566                                         cross_v3_v3v3(no, dPdu, dPdv);
567                                         normalize_v3(no);
568                                 }
569
570                                 if (x == gridSize - 1 && y == gridSize - 1) {
571                                         float *vert_co = VERT_getCo(FACE_getVerts(face)[S], subdivLevels);
572                                         VertDataCopy(vert_co, co, ss);
573                                         if (do_normals) {
574                                                 float *vert_no = VERT_getNo(FACE_getVerts(face)[S], subdivLevels);
575                                                 VertDataCopy(vert_no, no, ss);
576                                         }
577                                 }
578                                 if (S == 0 && x == 0 && y == 0) {
579                                         float *center_co = (float *)FACE_getCenterData(face);
580                                         VertDataCopy(center_co, co, ss);
581                                         if (do_normals) {
582                                                 float *center_no = (float *)((byte *)FACE_getCenterData(face) + normalDataOffset);
583                                                 VertDataCopy(center_no, no, ss);
584                                         }
585                                 }
586                         }
587                 }
588
589                 for (x = 0; x < gridSize; x++) {
590                         VertDataCopy(FACE_getIECo(face, subdivLevels, S, x),
591                                      FACE_getIFCo(face, subdivLevels, S, x, 0), ss);
592                         if (do_normals) {
593                                 VertDataCopy(FACE_getIENo(face, subdivLevels, S, x),
594                                              FACE_getIFNo(face, subdivLevels, S, x, 0), ss);
595                         }
596                 }
597
598                 for (k = 0; k < face->numVerts; k++) {
599                         CCGEdge *current_edge = FACE_getEdges(face)[k];
600                         CCGVert **face_verts = FACE_getVerts(face);
601                         if (current_edge->v0 == face_verts[S] &&
602                             current_edge->v1 == face_verts[(S + 1) % face->numVerts])
603                         {
604                                 edge = current_edge;
605                                 inverse_edge = false;
606                                 break;
607                         }
608                         if (current_edge->v1 == face_verts[S] &&
609                             current_edge->v0 == face_verts[(S + 1) % face->numVerts])
610                         {
611                                 edge = current_edge;
612                                 inverse_edge = true;
613                                 break;
614                         }
615                 }
616
617                 BLI_assert(edge != NULL);
618
619                 for (x = 0; x < edgeSize; x++) {
620                         float u = 0, v = 0;
621                         float *co = EDGE_getCo(edge, subdivLevels, x);
622                         float *no = EDGE_getNo(edge, subdivLevels, x);
623                         float P[3], dPdu[3], dPdv[3];
624                         ccgSubSurf__mapEdgeToFace(S, x,
625                                                   inverse_edge,
626                                                   edgeSize,
627                                                   &u, &v);
628
629                         /* TODO(sergey): Ideally we will re-use grid here, but for now
630                          * let's just re-evaluate for simplicity.
631                          */
632                         /* TODO(sergey): Need proper port. */
633                         openSubdiv_evaluateLimit(ss->osd_evaluator, osd_face_index, u, v, P, dPdu, dPdv);
634                         VertDataCopy(co, P, ss);
635                         if (do_normals) {
636                                 cross_v3_v3v3(no, dPdu, dPdv);
637                                 normalize_v3(no);
638                         }
639                 }
640         }
641 }
642
643 static void opensubdiv_evaluateNGonFaceGrids(CCGSubSurf *ss,
644                                              CCGFace *face,
645                                              const int osd_face_index)
646 {
647         CCGVert **all_verts = FACE_getVerts(face);
648         int normalDataOffset = ss->normalDataOffset;
649         int subdivLevels = ss->subdivLevels;
650         int gridSize = ccg_gridsize(subdivLevels);
651         int edgeSize = ccg_edgesize(subdivLevels);
652         int vertDataSize = ss->meshIFC.vertDataSize;
653         int S;
654         bool do_normals = ss->meshIFC.numLayers == 3;
655
656         /* Note about handling non-quad faces.
657          *
658          * In order to deal with non-quad faces we need to split them
659          * into a quads in the following way:
660          *
661          *                                                     |
662          *                                                (vert_next)
663          *                                                     |
664          *                                                     |
665          *                                                     |
666          *                  (face_center) ------------------- (v2)
667          *                         | (o)-------------------->  |
668          *                         |  |                     v  |
669          *                         |  |                        |
670          *                         |  |                        |
671          *                         |  |                        |
672          *                         |  |                   y ^  |
673          *                         |  |                     |  |
674          *                         |  v  u             x    |  |
675          *                         |                   <---(o) |
676          * ---- (vert_prev) ---- (v1)  --------------------  (vert)
677          *
678          * This is how grids are expected to be stored and it's how
679          * OpenSubdiv deals with non-quad faces using ptex face indices.
680          * We only need to convert ptex (x, y) to grid (u, v) by some
681          * simple flips and evaluate the ptex face.
682          */
683
684         /* Evaluate face grids. */
685 #pragma omp parallel for
686         for (S = 0; S < face->numVerts; S++) {
687                 int x, y;
688                 for (x = 0; x < gridSize; x++) {
689                         for (y = 0; y < gridSize; y++) {
690                                 float *co = FACE_getIFCo(face, subdivLevels, S, x, y);
691                                 float *no = FACE_getIFNo(face, subdivLevels, S, x, y);
692                                 float u = 1.0f - (float) y / (gridSize - 1),
693                                       v = 1.0f - (float) x / (gridSize - 1);
694                                 float P[3], dPdu[3], dPdv[3];
695
696                                 /* TODO(sergey): Need proper port. */
697                                 openSubdiv_evaluateLimit(ss->osd_evaluator, osd_face_index + S, u, v, P, dPdu, dPdv);
698
699                                 OSD_LOG("face=%d, corner=%d, u=%f, v=%f, P=(%f, %f, %f)\n",
700                                         osd_face_index + S, S, u, v, P[0], P[1], P[2]);
701
702                                 VertDataCopy(co, P, ss);
703                                 if (do_normals) {
704                                         cross_v3_v3v3(no, dPdu, dPdv);
705                                         normalize_v3(no);
706                                 }
707
708                                 /* TODO(sergey): De-dpuplicate with the quad case. */
709                                 if (x == gridSize - 1 && y == gridSize - 1) {
710                                         float *vert_co = VERT_getCo(FACE_getVerts(face)[S], subdivLevels);
711                                         VertDataCopy(vert_co, co, ss);
712                                         if (do_normals) {
713                                                 float *vert_no = VERT_getNo(FACE_getVerts(face)[S], subdivLevels);
714                                                 VertDataCopy(vert_no, no, ss);
715                                         }
716                                 }
717                                 if (S == 0 && x == 0 && y == 0) {
718                                         float *center_co = (float *)FACE_getCenterData(face);
719                                         VertDataCopy(center_co, co, ss);
720                                         if (do_normals) {
721                                                 float *center_no = (float *)((byte *)FACE_getCenterData(face) + normalDataOffset);
722                                                 VertDataCopy(center_no, no, ss);
723                                         }
724                                 }
725                         }
726                 }
727                 for (x = 0; x < gridSize; x++) {
728                         VertDataCopy(FACE_getIECo(face, subdivLevels, S, x),
729                                      FACE_getIFCo(face, subdivLevels, S, x, 0), ss);
730                         if (do_normals) {
731                                 VertDataCopy(FACE_getIENo(face, subdivLevels, S, x),
732                                              FACE_getIFNo(face, subdivLevels, S, x, 0), ss);
733                         }
734                 }
735         }
736
737         /* Evaluate edges. */
738         for (S = 0; S < face->numVerts; S++) {
739                 CCGEdge *edge = FACE_getEdges(face)[S];
740                 int x, S0, S1;
741                 bool flip;
742
743                 for (x = 0; x < face->numVerts; ++x) {
744                         if (all_verts[x] == edge->v0) {
745                                 S0 = x;
746                         }
747                         else if (all_verts[x] == edge->v1) {
748                                 S1 = x;
749                         }
750                 }
751                 if (S == face->numVerts - 1) {
752                         flip = S0 > S1;
753                 }
754                 else {
755                         flip = S0 < S1;
756                 }
757
758                 for (x = 0; x <= edgeSize / 2; x++) {
759                         float *edge_co = EDGE_getCo(edge, subdivLevels, x);
760                         float *edge_no = EDGE_getNo(edge, subdivLevels, x);
761                         float *face_edge_co;
762                         float *face_edge_no;
763                         if (flip) {
764                                 face_edge_co = FACE_getIFCo(face, subdivLevels, S0, gridSize - 1, gridSize - 1 - x);
765                                 face_edge_no = FACE_getIFNo(face, subdivLevels, S0, gridSize - 1, gridSize - 1 - x);
766                         }
767                         else {
768                                 face_edge_co = FACE_getIFCo(face, subdivLevels, S0, gridSize - 1 - x, gridSize - 1);
769                                 face_edge_no = FACE_getIFNo(face, subdivLevels, S0, gridSize - 1 - x, gridSize - 1);
770                         }
771                         VertDataCopy(edge_co, face_edge_co, ss);
772                         if (do_normals) {
773                                 VertDataCopy(edge_no, face_edge_no, ss);
774                         }
775                 }
776                 for (x = edgeSize / 2 + 1; x < edgeSize; x++) {
777                         float *edge_co = EDGE_getCo(edge, subdivLevels, x);
778                         float *edge_no = EDGE_getNo(edge, subdivLevels, x);
779                         float *face_edge_co;
780                         float *face_edge_no;
781                         if (flip) {
782                                 face_edge_co = FACE_getIFCo(face, subdivLevels, S1, x - edgeSize / 2, gridSize - 1);
783                                 face_edge_no = FACE_getIFNo(face, subdivLevels, S1, x - edgeSize / 2, gridSize - 1);
784                         }
785                         else {
786                                 face_edge_co = FACE_getIFCo(face, subdivLevels, S1, gridSize - 1, x - edgeSize / 2);
787                                 face_edge_no = FACE_getIFNo(face, subdivLevels, S1, gridSize - 1, x - edgeSize / 2);
788                         }
789                         VertDataCopy(edge_co, face_edge_co, ss);
790                         if (do_normals) {
791                                 VertDataCopy(edge_no, face_edge_no, ss);
792                         }
793                 }
794         }
795 }
796
797 static void opensubdiv_evaluateGrids(CCGSubSurf *ss)
798 {
799         int i;
800         for (i = 0; i < ss->fMap->curSize; i++) {
801                 CCGFace *face = (CCGFace *) ss->fMap->buckets[i];
802                 for (; face; face = face->next) {
803                         if (face->numVerts == 4) {
804                                 /* For quads we do special magic with converting face coords
805                                  * into corner coords and interpolating grids from it.
806                                  */
807                                 opensubdiv_evaluateQuadFaceGrids(ss, face, face->osd_index);
808                         }
809                         else {
810                                 /* NGons and tris are split into separate osd faces which
811                                  * evaluates onto grids directly.
812                                  */
813                                 opensubdiv_evaluateNGonFaceGrids(ss, face, face->osd_index);
814                         }
815                 }
816         }
817 }
818
819 CCGError ccgSubSurf_initOpenSubdivSync(CCGSubSurf *ss)
820 {
821         if (ss->syncState != eSyncState_None) {
822                 return eCCGError_InvalidSyncState;
823         }
824         ss->syncState = eSyncState_OpenSubdiv;
825         return eCCGError_None;
826 }
827
828 void ccgSubSurf_prepareTopologyRefiner(CCGSubSurf *ss, DerivedMesh *dm)
829 {
830         if (ss->osd_mesh == NULL || ss->osd_mesh_invalid) {
831                 if (dm->getNumPolys(dm) != 0) {
832                         OpenSubdiv_Converter converter;
833                         ccgSubSurf_converter_setup_from_derivedmesh(ss, dm, &converter);
834                         /* TODO(sergey): Remove possibly previously allocated refiner. */
835                         ss->osd_topology_refiner = openSubdiv_createTopologyRefinerDescr(&converter);
836                         ccgSubSurf_converter_free(&converter);
837                 }
838         }
839
840         /* Update number of grids, needed for things like final faces
841          * counter, used by display drawing.
842          */
843         {
844                 const int num_polys = dm->getNumPolys(dm);
845                 const MPoly *mpoly = dm->getPolyArray(dm);
846                 int poly;
847                 ss->numGrids = 0;
848                 for (poly = 0; poly < num_polys; ++poly) {
849                         ss->numGrids += mpoly[poly].totloop;
850                 }
851         }
852
853         {
854                 const int num_verts = dm->getNumVerts(dm);
855                 const MVert *mvert = dm->getVertArray(dm);
856                 int vert;
857                 if (ss->osd_coarse_coords != NULL &&
858                     num_verts != ss->osd_num_coarse_coords)
859                 {
860                         MEM_freeN(ss->osd_coarse_coords);
861                         ss->osd_coarse_coords = NULL;
862                 }
863                 if (ss->osd_coarse_coords == NULL) {
864                         ss->osd_coarse_coords = MEM_mallocN(sizeof(float) * 6 * num_verts, "osd coarse positions");
865                 }
866                 for (vert = 0; vert < num_verts; vert++) {
867                         copy_v3_v3(ss->osd_coarse_coords[vert * 2 + 0], mvert[vert].co);
868                         normal_short_to_float_v3(ss->osd_coarse_coords[vert * 2 + 1], mvert[vert].no);
869                 }
870                 ss->osd_num_coarse_coords = num_verts;
871                 ss->osd_coarse_coords_invalid = true;
872         }
873 }
874
875 void ccgSubSurf__sync_opensubdiv(CCGSubSurf *ss)
876 {
877         BLI_assert(ss->meshIFC.numLayers == 2 || ss->meshIFC.numLayers == 3);
878
879         /* Common synchronization steps */
880         ss->osd_compute = U.opensubdiv_compute_type;
881
882         if (ss->skip_grids == false) {
883                 /* Make sure OSD evaluator is up-to-date. */
884                 if (opensubdiv_ensureEvaluator(ss)) {
885                         /* Update coarse points in the OpenSubdiv evaluator. */
886                         opensubdiv_updateEvaluatorCoarsePositions(ss);
887
888                         /* Evaluate opensubdiv mesh into the CCG grids. */
889                         opensubdiv_evaluateGrids(ss);
890                 }
891         }
892         else {
893                 BLI_assert(ss->meshIFC.numLayers == 3);
894         }
895
896 #ifdef DUMP_RESULT_GRIDS
897         ccgSubSurf__dumpCoords(ss);
898 #endif
899 }
900
901 void ccgSubSurf_free_osd_mesh(CCGSubSurf *ss)
902 {
903         if (ss->osd_mesh != NULL) {
904                 ccgSubSurf__delete_osdGLMesh(ss->osd_mesh);
905                 ss->osd_mesh = NULL;
906         }
907         if (ss->osd_vao != 0) {
908                 glDeleteVertexArrays(1, &ss->osd_vao);
909                 ss->osd_vao = 0;
910         }
911 }
912
913 void ccgSubSurf_getMinMax(CCGSubSurf *ss, float r_min[3], float r_max[3])
914 {
915         int i;
916         BLI_assert(ss->skip_grids == true);
917         if (ss->osd_num_coarse_coords == 0) {
918                 zero_v3(r_min);
919                 zero_v3(r_max);
920         }
921         for (i = 0; i < ss->osd_num_coarse_coords; i++) {
922                 /* Coarse coordinates has normals interleaved into the array. */
923                 DO_MINMAX(ss->osd_coarse_coords[2 * i], r_min, r_max);
924         }
925 }
926
927 /* ** Delayed delete routines ** */
928
929 typedef struct OsdDeletePendingItem {
930         struct OsdDeletePendingItem *next, *prev;
931         OpenSubdiv_GLMesh *osd_mesh;
932         unsigned int vao;
933 } OsdDeletePendingItem;
934
935 static SpinLock delete_spin;
936 static ListBase delete_pool = {NULL, NULL};
937
938 static void delete_pending_push(OpenSubdiv_GLMesh *osd_mesh,
939                                 unsigned int vao)
940 {
941         OsdDeletePendingItem *new_entry = MEM_mallocN(sizeof(OsdDeletePendingItem),
942                                                       "opensubdiv delete entry");
943         new_entry->osd_mesh = osd_mesh;
944         new_entry->vao = vao;
945         BLI_spin_lock(&delete_spin);
946         BLI_addtail(&delete_pool, new_entry);
947         BLI_spin_unlock(&delete_spin);
948 }
949
950 void ccgSubSurf__delete_osdGLMesh(OpenSubdiv_GLMesh *osd_mesh)
951 {
952         if (BLI_thread_is_main()) {
953                 openSubdiv_deleteOsdGLMesh(osd_mesh);
954         }
955         else {
956                 delete_pending_push(osd_mesh, 0);
957         }
958 }
959
960 void ccgSubSurf__delete_vertex_array(unsigned int vao)
961 {
962         if (BLI_thread_is_main()) {
963                 glDeleteVertexArrays(1, &vao);
964         }
965         else {
966                 delete_pending_push(NULL, vao);
967         }
968 }
969
970 void ccgSubSurf__delete_pending(void)
971 {
972         OsdDeletePendingItem *entry;
973         BLI_assert(BLI_thread_is_main());
974         BLI_spin_lock(&delete_spin);
975         for (entry = delete_pool.first; entry != NULL; entry = entry->next) {
976                 if (entry->osd_mesh != NULL) {
977                         openSubdiv_deleteOsdGLMesh(entry->osd_mesh);
978                 }
979                 if (entry->vao != 0) {
980                         glDeleteVertexArrays(1, &entry->vao);
981                 }
982         }
983         BLI_freelistN(&delete_pool);
984         BLI_spin_unlock(&delete_spin);
985 }
986
987 void ccgSubSurf__sync_subdivUvs(CCGSubSurf *ss, bool subdiv_uvs)
988 {
989     ss->osd_subdiv_uvs = subdiv_uvs;
990 }
991
992 /* ** Public API ** */
993
994 void BKE_subsurf_osd_init(void)
995 {
996         openSubdiv_init(GPU_legacy_support());
997         BLI_spin_init(&delete_spin);
998 }
999
1000 void BKE_subsurf_free_unused_buffers(void)
1001 {
1002         ccgSubSurf__delete_pending();
1003 }
1004
1005 void BKE_subsurf_osd_cleanup(void)
1006 {
1007         openSubdiv_cleanup();
1008         ccgSubSurf__delete_pending();
1009         BLI_spin_end(&delete_spin);
1010 }
1011
1012 #endif  /* WITH_OPENSUBDIV */