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