simplifier.cpp 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913
  1. // This file is part of meshoptimizer library; see meshoptimizer.h for version/license details
  2. #include "meshoptimizer.h"
  3. #include <assert.h>
  4. #include <float.h>
  5. #include <math.h>
  6. #include <string.h>
  7. #ifndef TRACE
  8. #define TRACE 0
  9. #endif
  10. #if TRACE
  11. #include <stdio.h>
  12. #endif
  13. #if TRACE
  14. #define TRACESTATS(i) stats[i]++;
  15. #else
  16. #define TRACESTATS(i) (void)0
  17. #endif
  18. // This work is based on:
  19. // Michael Garland and Paul S. Heckbert. Surface simplification using quadric error metrics. 1997
  20. // Michael Garland. Quadric-based polygonal surface simplification. 1999
  21. // Peter Lindstrom. Out-of-Core Simplification of Large Polygonal Models. 2000
  22. // Matthias Teschner, Bruno Heidelberger, Matthias Mueller, Danat Pomeranets, Markus Gross. Optimized Spatial Hashing for Collision Detection of Deformable Objects. 2003
  23. // Peter Van Sandt, Yannis Chronis, Jignesh M. Patel. Efficiently Searching In-Memory Sorted Arrays: Revenge of the Interpolation Search? 2019
  24. // Hugues Hoppe. New Quadric Metric for Simplifying Meshes with Appearance Attributes. 1999
  25. namespace meshopt
  26. {
  27. struct EdgeAdjacency
  28. {
  29. struct Edge
  30. {
  31. unsigned int next;
  32. unsigned int prev;
  33. };
  34. unsigned int* offsets;
  35. Edge* data;
  36. };
  37. static void prepareEdgeAdjacency(EdgeAdjacency& adjacency, size_t index_count, size_t vertex_count, meshopt_Allocator& allocator)
  38. {
  39. adjacency.offsets = allocator.allocate<unsigned int>(vertex_count + 1);
  40. adjacency.data = allocator.allocate<EdgeAdjacency::Edge>(index_count);
  41. }
  42. static void updateEdgeAdjacency(EdgeAdjacency& adjacency, const unsigned int* indices, size_t index_count, size_t vertex_count, const unsigned int* remap)
  43. {
  44. size_t face_count = index_count / 3;
  45. unsigned int* offsets = adjacency.offsets + 1;
  46. EdgeAdjacency::Edge* data = adjacency.data;
  47. // fill edge counts
  48. memset(offsets, 0, vertex_count * sizeof(unsigned int));
  49. for (size_t i = 0; i < index_count; ++i)
  50. {
  51. unsigned int v = remap ? remap[indices[i]] : indices[i];
  52. assert(v < vertex_count);
  53. offsets[v]++;
  54. }
  55. // fill offset table
  56. unsigned int offset = 0;
  57. for (size_t i = 0; i < vertex_count; ++i)
  58. {
  59. unsigned int count = offsets[i];
  60. offsets[i] = offset;
  61. offset += count;
  62. }
  63. assert(offset == index_count);
  64. // fill edge data
  65. for (size_t i = 0; i < face_count; ++i)
  66. {
  67. unsigned int a = indices[i * 3 + 0], b = indices[i * 3 + 1], c = indices[i * 3 + 2];
  68. if (remap)
  69. {
  70. a = remap[a];
  71. b = remap[b];
  72. c = remap[c];
  73. }
  74. data[offsets[a]].next = b;
  75. data[offsets[a]].prev = c;
  76. offsets[a]++;
  77. data[offsets[b]].next = c;
  78. data[offsets[b]].prev = a;
  79. offsets[b]++;
  80. data[offsets[c]].next = a;
  81. data[offsets[c]].prev = b;
  82. offsets[c]++;
  83. }
  84. // finalize offsets
  85. adjacency.offsets[0] = 0;
  86. assert(adjacency.offsets[vertex_count] == index_count);
  87. }
  88. struct PositionHasher
  89. {
  90. const float* vertex_positions;
  91. size_t vertex_stride_float;
  92. size_t hash(unsigned int index) const
  93. {
  94. const unsigned int* key = reinterpret_cast<const unsigned int*>(vertex_positions + index * vertex_stride_float);
  95. // scramble bits to make sure that integer coordinates have entropy in lower bits
  96. unsigned int x = key[0] ^ (key[0] >> 17);
  97. unsigned int y = key[1] ^ (key[1] >> 17);
  98. unsigned int z = key[2] ^ (key[2] >> 17);
  99. // Optimized Spatial Hashing for Collision Detection of Deformable Objects
  100. return (x * 73856093) ^ (y * 19349663) ^ (z * 83492791);
  101. }
  102. bool equal(unsigned int lhs, unsigned int rhs) const
  103. {
  104. return memcmp(vertex_positions + lhs * vertex_stride_float, vertex_positions + rhs * vertex_stride_float, sizeof(float) * 3) == 0;
  105. }
  106. };
  107. static size_t hashBuckets2(size_t count)
  108. {
  109. size_t buckets = 1;
  110. while (buckets < count + count / 4)
  111. buckets *= 2;
  112. return buckets;
  113. }
  114. template <typename T, typename Hash>
  115. static T* hashLookup2(T* table, size_t buckets, const Hash& hash, const T& key, const T& empty)
  116. {
  117. assert(buckets > 0);
  118. assert((buckets & (buckets - 1)) == 0);
  119. size_t hashmod = buckets - 1;
  120. size_t bucket = hash.hash(key) & hashmod;
  121. for (size_t probe = 0; probe <= hashmod; ++probe)
  122. {
  123. T& item = table[bucket];
  124. if (item == empty)
  125. return &item;
  126. if (hash.equal(item, key))
  127. return &item;
  128. // hash collision, quadratic probing
  129. bucket = (bucket + probe + 1) & hashmod;
  130. }
  131. assert(false && "Hash table is full"); // unreachable
  132. return NULL;
  133. }
  134. static void buildPositionRemap(unsigned int* remap, unsigned int* wedge, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, meshopt_Allocator& allocator)
  135. {
  136. PositionHasher hasher = {vertex_positions_data, vertex_positions_stride / sizeof(float)};
  137. size_t table_size = hashBuckets2(vertex_count);
  138. unsigned int* table = allocator.allocate<unsigned int>(table_size);
  139. memset(table, -1, table_size * sizeof(unsigned int));
  140. // build forward remap: for each vertex, which other (canonical) vertex does it map to?
  141. // we use position equivalence for this, and remap vertices to other existing vertices
  142. for (size_t i = 0; i < vertex_count; ++i)
  143. {
  144. unsigned int index = unsigned(i);
  145. unsigned int* entry = hashLookup2(table, table_size, hasher, index, ~0u);
  146. if (*entry == ~0u)
  147. *entry = index;
  148. remap[index] = *entry;
  149. }
  150. // build wedge table: for each vertex, which other vertex is the next wedge that also maps to the same vertex?
  151. // entries in table form a (cyclic) wedge loop per vertex; for manifold vertices, wedge[i] == remap[i] == i
  152. for (size_t i = 0; i < vertex_count; ++i)
  153. wedge[i] = unsigned(i);
  154. for (size_t i = 0; i < vertex_count; ++i)
  155. if (remap[i] != i)
  156. {
  157. unsigned int r = remap[i];
  158. wedge[i] = wedge[r];
  159. wedge[r] = unsigned(i);
  160. }
  161. allocator.deallocate(table);
  162. }
  163. enum VertexKind
  164. {
  165. Kind_Manifold, // not on an attribute seam, not on any boundary
  166. Kind_Border, // not on an attribute seam, has exactly two open edges
  167. Kind_Seam, // on an attribute seam with exactly two attribute seam edges
  168. Kind_Complex, // none of the above; these vertices can move as long as all wedges move to the target vertex
  169. Kind_Locked, // none of the above; these vertices can't move
  170. Kind_Count
  171. };
  172. // manifold vertices can collapse onto anything
  173. // border/seam vertices can only be collapsed onto border/seam respectively
  174. // complex vertices can collapse onto complex/locked
  175. // a rule of thumb is that collapsing kind A into kind B preserves the kind B in the target vertex
  176. // for example, while we could collapse Complex into Manifold, this would mean the target vertex isn't Manifold anymore
  177. const unsigned char kCanCollapse[Kind_Count][Kind_Count] = {
  178. {1, 1, 1, 1, 1},
  179. {0, 1, 0, 0, 0},
  180. {0, 0, 1, 0, 0},
  181. {0, 0, 0, 1, 1},
  182. {0, 0, 0, 0, 0},
  183. };
  184. // if a vertex is manifold or seam, adjoining edges are guaranteed to have an opposite edge
  185. // note that for seam edges, the opposite edge isn't present in the attribute-based topology
  186. // but is present if you consider a position-only mesh variant
  187. const unsigned char kHasOpposite[Kind_Count][Kind_Count] = {
  188. {1, 1, 1, 0, 1},
  189. {1, 0, 1, 0, 0},
  190. {1, 1, 1, 0, 1},
  191. {0, 0, 0, 0, 0},
  192. {1, 0, 1, 0, 0},
  193. };
  194. static bool hasEdge(const EdgeAdjacency& adjacency, unsigned int a, unsigned int b)
  195. {
  196. unsigned int count = adjacency.offsets[a + 1] - adjacency.offsets[a];
  197. const EdgeAdjacency::Edge* edges = adjacency.data + adjacency.offsets[a];
  198. for (size_t i = 0; i < count; ++i)
  199. if (edges[i].next == b)
  200. return true;
  201. return false;
  202. }
  203. static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned int* loopback, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* wedge, const unsigned char* vertex_lock, unsigned int options)
  204. {
  205. memset(loop, -1, vertex_count * sizeof(unsigned int));
  206. memset(loopback, -1, vertex_count * sizeof(unsigned int));
  207. // incoming & outgoing open edges: ~0u if no open edges, i if there are more than 1
  208. // note that this is the same data as required in loop[] arrays; loop[] data is only valid for border/seam
  209. // but here it's okay to fill the data out for other types of vertices as well
  210. unsigned int* openinc = loopback;
  211. unsigned int* openout = loop;
  212. for (size_t i = 0; i < vertex_count; ++i)
  213. {
  214. unsigned int vertex = unsigned(i);
  215. unsigned int count = adjacency.offsets[vertex + 1] - adjacency.offsets[vertex];
  216. const EdgeAdjacency::Edge* edges = adjacency.data + adjacency.offsets[vertex];
  217. for (size_t j = 0; j < count; ++j)
  218. {
  219. unsigned int target = edges[j].next;
  220. if (target == vertex)
  221. {
  222. // degenerate triangles have two distinct edges instead of three, and the self edge
  223. // is bi-directional by definition; this can break border/seam classification by "closing"
  224. // the open edge from another triangle and falsely marking the vertex as manifold
  225. // instead we mark the vertex as having >1 open edges which turns it into locked/complex
  226. openinc[vertex] = openout[vertex] = vertex;
  227. }
  228. else if (!hasEdge(adjacency, target, vertex))
  229. {
  230. openinc[target] = (openinc[target] == ~0u) ? vertex : target;
  231. openout[vertex] = (openout[vertex] == ~0u) ? target : vertex;
  232. }
  233. }
  234. }
  235. #if TRACE
  236. size_t stats[4] = {};
  237. #endif
  238. for (size_t i = 0; i < vertex_count; ++i)
  239. {
  240. if (remap[i] == i)
  241. {
  242. if (vertex_lock && vertex_lock[i])
  243. {
  244. // vertex is explicitly locked
  245. result[i] = Kind_Locked;
  246. }
  247. else if (wedge[i] == i)
  248. {
  249. // no attribute seam, need to check if it's manifold
  250. unsigned int openi = openinc[i], openo = openout[i];
  251. // note: we classify any vertices with no open edges as manifold
  252. // this is technically incorrect - if 4 triangles share an edge, we'll classify vertices as manifold
  253. // it's unclear if this is a problem in practice
  254. if (openi == ~0u && openo == ~0u)
  255. {
  256. result[i] = Kind_Manifold;
  257. }
  258. else if (openi != i && openo != i)
  259. {
  260. result[i] = Kind_Border;
  261. }
  262. else
  263. {
  264. result[i] = Kind_Locked;
  265. TRACESTATS(0);
  266. }
  267. }
  268. else if (wedge[wedge[i]] == i)
  269. {
  270. // attribute seam; need to distinguish between Seam and Locked
  271. unsigned int w = wedge[i];
  272. unsigned int openiv = openinc[i], openov = openout[i];
  273. unsigned int openiw = openinc[w], openow = openout[w];
  274. // seam should have one open half-edge for each vertex, and the edges need to "connect" - point to the same vertex post-remap
  275. if (openiv != ~0u && openiv != i && openov != ~0u && openov != i &&
  276. openiw != ~0u && openiw != w && openow != ~0u && openow != w)
  277. {
  278. if (remap[openiv] == remap[openow] && remap[openov] == remap[openiw])
  279. {
  280. result[i] = Kind_Seam;
  281. }
  282. else
  283. {
  284. result[i] = Kind_Locked;
  285. TRACESTATS(1);
  286. }
  287. }
  288. else
  289. {
  290. result[i] = Kind_Locked;
  291. TRACESTATS(2);
  292. }
  293. }
  294. else
  295. {
  296. // more than one vertex maps to this one; we don't have classification available
  297. result[i] = Kind_Locked;
  298. TRACESTATS(3);
  299. }
  300. }
  301. else
  302. {
  303. assert(remap[i] < i);
  304. result[i] = result[remap[i]];
  305. }
  306. }
  307. if (options & meshopt_SimplifyLockBorder)
  308. for (size_t i = 0; i < vertex_count; ++i)
  309. if (result[i] == Kind_Border)
  310. result[i] = Kind_Locked;
  311. #if TRACE
  312. printf("locked: many open edges %d, disconnected seam %d, many seam edges %d, many wedges %d\n",
  313. int(stats[0]), int(stats[1]), int(stats[2]), int(stats[3]));
  314. #endif
  315. }
  316. struct Vector3
  317. {
  318. float x, y, z;
  319. };
  320. static float rescalePositions(Vector3* result, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride)
  321. {
  322. size_t vertex_stride_float = vertex_positions_stride / sizeof(float);
  323. float minv[3] = {FLT_MAX, FLT_MAX, FLT_MAX};
  324. float maxv[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
  325. for (size_t i = 0; i < vertex_count; ++i)
  326. {
  327. const float* v = vertex_positions_data + i * vertex_stride_float;
  328. if (result)
  329. {
  330. result[i].x = v[0];
  331. result[i].y = v[1];
  332. result[i].z = v[2];
  333. }
  334. for (int j = 0; j < 3; ++j)
  335. {
  336. float vj = v[j];
  337. minv[j] = minv[j] > vj ? vj : minv[j];
  338. maxv[j] = maxv[j] < vj ? vj : maxv[j];
  339. }
  340. }
  341. float extent = 0.f;
  342. extent = (maxv[0] - minv[0]) < extent ? extent : (maxv[0] - minv[0]);
  343. extent = (maxv[1] - minv[1]) < extent ? extent : (maxv[1] - minv[1]);
  344. extent = (maxv[2] - minv[2]) < extent ? extent : (maxv[2] - minv[2]);
  345. if (result)
  346. {
  347. float scale = extent == 0 ? 0.f : 1.f / extent;
  348. for (size_t i = 0; i < vertex_count; ++i)
  349. {
  350. result[i].x = (result[i].x - minv[0]) * scale;
  351. result[i].y = (result[i].y - minv[1]) * scale;
  352. result[i].z = (result[i].z - minv[2]) * scale;
  353. }
  354. }
  355. return extent;
  356. }
  357. static void rescaleAttributes(float* result, const float* vertex_attributes_data, size_t vertex_count, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count)
  358. {
  359. size_t vertex_attributes_stride_float = vertex_attributes_stride / sizeof(float);
  360. for (size_t i = 0; i < vertex_count; ++i)
  361. {
  362. for (size_t k = 0; k < attribute_count; ++k)
  363. {
  364. float a = vertex_attributes_data[i * vertex_attributes_stride_float + k];
  365. result[i * attribute_count + k] = a * attribute_weights[k];
  366. }
  367. }
  368. }
  369. static const size_t kMaxAttributes = 16;
  370. struct Quadric
  371. {
  372. // a00*x^2 + a11*y^2 + a22*z^2 + 2*(a10*xy + a20*xz + a21*yz) + b0*x + b1*y + b2*z + c
  373. float a00, a11, a22;
  374. float a10, a20, a21;
  375. float b0, b1, b2, c;
  376. float w;
  377. };
  378. struct QuadricGrad
  379. {
  380. // gx*x + gy*y + gz*z + gw
  381. float gx, gy, gz, gw;
  382. };
  383. struct Reservoir
  384. {
  385. float x, y, z;
  386. float r, g, b;
  387. float w;
  388. };
  389. struct Collapse
  390. {
  391. unsigned int v0;
  392. unsigned int v1;
  393. union
  394. {
  395. unsigned int bidi;
  396. float error;
  397. unsigned int errorui;
  398. };
  399. };
  400. static float normalize(Vector3& v)
  401. {
  402. float length = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z);
  403. if (length > 0)
  404. {
  405. v.x /= length;
  406. v.y /= length;
  407. v.z /= length;
  408. }
  409. return length;
  410. }
  411. static void quadricAdd(Quadric& Q, const Quadric& R)
  412. {
  413. Q.a00 += R.a00;
  414. Q.a11 += R.a11;
  415. Q.a22 += R.a22;
  416. Q.a10 += R.a10;
  417. Q.a20 += R.a20;
  418. Q.a21 += R.a21;
  419. Q.b0 += R.b0;
  420. Q.b1 += R.b1;
  421. Q.b2 += R.b2;
  422. Q.c += R.c;
  423. Q.w += R.w;
  424. }
  425. static void quadricAdd(QuadricGrad* G, const QuadricGrad* R, size_t attribute_count)
  426. {
  427. for (size_t k = 0; k < attribute_count; ++k)
  428. {
  429. G[k].gx += R[k].gx;
  430. G[k].gy += R[k].gy;
  431. G[k].gz += R[k].gz;
  432. G[k].gw += R[k].gw;
  433. }
  434. }
  435. static float quadricError(const Quadric& Q, const Vector3& v)
  436. {
  437. float rx = Q.b0;
  438. float ry = Q.b1;
  439. float rz = Q.b2;
  440. rx += Q.a10 * v.y;
  441. ry += Q.a21 * v.z;
  442. rz += Q.a20 * v.x;
  443. rx *= 2;
  444. ry *= 2;
  445. rz *= 2;
  446. rx += Q.a00 * v.x;
  447. ry += Q.a11 * v.y;
  448. rz += Q.a22 * v.z;
  449. float r = Q.c;
  450. r += rx * v.x;
  451. r += ry * v.y;
  452. r += rz * v.z;
  453. float s = Q.w == 0.f ? 0.f : 1.f / Q.w;
  454. return fabsf(r) * s;
  455. }
  456. static float quadricError(const Quadric& Q, const QuadricGrad* G, size_t attribute_count, const Vector3& v, const float* va)
  457. {
  458. float rx = Q.b0;
  459. float ry = Q.b1;
  460. float rz = Q.b2;
  461. rx += Q.a10 * v.y;
  462. ry += Q.a21 * v.z;
  463. rz += Q.a20 * v.x;
  464. rx *= 2;
  465. ry *= 2;
  466. rz *= 2;
  467. rx += Q.a00 * v.x;
  468. ry += Q.a11 * v.y;
  469. rz += Q.a22 * v.z;
  470. float r = Q.c;
  471. r += rx * v.x;
  472. r += ry * v.y;
  473. r += rz * v.z;
  474. // see quadricFromAttributes for general derivation; here we need to add the parts of (eval(pos) - attr)^2 that depend on attr
  475. for (size_t k = 0; k < attribute_count; ++k)
  476. {
  477. float a = va[k];
  478. float g = v.x * G[k].gx + v.y * G[k].gy + v.z * G[k].gz + G[k].gw;
  479. r += a * a * Q.w;
  480. r -= 2 * a * g;
  481. }
  482. // TODO: weight normalization is breaking attribute error somehow
  483. float s = 1; // Q.w == 0.f ? 0.f : 1.f / Q.w;
  484. return fabsf(r) * s;
  485. }
  486. static void quadricFromPlane(Quadric& Q, float a, float b, float c, float d, float w)
  487. {
  488. float aw = a * w;
  489. float bw = b * w;
  490. float cw = c * w;
  491. float dw = d * w;
  492. Q.a00 = a * aw;
  493. Q.a11 = b * bw;
  494. Q.a22 = c * cw;
  495. Q.a10 = a * bw;
  496. Q.a20 = a * cw;
  497. Q.a21 = b * cw;
  498. Q.b0 = a * dw;
  499. Q.b1 = b * dw;
  500. Q.b2 = c * dw;
  501. Q.c = d * dw;
  502. Q.w = w;
  503. }
  504. static void quadricFromTriangle(Quadric& Q, const Vector3& p0, const Vector3& p1, const Vector3& p2, float weight)
  505. {
  506. Vector3 p10 = {p1.x - p0.x, p1.y - p0.y, p1.z - p0.z};
  507. Vector3 p20 = {p2.x - p0.x, p2.y - p0.y, p2.z - p0.z};
  508. // normal = cross(p1 - p0, p2 - p0)
  509. Vector3 normal = {p10.y * p20.z - p10.z * p20.y, p10.z * p20.x - p10.x * p20.z, p10.x * p20.y - p10.y * p20.x};
  510. float area = normalize(normal);
  511. float distance = normal.x * p0.x + normal.y * p0.y + normal.z * p0.z;
  512. // we use sqrtf(area) so that the error is scaled linearly; this tends to improve silhouettes
  513. quadricFromPlane(Q, normal.x, normal.y, normal.z, -distance, sqrtf(area) * weight);
  514. }
  515. static void quadricFromTriangleEdge(Quadric& Q, const Vector3& p0, const Vector3& p1, const Vector3& p2, float weight)
  516. {
  517. Vector3 p10 = {p1.x - p0.x, p1.y - p0.y, p1.z - p0.z};
  518. float length = normalize(p10);
  519. // p20p = length of projection of p2-p0 onto normalize(p1 - p0)
  520. Vector3 p20 = {p2.x - p0.x, p2.y - p0.y, p2.z - p0.z};
  521. float p20p = p20.x * p10.x + p20.y * p10.y + p20.z * p10.z;
  522. // normal = altitude of triangle from point p2 onto edge p1-p0
  523. Vector3 normal = {p20.x - p10.x * p20p, p20.y - p10.y * p20p, p20.z - p10.z * p20p};
  524. normalize(normal);
  525. float distance = normal.x * p0.x + normal.y * p0.y + normal.z * p0.z;
  526. // note: the weight is scaled linearly with edge length; this has to match the triangle weight
  527. quadricFromPlane(Q, normal.x, normal.y, normal.z, -distance, length * weight);
  528. }
  529. static void quadricFromAttributes(Quadric& Q, QuadricGrad* G, const Vector3& p0, const Vector3& p1, const Vector3& p2, const float* va0, const float* va1, const float* va2, size_t attribute_count)
  530. {
  531. // for each attribute we want to encode the following function into the quadric:
  532. // (eval(pos) - attr)^2
  533. // where eval(pos) interpolates attribute across the triangle like so:
  534. // eval(pos) = pos.x * gx + pos.y * gy + pos.z * gz + gw
  535. // where gx/gy/gz/gw are gradients
  536. Vector3 p10 = {p1.x - p0.x, p1.y - p0.y, p1.z - p0.z};
  537. Vector3 p20 = {p2.x - p0.x, p2.y - p0.y, p2.z - p0.z};
  538. // weight is scaled linearly with edge length
  539. Vector3 normal = {p10.y * p20.z - p10.z * p20.y, p10.z * p20.x - p10.x * p20.z, p10.x * p20.y - p10.y * p20.x};
  540. float area = sqrtf(normal.x * normal.x + normal.y * normal.y + normal.z * normal.z);
  541. float w = sqrtf(area); // TODO this needs more experimentation
  542. // we compute gradients using barycentric coordinates; barycentric coordinates can be computed as follows:
  543. // v = (d11 * d20 - d01 * d21) / denom
  544. // w = (d00 * d21 - d01 * d20) / denom
  545. // u = 1 - v - w
  546. // here v0, v1 are triangle edge vectors, v2 is a vector from point to triangle corner, and dij = dot(vi, vj)
  547. const Vector3& v0 = p10;
  548. const Vector3& v1 = p20;
  549. float d00 = v0.x * v0.x + v0.y * v0.y + v0.z * v0.z;
  550. float d01 = v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
  551. float d11 = v1.x * v1.x + v1.y * v1.y + v1.z * v1.z;
  552. float denom = d00 * d11 - d01 * d01;
  553. float denomr = denom == 0 ? 0.f : 1.f / denom;
  554. // precompute gradient factors
  555. // these are derived by directly computing derivative of eval(pos) = a0 * u + a1 * v + a2 * w and factoring out common factors that are shared between attributes
  556. float gx1 = (d11 * v0.x - d01 * v1.x) * denomr;
  557. float gx2 = (d00 * v1.x - d01 * v0.x) * denomr;
  558. float gy1 = (d11 * v0.y - d01 * v1.y) * denomr;
  559. float gy2 = (d00 * v1.y - d01 * v0.y) * denomr;
  560. float gz1 = (d11 * v0.z - d01 * v1.z) * denomr;
  561. float gz2 = (d00 * v1.z - d01 * v0.z) * denomr;
  562. memset(&Q, 0, sizeof(Quadric));
  563. Q.w = w;
  564. for (size_t k = 0; k < attribute_count; ++k)
  565. {
  566. float a0 = va0[k], a1 = va1[k], a2 = va2[k];
  567. // compute gradient of eval(pos) for x/y/z/w
  568. // the formulas below are obtained by directly computing derivative of eval(pos) = a0 * u + a1 * v + a2 * w
  569. float gx = gx1 * (a1 - a0) + gx2 * (a2 - a0);
  570. float gy = gy1 * (a1 - a0) + gy2 * (a2 - a0);
  571. float gz = gz1 * (a1 - a0) + gz2 * (a2 - a0);
  572. float gw = a0 - p0.x * gx - p0.y * gy - p0.z * gz;
  573. // quadric encodes (eval(pos)-attr)^2; this means that the resulting expansion needs to compute, for example, pos.x * pos.y * K
  574. // since quadrics already encode factors for pos.x * pos.y, we can accumulate almost everything in basic quadric fields
  575. Q.a00 += w * (gx * gx);
  576. Q.a11 += w * (gy * gy);
  577. Q.a22 += w * (gz * gz);
  578. Q.a10 += w * (gy * gx);
  579. Q.a20 += w * (gz * gx);
  580. Q.a21 += w * (gz * gy);
  581. Q.b0 += w * (gx * gw);
  582. Q.b1 += w * (gy * gw);
  583. Q.b2 += w * (gz * gw);
  584. Q.c += w * (gw * gw);
  585. // the only remaining sum components are ones that depend on attr; these will be addded during error evaluation, see quadricError
  586. G[k].gx = w * gx;
  587. G[k].gy = w * gy;
  588. G[k].gz = w * gz;
  589. G[k].gw = w * gw;
  590. }
  591. }
  592. static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indices, size_t index_count, const Vector3* vertex_positions, const unsigned int* remap)
  593. {
  594. for (size_t i = 0; i < index_count; i += 3)
  595. {
  596. unsigned int i0 = indices[i + 0];
  597. unsigned int i1 = indices[i + 1];
  598. unsigned int i2 = indices[i + 2];
  599. Quadric Q;
  600. quadricFromTriangle(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], 1.f);
  601. quadricAdd(vertex_quadrics[remap[i0]], Q);
  602. quadricAdd(vertex_quadrics[remap[i1]], Q);
  603. quadricAdd(vertex_quadrics[remap[i2]], Q);
  604. }
  605. }
  606. static void fillEdgeQuadrics(Quadric* vertex_quadrics, const unsigned int* indices, size_t index_count, const Vector3* vertex_positions, const unsigned int* remap, const unsigned char* vertex_kind, const unsigned int* loop, const unsigned int* loopback)
  607. {
  608. for (size_t i = 0; i < index_count; i += 3)
  609. {
  610. static const int next[4] = {1, 2, 0, 1};
  611. for (int e = 0; e < 3; ++e)
  612. {
  613. unsigned int i0 = indices[i + e];
  614. unsigned int i1 = indices[i + next[e]];
  615. unsigned char k0 = vertex_kind[i0];
  616. unsigned char k1 = vertex_kind[i1];
  617. // check that either i0 or i1 are border/seam and are on the same edge loop
  618. // note that we need to add the error even for edged that connect e.g. border & locked
  619. // if we don't do that, the adjacent border->border edge won't have correct errors for corners
  620. if (k0 != Kind_Border && k0 != Kind_Seam && k1 != Kind_Border && k1 != Kind_Seam)
  621. continue;
  622. if ((k0 == Kind_Border || k0 == Kind_Seam) && loop[i0] != i1)
  623. continue;
  624. if ((k1 == Kind_Border || k1 == Kind_Seam) && loopback[i1] != i0)
  625. continue;
  626. // seam edges should occur twice (i0->i1 and i1->i0) - skip redundant edges
  627. if (kHasOpposite[k0][k1] && remap[i1] > remap[i0])
  628. continue;
  629. unsigned int i2 = indices[i + next[e + 1]];
  630. // we try hard to maintain border edge geometry; seam edges can move more freely
  631. // due to topological restrictions on collapses, seam quadrics slightly improves collapse structure but aren't critical
  632. const float kEdgeWeightSeam = 1.f;
  633. const float kEdgeWeightBorder = 10.f;
  634. float edgeWeight = (k0 == Kind_Border || k1 == Kind_Border) ? kEdgeWeightBorder : kEdgeWeightSeam;
  635. Quadric Q;
  636. quadricFromTriangleEdge(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], edgeWeight);
  637. quadricAdd(vertex_quadrics[remap[i0]], Q);
  638. quadricAdd(vertex_quadrics[remap[i1]], Q);
  639. }
  640. }
  641. }
  642. static void fillAttributeQuadrics(Quadric* attribute_quadrics, QuadricGrad* attribute_gradients, const unsigned int* indices, size_t index_count, const Vector3* vertex_positions, const float* vertex_attributes, size_t attribute_count, const unsigned int* remap)
  643. {
  644. for (size_t i = 0; i < index_count; i += 3)
  645. {
  646. unsigned int i0 = indices[i + 0];
  647. unsigned int i1 = indices[i + 1];
  648. unsigned int i2 = indices[i + 2];
  649. Quadric QA;
  650. QuadricGrad G[kMaxAttributes];
  651. quadricFromAttributes(QA, G, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], &vertex_attributes[i0 * attribute_count], &vertex_attributes[i1 * attribute_count], &vertex_attributes[i2 * attribute_count], attribute_count);
  652. // TODO: This blends together attribute weights across attribute discontinuities, which is probably not a great idea
  653. quadricAdd(attribute_quadrics[remap[i0]], QA);
  654. quadricAdd(attribute_quadrics[remap[i1]], QA);
  655. quadricAdd(attribute_quadrics[remap[i2]], QA);
  656. quadricAdd(&attribute_gradients[remap[i0] * attribute_count], G, attribute_count);
  657. quadricAdd(&attribute_gradients[remap[i1] * attribute_count], G, attribute_count);
  658. quadricAdd(&attribute_gradients[remap[i2] * attribute_count], G, attribute_count);
  659. }
  660. }
  661. // does triangle ABC flip when C is replaced with D?
  662. static bool hasTriangleFlip(const Vector3& a, const Vector3& b, const Vector3& c, const Vector3& d)
  663. {
  664. Vector3 eb = {b.x - a.x, b.y - a.y, b.z - a.z};
  665. Vector3 ec = {c.x - a.x, c.y - a.y, c.z - a.z};
  666. Vector3 ed = {d.x - a.x, d.y - a.y, d.z - a.z};
  667. Vector3 nbc = {eb.y * ec.z - eb.z * ec.y, eb.z * ec.x - eb.x * ec.z, eb.x * ec.y - eb.y * ec.x};
  668. Vector3 nbd = {eb.y * ed.z - eb.z * ed.y, eb.z * ed.x - eb.x * ed.z, eb.x * ed.y - eb.y * ed.x};
  669. return nbc.x * nbd.x + nbc.y * nbd.y + nbc.z * nbd.z <= 0;
  670. }
  671. static bool hasTriangleFlips(const EdgeAdjacency& adjacency, const Vector3* vertex_positions, const unsigned int* collapse_remap, unsigned int i0, unsigned int i1)
  672. {
  673. assert(collapse_remap[i0] == i0);
  674. assert(collapse_remap[i1] == i1);
  675. const Vector3& v0 = vertex_positions[i0];
  676. const Vector3& v1 = vertex_positions[i1];
  677. const EdgeAdjacency::Edge* edges = &adjacency.data[adjacency.offsets[i0]];
  678. size_t count = adjacency.offsets[i0 + 1] - adjacency.offsets[i0];
  679. for (size_t i = 0; i < count; ++i)
  680. {
  681. unsigned int a = collapse_remap[edges[i].next];
  682. unsigned int b = collapse_remap[edges[i].prev];
  683. // skip triangles that will get collapsed by i0->i1 collapse or already got collapsed previously
  684. if (a == i1 || b == i1 || a == b)
  685. continue;
  686. // early-out when at least one triangle flips due to a collapse
  687. if (hasTriangleFlip(vertex_positions[a], vertex_positions[b], v0, v1))
  688. return true;
  689. }
  690. return false;
  691. }
  692. static size_t boundEdgeCollapses(const EdgeAdjacency& adjacency, size_t vertex_count, size_t index_count, unsigned char* vertex_kind)
  693. {
  694. size_t dual_count = 0;
  695. for (size_t i = 0; i < vertex_count; ++i)
  696. {
  697. unsigned char k = vertex_kind[i];
  698. unsigned int e = adjacency.offsets[i + 1] - adjacency.offsets[i];
  699. dual_count += (k == Kind_Manifold || k == Kind_Seam) ? e : 0;
  700. }
  701. assert(dual_count <= index_count);
  702. // pad capacity by 3 so that we can check for overflow once per triangle instead of once per edge
  703. return (index_count - dual_count / 2) + 3;
  704. }
  705. static size_t pickEdgeCollapses(Collapse* collapses, size_t collapse_capacity, const unsigned int* indices, size_t index_count, const unsigned int* remap, const unsigned char* vertex_kind, const unsigned int* loop)
  706. {
  707. size_t collapse_count = 0;
  708. for (size_t i = 0; i < index_count; i += 3)
  709. {
  710. static const int next[3] = {1, 2, 0};
  711. // this should never happen as boundEdgeCollapses should give an upper bound for the collapse count, but in an unlikely event it does we can just drop extra collapses
  712. if (collapse_count + 3 > collapse_capacity)
  713. break;
  714. for (int e = 0; e < 3; ++e)
  715. {
  716. unsigned int i0 = indices[i + e];
  717. unsigned int i1 = indices[i + next[e]];
  718. // this can happen either when input has a zero-length edge, or when we perform collapses for complex
  719. // topology w/seams and collapse a manifold vertex that connects to both wedges onto one of them
  720. // we leave edges like this alone since they may be important for preserving mesh integrity
  721. if (remap[i0] == remap[i1])
  722. continue;
  723. unsigned char k0 = vertex_kind[i0];
  724. unsigned char k1 = vertex_kind[i1];
  725. // the edge has to be collapsible in at least one direction
  726. if (!(kCanCollapse[k0][k1] | kCanCollapse[k1][k0]))
  727. continue;
  728. // manifold and seam edges should occur twice (i0->i1 and i1->i0) - skip redundant edges
  729. if (kHasOpposite[k0][k1] && remap[i1] > remap[i0])
  730. continue;
  731. // two vertices are on a border or a seam, but there's no direct edge between them
  732. // this indicates that they belong to two different edge loops and we should not collapse this edge
  733. // loop[] tracks half edges so we only need to check i0->i1
  734. if (k0 == k1 && (k0 == Kind_Border || k0 == Kind_Seam) && loop[i0] != i1)
  735. continue;
  736. // edge can be collapsed in either direction - we will pick the one with minimum error
  737. // note: we evaluate error later during collapse ranking, here we just tag the edge as bidirectional
  738. if (kCanCollapse[k0][k1] & kCanCollapse[k1][k0])
  739. {
  740. Collapse c = {i0, i1, {/* bidi= */ 1}};
  741. collapses[collapse_count++] = c;
  742. }
  743. else
  744. {
  745. // edge can only be collapsed in one direction
  746. unsigned int e0 = kCanCollapse[k0][k1] ? i0 : i1;
  747. unsigned int e1 = kCanCollapse[k0][k1] ? i1 : i0;
  748. Collapse c = {e0, e1, {/* bidi= */ 0}};
  749. collapses[collapse_count++] = c;
  750. }
  751. }
  752. }
  753. return collapse_count;
  754. }
  755. static void rankEdgeCollapses(Collapse* collapses, size_t collapse_count, const Vector3* vertex_positions, const float* vertex_attributes, const Quadric* vertex_quadrics, const Quadric* attribute_quadrics, const QuadricGrad* attribute_gradients, size_t attribute_count, const unsigned int* remap)
  756. {
  757. for (size_t i = 0; i < collapse_count; ++i)
  758. {
  759. Collapse& c = collapses[i];
  760. unsigned int i0 = c.v0;
  761. unsigned int i1 = c.v1;
  762. // most edges are bidirectional which means we need to evaluate errors for two collapses
  763. // to keep this code branchless we just use the same edge for unidirectional edges
  764. unsigned int j0 = c.bidi ? i1 : i0;
  765. unsigned int j1 = c.bidi ? i0 : i1;
  766. float ei = quadricError(vertex_quadrics[remap[i0]], vertex_positions[i1]);
  767. float ej = quadricError(vertex_quadrics[remap[j0]], vertex_positions[j1]);
  768. if (attribute_count)
  769. {
  770. ei += quadricError(attribute_quadrics[remap[i0]], &attribute_gradients[remap[i0] * attribute_count], attribute_count, vertex_positions[i1], &vertex_attributes[i1 * attribute_count]);
  771. ej += quadricError(attribute_quadrics[remap[j0]], &attribute_gradients[remap[j0] * attribute_count], attribute_count, vertex_positions[j1], &vertex_attributes[j1 * attribute_count]);
  772. }
  773. // pick edge direction with minimal error
  774. c.v0 = ei <= ej ? i0 : j0;
  775. c.v1 = ei <= ej ? i1 : j1;
  776. c.error = ei <= ej ? ei : ej;
  777. }
  778. }
  779. static void sortEdgeCollapses(unsigned int* sort_order, const Collapse* collapses, size_t collapse_count)
  780. {
  781. const int sort_bits = 11;
  782. // fill histogram for counting sort
  783. unsigned int histogram[1 << sort_bits];
  784. memset(histogram, 0, sizeof(histogram));
  785. for (size_t i = 0; i < collapse_count; ++i)
  786. {
  787. // skip sign bit since error is non-negative
  788. unsigned int key = (collapses[i].errorui << 1) >> (32 - sort_bits);
  789. histogram[key]++;
  790. }
  791. // compute offsets based on histogram data
  792. size_t histogram_sum = 0;
  793. for (size_t i = 0; i < 1 << sort_bits; ++i)
  794. {
  795. size_t count = histogram[i];
  796. histogram[i] = unsigned(histogram_sum);
  797. histogram_sum += count;
  798. }
  799. assert(histogram_sum == collapse_count);
  800. // compute sort order based on offsets
  801. for (size_t i = 0; i < collapse_count; ++i)
  802. {
  803. // skip sign bit since error is non-negative
  804. unsigned int key = (collapses[i].errorui << 1) >> (32 - sort_bits);
  805. sort_order[histogram[key]++] = unsigned(i);
  806. }
  807. }
  808. static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char* collapse_locked, Quadric* vertex_quadrics, Quadric* attribute_quadrics, QuadricGrad* attribute_gradients, size_t attribute_count, const Collapse* collapses, size_t collapse_count, const unsigned int* collapse_order, const unsigned int* remap, const unsigned int* wedge, const unsigned char* vertex_kind, const Vector3* vertex_positions, const EdgeAdjacency& adjacency, size_t triangle_collapse_goal, float error_limit, float& result_error)
  809. {
  810. size_t edge_collapses = 0;
  811. size_t triangle_collapses = 0;
  812. // most collapses remove 2 triangles; use this to establish a bound on the pass in terms of error limit
  813. // note that edge_collapse_goal is an estimate; triangle_collapse_goal will be used to actually limit collapses
  814. size_t edge_collapse_goal = triangle_collapse_goal / 2;
  815. #if TRACE
  816. size_t stats[4] = {};
  817. #endif
  818. for (size_t i = 0; i < collapse_count; ++i)
  819. {
  820. const Collapse& c = collapses[collapse_order[i]];
  821. TRACESTATS(0);
  822. if (c.error > error_limit)
  823. break;
  824. if (triangle_collapses >= triangle_collapse_goal)
  825. break;
  826. // we limit the error in each pass based on the error of optimal last collapse; since many collapses will be locked
  827. // as they will share vertices with other successfull collapses, we need to increase the acceptable error by some factor
  828. float error_goal = edge_collapse_goal < collapse_count ? 1.5f * collapses[collapse_order[edge_collapse_goal]].error : FLT_MAX;
  829. // on average, each collapse is expected to lock 6 other collapses; to avoid degenerate passes on meshes with odd
  830. // topology, we only abort if we got over 1/6 collapses accordingly.
  831. if (c.error > error_goal && triangle_collapses > triangle_collapse_goal / 6)
  832. break;
  833. unsigned int i0 = c.v0;
  834. unsigned int i1 = c.v1;
  835. unsigned int r0 = remap[i0];
  836. unsigned int r1 = remap[i1];
  837. // we don't collapse vertices that had source or target vertex involved in a collapse
  838. // it's important to not move the vertices twice since it complicates the tracking/remapping logic
  839. // it's important to not move other vertices towards a moved vertex to preserve error since we don't re-rank collapses mid-pass
  840. if (collapse_locked[r0] | collapse_locked[r1])
  841. {
  842. TRACESTATS(1);
  843. continue;
  844. }
  845. if (hasTriangleFlips(adjacency, vertex_positions, collapse_remap, r0, r1))
  846. {
  847. // adjust collapse goal since this collapse is invalid and shouldn't factor into error goal
  848. edge_collapse_goal++;
  849. TRACESTATS(2);
  850. continue;
  851. }
  852. assert(collapse_remap[r0] == r0);
  853. assert(collapse_remap[r1] == r1);
  854. quadricAdd(vertex_quadrics[r1], vertex_quadrics[r0]);
  855. if (attribute_count)
  856. {
  857. quadricAdd(attribute_quadrics[r1], attribute_quadrics[r0]);
  858. quadricAdd(&attribute_gradients[r1 * attribute_count], &attribute_gradients[r0 * attribute_count], attribute_count);
  859. }
  860. if (vertex_kind[i0] == Kind_Complex)
  861. {
  862. unsigned int v = i0;
  863. do
  864. {
  865. collapse_remap[v] = r1;
  866. v = wedge[v];
  867. } while (v != i0);
  868. }
  869. else if (vertex_kind[i0] == Kind_Seam)
  870. {
  871. // remap v0 to v1 and seam pair of v0 to seam pair of v1
  872. unsigned int s0 = wedge[i0];
  873. unsigned int s1 = wedge[i1];
  874. assert(s0 != i0 && s1 != i1);
  875. assert(wedge[s0] == i0 && wedge[s1] == i1);
  876. collapse_remap[i0] = i1;
  877. collapse_remap[s0] = s1;
  878. }
  879. else
  880. {
  881. assert(wedge[i0] == i0);
  882. collapse_remap[i0] = i1;
  883. }
  884. collapse_locked[r0] = 1;
  885. collapse_locked[r1] = 1;
  886. // border edges collapse 1 triangle, other edges collapse 2 or more
  887. triangle_collapses += (vertex_kind[i0] == Kind_Border) ? 1 : 2;
  888. edge_collapses++;
  889. result_error = result_error < c.error ? c.error : result_error;
  890. }
  891. #if TRACE
  892. float error_goal_perfect = edge_collapse_goal < collapse_count ? collapses[collapse_order[edge_collapse_goal]].error : 0.f;
  893. printf("removed %d triangles, error %e (goal %e); evaluated %d/%d collapses (done %d, skipped %d, invalid %d)\n",
  894. int(triangle_collapses), sqrtf(result_error), sqrtf(error_goal_perfect),
  895. int(stats[0]), int(collapse_count), int(edge_collapses), int(stats[1]), int(stats[2]));
  896. #endif
  897. return edge_collapses;
  898. }
  899. static size_t remapIndexBuffer(unsigned int* indices, size_t index_count, const unsigned int* collapse_remap)
  900. {
  901. size_t write = 0;
  902. for (size_t i = 0; i < index_count; i += 3)
  903. {
  904. unsigned int v0 = collapse_remap[indices[i + 0]];
  905. unsigned int v1 = collapse_remap[indices[i + 1]];
  906. unsigned int v2 = collapse_remap[indices[i + 2]];
  907. // we never move the vertex twice during a single pass
  908. assert(collapse_remap[v0] == v0);
  909. assert(collapse_remap[v1] == v1);
  910. assert(collapse_remap[v2] == v2);
  911. if (v0 != v1 && v0 != v2 && v1 != v2)
  912. {
  913. indices[write + 0] = v0;
  914. indices[write + 1] = v1;
  915. indices[write + 2] = v2;
  916. write += 3;
  917. }
  918. }
  919. return write;
  920. }
  921. static void remapEdgeLoops(unsigned int* loop, size_t vertex_count, const unsigned int* collapse_remap)
  922. {
  923. for (size_t i = 0; i < vertex_count; ++i)
  924. {
  925. if (loop[i] != ~0u)
  926. {
  927. unsigned int l = loop[i];
  928. unsigned int r = collapse_remap[l];
  929. // i == r is a special case when the seam edge is collapsed in a direction opposite to where loop goes
  930. loop[i] = (i == r) ? loop[l] : r;
  931. }
  932. }
  933. }
  934. struct CellHasher
  935. {
  936. const unsigned int* vertex_ids;
  937. size_t hash(unsigned int i) const
  938. {
  939. unsigned int h = vertex_ids[i];
  940. // MurmurHash2 finalizer
  941. h ^= h >> 13;
  942. h *= 0x5bd1e995;
  943. h ^= h >> 15;
  944. return h;
  945. }
  946. bool equal(unsigned int lhs, unsigned int rhs) const
  947. {
  948. return vertex_ids[lhs] == vertex_ids[rhs];
  949. }
  950. };
  951. struct IdHasher
  952. {
  953. size_t hash(unsigned int id) const
  954. {
  955. unsigned int h = id;
  956. // MurmurHash2 finalizer
  957. h ^= h >> 13;
  958. h *= 0x5bd1e995;
  959. h ^= h >> 15;
  960. return h;
  961. }
  962. bool equal(unsigned int lhs, unsigned int rhs) const
  963. {
  964. return lhs == rhs;
  965. }
  966. };
  967. struct TriangleHasher
  968. {
  969. const unsigned int* indices;
  970. size_t hash(unsigned int i) const
  971. {
  972. const unsigned int* tri = indices + i * 3;
  973. // Optimized Spatial Hashing for Collision Detection of Deformable Objects
  974. return (tri[0] * 73856093) ^ (tri[1] * 19349663) ^ (tri[2] * 83492791);
  975. }
  976. bool equal(unsigned int lhs, unsigned int rhs) const
  977. {
  978. const unsigned int* lt = indices + lhs * 3;
  979. const unsigned int* rt = indices + rhs * 3;
  980. return lt[0] == rt[0] && lt[1] == rt[1] && lt[2] == rt[2];
  981. }
  982. };
  983. static void computeVertexIds(unsigned int* vertex_ids, const Vector3* vertex_positions, size_t vertex_count, int grid_size)
  984. {
  985. assert(grid_size >= 1 && grid_size <= 1024);
  986. float cell_scale = float(grid_size - 1);
  987. for (size_t i = 0; i < vertex_count; ++i)
  988. {
  989. const Vector3& v = vertex_positions[i];
  990. int xi = int(v.x * cell_scale + 0.5f);
  991. int yi = int(v.y * cell_scale + 0.5f);
  992. int zi = int(v.z * cell_scale + 0.5f);
  993. vertex_ids[i] = (xi << 20) | (yi << 10) | zi;
  994. }
  995. }
  996. static size_t countTriangles(const unsigned int* vertex_ids, const unsigned int* indices, size_t index_count)
  997. {
  998. size_t result = 0;
  999. for (size_t i = 0; i < index_count; i += 3)
  1000. {
  1001. unsigned int id0 = vertex_ids[indices[i + 0]];
  1002. unsigned int id1 = vertex_ids[indices[i + 1]];
  1003. unsigned int id2 = vertex_ids[indices[i + 2]];
  1004. result += (id0 != id1) & (id0 != id2) & (id1 != id2);
  1005. }
  1006. return result;
  1007. }
  1008. static size_t fillVertexCells(unsigned int* table, size_t table_size, unsigned int* vertex_cells, const unsigned int* vertex_ids, size_t vertex_count)
  1009. {
  1010. CellHasher hasher = {vertex_ids};
  1011. memset(table, -1, table_size * sizeof(unsigned int));
  1012. size_t result = 0;
  1013. for (size_t i = 0; i < vertex_count; ++i)
  1014. {
  1015. unsigned int* entry = hashLookup2(table, table_size, hasher, unsigned(i), ~0u);
  1016. if (*entry == ~0u)
  1017. {
  1018. *entry = unsigned(i);
  1019. vertex_cells[i] = unsigned(result++);
  1020. }
  1021. else
  1022. {
  1023. vertex_cells[i] = vertex_cells[*entry];
  1024. }
  1025. }
  1026. return result;
  1027. }
  1028. static size_t countVertexCells(unsigned int* table, size_t table_size, const unsigned int* vertex_ids, size_t vertex_count)
  1029. {
  1030. IdHasher hasher;
  1031. memset(table, -1, table_size * sizeof(unsigned int));
  1032. size_t result = 0;
  1033. for (size_t i = 0; i < vertex_count; ++i)
  1034. {
  1035. unsigned int id = vertex_ids[i];
  1036. unsigned int* entry = hashLookup2(table, table_size, hasher, id, ~0u);
  1037. result += (*entry == ~0u);
  1038. *entry = id;
  1039. }
  1040. return result;
  1041. }
  1042. static void fillCellQuadrics(Quadric* cell_quadrics, const unsigned int* indices, size_t index_count, const Vector3* vertex_positions, const unsigned int* vertex_cells)
  1043. {
  1044. for (size_t i = 0; i < index_count; i += 3)
  1045. {
  1046. unsigned int i0 = indices[i + 0];
  1047. unsigned int i1 = indices[i + 1];
  1048. unsigned int i2 = indices[i + 2];
  1049. unsigned int c0 = vertex_cells[i0];
  1050. unsigned int c1 = vertex_cells[i1];
  1051. unsigned int c2 = vertex_cells[i2];
  1052. int single_cell = (c0 == c1) & (c0 == c2);
  1053. Quadric Q;
  1054. quadricFromTriangle(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], single_cell ? 3.f : 1.f);
  1055. if (single_cell)
  1056. {
  1057. quadricAdd(cell_quadrics[c0], Q);
  1058. }
  1059. else
  1060. {
  1061. quadricAdd(cell_quadrics[c0], Q);
  1062. quadricAdd(cell_quadrics[c1], Q);
  1063. quadricAdd(cell_quadrics[c2], Q);
  1064. }
  1065. }
  1066. }
  1067. static void fillCellReservoirs(Reservoir* cell_reservoirs, size_t cell_count, const Vector3* vertex_positions, const float* vertex_colors, size_t vertex_colors_stride, size_t vertex_count, const unsigned int* vertex_cells)
  1068. {
  1069. static const float dummy_color[] = {0.f, 0.f, 0.f};
  1070. size_t vertex_colors_stride_float = vertex_colors_stride / sizeof(float);
  1071. for (size_t i = 0; i < vertex_count; ++i)
  1072. {
  1073. unsigned int cell = vertex_cells[i];
  1074. const Vector3& v = vertex_positions[i];
  1075. Reservoir& r = cell_reservoirs[cell];
  1076. const float* color = vertex_colors ? &vertex_colors[i * vertex_colors_stride_float] : dummy_color;
  1077. r.x += v.x;
  1078. r.y += v.y;
  1079. r.z += v.z;
  1080. r.r += color[0];
  1081. r.g += color[1];
  1082. r.b += color[2];
  1083. r.w += 1.f;
  1084. }
  1085. for (size_t i = 0; i < cell_count; ++i)
  1086. {
  1087. Reservoir& r = cell_reservoirs[i];
  1088. float iw = r.w == 0.f ? 0.f : 1.f / r.w;
  1089. r.x *= iw;
  1090. r.y *= iw;
  1091. r.z *= iw;
  1092. r.r *= iw;
  1093. r.g *= iw;
  1094. r.b *= iw;
  1095. }
  1096. }
  1097. static void fillCellRemap(unsigned int* cell_remap, float* cell_errors, size_t cell_count, const unsigned int* vertex_cells, const Quadric* cell_quadrics, const Vector3* vertex_positions, size_t vertex_count)
  1098. {
  1099. memset(cell_remap, -1, cell_count * sizeof(unsigned int));
  1100. for (size_t i = 0; i < vertex_count; ++i)
  1101. {
  1102. unsigned int cell = vertex_cells[i];
  1103. float error = quadricError(cell_quadrics[cell], vertex_positions[i]);
  1104. if (cell_remap[cell] == ~0u || cell_errors[cell] > error)
  1105. {
  1106. cell_remap[cell] = unsigned(i);
  1107. cell_errors[cell] = error;
  1108. }
  1109. }
  1110. }
  1111. static void fillCellRemap(unsigned int* cell_remap, float* cell_errors, size_t cell_count, const unsigned int* vertex_cells, const Reservoir* cell_reservoirs, const Vector3* vertex_positions, const float* vertex_colors, size_t vertex_colors_stride, float color_weight, size_t vertex_count)
  1112. {
  1113. static const float dummy_color[] = {0.f, 0.f, 0.f};
  1114. size_t vertex_colors_stride_float = vertex_colors_stride / sizeof(float);
  1115. memset(cell_remap, -1, cell_count * sizeof(unsigned int));
  1116. for (size_t i = 0; i < vertex_count; ++i)
  1117. {
  1118. unsigned int cell = vertex_cells[i];
  1119. const Vector3& v = vertex_positions[i];
  1120. const Reservoir& r = cell_reservoirs[cell];
  1121. const float* color = vertex_colors ? &vertex_colors[i * vertex_colors_stride_float] : dummy_color;
  1122. float pos_error = (v.x - r.x) * (v.x - r.x) + (v.y - r.y) * (v.y - r.y) + (v.z - r.z) * (v.z - r.z);
  1123. float col_error = (color[0] - r.r) * (color[0] - r.r) + (color[1] - r.g) * (color[1] - r.g) + (color[2] - r.b) * (color[2] - r.b);
  1124. float error = pos_error + color_weight * col_error;
  1125. if (cell_remap[cell] == ~0u || cell_errors[cell] > error)
  1126. {
  1127. cell_remap[cell] = unsigned(i);
  1128. cell_errors[cell] = error;
  1129. }
  1130. }
  1131. }
  1132. static size_t filterTriangles(unsigned int* destination, unsigned int* tritable, size_t tritable_size, const unsigned int* indices, size_t index_count, const unsigned int* vertex_cells, const unsigned int* cell_remap)
  1133. {
  1134. TriangleHasher hasher = {destination};
  1135. memset(tritable, -1, tritable_size * sizeof(unsigned int));
  1136. size_t result = 0;
  1137. for (size_t i = 0; i < index_count; i += 3)
  1138. {
  1139. unsigned int c0 = vertex_cells[indices[i + 0]];
  1140. unsigned int c1 = vertex_cells[indices[i + 1]];
  1141. unsigned int c2 = vertex_cells[indices[i + 2]];
  1142. if (c0 != c1 && c0 != c2 && c1 != c2)
  1143. {
  1144. unsigned int a = cell_remap[c0];
  1145. unsigned int b = cell_remap[c1];
  1146. unsigned int c = cell_remap[c2];
  1147. if (b < a && b < c)
  1148. {
  1149. unsigned int t = a;
  1150. a = b, b = c, c = t;
  1151. }
  1152. else if (c < a && c < b)
  1153. {
  1154. unsigned int t = c;
  1155. c = b, b = a, a = t;
  1156. }
  1157. destination[result * 3 + 0] = a;
  1158. destination[result * 3 + 1] = b;
  1159. destination[result * 3 + 2] = c;
  1160. unsigned int* entry = hashLookup2(tritable, tritable_size, hasher, unsigned(result), ~0u);
  1161. if (*entry == ~0u)
  1162. *entry = unsigned(result++);
  1163. }
  1164. }
  1165. return result * 3;
  1166. }
  1167. static float interpolate(float y, float x0, float y0, float x1, float y1, float x2, float y2)
  1168. {
  1169. // three point interpolation from "revenge of interpolation search" paper
  1170. float num = (y1 - y) * (x1 - x2) * (x1 - x0) * (y2 - y0);
  1171. float den = (y2 - y) * (x1 - x2) * (y0 - y1) + (y0 - y) * (x1 - x0) * (y1 - y2);
  1172. return x1 + num / den;
  1173. }
  1174. } // namespace meshopt
  1175. #ifndef NDEBUG
  1176. // Note: this is only exposed for debug visualization purposes; do *not* use these in debug builds
  1177. MESHOPTIMIZER_API unsigned char* meshopt_simplifyDebugKind = NULL;
  1178. MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoop = NULL;
  1179. MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = NULL;
  1180. #endif
  1181. size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes_data, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* out_result_error)
  1182. {
  1183. using namespace meshopt;
  1184. assert(index_count % 3 == 0);
  1185. assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
  1186. assert(vertex_positions_stride % sizeof(float) == 0);
  1187. assert(target_index_count <= index_count);
  1188. assert((options & ~(meshopt_SimplifyLockBorder)) == 0);
  1189. assert(vertex_attributes_stride >= attribute_count * sizeof(float) && vertex_attributes_stride <= 256);
  1190. assert(vertex_attributes_stride % sizeof(float) == 0);
  1191. assert(attribute_count <= kMaxAttributes);
  1192. meshopt_Allocator allocator;
  1193. unsigned int* result = destination;
  1194. // build adjacency information
  1195. EdgeAdjacency adjacency = {};
  1196. prepareEdgeAdjacency(adjacency, index_count, vertex_count, allocator);
  1197. updateEdgeAdjacency(adjacency, indices, index_count, vertex_count, NULL);
  1198. // build position remap that maps each vertex to the one with identical position
  1199. unsigned int* remap = allocator.allocate<unsigned int>(vertex_count);
  1200. unsigned int* wedge = allocator.allocate<unsigned int>(vertex_count);
  1201. buildPositionRemap(remap, wedge, vertex_positions_data, vertex_count, vertex_positions_stride, allocator);
  1202. // classify vertices; vertex kind determines collapse rules, see kCanCollapse
  1203. unsigned char* vertex_kind = allocator.allocate<unsigned char>(vertex_count);
  1204. unsigned int* loop = allocator.allocate<unsigned int>(vertex_count);
  1205. unsigned int* loopback = allocator.allocate<unsigned int>(vertex_count);
  1206. classifyVertices(vertex_kind, loop, loopback, vertex_count, adjacency, remap, wedge, vertex_lock, options);
  1207. #if TRACE
  1208. size_t unique_positions = 0;
  1209. for (size_t i = 0; i < vertex_count; ++i)
  1210. unique_positions += remap[i] == i;
  1211. printf("position remap: %d vertices => %d positions\n", int(vertex_count), int(unique_positions));
  1212. size_t kinds[Kind_Count] = {};
  1213. for (size_t i = 0; i < vertex_count; ++i)
  1214. kinds[vertex_kind[i]] += remap[i] == i;
  1215. printf("kinds: manifold %d, border %d, seam %d, complex %d, locked %d\n",
  1216. int(kinds[Kind_Manifold]), int(kinds[Kind_Border]), int(kinds[Kind_Seam]), int(kinds[Kind_Complex]), int(kinds[Kind_Locked]));
  1217. #endif
  1218. Vector3* vertex_positions = allocator.allocate<Vector3>(vertex_count);
  1219. rescalePositions(vertex_positions, vertex_positions_data, vertex_count, vertex_positions_stride);
  1220. float* vertex_attributes = NULL;
  1221. if (attribute_count)
  1222. {
  1223. vertex_attributes = allocator.allocate<float>(vertex_count * attribute_count);
  1224. rescaleAttributes(vertex_attributes, vertex_attributes_data, vertex_count, vertex_attributes_stride, attribute_weights, attribute_count);
  1225. }
  1226. Quadric* vertex_quadrics = allocator.allocate<Quadric>(vertex_count);
  1227. memset(vertex_quadrics, 0, vertex_count * sizeof(Quadric));
  1228. Quadric* attribute_quadrics = NULL;
  1229. QuadricGrad* attribute_gradients = NULL;
  1230. if (attribute_count)
  1231. {
  1232. attribute_quadrics = allocator.allocate<Quadric>(vertex_count);
  1233. memset(attribute_quadrics, 0, vertex_count * sizeof(Quadric));
  1234. attribute_gradients = allocator.allocate<QuadricGrad>(vertex_count * attribute_count);
  1235. memset(attribute_gradients, 0, vertex_count * attribute_count * sizeof(QuadricGrad));
  1236. }
  1237. fillFaceQuadrics(vertex_quadrics, indices, index_count, vertex_positions, remap);
  1238. fillEdgeQuadrics(vertex_quadrics, indices, index_count, vertex_positions, remap, vertex_kind, loop, loopback);
  1239. if (attribute_count)
  1240. fillAttributeQuadrics(attribute_quadrics, attribute_gradients, indices, index_count, vertex_positions, vertex_attributes, attribute_count, remap);
  1241. if (result != indices)
  1242. memcpy(result, indices, index_count * sizeof(unsigned int));
  1243. #if TRACE
  1244. size_t pass_count = 0;
  1245. #endif
  1246. size_t collapse_capacity = boundEdgeCollapses(adjacency, vertex_count, index_count, vertex_kind);
  1247. Collapse* edge_collapses = allocator.allocate<Collapse>(collapse_capacity);
  1248. unsigned int* collapse_order = allocator.allocate<unsigned int>(collapse_capacity);
  1249. unsigned int* collapse_remap = allocator.allocate<unsigned int>(vertex_count);
  1250. unsigned char* collapse_locked = allocator.allocate<unsigned char>(vertex_count);
  1251. size_t result_count = index_count;
  1252. float result_error = 0;
  1253. // target_error input is linear; we need to adjust it to match quadricError units
  1254. float error_limit = target_error * target_error;
  1255. while (result_count > target_index_count)
  1256. {
  1257. // note: throughout the simplification process adjacency structure reflects welded topology for result-in-progress
  1258. updateEdgeAdjacency(adjacency, result, result_count, vertex_count, remap);
  1259. size_t edge_collapse_count = pickEdgeCollapses(edge_collapses, collapse_capacity, result, result_count, remap, vertex_kind, loop);
  1260. assert(edge_collapse_count <= collapse_capacity);
  1261. // no edges can be collapsed any more due to topology restrictions
  1262. if (edge_collapse_count == 0)
  1263. break;
  1264. rankEdgeCollapses(edge_collapses, edge_collapse_count, vertex_positions, vertex_attributes, vertex_quadrics, attribute_quadrics, attribute_gradients, attribute_count, remap);
  1265. sortEdgeCollapses(collapse_order, edge_collapses, edge_collapse_count);
  1266. size_t triangle_collapse_goal = (result_count - target_index_count) / 3;
  1267. for (size_t i = 0; i < vertex_count; ++i)
  1268. collapse_remap[i] = unsigned(i);
  1269. memset(collapse_locked, 0, vertex_count);
  1270. #if TRACE
  1271. printf("pass %d: ", int(pass_count++));
  1272. #endif
  1273. size_t collapses = performEdgeCollapses(collapse_remap, collapse_locked, vertex_quadrics, attribute_quadrics, attribute_gradients, attribute_count, edge_collapses, edge_collapse_count, collapse_order, remap, wedge, vertex_kind, vertex_positions, adjacency, triangle_collapse_goal, error_limit, result_error);
  1274. // no edges can be collapsed any more due to hitting the error limit or triangle collapse limit
  1275. if (collapses == 0)
  1276. break;
  1277. remapEdgeLoops(loop, vertex_count, collapse_remap);
  1278. remapEdgeLoops(loopback, vertex_count, collapse_remap);
  1279. size_t new_count = remapIndexBuffer(result, result_count, collapse_remap);
  1280. assert(new_count < result_count);
  1281. result_count = new_count;
  1282. }
  1283. #if TRACE
  1284. printf("result: %d triangles, error: %e; total %d passes\n", int(result_count / 3), sqrtf(result_error), int(pass_count));
  1285. #endif
  1286. #ifndef NDEBUG
  1287. if (meshopt_simplifyDebugKind)
  1288. memcpy(meshopt_simplifyDebugKind, vertex_kind, vertex_count);
  1289. if (meshopt_simplifyDebugLoop)
  1290. memcpy(meshopt_simplifyDebugLoop, loop, vertex_count * sizeof(unsigned int));
  1291. if (meshopt_simplifyDebugLoopBack)
  1292. memcpy(meshopt_simplifyDebugLoopBack, loopback, vertex_count * sizeof(unsigned int));
  1293. #endif
  1294. // result_error is quadratic; we need to remap it back to linear
  1295. if (out_result_error)
  1296. *out_result_error = sqrtf(result_error);
  1297. return result_count;
  1298. }
  1299. size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float* out_result_error)
  1300. {
  1301. return meshopt_simplifyEdge(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, NULL, 0, NULL, 0, NULL, target_index_count, target_error, options, out_result_error);
  1302. }
  1303. size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes_data, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* out_result_error)
  1304. {
  1305. return meshopt_simplifyEdge(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, vertex_attributes_data, vertex_attributes_stride, attribute_weights, attribute_count, vertex_lock, target_index_count, target_error, options, out_result_error);
  1306. }
  1307. size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* out_result_error)
  1308. {
  1309. using namespace meshopt;
  1310. assert(index_count % 3 == 0);
  1311. assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
  1312. assert(vertex_positions_stride % sizeof(float) == 0);
  1313. assert(target_index_count <= index_count);
  1314. // we expect to get ~2 triangles/vertex in the output
  1315. size_t target_cell_count = target_index_count / 6;
  1316. meshopt_Allocator allocator;
  1317. Vector3* vertex_positions = allocator.allocate<Vector3>(vertex_count);
  1318. rescalePositions(vertex_positions, vertex_positions_data, vertex_count, vertex_positions_stride);
  1319. // find the optimal grid size using guided binary search
  1320. #if TRACE
  1321. printf("source: %d vertices, %d triangles\n", int(vertex_count), int(index_count / 3));
  1322. printf("target: %d cells, %d triangles\n", int(target_cell_count), int(target_index_count / 3));
  1323. #endif
  1324. unsigned int* vertex_ids = allocator.allocate<unsigned int>(vertex_count);
  1325. const int kInterpolationPasses = 5;
  1326. // invariant: # of triangles in min_grid <= target_count
  1327. int min_grid = int(1.f / (target_error < 1e-3f ? 1e-3f : target_error));
  1328. int max_grid = 1025;
  1329. size_t min_triangles = 0;
  1330. size_t max_triangles = index_count / 3;
  1331. // when we're error-limited, we compute the triangle count for the min. size; this accelerates convergence and provides the correct answer when we can't use a larger grid
  1332. if (min_grid > 1)
  1333. {
  1334. computeVertexIds(vertex_ids, vertex_positions, vertex_count, min_grid);
  1335. min_triangles = countTriangles(vertex_ids, indices, index_count);
  1336. }
  1337. // instead of starting in the middle, let's guess as to what the answer might be! triangle count usually grows as a square of grid size...
  1338. int next_grid_size = int(sqrtf(float(target_cell_count)) + 0.5f);
  1339. for (int pass = 0; pass < 10 + kInterpolationPasses; ++pass)
  1340. {
  1341. if (min_triangles >= target_index_count / 3 || max_grid - min_grid <= 1)
  1342. break;
  1343. // we clamp the prediction of the grid size to make sure that the search converges
  1344. int grid_size = next_grid_size;
  1345. grid_size = (grid_size <= min_grid) ? min_grid + 1 : (grid_size >= max_grid) ? max_grid - 1 : grid_size;
  1346. computeVertexIds(vertex_ids, vertex_positions, vertex_count, grid_size);
  1347. size_t triangles = countTriangles(vertex_ids, indices, index_count);
  1348. #if TRACE
  1349. printf("pass %d (%s): grid size %d, triangles %d, %s\n",
  1350. pass, (pass == 0) ? "guess" : (pass <= kInterpolationPasses) ? "lerp" : "binary",
  1351. grid_size, int(triangles),
  1352. (triangles <= target_index_count / 3) ? "under" : "over");
  1353. #endif
  1354. float tip = interpolate(float(target_index_count / 3), float(min_grid), float(min_triangles), float(grid_size), float(triangles), float(max_grid), float(max_triangles));
  1355. if (triangles <= target_index_count / 3)
  1356. {
  1357. min_grid = grid_size;
  1358. min_triangles = triangles;
  1359. }
  1360. else
  1361. {
  1362. max_grid = grid_size;
  1363. max_triangles = triangles;
  1364. }
  1365. // we start by using interpolation search - it usually converges faster
  1366. // however, interpolation search has a worst case of O(N) so we switch to binary search after a few iterations which converges in O(logN)
  1367. next_grid_size = (pass < kInterpolationPasses) ? int(tip + 0.5f) : (min_grid + max_grid) / 2;
  1368. }
  1369. if (min_triangles == 0)
  1370. {
  1371. if (out_result_error)
  1372. *out_result_error = 1.f;
  1373. return 0;
  1374. }
  1375. // build vertex->cell association by mapping all vertices with the same quantized position to the same cell
  1376. size_t table_size = hashBuckets2(vertex_count);
  1377. unsigned int* table = allocator.allocate<unsigned int>(table_size);
  1378. unsigned int* vertex_cells = allocator.allocate<unsigned int>(vertex_count);
  1379. computeVertexIds(vertex_ids, vertex_positions, vertex_count, min_grid);
  1380. size_t cell_count = fillVertexCells(table, table_size, vertex_cells, vertex_ids, vertex_count);
  1381. // build a quadric for each target cell
  1382. Quadric* cell_quadrics = allocator.allocate<Quadric>(cell_count);
  1383. memset(cell_quadrics, 0, cell_count * sizeof(Quadric));
  1384. fillCellQuadrics(cell_quadrics, indices, index_count, vertex_positions, vertex_cells);
  1385. // for each target cell, find the vertex with the minimal error
  1386. unsigned int* cell_remap = allocator.allocate<unsigned int>(cell_count);
  1387. float* cell_errors = allocator.allocate<float>(cell_count);
  1388. fillCellRemap(cell_remap, cell_errors, cell_count, vertex_cells, cell_quadrics, vertex_positions, vertex_count);
  1389. // compute error
  1390. float result_error = 0.f;
  1391. for (size_t i = 0; i < cell_count; ++i)
  1392. result_error = result_error < cell_errors[i] ? cell_errors[i] : result_error;
  1393. // collapse triangles!
  1394. // note that we need to filter out triangles that we've already output because we very frequently generate redundant triangles between cells :(
  1395. size_t tritable_size = hashBuckets2(min_triangles);
  1396. unsigned int* tritable = allocator.allocate<unsigned int>(tritable_size);
  1397. size_t write = filterTriangles(destination, tritable, tritable_size, indices, index_count, vertex_cells, cell_remap);
  1398. #if TRACE
  1399. printf("result: %d cells, %d triangles (%d unfiltered), error %e\n", int(cell_count), int(write / 3), int(min_triangles), sqrtf(result_error));
  1400. #endif
  1401. if (out_result_error)
  1402. *out_result_error = sqrtf(result_error);
  1403. return write;
  1404. }
  1405. size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_colors, size_t vertex_colors_stride, float color_weight, size_t target_vertex_count)
  1406. {
  1407. using namespace meshopt;
  1408. assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
  1409. assert(vertex_positions_stride % sizeof(float) == 0);
  1410. assert(vertex_colors_stride == 0 || (vertex_colors_stride >= 12 && vertex_colors_stride <= 256));
  1411. assert(vertex_colors_stride % sizeof(float) == 0);
  1412. assert(vertex_colors == NULL || vertex_colors_stride != 0);
  1413. assert(target_vertex_count <= vertex_count);
  1414. size_t target_cell_count = target_vertex_count;
  1415. if (target_cell_count == 0)
  1416. return 0;
  1417. meshopt_Allocator allocator;
  1418. Vector3* vertex_positions = allocator.allocate<Vector3>(vertex_count);
  1419. rescalePositions(vertex_positions, vertex_positions_data, vertex_count, vertex_positions_stride);
  1420. // find the optimal grid size using guided binary search
  1421. #if TRACE
  1422. printf("source: %d vertices\n", int(vertex_count));
  1423. printf("target: %d cells\n", int(target_cell_count));
  1424. #endif
  1425. unsigned int* vertex_ids = allocator.allocate<unsigned int>(vertex_count);
  1426. size_t table_size = hashBuckets2(vertex_count);
  1427. unsigned int* table = allocator.allocate<unsigned int>(table_size);
  1428. const int kInterpolationPasses = 5;
  1429. // invariant: # of vertices in min_grid <= target_count
  1430. int min_grid = 0;
  1431. int max_grid = 1025;
  1432. size_t min_vertices = 0;
  1433. size_t max_vertices = vertex_count;
  1434. // instead of starting in the middle, let's guess as to what the answer might be! triangle count usually grows as a square of grid size...
  1435. int next_grid_size = int(sqrtf(float(target_cell_count)) + 0.5f);
  1436. for (int pass = 0; pass < 10 + kInterpolationPasses; ++pass)
  1437. {
  1438. assert(min_vertices < target_vertex_count);
  1439. assert(max_grid - min_grid > 1);
  1440. // we clamp the prediction of the grid size to make sure that the search converges
  1441. int grid_size = next_grid_size;
  1442. grid_size = (grid_size <= min_grid) ? min_grid + 1 : (grid_size >= max_grid) ? max_grid - 1 : grid_size;
  1443. computeVertexIds(vertex_ids, vertex_positions, vertex_count, grid_size);
  1444. size_t vertices = countVertexCells(table, table_size, vertex_ids, vertex_count);
  1445. #if TRACE
  1446. printf("pass %d (%s): grid size %d, vertices %d, %s\n",
  1447. pass, (pass == 0) ? "guess" : (pass <= kInterpolationPasses) ? "lerp" : "binary",
  1448. grid_size, int(vertices),
  1449. (vertices <= target_vertex_count) ? "under" : "over");
  1450. #endif
  1451. float tip = interpolate(float(target_vertex_count), float(min_grid), float(min_vertices), float(grid_size), float(vertices), float(max_grid), float(max_vertices));
  1452. if (vertices <= target_vertex_count)
  1453. {
  1454. min_grid = grid_size;
  1455. min_vertices = vertices;
  1456. }
  1457. else
  1458. {
  1459. max_grid = grid_size;
  1460. max_vertices = vertices;
  1461. }
  1462. if (vertices == target_vertex_count || max_grid - min_grid <= 1)
  1463. break;
  1464. // we start by using interpolation search - it usually converges faster
  1465. // however, interpolation search has a worst case of O(N) so we switch to binary search after a few iterations which converges in O(logN)
  1466. next_grid_size = (pass < kInterpolationPasses) ? int(tip + 0.5f) : (min_grid + max_grid) / 2;
  1467. }
  1468. if (min_vertices == 0)
  1469. return 0;
  1470. // build vertex->cell association by mapping all vertices with the same quantized position to the same cell
  1471. unsigned int* vertex_cells = allocator.allocate<unsigned int>(vertex_count);
  1472. computeVertexIds(vertex_ids, vertex_positions, vertex_count, min_grid);
  1473. size_t cell_count = fillVertexCells(table, table_size, vertex_cells, vertex_ids, vertex_count);
  1474. // accumulate points into a reservoir for each target cell
  1475. Reservoir* cell_reservoirs = allocator.allocate<Reservoir>(cell_count);
  1476. memset(cell_reservoirs, 0, cell_count * sizeof(Reservoir));
  1477. fillCellReservoirs(cell_reservoirs, cell_count, vertex_positions, vertex_colors, vertex_colors_stride, vertex_count, vertex_cells);
  1478. // for each target cell, find the vertex with the minimal error
  1479. unsigned int* cell_remap = allocator.allocate<unsigned int>(cell_count);
  1480. float* cell_errors = allocator.allocate<float>(cell_count);
  1481. fillCellRemap(cell_remap, cell_errors, cell_count, vertex_cells, cell_reservoirs, vertex_positions, vertex_colors, vertex_colors_stride, color_weight * color_weight, vertex_count);
  1482. // copy results to the output
  1483. assert(cell_count <= target_vertex_count);
  1484. memcpy(destination, cell_remap, sizeof(unsigned int) * cell_count);
  1485. #if TRACE
  1486. // compute error
  1487. float result_error = 0.f;
  1488. for (size_t i = 0; i < cell_count; ++i)
  1489. result_error = result_error < cell_errors[i] ? cell_errors[i] : result_error;
  1490. printf("result: %d cells, %e error\n", int(cell_count), sqrtf(result_error));
  1491. #endif
  1492. return cell_count;
  1493. }
  1494. float meshopt_simplifyScale(const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride)
  1495. {
  1496. using namespace meshopt;
  1497. assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
  1498. assert(vertex_positions_stride % sizeof(float) == 0);
  1499. float extent = rescalePositions(NULL, vertex_positions, vertex_count, vertex_positions_stride);
  1500. return extent;
  1501. }