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