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