5#ifdef WITH_CXX_GUARDEDALLOC
25# define dc_printf printf
28# define dc_printf(...) \
60 hermite_num(sharpness),
62 alloc_output(alloc_output_func),
63 add_vert(add_vert_func),
64 add_quad(add_quad_func)
103 clock_t start, finish;
114 (
double)(finish - start) / CLOCKS_PER_SEC);
126 dc_printf(
"Time taken: %f seconds \n", (
double)(finish - start) / CLOCKS_PER_SEC);
127# ifdef IN_VERBOSE_MODE
128 dc_printf(
"Holes: %d Average Length: %f Max Length: %d \n",
130 (
float)totRingLengths / (
float)numRings,
136 int tnumRings = numRings;
138#ifdef IN_VERBOSE_MODE
139 dc_printf(
"Holes after patching: %d \n", numRings);
141 numRings = tnumRings;
150 dc_printf(
"Time taken: %f seconds \n", (
double)(finish - start) / CLOCKS_PER_SEC);
176 dc_printf(
"Time taken: %f seconds \n", (
double)(finish - start) / CLOCKS_PER_SEC);
191#ifdef IN_VERBOSE_MODE
196void Octree::initMemory()
214void Octree::freeMemory()
216 for (
int i = 0; i < 9; i++) {
221 for (
int i = 0; i < 4; i++) {
227void Octree::printMemUsage()
230 dc_printf(
"********* Internal nodes: \n");
231 for (
int i = 0; i < 9; i++) {
238 for (
int i = 0; i < 4; i++) {
245 dc_printf(
"Total allocated bytes on disk: %d \n", totalbytes);
246 dc_printf(
"Total leaf nodes: %d\n", totalLeafs);
253void Octree::resetMinimalEdges()
258void Octree::addAllTriangles()
265 int unitcount = 1000;
274 addTriangle(trian,
count);
281 if (
count % unitcount == 0) {
284 switch ((
count / unitcount) % 4) {
313 dc_printf(
" %f%% complete.", 100 * percent);
322void Octree::addTriangle(
Triangle *trian,
int triind)
327 for (i = 0; i < 3; i++) {
328 for (j = 0; j < 3; j++) {
336 for (i = 0; i < 3; i++) {
337 for (j = 0; j < 3; j++) {
352static void print_depth(
int height,
int maxDepth)
354 for (
int i = 0; i < maxDepth - height; i++)
362 const int vertdiff[8][3] = {
363 {0, 0, 0}, {0, 0, 1}, {0, 1, -1}, {0, 0, 1}, {1, -1, -1}, {0, 0, 1}, {0, 1, -1}, {0, 0, 1}};
368 int tempdiff[3] = {0, 0, 0};
371 for (i = 0; i < 8; i++) {
372 tempdiff[0] += vertdiff[i][0];
373 tempdiff[1] += vertdiff[i][1];
374 tempdiff[2] += vertdiff[i][2];
377 if (boxmask & (1 << i)) {
378 subp->
shift(tempdiff);
379 tempdiff[0] = tempdiff[1] = tempdiff[2] = 0;
383 if (!node->has_child(i)) {
385 node = addLeafChild(node, i,
count, createLeaf(0));
388 node = addInternalChild(node, i,
count, createInternal(0));
393 if (node->is_child_leaf(i)) {
394 node->set_child(
count, (
Node *)updateCell(&chd->
leaf, subp));
402 if (node->has_child(i)) {
417 int mask[3] = {0, 4, 8};
418 int oldc = 0, newc = 0;
420 float a[3],
b[3], c[3];
422 for (i = 0; i < 3; i++) {
423 if (!getEdgeParity(node, mask[i])) {
426 setEdge(node, mask[i]);
435 offs[newc] = getEdgeOffsetNormal(node, oldc, a[newc],
b[newc], c[newc]);
444 node = updateEdgeOffsetsNormals(node, oldc, newc, offs, a,
b, c);
453 for (
int i = 0; i < 8; i++) {
454 if (node->has_child(i)) {
455 if (node->is_child_leaf(i)) {
456 createPrimalEdgesMask(&node->get_child(
count)->leaf);
459 preparePrimalEdgesMask(&node->get_child(
count)->internal);
481 if (chdpath !=
NULL) {
482 dc_printf(
"there are incomplete rings.\n");
500 for (i = 0; i < 8; i++) {
501 for (j = 0; j < 3; j++) {
509 trace(chd[i], nst[i],
len, depth - 1, chdpaths[i]);
517 int df[2] = {depth - 1, depth - 1};
522 for (i = 0; i < 12; i++) {
525 for (
int j = 0; j < 2; j++) {
526 lf[j] = chdleaf[c[j]];
544 combinePaths(chdpaths[0], chdpaths[1], conn[8], rings);
545 combinePaths(chdpaths[2], chdpaths[3], conn[9], rings);
546 combinePaths(chdpaths[4], chdpaths[5], conn[10], rings);
547 combinePaths(chdpaths[6], chdpaths[7], conn[11], rings);
549 combinePaths(chdpaths[0], chdpaths[2], conn[4], rings);
550 combinePaths(chdpaths[4], chdpaths[6], conn[5], rings);
551 combinePaths(chdpaths[0],
NULL, conn[6], rings);
552 combinePaths(chdpaths[4],
NULL, conn[7], rings);
554 combinePaths(chdpaths[0], chdpaths[4], conn[0], rings);
555 combinePaths(chdpaths[0],
NULL, conn[1], rings);
556 combinePaths(chdpaths[0],
NULL, conn[2], rings);
557 combinePaths(chdpaths[0],
NULL, conn[3], rings);
569 totRingLengths += trings->
length;
570 if (trings->
length > maxRingLength) {
571 maxRingLength = trings->
length;
573 trings = trings->
next;
577 newnode = patch(newnode, st, (
len << 1), rings);
585void Octree::findPaths(
586 Node *node[2],
int leaf[2],
int depth[2],
int *st[2],
int maxdep,
int dir,
PathList *&paths)
588 if (!(node[0] && node[1])) {
592 if (!(leaf[0] && leaf[1])) {
601 for (j = 0; j < 2; j++) {
606 for (i = 0; i < 8; i++) {
607 for (
int k = 0; k < 3; k++) {
608 nst[j][i][k] = st[j][k] +
len *
vertmap[i][k];
619 for (i = 0; i < 4; i++) {
621 for (
int j = 0; j < 2; j++) {
629 lf[j] = chdleaf[j][c[j]];
630 nf[j] = chd[j][c[j]];
631 df[j] = depth[j] - 1;
632 nstf[j] = nst[j][c[j]];
635 findPaths(nf, lf, df, nstf, maxdep - 1,
faceProcFaceMask[dir][i][2], paths);
640 int ind = (depth[0] == maxdep ? 0 : 1);
641 int fcind = 2 * dir + (1 - ind);
642 if (getFaceParity((
LeafNode *)node[ind], fcind)) {
647 ele1->
pos[0] = st[0][0];
648 ele1->
pos[1] = st[0][1];
649 ele1->
pos[2] = st[0][2];
651 ele2->
pos[0] = st[1][0];
652 ele2->
pos[1] = st[1][1];
653 ele2->
pos[2] = st[1][2];
681 tpaths = tpaths->
next;
688 if ((templist = combineSinglePath(list1, pre, tlist, singlist,
NULL, singlist)) !=
NULL) {
700 if ((templist = combineSinglePath(list2, pre, tlist, singlist,
NULL, singlist)) !=
NULL) {
712 if ((templist = combineSinglePath(nlist, pre, tlist, singlist,
NULL, singlist)) !=
NULL) {
721 if (isEqual(singlist->
head, singlist->
tail)) {
728 singlist->
next = rings;
732 singlist->
next = nlist;
769 if (isEqual(list1->
head, list2->
head) || isEqual(list1->
tail, list2->
tail)) {
805 if (isEqual(list1->
head, list2->
tail)) {
818 deletePath(head1, pre1, list1);
819 deletePath(head2, pre2, list2);
823 else if (isEqual(list1->
tail, list2->
head)) {
835 deletePath(head1, pre1, list1);
836 deletePath(head2, pre2, list2);
865void Octree::printPath(
PathList *path)
873 while (n && (same == 0 || n != path->
head)) {
879 if (n == path->
head) {
894 while (n && (same == 0 || n != path)) {
908void Octree::printPaths(
PathList *path)
911 while (iter !=
NULL) {
921 dc_printf(
"Call to PATCH with rings: \n");
944 dc_printf(
"Error! should have no list by now.\n");
950 newnode = patchSplit(newnode, st,
len, rings, 0, xlists[0], xlists[1]);
954 newnode = patchSplit(newnode, st,
len, xlists[0], 1, ylists[0], ylists[1]);
955 newnode = patchSplit(newnode, st,
len, xlists[1], 1, ylists[2], ylists[3]);
959 newnode = patchSplit(newnode, st,
len, ylists[0], 2, zlists[0], zlists[1]);
960 newnode = patchSplit(newnode, st,
len, ylists[1], 2, zlists[2], zlists[3]);
961 newnode = patchSplit(newnode, st,
len, ylists[2], 2, zlists[4], zlists[5]);
962 newnode = patchSplit(newnode, st,
len, ylists[3], 2, zlists[6], zlists[7]);
967 for (
int i = 0; i < 8; i++) {
968 if (zlists[i] !=
NULL) {
984Node *Octree::patchSplit(
Node *newnode,
993 dc_printf(
"Call to PATCHSPLIT with direction %d and rings: \n", dir);
1000 while (rings !=
NULL) {
1002 newnode = patchSplitSingle(newnode, st,
len, rings->
head, dir, nrings1, nrings2);
1006 rings = rings->
next;
1011 dc_printf(
"Return from PATCHSPLIT with \n");
1013 printPaths(nrings1);
1015 printPaths(nrings2);
1021Node *Octree::patchSplitSingle(
Node *newnode,
1030 dc_printf(
"Call to PATCHSPLITSINGLE with direction %d and path: \n", dir);
1036 dc_printf(
"Return from PATCHSPLITSINGLE with head==NULL.\n");
1047 int side = findPair(head, st[dir] +
len / 2, dir, pre1, pre2);
1052 dc_printf(
"Location: %d %d %d Direction: %d Reso: %d\n",
1069 nring->
next = nrings1;
1073 nring->
next = nrings2;
1084 newnode = connectFace(newnode, st,
len, dir, pre1, pre2);
1086 if (isEqual(pre1, pre1->
next)) {
1087 if (pre1 == pre1->
next) {
1097 if (isEqual(pre2, pre2->
next)) {
1098 if (pre2 == pre2->
next) {
1113 newnode = patchSplitSingle(newnode, st,
len, pre1, dir, nrings1, nrings2);
1114 newnode = patchSplitSingle(newnode, st,
len, pre2, dir, nrings1, nrings2);
1118 dc_printf(
"Return from PATCHSPLITSINGLE with \n");
1120 printPaths(nrings1);
1122 printPaths(nrings2);
1128Node *Octree::connectFace(
1132 dc_printf(
"Call to CONNECTFACE with direction %d and length %d path: \n", dir,
len);
1142 int pos = st[dir] +
len / 2;
1143 int xdir = (dir + 1) % 3;
1144 int ydir = (dir + 2) % 3;
1148 float p1,
q1, p2, q2;
1150 getFacePoint(f2->
next, dir, x1, y1, p1,
q1);
1151 getFacePoint(f2, dir, x2, y2, p2, q2);
1153 float dx = x2 + p2 - x1 - p1;
1154 float dy = y2 + q2 - y1 -
q1;
1157 float rx = p1, ry =
q1;
1158 int incx = 1, incy = 1;
1159 int lx = x1, ly = y1;
1160 int hx = x2, hy = y2;
1175 float sx = dx * incx;
1176 float sy = dy * incy;
1191 if (curN ==
NULL || curP ==
NULL) {
1206 while (ori[xdir] != x2 || ori[ydir] != y2) {
1208 if (sy * (1 - rx) > sx * (1 - ry)) {
1210 next = ori[ydir] + incy;
1213 next = ori[xdir] + incx;
1218 next = ori[xdir] + incx;
1221 next = ori[ydir] + incy;
1228 rx += (sy == 0 ? 0 : (1 - ry) * sx / sy);
1234 alpha = x2 < x1 ? 1 - rx : rx;
1239 ry += (sx == 0 ? 0 : (1 - rx) * sy / sx);
1245 alpha = y2 < y1 ? 1 - ry : ry;
1250 float spt[3] = {(
float)nori[0], (
float)nori[1], (
float)nori[2]};
1251 spt[(dir + (3 - walkdir)) % 3] += alpha *
mindimen;
1253 spt[(dir + walkdir) % 3] +=
mindimen;
1257 dc_printf(
"new x,y: %d %d\n", ori[xdir] / edgelen, ori[ydir] / edgelen);
1258 dc_printf(
"nori: %d %d %d alpha: %f walkdir: %d\n", nori[0], nori[1], nori[2], alpha, walkdir);
1259 dc_printf(
"%f %f %f\n", spt[0], spt[1], spt[2]);
1263 newnode = locateCell(&newnode->
internal, st,
len, nori, dir, 1, nodeN, stN, lenN);
1264 newnode = locateCell(&newnode->
internal, st,
len, nori, dir, 0, nodeP, stP, lenP);
1270 if (curEleN->
pos[0] != stN[0] || curEleN->
pos[1] != stN[1] || curEleN->
pos[2] != stN[2]) {
1271 if (curEleN->
next->
pos[0] != stN[0] || curEleN->
next->
pos[1] != stN[1] ||
1272 curEleN->
next->
pos[2] != stN[2])
1276 newEleN->
pos[0] = stN[0];
1277 newEleN->
pos[1] = stN[1];
1278 newEleN->
pos[2] = stN[2];
1280 curEleN->
next = newEleN;
1283 newEleN = curEleN->
next;
1285 curN = patchAdjacent(&newnode->
internal,
1301 if (curEleP->
pos[0] != stP[0] || curEleP->
pos[1] != stP[1] || curEleP->
pos[2] != stP[2]) {
1302 if (f2->
pos[0] != stP[0] || f2->
pos[1] != stP[1] || f2->
pos[2] != stP[2]) {
1304 newEleP->
next = curEleP;
1305 newEleP->
pos[0] = stP[0];
1306 newEleP->
pos[1] = stP[1];
1307 newEleP->
pos[2] = stP[2];
1314 curP = patchAdjacent(&newnode->
internal,
1337 dc_printf(
"Return from CONNECTFACE with \n");
1366 "-----------------%d %d %d; %d %d %d\n", st1[0], st2[1], st1[2], st2[0], st2[1], st2[2]);
1370 int edgedir = (dir + (3 - walkdir)) % 3;
1371 int incdir = (dir + walkdir) % 3;
1372 int ind1 = (edgedir == 1 ? (dir + 3 - edgedir) % 3 - 1 : 2 - (dir + 3 - edgedir) % 3);
1373 int ind2 = (edgedir == 1 ? (incdir + 3 - edgedir) % 3 - 1 : 2 - (incdir + 3 - edgedir) % 3);
1375 int eind1 = ((edgedir << 2) | (side << ind1) | ((inc > 0 ? 1 : 0) << ind2));
1376 int eind2 = ((edgedir << 2) | (side << ind1) | ((inc > 0 ? 0 : 1) << ind2));
1379 dc_printf(
"Index 1: %d Alpha 1: %f Index 2: %d Alpha 2: %f\n", eind1, alpha, eind2, alpha);
1390 LeafNode *nleaf1 = flipEdge(leaf1, eind1, alpha);
1391 LeafNode *nleaf2 = flipEdge(leaf2, eind2, alpha);
1394 updateParent(node,
len, st1, nleaf1);
1395 updateParent(node,
len, st2, nleaf2);
1434 for (i = 0; i < 3; i++) {
1436 if (i == dir && side == 1) {
1437 ind |= (ori[i] <= (st[i] +
len) ? 0 : 1);
1440 ind |= (ori[i] < (st[i] +
len) ? 0 : 1);
1447 "In LOCATECELL index of ori(%d %d %d) with dir %d side %d in st(%d %d %d, %d) is: %d\n",
1465 if (node->has_child(ind)) {
1466 int count = node->get_child_count(ind);
1468 if (node->is_child_leaf(ind)) {
1474 node->set_child(
count,
1475 locateCell(&chd->
internal, rst,
len, ori, dir, side, rleaf, rst, rlen));
1482 node = addChild(node, ind, (
Node *)chd, 1);
1483 rleaf = (
Node *)chd;
1489 node = addChild(node, ind, locateCell(chd, rst,
len, ori, dir, side, rleaf, rst, rlen), 0);
1503 if (ele !=
NULL && locateLeafCheck(ele->
pos) != ele->node) {
1504 dc_printf(
"Screwed! at pos: %d %d %d\n",
1517 while (n && (same == 0 || n != path)) {
1528 for (i = 0; i < 3; i++) {
1529 if (e1->
pos[i] != e2->
pos[i]) {
1530 if (e1->
pos[i] < e2->
pos[i]) {
1543 getFacePoint(
e, i, x, y, p, q);
1546void Octree::getFacePoint(
PathElement *leaf,
int dir,
int &x,
int &y,
float &p,
float &q)
1549 float avg[3] = {0, 0, 0};
1551 int num = 0, num2 = 0;
1556 for (
int i = 0; i < 4; i++) {
1557 int edgeind =
faceMap[dir * 2][i];
1559 for (
int j = 0; j < 3; j++) {
1563 if (getEdgeIntersectionByIndex(nst, edgeind / 4, off, 1)) {
1569 if (getEdgeParity(leafnode, edgeind)) {
1574 dc_printf(
"Wrong! dir: %d pos: %d %d %d num: %d\n",
1595 int xdir = (dir + 1) % 3;
1596 int ydir = (dir + 2) % 3;
1598 float xf = avg[xdir];
1599 float yf = avg[ydir];
1605 float *m = (leaf == leaf1 ? m1 : m2);
1606 if (xf < leaf->
pos[xdir] || yf < leaf->
pos[ydir] || xf > leaf->
pos[xdir] + leaf->len ||
1607 yf > leaf->
pos[ydir] + leaf->len) {
1608 dc_printf(
"Outside cube(%d %d %d), %d : %d %d %f %f\n",
1625 if (alpha < 0 || alpha > 1 || xf < leaf->
pos[xdir] || xf > leaf->
pos[xdir] + leaf->len ||
1626 yf < leaf->
pos[ydir] || yf > leaf->
pos[ydir] + leaf->len) {
1627 dc_printf(
"Alpha: %f Address: %d and %d\n", alpha, leaf1->node, leaf2->node);
1628 dc_printf(
"GETFACEPOINT result:(%d %d %d) %d min:(%f %f %f);(%d %d %d) %d min:(%f %f %f).\n",
1643 dc_printf(
"Face point at dir %d pos %d: %f %f\n", dir,
pos, xf, yf);
1656 dc_printf(
"Face point at dir %d : %f %f\n", dir, xf, yf);
1662 int side = getSide(head,
pos, dir);
1671 while (cur != anchor && (getSide(cur,
pos, dir) == side)) {
1675 if (cur == anchor) {
1680 side = getSide(cur,
pos, dir);
1683 while (getSide(cur,
pos, dir) == side) {
1703 return (
e->pos[dir] <
pos ? -1 : 1);
1708 return (e1->
pos[0] == e2->
pos[0] && e1->
pos[1] == e2->
pos[1] && e1->
pos[2] == e2->
pos[2]);
1717 dc_printf(
"Call to COMPRESSRING with path: \n");
1727 while (isEqual(cur, prepre)) {
1729 if (cur == prepre) {
1746 if (anchor ==
NULL) {
1753 }
while (prepre != anchor);
1758 dc_printf(
"Return from COMPRESSRING with path: \n");
1763void Octree::buildSigns()
1768 unsigned char table[1 << 12];
1769 for (
int i = 0; i <
size; i++) {
1772 for (
int i = 0; i < 256; i++) {
1774 for (
int j = 11; j >= 0; j--) {
1787 buildSigns(table,
root, 0, sg, cube);
1790void Octree::buildSigns(
unsigned char table[],
Node *node,
int isLeaf,
int sg,
int rvalue[8])
1793 for (
int i = 0; i < 8; i++) {
1803 node->internal.fill_children(chd, leaf);
1808 buildSigns(table, chd[0], leaf[0], sg, oris);
1812 for (
int i = 1; i < 8; i++) {
1813 buildSigns(table, chd[i], leaf[i], oris[i], cube);
1814 rvalue[i] = cube[i];
1819 generateSigns(&node->leaf, table, sg);
1821 for (
int i = 0; i < 8; i++) {
1822 rvalue[i] = getSign(&node->leaf, i);
1827void Octree::floodFill()
1830 int st[3] = {0, 0, 0};
1838 dc_printf(
"Largest component: %d\n", threshold);
1840 dc_printf(
"Removing all components smaller than %d\n", threshold);
1842 int st2[3] = {0, 0, 0};
1847void Octree::clearProcessBits(
Node *node,
int height)
1853 for (i = 0; i < 12; i++) {
1854 setOutProcess(&node->leaf, i);
1860 for (i = 0; i < 8; i++) {
1861 if (node->internal.has_child(i)) {
1862 clearProcessBits(node->internal.get_child(
count), height - 1);
1869int Octree::floodFill(
LeafNode *leaf,
int st[3],
int len,
int ,
int threshold)
1878 for (i = 0; i < 12; i++) {
1879 par = getEdgeParity(leaf, i);
1880 inp = isInProcess(leaf, i);
1882 if (par == 1 && inp == 0) {
1894 setInProcessAll(mst, mdir);
1897 queue->pushQueue(mst, mdir);
1901 while (queue->popQueue(nst, dir) == 1) {
1910 int stMask[3][3] = {{0, 0 -
len, 0 -
len}, {0 -
len, 0, 0 -
len}, {0 -
len, 0 -
len, 0}};
1912 for (j = 0; j < 3; j++) {
1914 cst[1][j] = nst[j] + stMask[dir][j];
1919 for (j = 0; j < 2; j++) {
1920 cs[j] = locateLeaf(cst[j]);
1924 int s = getSign(cs[0], 0);
1927 int fcCells[4] = {1, 0, 1, 0};
1928 int fcEdges[3][4][3] = {{{9, 2, 11}, {8, 1, 10}, {5, 1, 7}, {4, 2, 6}},
1929 {{10, 6, 11}, {8, 5, 9}, {1, 5, 3}, {0, 6, 2}},
1930 {{6, 10, 7}, {4, 9, 5}, {2, 9, 3}, {0, 10, 1}}};
1933 for (
int find = 0; find < 4; find++) {
1934 int cind = fcCells[find];
1938 for (eind = 0; eind < 3; eind++) {
1939 edge = fcEdges[dir][find][eind];
1940 if (getEdgeParity(cs[cind], edge) == 1) {
1947 for (eind = 2; eind >= 0; eind--) {
1948 edge = fcEdges[dir][find][eind];
1949 if (getEdgeParity(cs[cind], edge) == 1) {
1955 if (eind == 3 || eind == -1) {
1956 dc_printf(
"Wrong! this is not a consistent sign. %d\n", eind);
1963 int edir = edge / 4;
1965 if (isInProcess(cs[cind], edge) == 0) {
1966 setInProcessAll(est, edir);
1967 queue->pushQueue(est, edir);
1969 dc_printf(
"Pushed: est: %d %d %d, edir: %d\n",
1981 dc_printf(
"Size of component: %d ", total);
1983 if (threshold == 0) {
1985 if (total > maxtotal) {
1993 if (total >= threshold) {
1998 dc_printf(
"Less than %d, removing...\n", threshold);
2004 flipParityAll(mst, mdir);
2007 queue->pushQueue(mst, mdir);
2010 while (queue->popQueue(nst, dir) == 1) {
2019 int stMask[3][3] = {{0, 0 -
len, 0 -
len}, {0 -
len, 0, 0 -
len}, {0 -
len, 0 -
len, 0}};
2021 for (j = 0; j < 3; j++) {
2023 cst[1][j] = nst[j] + stMask[dir][j];
2028 for (j = 0; j < 2; j++) {
2029 cs[j] = locateLeaf(cst[j]);
2033 int s = getSign(cs[0], 0);
2036 int fcCells[4] = {1, 0, 1, 0};
2037 int fcEdges[3][4][3] = {{{9, 2, 11}, {8, 1, 10}, {5, 1, 7}, {4, 2, 6}},
2038 {{10, 6, 11}, {8, 5, 9}, {1, 5, 3}, {0, 6, 2}},
2039 {{6, 10, 7}, {4, 9, 5}, {2, 9, 3}, {0, 10, 1}}};
2042 for (
int find = 0; find < 4; find++) {
2043 int cind = fcCells[find];
2047 for (eind = 0; eind < 3; eind++) {
2048 edge = fcEdges[dir][find][eind];
2049 if (isInProcess(cs[cind], edge) == 1) {
2056 for (eind = 2; eind >= 0; eind--) {
2057 edge = fcEdges[dir][find][eind];
2058 if (isInProcess(cs[cind], edge) == 1) {
2064 if (eind == 3 || eind == -1) {
2065 dc_printf(
"Wrong! this is not a consistent sign. %d\n", eind);
2072 int edir = edge / 4;
2074 if (getEdgeParity(cs[cind], edge) == 1) {
2075 flipParityAll(est, edir);
2076 queue->pushQueue(est, edir);
2078 dc_printf(
"Pushed: est: %d %d %d, edir: %d\n",
2097int Octree::floodFill(
Node *node,
int st[3],
int len,
int height,
int threshold)
2103 maxtotal = floodFill(&node->leaf, st,
len, height, threshold);
2109 for (i = 0; i < 8; i++) {
2110 if (node->internal.has_child(i)) {
2116 int d = floodFill(node->internal.get_child(
count), nst,
len, height - 1, threshold);
2128void Octree::writeOut()
2137 output_mesh = alloc_output(
numVertices, numQuads);
2139 int st[3] = {0, 0, 0};
2151void Octree::countIntersection(
Node *node,
int height,
int &nedge,
int &ncell,
int &nface)
2154 int total = node->internal.get_num_children();
2155 for (
int i = 0; i < total; i++) {
2156 countIntersection(node->internal.get_child(i), height - 1, nedge, ncell, nface);
2160 nedge += getNumEdges2(&node->leaf);
2162 int smask = getSignMask(&node->leaf);
2169 if (smask > 0 && smask < 255) {
2174 for (
int i = 0; i < 3; i++) {
2175 if (getFaceEdgeNum(&node->leaf, i * 2)) {
2183static void pseudoInverse(
const Eigen::Matrix3f &a, Eigen::Matrix3f &result,
float tolerance)
2185 Eigen::JacobiSVD<Eigen::Matrix3f> svd = a.jacobiSvd(Eigen::ComputeFullU | Eigen::ComputeFullV);
2187 result = svd.matrixV() *
2188 Eigen::Vector3f((svd.singularValues().array().abs() > tolerance)
2189 .select(svd.singularValues().array().inverse(), 0))
2191 svd.matrixU().adjoint();
2196 const float midpoint[],
2200 Eigen::Matrix3f
A, pinv;
2201 A << halfA[0], halfA[1], halfA[2], halfA[1], halfA[3], halfA[4], halfA[2], halfA[4], halfA[5];
2204 Eigen::Vector3f b2(
b), mp(midpoint),
result;
2206 result = pinv * b2 + mp;
2208 for (
int i = 0; i < 3; i++) {
2213static void mass_point(
float mp[3],
const float pts[12][3],
const int parity[12])
2217 for (
int i = 0; i < 12; i++) {
2219 const float *p = pts[i];
2239 const float pts[12][3],
2240 const float norms[12][3],
2241 const int parity[12])
2243 float ata[6] = {0, 0, 0, 0, 0, 0};
2244 float atb[3] = {0, 0, 0};
2247 for (
int i = 0; i < 12; i++) {
2250 const float *
norm = norms[i];
2251 const float *p = pts[i];
2261 const float pn = p[0] *
norm[0] + p[1] *
norm[1] + p[2] *
norm[2];
2287void Octree::computeMinimizer(
const LeafNode *leaf,
int st[3],
int len,
float rvalue[3])
const
2290 float pts[12][3], norms[12][3];
2292 fillEdgeIntersections(leaf, st,
len, pts, norms, parity);
2296 rvalue[0] = (
float)st[0] +
len / 2;
2297 rvalue[1] = (
float)st[1] +
len / 2;
2298 rvalue[2] = (
float)st[2] +
len / 2;
2302 rvalue[0] = rvalue[1] = rvalue[2] = 0;
2310 float mp[3] = {0, 0, 0};
2311 minimize(rvalue, mp, pts, norms, parity);
2317 if (rvalue[0] < st[0] - nh1 || rvalue[1] < st[1] - nh1 || rvalue[2] < st[2] - nh1 ||
2319 rvalue[0] > st[0] + nh2 || rvalue[1] > st[1] + nh2 || rvalue[2] > st[2] + nh2)
2331void Octree::generateMinimizer(
Node *node,
int st[3],
int len,
int height,
int &offset)
2340 rvalue[0] = (
float)st[0] +
len / 2;
2341 rvalue[1] = (
float)st[1] +
len / 2;
2342 rvalue[2] = (
float)st[2] +
len / 2;
2343 computeMinimizer(&node->leaf, st,
len, rvalue);
2347 for (j = 0; j < 3; j++) {
2348 rvalue[j] = rvalue[j] * range /
dimen +
origin[j];
2352 int mult = 0, smask = getSignMask(&node->leaf);
2358 if (smask > 0 && smask < 255) {
2363 for (j = 0; j <
mult; j++) {
2364 add_vert(output_mesh, rvalue);
2368 setMinimizerIndex(&node->leaf, offset);
2376 for (i = 0; i < 8; i++) {
2377 if (node->internal.has_child(i)) {
2383 generateMinimizer(node->internal.get_child(
count), nst,
len, height - 1, offset);
2390void Octree::processEdgeWrite(
Node *node[4],
int [4],
int ,
int dir)
2408 int seq[4] = {0, 1, 3, 2};
2409 for (
int k = 0; k < 4; k++) {
2414 if (vind[1] != -1) {
2418 ind[num - 1] = vind[0];
2419 ind[num - 2] = vind[1];
2430 ind[0] = getMinimizerIndex((
LeafNode *)(node[2]));
2431 ind[1] = getMinimizerIndex((
LeafNode *)(node[3]));
2432 ind[2] = getMinimizerIndex((
LeafNode *)(node[1]));
2433 ind[3] = getMinimizerIndex((
LeafNode *)(node[0]));
2436 ind[0] = getMinimizerIndex((
LeafNode *)(node[0]));
2437 ind[1] = getMinimizerIndex((
LeafNode *)(node[1]));
2438 ind[2] = getMinimizerIndex((
LeafNode *)(node[3]));
2439 ind[3] = getMinimizerIndex((
LeafNode *)(node[2]));
2442 add_quad(output_mesh, ind);
2453void Octree::edgeProcContour(
Node *node[4],
int leaf[4],
int depth[4],
int maxdep,
int dir)
2455 if (!(node[0] && node[1] && node[2] && node[3])) {
2458 if (leaf[0] && leaf[1] && leaf[2] && leaf[3]) {
2459 processEdgeWrite(node, depth, maxdep, dir);
2464 for (j = 0; j < 4; j++) {
2465 for (i = 0; i < 8; i++) {
2466 chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
2467 node[j]->internal.get_child(node[j]->internal.get_child_count(i)) :
2476 for (i = 0; i < 2; i++) {
2482 for (
int j = 0; j < 4; j++) {
2490 ne[j] = chd[j][c[j]];
2491 de[j] = depth[j] - 1;
2500void Octree::faceProcContour(
Node *node[2],
int leaf[2],
int depth[2],
int maxdep,
int dir)
2502 if (!(node[0] && node[1])) {
2506 if (!(leaf[0] && leaf[1])) {
2510 for (j = 0; j < 2; j++) {
2511 for (i = 0; i < 8; i++) {
2512 chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
2513 node[j]->internal.get_child(node[j]->internal.get_child_count(i)) :
2522 for (i = 0; i < 4; i++) {
2524 for (
int j = 0; j < 2; j++) {
2532 nf[j] = chd[j][c[j]];
2533 df[j] = depth[j] - 1;
2540 int orders[2][4] = {{0, 0, 1, 1}, {0, 1, 0, 1}};
2545 for (i = 0; i < 4; i++) {
2552 for (
int j = 0; j < 4; j++) {
2553 if (leaf[order[j]]) {
2554 le[j] = leaf[order[j]];
2555 ne[j] = node[order[j]];
2556 de[j] = depth[order[j]];
2560 ne[j] = chd[order[j]][c[j]];
2561 de[j] = depth[order[j]] - 1;
2570void Octree::cellProcContour(
Node *node,
int leaf,
int depth)
2581 for (i = 0; i < 8; i++) {
2582 chd[i] = ((!leaf) && node->internal.has_child(i)) ?
2588 for (i = 0; i < 8; i++) {
2589 cellProcContour(chd[i], node->internal.is_child_leaf(i), depth - 1);
2595 int df[2] = {depth - 1, depth - 1};
2596 for (i = 0; i < 12; i++) {
2600 lf[1] = node->internal.is_child_leaf(c[1]);
2611 int de[4] = {depth - 1, depth - 1, depth - 1, depth - 1};
2612 for (i = 0; i < 6; i++) {
2618 for (
int j = 0; j < 4; j++) {
2628void Octree::processEdgeParity(
LeafNode *node[4],
int [4],
int ,
int dir)
2631 for (
int i = 0; i < 4; i++) {
2643 for (
int i = 0; i < 4; i++) {
2649void Octree::edgeProcParity(
Node *node[4],
int leaf[4],
int depth[4],
int maxdep,
int dir)
2651 if (!(node[0] && node[1] && node[2] && node[3])) {
2654 if (leaf[0] && leaf[1] && leaf[2] && leaf[3]) {
2655 processEdgeParity((
LeafNode **)node, depth, maxdep, dir);
2660 for (j = 0; j < 4; j++) {
2661 for (i = 0; i < 8; i++) {
2662 chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
2663 node[j]->internal.get_child(node[j]->internal.get_child_count(i)) :
2672 for (i = 0; i < 2; i++) {
2679 for (
int j = 0; j < 4; j++) {
2688 ne[j] = chd[j][c[j]];
2689 de[j] = depth[j] - 1;
2698void Octree::faceProcParity(
Node *node[2],
int leaf[2],
int depth[2],
int maxdep,
int dir)
2700 if (!(node[0] && node[1])) {
2704 if (!(leaf[0] && leaf[1])) {
2708 for (j = 0; j < 2; j++) {
2709 for (i = 0; i < 8; i++) {
2710 chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
2711 node[j]->internal.get_child(node[j]->internal.get_child_count(i)) :
2720 for (i = 0; i < 4; i++) {
2722 for (
int j = 0; j < 2; j++) {
2730 nf[j] = chd[j][c[j]];
2731 df[j] = depth[j] - 1;
2738 int orders[2][4] = {{0, 0, 1, 1}, {0, 1, 0, 1}};
2743 for (i = 0; i < 4; i++) {
2750 for (
int j = 0; j < 4; j++) {
2751 if (leaf[order[j]]) {
2752 le[j] = leaf[order[j]];
2753 ne[j] = node[order[j]];
2754 de[j] = depth[order[j]];
2758 ne[j] = chd[order[j]][c[j]];
2759 de[j] = depth[order[j]] - 1;
2768void Octree::cellProcParity(
Node *node,
int leaf,
int depth)
2779 for (i = 0; i < 8; i++) {
2780 chd[i] = ((!leaf) && node->internal.has_child(i)) ?
2786 for (i = 0; i < 8; i++) {
2787 cellProcParity(chd[i], node->internal.is_child_leaf(i), depth - 1);
2793 int df[2] = {depth - 1, depth - 1};
2794 for (i = 0; i < 12; i++) {
2798 lf[1] = node->internal.is_child_leaf(c[1]);
2809 int de[4] = {depth - 1, depth - 1, depth - 1, depth - 1};
2810 for (i = 0; i < 6; i++) {
2816 for (
int j = 0; j < 4; j++) {
2862const int faceProcFaceMask[3][4][3] = {{{4, 0, 0}, {5, 1, 0}, {6, 2, 0}, {7, 3, 0}},
2863 {{2, 0, 1}, {6, 4, 1}, {3, 1, 1}, {7, 5, 1}},
2864 {{1, 0, 2}, {3, 2, 2}, {5, 4, 2}, {7, 6, 2}}};
2867 {{1, 4, 0, 5, 1, 1}, {1, 6, 2, 7, 3, 1}, {0, 4, 6, 0, 2, 2}, {0, 5, 7, 1, 3, 2}},
2868 {{0, 2, 3, 0, 1, 0}, {0, 6, 7, 4, 5, 0}, {1, 2, 0, 6, 4, 2}, {1, 3, 1, 7, 5, 2}},
2869 {{1, 1, 0, 3, 2, 0}, {1, 5, 4, 7, 6, 0}, {0, 1, 5, 0, 4, 1}, {0, 3, 7, 2, 6, 1}}};
2872 {{3, 2, 1, 0, 0}, {7, 6, 5, 4, 0}},
2873 {{5, 1, 4, 0, 1}, {7, 3, 6, 2, 1}},
2874 {{6, 4, 2, 0, 2}, {7, 5, 3, 1, 2}},
2883const int dirCell[3][4][3] = {{{0, -1, -1}, {0, -1, 0}, {0, 0, -1}, {0, 0, 0}},
2884 {{-1, 0, -1}, {-1, 0, 0}, {0, 0, -1}, {0, 0, 0}},
2885 {{-1, -1, 0}, {-1, 0, 0}, {0, -1, 0}, {0, 0, 0}}};
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
int isIntersecting() const
int isIntersectingPrimary(int edgeInd) const
unsigned char getBoxMask()
TriangleProjection * inherit
Inheritable portion.
float getIntersectionPrimary(int edgeInd) const
virtual float getBoundingBox(float origin[3])=0
Get bounding box.
virtual Triangle * getNextTriangle()=0
Get next triangle.
virtual int getNumTriangles()=0
Get number of triangles.
VirtualMemoryAllocator * alloc[9]
VirtualMemoryAllocator * leafalloc[4]
Octree(ModelReader *mr, DualConAllocOutput alloc_output_func, DualConAddVert add_vert_func, DualConAddQuad add_quad_func, DualConFlags flags, DualConMode mode, int depth, float threshold, float hermite_num)
virtual int getAllocated()=0
virtual void printInfo()=0
local_group_size(16, 16) .push_constant(Type b
void(* DualConAddQuad)(void *output, const int vert_indices[4])
void(* DualConAddVert)(void *output, const float co[3])
void *(* DualConAllocOutput)(int totvert, int totquad)
draw_view in_light_buf[] float
const ManifoldIndices manifold_table[256]
SymEdge< T > * prev(const SymEdge< T > *se)
const int processEdgeMask[3][4]
const int edgeProcEdgeMask[3][2][5]
static void pseudoInverse(const Eigen::Matrix3f &a, Eigen::Matrix3f &result, float tolerance)
const int faceProcFaceMask[3][4][3]
static void minimize(float rvalue[3], float mp[3], const float pts[12][3], const float norms[12][3], const int parity[12])
static void solve_least_squares(const float halfA[], const float b[], const float midpoint[], float rvalue[])
const int cellProcFaceMask[12][3]
const int faceProcEdgeMask[3][4][6]
const int cellProcEdgeMask[6][5]
static void mass_point(float mp[3], const float pts[12][3], const int parity[12])
const int dirCell[3][4][3]
const int processEdgeMask[3][4]
const int edgeProcEdgeMask[3][2][5]
const int faceProcFaceMask[3][4][3]
const int cellProcFaceMask[12][3]
const int faceProcEdgeMask[3][4][6]
const int cellProcEdgeMask[6][5]
Node * get_child(int count)
static int childrenCountTable[256][8]
static int numChildrenTable[256]
int has_child(int index) const
static int childrenIndexTable[256][8]
void fill_children(Node *children[8], int leaf[8])
int is_child_leaf(int index) const
double norm[3]
Normal of the triangle.