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