CCGSubSurf_opensubdiv.c 30 KB

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