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