Merge branch 'master' into blender2.8
[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 "GPU_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                 glBindVertexArray(0);
286         }
287         else if (ss->osd_coarse_coords_invalid) {
288                 ccgSubSurf__updateGLMeshCoords(ss);
289                 openSubdiv_osdGLMeshRefine(ss->osd_mesh);
290                 openSubdiv_osdGLMeshSynchronize(ss->osd_mesh);
291                 ss->osd_coarse_coords_invalid = false;
292         }
293
294         openSubdiv_osdGLMeshDisplayPrepare(use_osd_glsl, active_uv_index);
295
296         return true;
297 }
298
299 void ccgSubSurf_drawGLMesh(CCGSubSurf *ss, bool fill_quads,
300                            int start_partition, int num_partitions)
301 {
302         if (LIKELY(ss->osd_mesh != NULL)) {
303                 glBindVertexArray(ss->osd_vao);
304                 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
305                              openSubdiv_getOsdGLMeshPatchIndexBuffer(ss->osd_mesh));
306
307                 openSubdiv_osdGLMeshBindVertexBuffer(ss->osd_mesh);
308                 glBindVertexArray(ss->osd_vao);
309                 openSubdiv_osdGLMeshDisplay(ss->osd_mesh, fill_quads,
310                                             start_partition, num_partitions);
311                 glBindVertexArray(0);
312                 glBindBuffer(GL_ARRAY_BUFFER, 0);
313                 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
314         }
315 }
316
317 int ccgSubSurf_getNumGLMeshBaseFaces(CCGSubSurf *ss)
318 {
319         const OpenSubdiv_TopologyRefinerDescr *topology_refiner;
320         if (ss->osd_topology_refiner != NULL) {
321                 topology_refiner = ss->osd_topology_refiner;
322         }
323         else if (ss->osd_mesh != NULL) {
324                 topology_refiner = openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh);
325         }
326         else {
327                 return 0;
328         }
329         return openSubdiv_topologyRefinerGetNumFaces(topology_refiner);
330 }
331
332 /* Get number of vertices in base faces in a particular GL mesh. */
333 int ccgSubSurf_getNumGLMeshBaseFaceVerts(CCGSubSurf *ss, int face)
334 {
335         const OpenSubdiv_TopologyRefinerDescr *topology_refiner;
336         if (ss->osd_topology_refiner != NULL) {
337                 topology_refiner = ss->osd_topology_refiner;
338         }
339         else if (ss->osd_mesh != NULL) {
340                 topology_refiner = openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh);
341         }
342         else {
343                 return 0;
344         }
345         return openSubdiv_topologyRefinerGetNumFaceVerts(topology_refiner, face);
346 }
347
348 void ccgSubSurf_setSkipGrids(CCGSubSurf *ss, bool skip_grids)
349 {
350         ss->skip_grids = skip_grids;
351 }
352
353 bool ccgSubSurf_needGrids(CCGSubSurf *ss)
354 {
355         return ss->skip_grids == false;
356 }
357
358 BLI_INLINE void ccgSubSurf__mapGridToFace(int S, float grid_u, float grid_v,
359                                           float *face_u, float *face_v)
360 {
361         float u, v;
362
363         /* - Each grid covers half of the face along the edges.
364          * - Grid's (0, 0) starts from the middle of the face.
365          */
366         u = 0.5f - 0.5f * grid_u;
367         v = 0.5f - 0.5f * grid_v;
368
369         if (S == 0) {
370                 *face_u = v;
371                 *face_v = u;
372         }
373         else if (S == 1) {
374                 *face_u = 1.0f - u;
375                 *face_v = v;
376         }
377         else if (S == 2) {
378                 *face_u = 1.0f - v;
379                 *face_v = 1.0f - u;
380         }
381         else {
382                 *face_u = u;
383                 *face_v = 1.0f - v;
384         }
385 }
386
387 BLI_INLINE void ccgSubSurf__mapEdgeToFace(int S,
388                                           int edge_segment,
389                                           bool inverse_edge,
390                                           int edgeSize,
391                                           float *face_u, float *face_v)
392 {
393         int t = inverse_edge ? edgeSize - edge_segment - 1 : edge_segment;
394         if (S == 0) {
395                 *face_u = (float) t / (edgeSize - 1);
396                 *face_v = 0.0f;
397         }
398         else if (S == 1) {
399                 *face_u = 1.0f;
400                 *face_v = (float) t / (edgeSize - 1);
401         }
402         else if (S == 2) {
403                 *face_u = 1.0f - (float) t / (edgeSize - 1);
404                 *face_v = 1.0f;
405         }
406         else {
407                 *face_u = 0.0f;
408                 *face_v = 1.0f - (float) t / (edgeSize - 1);
409         }
410 }
411
412 void ccgSubSurf_evaluatorSetFVarUV(CCGSubSurf *ss,
413                                    DerivedMesh *dm,
414                                    int layer_index)
415 {
416         MPoly *mpoly = dm->getPolyArray(dm);
417         MLoopUV *mloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, layer_index);
418         int num_polys = dm->getNumPolys(dm);
419         int index, poly;
420         BLI_assert(ss->osd_evaluator != NULL);
421         for (poly = 0, index = 0; poly < num_polys; poly++) {
422                 int loop;
423                 MPoly *mp = &mpoly[poly];
424                 for (loop = 0; loop < mp->totloop; loop++, index++) {
425                         MLoopUV *mluv = &mloopuv[loop + mp->loopstart];
426                         (void)mluv;
427                         /* TODO(sergey): Send mluv->uv to the evaluator's face varying
428                          * buffer.
429                          */
430                 }
431         }
432         (void)ss;
433 }
434
435 void ccgSubSurf_evaluatorFVarUV(CCGSubSurf *ss,
436                                 int face_index, int S,
437                                 float grid_u, float grid_v,
438                                 float uv[2])
439 {
440         float face_u, face_v;
441         ccgSubSurf__mapGridToFace(S,
442                                   grid_u, grid_v,
443                                   &face_u, &face_v);
444         (void)ss;
445         (void)face_index;
446         /* TODO(sergey): Evaluate face varying coordinate. */
447         zero_v2(uv);
448 }
449
450 static bool opensubdiv_createEvaluator(CCGSubSurf *ss)
451 {
452         OpenSubdiv_Converter converter;
453         OpenSubdiv_TopologyRefinerDescr *topology_refiner;
454         if (ss->fMap->numEntries == 0) {
455                 /* OpenSubdiv doesn't support meshes without faces. */
456                 return false;
457         }
458         ccgSubSurf_converter_setup_from_ccg(ss, &converter);
459         topology_refiner = openSubdiv_createTopologyRefinerDescr(&converter);
460         ccgSubSurf_converter_free(&converter);
461         ss->osd_evaluator =
462                 openSubdiv_createEvaluatorDescr(topology_refiner,
463                                                 ss->subdivLevels);
464         if (ss->osd_evaluator == NULL) {
465                 BLI_assert(!"OpenSubdiv initialization failed, should not happen.");
466                 return false;
467         }
468         return true;
469 }
470
471 static bool opensubdiv_ensureEvaluator(CCGSubSurf *ss)
472 {
473         if (ss->osd_evaluator == NULL) {
474                 OSD_LOG("Allocating new evaluator, %d verts\n", ss->vMap->numEntries);
475                 opensubdiv_createEvaluator(ss);
476         }
477         return ss->osd_evaluator != NULL;
478 }
479
480 static void opensubdiv_updateEvaluatorCoarsePositions(CCGSubSurf *ss)
481 {
482         float (*positions)[3];
483         int vertDataSize = ss->meshIFC.vertDataSize;
484         int num_basis_verts = ss->vMap->numEntries;
485         int i;
486
487         /* TODO(sergey): Avoid allocation on every update. We could either update
488          * coordinates in chunks of 1K vertices (which will only use stack memory)
489          * or do some callback magic for OSD evaluator can invoke it and fill in
490          * buffer directly.
491          */
492         if (ss->meshIFC.numLayers == 3) {
493                 /* If all the components are to be initialized, no need to memset the
494                  * new memory block.
495                  */
496                 positions = MEM_mallocN(3 * sizeof(float) * num_basis_verts,
497                                         "OpenSubdiv coarse points");
498         }
499         else {
500                 /* Calloc in order to have z component initialized to 0 for Uvs */
501                 positions = MEM_callocN(3 * sizeof(float) * num_basis_verts,
502                                         "OpenSubdiv coarse points");
503         }
504 #pragma omp parallel for
505         for (i = 0; i < ss->vMap->curSize; i++) {
506                 CCGVert *v = (CCGVert *) ss->vMap->buckets[i];
507                 for (; v; v = v->next) {
508                         float *co = VERT_getCo(v, 0);
509                         BLI_assert(v->osd_index < ss->vMap->numEntries);
510                         VertDataCopy(positions[v->osd_index], co, ss);
511                         OSD_LOG("Point %d has value %f %f %f\n",
512                                 v->osd_index,
513                                 positions[v->osd_index][0],
514                                 positions[v->osd_index][1],
515                                 positions[v->osd_index][2]);
516                 }
517         }
518
519         openSubdiv_setEvaluatorCoarsePositions(ss->osd_evaluator,
520                                                (float *)positions,
521                                                0,
522                                                num_basis_verts);
523
524         MEM_freeN(positions);
525 }
526
527 static void opensubdiv_evaluateQuadFaceGrids(CCGSubSurf *ss,
528                                              CCGFace *face,
529                                              const int osd_face_index)
530 {
531         int normalDataOffset = ss->normalDataOffset;
532         int subdivLevels = ss->subdivLevels;
533         int gridSize = ccg_gridsize(subdivLevels);
534         int edgeSize = ccg_edgesize(subdivLevels);
535         int vertDataSize = ss->meshIFC.vertDataSize;
536         int S;
537         bool do_normals = ss->meshIFC.numLayers == 3;
538
539 #pragma omp parallel for
540         for (S = 0; S < face->numVerts; S++) {
541                 int x, y, k;
542                 CCGEdge *edge = NULL;
543                 bool inverse_edge;
544
545                 for (x = 0; x < gridSize; x++) {
546                         for (y = 0; y < gridSize; y++) {
547                                 float *co = FACE_getIFCo(face, subdivLevels, S, x, y);
548                                 float *no = FACE_getIFNo(face, subdivLevels, S, x, y);
549                                 float grid_u = (float) x / (gridSize - 1),
550                                       grid_v = (float) y / (gridSize - 1);
551                                 float face_u, face_v;
552                                 float P[3], dPdu[3], dPdv[3];
553
554                                 ccgSubSurf__mapGridToFace(S, grid_u, grid_v, &face_u, &face_v);
555
556                                 /* TODO(sergey): Need proper port. */
557                                 openSubdiv_evaluateLimit(ss->osd_evaluator, osd_face_index,
558                                                          face_u, face_v,
559                                                          P,
560                                                          do_normals ? dPdu : NULL,
561                                                          do_normals ? dPdv : NULL);
562
563                                 OSD_LOG("face=%d, corner=%d, grid_u=%f, grid_v=%f, face_u=%f, face_v=%f, P=(%f, %f, %f)\n",
564                                         osd_face_index, S, grid_u, grid_v, face_u, face_v, P[0], P[1], P[2]);
565
566                                 VertDataCopy(co, P, ss);
567                                 if (do_normals) {
568                                         cross_v3_v3v3(no, dPdu, dPdv);
569                                         normalize_v3(no);
570                                 }
571
572                                 if (x == gridSize - 1 && y == gridSize - 1) {
573                                         float *vert_co = VERT_getCo(FACE_getVerts(face)[S], subdivLevels);
574                                         VertDataCopy(vert_co, co, ss);
575                                         if (do_normals) {
576                                                 float *vert_no = VERT_getNo(FACE_getVerts(face)[S], subdivLevels);
577                                                 VertDataCopy(vert_no, no, ss);
578                                         }
579                                 }
580                                 if (S == 0 && x == 0 && y == 0) {
581                                         float *center_co = (float *)FACE_getCenterData(face);
582                                         VertDataCopy(center_co, co, ss);
583                                         if (do_normals) {
584                                                 float *center_no = (float *)((byte *)FACE_getCenterData(face) + normalDataOffset);
585                                                 VertDataCopy(center_no, no, ss);
586                                         }
587                                 }
588                         }
589                 }
590
591                 for (x = 0; x < gridSize; x++) {
592                         VertDataCopy(FACE_getIECo(face, subdivLevels, S, x),
593                                      FACE_getIFCo(face, subdivLevels, S, x, 0), ss);
594                         if (do_normals) {
595                                 VertDataCopy(FACE_getIENo(face, subdivLevels, S, x),
596                                              FACE_getIFNo(face, subdivLevels, S, x, 0), ss);
597                         }
598                 }
599
600                 for (k = 0; k < face->numVerts; k++) {
601                         CCGEdge *current_edge = FACE_getEdges(face)[k];
602                         CCGVert **face_verts = FACE_getVerts(face);
603                         if (current_edge->v0 == face_verts[S] &&
604                             current_edge->v1 == face_verts[(S + 1) % face->numVerts])
605                         {
606                                 edge = current_edge;
607                                 inverse_edge = false;
608                                 break;
609                         }
610                         if (current_edge->v1 == face_verts[S] &&
611                             current_edge->v0 == face_verts[(S + 1) % face->numVerts])
612                         {
613                                 edge = current_edge;
614                                 inverse_edge = true;
615                                 break;
616                         }
617                 }
618
619                 BLI_assert(edge != NULL);
620
621                 for (x = 0; x < edgeSize; x++) {
622                         float u = 0, v = 0;
623                         float *co = EDGE_getCo(edge, subdivLevels, x);
624                         float *no = EDGE_getNo(edge, subdivLevels, x);
625                         float P[3], dPdu[3], dPdv[3];
626                         ccgSubSurf__mapEdgeToFace(S, x,
627                                                   inverse_edge,
628                                                   edgeSize,
629                                                   &u, &v);
630
631                         /* TODO(sergey): Ideally we will re-use grid here, but for now
632                          * let's just re-evaluate for simplicity.
633                          */
634                         /* TODO(sergey): Need proper port. */
635                         openSubdiv_evaluateLimit(ss->osd_evaluator, osd_face_index, u, v, P, dPdu, dPdv);
636                         VertDataCopy(co, P, ss);
637                         if (do_normals) {
638                                 cross_v3_v3v3(no, dPdu, dPdv);
639                                 normalize_v3(no);
640                         }
641                 }
642         }
643 }
644
645 static void opensubdiv_evaluateNGonFaceGrids(CCGSubSurf *ss,
646                                              CCGFace *face,
647                                              const int osd_face_index)
648 {
649         CCGVert **all_verts = FACE_getVerts(face);
650         int normalDataOffset = ss->normalDataOffset;
651         int subdivLevels = ss->subdivLevels;
652         int gridSize = ccg_gridsize(subdivLevels);
653         int edgeSize = ccg_edgesize(subdivLevels);
654         int vertDataSize = ss->meshIFC.vertDataSize;
655         int S;
656         bool do_normals = ss->meshIFC.numLayers == 3;
657
658         /* Note about handling non-quad faces.
659          *
660          * In order to deal with non-quad faces we need to split them
661          * into a quads in the following way:
662          *
663          *                                                     |
664          *                                                (vert_next)
665          *                                                     |
666          *                                                     |
667          *                                                     |
668          *                  (face_center) ------------------- (v2)
669          *                         | (o)-------------------->  |
670          *                         |  |                     v  |
671          *                         |  |                        |
672          *                         |  |                        |
673          *                         |  |                        |
674          *                         |  |                   y ^  |
675          *                         |  |                     |  |
676          *                         |  v  u             x    |  |
677          *                         |                   <---(o) |
678          * ---- (vert_prev) ---- (v1)  --------------------  (vert)
679          *
680          * This is how grids are expected to be stored and it's how
681          * OpenSubdiv deals with non-quad faces using ptex face indices.
682          * We only need to convert ptex (x, y) to grid (u, v) by some
683          * simple flips and evaluate the ptex face.
684          */
685
686         /* Evaluate face grids. */
687 #pragma omp parallel for
688         for (S = 0; S < face->numVerts; S++) {
689                 int x, y;
690                 for (x = 0; x < gridSize; x++) {
691                         for (y = 0; y < gridSize; y++) {
692                                 float *co = FACE_getIFCo(face, subdivLevels, S, x, y);
693                                 float *no = FACE_getIFNo(face, subdivLevels, S, x, y);
694                                 float u = 1.0f - (float) y / (gridSize - 1),
695                                       v = 1.0f - (float) x / (gridSize - 1);
696                                 float P[3], dPdu[3], dPdv[3];
697
698                                 /* TODO(sergey): Need proper port. */
699                                 openSubdiv_evaluateLimit(ss->osd_evaluator, osd_face_index + S, u, v, P, dPdu, dPdv);
700
701                                 OSD_LOG("face=%d, corner=%d, u=%f, v=%f, P=(%f, %f, %f)\n",
702                                         osd_face_index + S, S, u, v, P[0], P[1], P[2]);
703
704                                 VertDataCopy(co, P, ss);
705                                 if (do_normals) {
706                                         cross_v3_v3v3(no, dPdu, dPdv);
707                                         normalize_v3(no);
708                                 }
709
710                                 /* TODO(sergey): De-dpuplicate with the quad case. */
711                                 if (x == gridSize - 1 && y == gridSize - 1) {
712                                         float *vert_co = VERT_getCo(FACE_getVerts(face)[S], subdivLevels);
713                                         VertDataCopy(vert_co, co, ss);
714                                         if (do_normals) {
715                                                 float *vert_no = VERT_getNo(FACE_getVerts(face)[S], subdivLevels);
716                                                 VertDataCopy(vert_no, no, ss);
717                                         }
718                                 }
719                                 if (S == 0 && x == 0 && y == 0) {
720                                         float *center_co = (float *)FACE_getCenterData(face);
721                                         VertDataCopy(center_co, co, ss);
722                                         if (do_normals) {
723                                                 float *center_no = (float *)((byte *)FACE_getCenterData(face) + normalDataOffset);
724                                                 VertDataCopy(center_no, no, ss);
725                                         }
726                                 }
727                         }
728                 }
729                 for (x = 0; x < gridSize; x++) {
730                         VertDataCopy(FACE_getIECo(face, subdivLevels, S, x),
731                                      FACE_getIFCo(face, subdivLevels, S, x, 0), ss);
732                         if (do_normals) {
733                                 VertDataCopy(FACE_getIENo(face, subdivLevels, S, x),
734                                              FACE_getIFNo(face, subdivLevels, S, x, 0), ss);
735                         }
736                 }
737         }
738
739         /* Evaluate edges. */
740         for (S = 0; S < face->numVerts; S++) {
741                 CCGEdge *edge = FACE_getEdges(face)[S];
742                 int x, S0, S1;
743                 bool flip;
744
745                 for (x = 0; x < face->numVerts; ++x) {
746                         if (all_verts[x] == edge->v0) {
747                                 S0 = x;
748                         }
749                         else if (all_verts[x] == edge->v1) {
750                                 S1 = x;
751                         }
752                 }
753                 if (S == face->numVerts - 1) {
754                         flip = S0 > S1;
755                 }
756                 else {
757                         flip = S0 < S1;
758                 }
759
760                 for (x = 0; x <= edgeSize / 2; x++) {
761                         float *edge_co = EDGE_getCo(edge, subdivLevels, x);
762                         float *edge_no = EDGE_getNo(edge, subdivLevels, x);
763                         float *face_edge_co;
764                         float *face_edge_no;
765                         if (flip) {
766                                 face_edge_co = FACE_getIFCo(face, subdivLevels, S0, gridSize - 1, gridSize - 1 - x);
767                                 face_edge_no = FACE_getIFNo(face, subdivLevels, S0, gridSize - 1, gridSize - 1 - x);
768                         }
769                         else {
770                                 face_edge_co = FACE_getIFCo(face, subdivLevels, S0, gridSize - 1 - x, gridSize - 1);
771                                 face_edge_no = FACE_getIFNo(face, subdivLevels, S0, gridSize - 1 - x, gridSize - 1);
772                         }
773                         VertDataCopy(edge_co, face_edge_co, ss);
774                         if (do_normals) {
775                                 VertDataCopy(edge_no, face_edge_no, ss);
776                         }
777                 }
778                 for (x = edgeSize / 2 + 1; x < edgeSize; x++) {
779                         float *edge_co = EDGE_getCo(edge, subdivLevels, x);
780                         float *edge_no = EDGE_getNo(edge, subdivLevels, x);
781                         float *face_edge_co;
782                         float *face_edge_no;
783                         if (flip) {
784                                 face_edge_co = FACE_getIFCo(face, subdivLevels, S1, x - edgeSize / 2, gridSize - 1);
785                                 face_edge_no = FACE_getIFNo(face, subdivLevels, S1, x - edgeSize / 2, gridSize - 1);
786                         }
787                         else {
788                                 face_edge_co = FACE_getIFCo(face, subdivLevels, S1, gridSize - 1, x - edgeSize / 2);
789                                 face_edge_no = FACE_getIFNo(face, subdivLevels, S1, gridSize - 1, x - edgeSize / 2);
790                         }
791                         VertDataCopy(edge_co, face_edge_co, ss);
792                         if (do_normals) {
793                                 VertDataCopy(edge_no, face_edge_no, ss);
794                         }
795                 }
796         }
797 }
798
799 static void opensubdiv_evaluateGrids(CCGSubSurf *ss)
800 {
801         int i;
802         for (i = 0; i < ss->fMap->curSize; i++) {
803                 CCGFace *face = (CCGFace *) ss->fMap->buckets[i];
804                 for (; face; face = face->next) {
805                         if (face->numVerts == 4) {
806                                 /* For quads we do special magic with converting face coords
807                                  * into corner coords and interpolating grids from it.
808                                  */
809                                 opensubdiv_evaluateQuadFaceGrids(ss, face, face->osd_index);
810                         }
811                         else {
812                                 /* NGons and tris are split into separate osd faces which
813                                  * evaluates onto grids directly.
814                                  */
815                                 opensubdiv_evaluateNGonFaceGrids(ss, face, face->osd_index);
816                         }
817                 }
818         }
819 }
820
821 CCGError ccgSubSurf_initOpenSubdivSync(CCGSubSurf *ss)
822 {
823         if (ss->syncState != eSyncState_None) {
824                 return eCCGError_InvalidSyncState;
825         }
826         ss->syncState = eSyncState_OpenSubdiv;
827         return eCCGError_None;
828 }
829
830 void ccgSubSurf_prepareTopologyRefiner(CCGSubSurf *ss, DerivedMesh *dm)
831 {
832         if (ss->osd_mesh == NULL || ss->osd_mesh_invalid) {
833                 if (dm->getNumPolys(dm) != 0) {
834                         OpenSubdiv_Converter converter;
835                         ccgSubSurf_converter_setup_from_derivedmesh(ss, dm, &converter);
836                         /* TODO(sergey): Remove possibly previously allocated refiner. */
837                         ss->osd_topology_refiner = openSubdiv_createTopologyRefinerDescr(&converter);
838                         ccgSubSurf_converter_free(&converter);
839                 }
840         }
841
842         /* Update number of grids, needed for things like final faces
843          * counter, used by display drawing.
844          */
845         {
846                 const int num_polys = dm->getNumPolys(dm);
847                 const MPoly *mpoly = dm->getPolyArray(dm);
848                 int poly;
849                 ss->numGrids = 0;
850                 for (poly = 0; poly < num_polys; ++poly) {
851                         ss->numGrids += mpoly[poly].totloop;
852                 }
853         }
854
855         {
856                 const int num_verts = dm->getNumVerts(dm);
857                 const MVert *mvert = dm->getVertArray(dm);
858                 int vert;
859                 if (ss->osd_coarse_coords != NULL &&
860                     num_verts != ss->osd_num_coarse_coords)
861                 {
862                         MEM_freeN(ss->osd_coarse_coords);
863                         ss->osd_coarse_coords = NULL;
864                 }
865                 if (ss->osd_coarse_coords == NULL) {
866                         ss->osd_coarse_coords = MEM_mallocN(sizeof(float) * 6 * num_verts, "osd coarse positions");
867                 }
868                 for (vert = 0; vert < num_verts; vert++) {
869                         copy_v3_v3(ss->osd_coarse_coords[vert * 2 + 0], mvert[vert].co);
870                         normal_short_to_float_v3(ss->osd_coarse_coords[vert * 2 + 1], mvert[vert].no);
871                 }
872                 ss->osd_num_coarse_coords = num_verts;
873                 ss->osd_coarse_coords_invalid = true;
874         }
875 }
876
877 void ccgSubSurf__sync_opensubdiv(CCGSubSurf *ss)
878 {
879         BLI_assert(ss->meshIFC.numLayers == 2 || ss->meshIFC.numLayers == 3);
880
881         /* Common synchronization steps */
882         ss->osd_compute = U.opensubdiv_compute_type;
883
884         if (ss->skip_grids == false) {
885                 /* Make sure OSD evaluator is up-to-date. */
886                 if (opensubdiv_ensureEvaluator(ss)) {
887                         /* Update coarse points in the OpenSubdiv evaluator. */
888                         opensubdiv_updateEvaluatorCoarsePositions(ss);
889
890                         /* Evaluate opensubdiv mesh into the CCG grids. */
891                         opensubdiv_evaluateGrids(ss);
892                 }
893         }
894         else {
895                 BLI_assert(ss->meshIFC.numLayers == 3);
896         }
897
898 #ifdef DUMP_RESULT_GRIDS
899         ccgSubSurf__dumpCoords(ss);
900 #endif
901 }
902
903 void ccgSubSurf_free_osd_mesh(CCGSubSurf *ss)
904 {
905         if (ss->osd_mesh != NULL) {
906                 ccgSubSurf__delete_osdGLMesh(ss->osd_mesh);
907                 ss->osd_mesh = NULL;
908         }
909         if (ss->osd_vao != 0) {
910                 glDeleteVertexArrays(1, &ss->osd_vao);
911                 ss->osd_vao = 0;
912         }
913 }
914
915 void ccgSubSurf_getMinMax(CCGSubSurf *ss, float r_min[3], float r_max[3])
916 {
917         int i;
918         BLI_assert(ss->skip_grids == true);
919         if (ss->osd_num_coarse_coords == 0) {
920                 zero_v3(r_min);
921                 zero_v3(r_max);
922         }
923         for (i = 0; i < ss->osd_num_coarse_coords; i++) {
924                 /* Coarse coordinates has normals interleaved into the array. */
925                 DO_MINMAX(ss->osd_coarse_coords[2 * i], r_min, r_max);
926         }
927 }
928
929 /* ** Delayed delete routines ** */
930
931 typedef struct OsdDeletePendingItem {
932         struct OsdDeletePendingItem *next, *prev;
933         OpenSubdiv_GLMesh *osd_mesh;
934         unsigned int vao;
935 } OsdDeletePendingItem;
936
937 static SpinLock delete_spin;
938 static ListBase delete_pool = {NULL, NULL};
939
940 static void delete_pending_push(OpenSubdiv_GLMesh *osd_mesh,
941                                 unsigned int vao)
942 {
943         OsdDeletePendingItem *new_entry = MEM_mallocN(sizeof(OsdDeletePendingItem),
944                                                       "opensubdiv delete entry");
945         new_entry->osd_mesh = osd_mesh;
946         new_entry->vao = vao;
947         BLI_spin_lock(&delete_spin);
948         BLI_addtail(&delete_pool, new_entry);
949         BLI_spin_unlock(&delete_spin);
950 }
951
952 void ccgSubSurf__delete_osdGLMesh(OpenSubdiv_GLMesh *osd_mesh)
953 {
954         if (BLI_thread_is_main()) {
955                 openSubdiv_deleteOsdGLMesh(osd_mesh);
956         }
957         else {
958                 delete_pending_push(osd_mesh, 0);
959         }
960 }
961
962 void ccgSubSurf__delete_vertex_array(unsigned int vao)
963 {
964         if (BLI_thread_is_main()) {
965                 glDeleteVertexArrays(1, &vao);
966         }
967         else {
968                 delete_pending_push(NULL, vao);
969         }
970 }
971
972 void ccgSubSurf__delete_pending(void)
973 {
974         OsdDeletePendingItem *entry;
975         BLI_assert(BLI_thread_is_main());
976         BLI_spin_lock(&delete_spin);
977         for (entry = delete_pool.first; entry != NULL; entry = entry->next) {
978                 if (entry->osd_mesh != NULL) {
979                         openSubdiv_deleteOsdGLMesh(entry->osd_mesh);
980                 }
981                 if (entry->vao != 0) {
982                         glDeleteVertexArrays(1, &entry->vao);
983                 }
984         }
985         BLI_freelistN(&delete_pool);
986         BLI_spin_unlock(&delete_spin);
987 }
988
989 void ccgSubSurf__sync_subdivUvs(CCGSubSurf *ss, bool subdiv_uvs)
990 {
991     ss->osd_subdiv_uvs = subdiv_uvs;
992 }
993
994 /* ** Public API ** */
995
996 void BKE_subsurf_osd_init(void)
997 {
998         openSubdiv_init();
999         BLI_spin_init(&delete_spin);
1000 }
1001
1002 void BKE_subsurf_free_unused_buffers(void)
1003 {
1004         ccgSubSurf__delete_pending();
1005 }
1006
1007 void BKE_subsurf_osd_cleanup(void)
1008 {
1009         openSubdiv_cleanup();
1010         ccgSubSurf__delete_pending();
1011         BLI_spin_end(&delete_spin);
1012 }
1013
1014 #endif  /* WITH_OPENSUBDIV */