2
0

btMiniSDF.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. #include "btMiniSDF.h"
  2. //
  3. //Based on code from DiscreGrid, https://github.com/InteractiveComputerGraphics/Discregrid
  4. //example:
  5. //GenerateSDF.exe -r "32 32 32" -d "-1.6 -1.6 -.6 1.6 1.6 .6" concave_box.obj
  6. //The MIT License (MIT)
  7. //
  8. //Copyright (c) 2017 Dan Koschier
  9. //
  10. #include <limits.h>
  11. #include <string.h> //memcpy
  12. struct btSdfDataStream
  13. {
  14. const char* m_data;
  15. int m_size;
  16. int m_currentOffset;
  17. btSdfDataStream(const char* data, int size)
  18. : m_data(data),
  19. m_size(size),
  20. m_currentOffset(0)
  21. {
  22. }
  23. template <class T>
  24. bool read(T& val)
  25. {
  26. int bytes = sizeof(T);
  27. if (m_currentOffset + bytes <= m_size)
  28. {
  29. char* dest = (char*)&val;
  30. memcpy(dest, &m_data[m_currentOffset], bytes);
  31. m_currentOffset += bytes;
  32. return true;
  33. }
  34. btAssert(0);
  35. return false;
  36. }
  37. };
  38. bool btMiniSDF::load(const char* data, int size)
  39. {
  40. int fileSize = -1;
  41. btSdfDataStream ds(data, size);
  42. {
  43. double buf[6];
  44. ds.read(buf);
  45. m_domain.m_min[0] = buf[0];
  46. m_domain.m_min[1] = buf[1];
  47. m_domain.m_min[2] = buf[2];
  48. m_domain.m_min[3] = 0;
  49. m_domain.m_max[0] = buf[3];
  50. m_domain.m_max[1] = buf[4];
  51. m_domain.m_max[2] = buf[5];
  52. m_domain.m_max[3] = 0;
  53. }
  54. {
  55. unsigned int buf2[3];
  56. ds.read(buf2);
  57. m_resolution[0] = buf2[0];
  58. m_resolution[1] = buf2[1];
  59. m_resolution[2] = buf2[2];
  60. }
  61. {
  62. double buf[3];
  63. ds.read(buf);
  64. m_cell_size[0] = buf[0];
  65. m_cell_size[1] = buf[1];
  66. m_cell_size[2] = buf[2];
  67. }
  68. {
  69. double buf[3];
  70. ds.read(buf);
  71. m_inv_cell_size[0] = buf[0];
  72. m_inv_cell_size[1] = buf[1];
  73. m_inv_cell_size[2] = buf[2];
  74. }
  75. {
  76. unsigned long long int cells;
  77. ds.read(cells);
  78. m_n_cells = cells;
  79. }
  80. {
  81. unsigned long long int fields;
  82. ds.read(fields);
  83. m_n_fields = fields;
  84. }
  85. unsigned long long int nodes0;
  86. std::size_t n_nodes0;
  87. ds.read(nodes0);
  88. n_nodes0 = nodes0;
  89. if (n_nodes0 > 1024 * 1024 * 1024)
  90. {
  91. return m_isValid;
  92. }
  93. m_nodes.resize(n_nodes0);
  94. for (unsigned int i = 0; i < n_nodes0; i++)
  95. {
  96. unsigned long long int n_nodes1;
  97. ds.read(n_nodes1);
  98. btAlignedObjectArray<double>& nodes = m_nodes[i];
  99. nodes.resize(n_nodes1);
  100. for (int j = 0; j < nodes.size(); j++)
  101. {
  102. double& node = nodes[j];
  103. ds.read(node);
  104. }
  105. }
  106. unsigned long long int n_cells0;
  107. ds.read(n_cells0);
  108. m_cells.resize(n_cells0);
  109. for (int i = 0; i < n_cells0; i++)
  110. {
  111. unsigned long long int n_cells1;
  112. btAlignedObjectArray<btCell32>& cells = m_cells[i];
  113. ds.read(n_cells1);
  114. cells.resize(n_cells1);
  115. for (int j = 0; j < n_cells1; j++)
  116. {
  117. btCell32& cell = cells[j];
  118. ds.read(cell);
  119. }
  120. }
  121. {
  122. unsigned long long int n_cell_maps0;
  123. ds.read(n_cell_maps0);
  124. m_cell_map.resize(n_cell_maps0);
  125. for (int i = 0; i < n_cell_maps0; i++)
  126. {
  127. unsigned long long int n_cell_maps1;
  128. btAlignedObjectArray<unsigned int>& cell_maps = m_cell_map[i];
  129. ds.read(n_cell_maps1);
  130. cell_maps.resize(n_cell_maps1);
  131. for (int j = 0; j < n_cell_maps1; j++)
  132. {
  133. unsigned int& cell_map = cell_maps[j];
  134. ds.read(cell_map);
  135. }
  136. }
  137. }
  138. m_isValid = (ds.m_currentOffset == ds.m_size);
  139. return m_isValid;
  140. }
  141. unsigned int btMiniSDF::multiToSingleIndex(btMultiIndex const& ijk) const
  142. {
  143. return m_resolution[1] * m_resolution[0] * ijk.ijk[2] + m_resolution[0] * ijk.ijk[1] + ijk.ijk[0];
  144. }
  145. btAlignedBox3d
  146. btMiniSDF::subdomain(btMultiIndex const& ijk) const
  147. {
  148. btAssert(m_isValid);
  149. btVector3 tmp;
  150. tmp.m_floats[0] = m_cell_size[0] * (double)ijk.ijk[0];
  151. tmp.m_floats[1] = m_cell_size[1] * (double)ijk.ijk[1];
  152. tmp.m_floats[2] = m_cell_size[2] * (double)ijk.ijk[2];
  153. btVector3 origin = m_domain.min() + tmp;
  154. btAlignedBox3d box = btAlignedBox3d(origin, origin + m_cell_size);
  155. return box;
  156. }
  157. btMultiIndex
  158. btMiniSDF::singleToMultiIndex(unsigned int l) const
  159. {
  160. btAssert(m_isValid);
  161. unsigned int n01 = m_resolution[0] * m_resolution[1];
  162. unsigned int k = l / n01;
  163. unsigned int temp = l % n01;
  164. unsigned int j = temp / m_resolution[0];
  165. unsigned int i = temp % m_resolution[0];
  166. btMultiIndex mi;
  167. mi.ijk[0] = i;
  168. mi.ijk[1] = j;
  169. mi.ijk[2] = k;
  170. return mi;
  171. }
  172. btAlignedBox3d
  173. btMiniSDF::subdomain(unsigned int l) const
  174. {
  175. btAssert(m_isValid);
  176. return subdomain(singleToMultiIndex(l));
  177. }
  178. btShapeMatrix
  179. btMiniSDF::shape_function_(btVector3 const& xi, btShapeGradients* gradient) const
  180. {
  181. btAssert(m_isValid);
  182. btShapeMatrix res;
  183. btScalar x = xi[0];
  184. btScalar y = xi[1];
  185. btScalar z = xi[2];
  186. btScalar x2 = x * x;
  187. btScalar y2 = y * y;
  188. btScalar z2 = z * z;
  189. btScalar _1mx = 1.0 - x;
  190. btScalar _1my = 1.0 - y;
  191. btScalar _1mz = 1.0 - z;
  192. btScalar _1px = 1.0 + x;
  193. btScalar _1py = 1.0 + y;
  194. btScalar _1pz = 1.0 + z;
  195. btScalar _1m3x = 1.0 - 3.0 * x;
  196. btScalar _1m3y = 1.0 - 3.0 * y;
  197. btScalar _1m3z = 1.0 - 3.0 * z;
  198. btScalar _1p3x = 1.0 + 3.0 * x;
  199. btScalar _1p3y = 1.0 + 3.0 * y;
  200. btScalar _1p3z = 1.0 + 3.0 * z;
  201. btScalar _1mxt1my = _1mx * _1my;
  202. btScalar _1mxt1py = _1mx * _1py;
  203. btScalar _1pxt1my = _1px * _1my;
  204. btScalar _1pxt1py = _1px * _1py;
  205. btScalar _1mxt1mz = _1mx * _1mz;
  206. btScalar _1mxt1pz = _1mx * _1pz;
  207. btScalar _1pxt1mz = _1px * _1mz;
  208. btScalar _1pxt1pz = _1px * _1pz;
  209. btScalar _1myt1mz = _1my * _1mz;
  210. btScalar _1myt1pz = _1my * _1pz;
  211. btScalar _1pyt1mz = _1py * _1mz;
  212. btScalar _1pyt1pz = _1py * _1pz;
  213. btScalar _1mx2 = 1.0 - x2;
  214. btScalar _1my2 = 1.0 - y2;
  215. btScalar _1mz2 = 1.0 - z2;
  216. // Corner nodes.
  217. btScalar fac = 1.0 / 64.0 * (9.0 * (x2 + y2 + z2) - 19.0);
  218. res[0] = fac * _1mxt1my * _1mz;
  219. res[1] = fac * _1pxt1my * _1mz;
  220. res[2] = fac * _1mxt1py * _1mz;
  221. res[3] = fac * _1pxt1py * _1mz;
  222. res[4] = fac * _1mxt1my * _1pz;
  223. res[5] = fac * _1pxt1my * _1pz;
  224. res[6] = fac * _1mxt1py * _1pz;
  225. res[7] = fac * _1pxt1py * _1pz;
  226. // Edge nodes.
  227. fac = 9.0 / 64.0 * _1mx2;
  228. btScalar fact1m3x = fac * _1m3x;
  229. btScalar fact1p3x = fac * _1p3x;
  230. res[8] = fact1m3x * _1myt1mz;
  231. res[9] = fact1p3x * _1myt1mz;
  232. res[10] = fact1m3x * _1myt1pz;
  233. res[11] = fact1p3x * _1myt1pz;
  234. res[12] = fact1m3x * _1pyt1mz;
  235. res[13] = fact1p3x * _1pyt1mz;
  236. res[14] = fact1m3x * _1pyt1pz;
  237. res[15] = fact1p3x * _1pyt1pz;
  238. fac = 9.0 / 64.0 * _1my2;
  239. btScalar fact1m3y = fac * _1m3y;
  240. btScalar fact1p3y = fac * _1p3y;
  241. res[16] = fact1m3y * _1mxt1mz;
  242. res[17] = fact1p3y * _1mxt1mz;
  243. res[18] = fact1m3y * _1pxt1mz;
  244. res[19] = fact1p3y * _1pxt1mz;
  245. res[20] = fact1m3y * _1mxt1pz;
  246. res[21] = fact1p3y * _1mxt1pz;
  247. res[22] = fact1m3y * _1pxt1pz;
  248. res[23] = fact1p3y * _1pxt1pz;
  249. fac = 9.0 / 64.0 * _1mz2;
  250. btScalar fact1m3z = fac * _1m3z;
  251. btScalar fact1p3z = fac * _1p3z;
  252. res[24] = fact1m3z * _1mxt1my;
  253. res[25] = fact1p3z * _1mxt1my;
  254. res[26] = fact1m3z * _1mxt1py;
  255. res[27] = fact1p3z * _1mxt1py;
  256. res[28] = fact1m3z * _1pxt1my;
  257. res[29] = fact1p3z * _1pxt1my;
  258. res[30] = fact1m3z * _1pxt1py;
  259. res[31] = fact1p3z * _1pxt1py;
  260. if (gradient)
  261. {
  262. btShapeGradients& dN = *gradient;
  263. btScalar _9t3x2py2pz2m19 = 9.0 * (3.0 * x2 + y2 + z2) - 19.0;
  264. btScalar _9tx2p3y2pz2m19 = 9.0 * (x2 + 3.0 * y2 + z2) - 19.0;
  265. btScalar _9tx2py2p3z2m19 = 9.0 * (x2 + y2 + 3.0 * z2) - 19.0;
  266. btScalar _18x = 18.0 * x;
  267. btScalar _18y = 18.0 * y;
  268. btScalar _18z = 18.0 * z;
  269. btScalar _3m9x2 = 3.0 - 9.0 * x2;
  270. btScalar _3m9y2 = 3.0 - 9.0 * y2;
  271. btScalar _3m9z2 = 3.0 - 9.0 * z2;
  272. btScalar _2x = 2.0 * x;
  273. btScalar _2y = 2.0 * y;
  274. btScalar _2z = 2.0 * z;
  275. btScalar _18xm9t3x2py2pz2m19 = _18x - _9t3x2py2pz2m19;
  276. btScalar _18xp9t3x2py2pz2m19 = _18x + _9t3x2py2pz2m19;
  277. btScalar _18ym9tx2p3y2pz2m19 = _18y - _9tx2p3y2pz2m19;
  278. btScalar _18yp9tx2p3y2pz2m19 = _18y + _9tx2p3y2pz2m19;
  279. btScalar _18zm9tx2py2p3z2m19 = _18z - _9tx2py2p3z2m19;
  280. btScalar _18zp9tx2py2p3z2m19 = _18z + _9tx2py2p3z2m19;
  281. dN(0, 0) = _18xm9t3x2py2pz2m19 * _1myt1mz;
  282. dN(0, 1) = _1mxt1mz * _18ym9tx2p3y2pz2m19;
  283. dN(0, 2) = _1mxt1my * _18zm9tx2py2p3z2m19;
  284. dN(1, 0) = _18xp9t3x2py2pz2m19 * _1myt1mz;
  285. dN(1, 1) = _1pxt1mz * _18ym9tx2p3y2pz2m19;
  286. dN(1, 2) = _1pxt1my * _18zm9tx2py2p3z2m19;
  287. dN(2, 0) = _18xm9t3x2py2pz2m19 * _1pyt1mz;
  288. dN(2, 1) = _1mxt1mz * _18yp9tx2p3y2pz2m19;
  289. dN(2, 2) = _1mxt1py * _18zm9tx2py2p3z2m19;
  290. dN(3, 0) = _18xp9t3x2py2pz2m19 * _1pyt1mz;
  291. dN(3, 1) = _1pxt1mz * _18yp9tx2p3y2pz2m19;
  292. dN(3, 2) = _1pxt1py * _18zm9tx2py2p3z2m19;
  293. dN(4, 0) = _18xm9t3x2py2pz2m19 * _1myt1pz;
  294. dN(4, 1) = _1mxt1pz * _18ym9tx2p3y2pz2m19;
  295. dN(4, 2) = _1mxt1my * _18zp9tx2py2p3z2m19;
  296. dN(5, 0) = _18xp9t3x2py2pz2m19 * _1myt1pz;
  297. dN(5, 1) = _1pxt1pz * _18ym9tx2p3y2pz2m19;
  298. dN(5, 2) = _1pxt1my * _18zp9tx2py2p3z2m19;
  299. dN(6, 0) = _18xm9t3x2py2pz2m19 * _1pyt1pz;
  300. dN(6, 1) = _1mxt1pz * _18yp9tx2p3y2pz2m19;
  301. dN(6, 2) = _1mxt1py * _18zp9tx2py2p3z2m19;
  302. dN(7, 0) = _18xp9t3x2py2pz2m19 * _1pyt1pz;
  303. dN(7, 1) = _1pxt1pz * _18yp9tx2p3y2pz2m19;
  304. dN(7, 2) = _1pxt1py * _18zp9tx2py2p3z2m19;
  305. dN.topRowsDivide(8, 64.0);
  306. btScalar _m3m9x2m2x = -_3m9x2 - _2x;
  307. btScalar _p3m9x2m2x = _3m9x2 - _2x;
  308. btScalar _1mx2t1m3x = _1mx2 * _1m3x;
  309. btScalar _1mx2t1p3x = _1mx2 * _1p3x;
  310. dN(8, 0) = _m3m9x2m2x * _1myt1mz,
  311. dN(8, 1) = -_1mx2t1m3x * _1mz,
  312. dN(8, 2) = -_1mx2t1m3x * _1my;
  313. dN(9, 0) = _p3m9x2m2x * _1myt1mz,
  314. dN(9, 1) = -_1mx2t1p3x * _1mz,
  315. dN(9, 2) = -_1mx2t1p3x * _1my;
  316. dN(10, 0) = _m3m9x2m2x * _1myt1pz,
  317. dN(10, 1) = -_1mx2t1m3x * _1pz,
  318. dN(10, 2) = _1mx2t1m3x * _1my;
  319. dN(11, 0) = _p3m9x2m2x * _1myt1pz,
  320. dN(11, 1) = -_1mx2t1p3x * _1pz,
  321. dN(11, 2) = _1mx2t1p3x * _1my;
  322. dN(12, 0) = _m3m9x2m2x * _1pyt1mz,
  323. dN(12, 1) = _1mx2t1m3x * _1mz,
  324. dN(12, 2) = -_1mx2t1m3x * _1py;
  325. dN(13, 0) = _p3m9x2m2x * _1pyt1mz,
  326. dN(13, 1) = _1mx2t1p3x * _1mz,
  327. dN(13, 2) = -_1mx2t1p3x * _1py;
  328. dN(14, 0) = _m3m9x2m2x * _1pyt1pz,
  329. dN(14, 1) = _1mx2t1m3x * _1pz,
  330. dN(14, 2) = _1mx2t1m3x * _1py;
  331. dN(15, 0) = _p3m9x2m2x * _1pyt1pz,
  332. dN(15, 1) = _1mx2t1p3x * _1pz,
  333. dN(15, 2) = _1mx2t1p3x * _1py;
  334. btScalar _m3m9y2m2y = -_3m9y2 - _2y;
  335. btScalar _p3m9y2m2y = _3m9y2 - _2y;
  336. btScalar _1my2t1m3y = _1my2 * _1m3y;
  337. btScalar _1my2t1p3y = _1my2 * _1p3y;
  338. dN(16, 0) = -_1my2t1m3y * _1mz,
  339. dN(16, 1) = _m3m9y2m2y * _1mxt1mz,
  340. dN(16, 2) = -_1my2t1m3y * _1mx;
  341. dN(17, 0) = -_1my2t1p3y * _1mz,
  342. dN(17, 1) = _p3m9y2m2y * _1mxt1mz,
  343. dN(17, 2) = -_1my2t1p3y * _1mx;
  344. dN(18, 0) = _1my2t1m3y * _1mz,
  345. dN(18, 1) = _m3m9y2m2y * _1pxt1mz,
  346. dN(18, 2) = -_1my2t1m3y * _1px;
  347. dN(19, 0) = _1my2t1p3y * _1mz,
  348. dN(19, 1) = _p3m9y2m2y * _1pxt1mz,
  349. dN(19, 2) = -_1my2t1p3y * _1px;
  350. dN(20, 0) = -_1my2t1m3y * _1pz,
  351. dN(20, 1) = _m3m9y2m2y * _1mxt1pz,
  352. dN(20, 2) = _1my2t1m3y * _1mx;
  353. dN(21, 0) = -_1my2t1p3y * _1pz,
  354. dN(21, 1) = _p3m9y2m2y * _1mxt1pz,
  355. dN(21, 2) = _1my2t1p3y * _1mx;
  356. dN(22, 0) = _1my2t1m3y * _1pz,
  357. dN(22, 1) = _m3m9y2m2y * _1pxt1pz,
  358. dN(22, 2) = _1my2t1m3y * _1px;
  359. dN(23, 0) = _1my2t1p3y * _1pz,
  360. dN(23, 1) = _p3m9y2m2y * _1pxt1pz,
  361. dN(23, 2) = _1my2t1p3y * _1px;
  362. btScalar _m3m9z2m2z = -_3m9z2 - _2z;
  363. btScalar _p3m9z2m2z = _3m9z2 - _2z;
  364. btScalar _1mz2t1m3z = _1mz2 * _1m3z;
  365. btScalar _1mz2t1p3z = _1mz2 * _1p3z;
  366. dN(24, 0) = -_1mz2t1m3z * _1my,
  367. dN(24, 1) = -_1mz2t1m3z * _1mx,
  368. dN(24, 2) = _m3m9z2m2z * _1mxt1my;
  369. dN(25, 0) = -_1mz2t1p3z * _1my,
  370. dN(25, 1) = -_1mz2t1p3z * _1mx,
  371. dN(25, 2) = _p3m9z2m2z * _1mxt1my;
  372. dN(26, 0) = -_1mz2t1m3z * _1py,
  373. dN(26, 1) = _1mz2t1m3z * _1mx,
  374. dN(26, 2) = _m3m9z2m2z * _1mxt1py;
  375. dN(27, 0) = -_1mz2t1p3z * _1py,
  376. dN(27, 1) = _1mz2t1p3z * _1mx,
  377. dN(27, 2) = _p3m9z2m2z * _1mxt1py;
  378. dN(28, 0) = _1mz2t1m3z * _1my,
  379. dN(28, 1) = -_1mz2t1m3z * _1px,
  380. dN(28, 2) = _m3m9z2m2z * _1pxt1my;
  381. dN(29, 0) = _1mz2t1p3z * _1my,
  382. dN(29, 1) = -_1mz2t1p3z * _1px,
  383. dN(29, 2) = _p3m9z2m2z * _1pxt1my;
  384. dN(30, 0) = _1mz2t1m3z * _1py,
  385. dN(30, 1) = _1mz2t1m3z * _1px,
  386. dN(30, 2) = _m3m9z2m2z * _1pxt1py;
  387. dN(31, 0) = _1mz2t1p3z * _1py,
  388. dN(31, 1) = _1mz2t1p3z * _1px,
  389. dN(31, 2) = _p3m9z2m2z * _1pxt1py;
  390. dN.bottomRowsMul(32u - 8u, 9.0 / 64.0);
  391. }
  392. return res;
  393. }
  394. bool btMiniSDF::interpolate(unsigned int field_id, double& dist, btVector3 const& x,
  395. btVector3* gradient) const
  396. {
  397. btAssert(m_isValid);
  398. if (!m_isValid)
  399. return false;
  400. if (!m_domain.contains(x))
  401. return false;
  402. btVector3 tmpmi = ((x - m_domain.min()) * (m_inv_cell_size)); //.cast<unsigned int>().eval();
  403. unsigned int mi[3] = {(unsigned int)tmpmi[0], (unsigned int)tmpmi[1], (unsigned int)tmpmi[2]};
  404. if (mi[0] >= m_resolution[0])
  405. mi[0] = m_resolution[0] - 1;
  406. if (mi[1] >= m_resolution[1])
  407. mi[1] = m_resolution[1] - 1;
  408. if (mi[2] >= m_resolution[2])
  409. mi[2] = m_resolution[2] - 1;
  410. btMultiIndex mui;
  411. mui.ijk[0] = mi[0];
  412. mui.ijk[1] = mi[1];
  413. mui.ijk[2] = mi[2];
  414. int i = multiToSingleIndex(mui);
  415. unsigned int i_ = m_cell_map[field_id][i];
  416. if (i_ == UINT_MAX)
  417. return false;
  418. btAlignedBox3d sd = subdomain(i);
  419. i = i_;
  420. btVector3 d = sd.m_max - sd.m_min; //.diagonal().eval();
  421. btVector3 denom = (sd.max() - sd.min());
  422. btVector3 c0 = btVector3(2.0, 2.0, 2.0) / denom;
  423. btVector3 c1 = (sd.max() + sd.min()) / denom;
  424. btVector3 xi = (c0 * x - c1);
  425. btCell32 const& cell = m_cells[field_id][i];
  426. if (!gradient)
  427. {
  428. //auto phi = m_coefficients[field_id][i].dot(shape_function_(xi, 0));
  429. double phi = 0.0;
  430. btShapeMatrix N = shape_function_(xi, 0);
  431. for (unsigned int j = 0u; j < 32u; ++j)
  432. {
  433. unsigned int v = cell.m_cells[j];
  434. double c = m_nodes[field_id][v];
  435. if (c == DBL_MAX)
  436. {
  437. return false;
  438. ;
  439. }
  440. phi += c * N[j];
  441. }
  442. dist = phi;
  443. return true;
  444. }
  445. btShapeGradients dN;
  446. btShapeMatrix N = shape_function_(xi, &dN);
  447. double phi = 0.0;
  448. gradient->setZero();
  449. for (unsigned int j = 0u; j < 32u; ++j)
  450. {
  451. unsigned int v = cell.m_cells[j];
  452. double c = m_nodes[field_id][v];
  453. if (c == DBL_MAX)
  454. {
  455. gradient->setZero();
  456. return false;
  457. }
  458. phi += c * N[j];
  459. (*gradient)[0] += c * dN(j, 0);
  460. (*gradient)[1] += c * dN(j, 1);
  461. (*gradient)[2] += c * dN(j, 2);
  462. }
  463. (*gradient) *= c0;
  464. dist = phi;
  465. return true;
  466. }