Showing the changes to interface/src/MetavoxelSystem.cpp (1 of 2 files). Show all
Unified · Split
| @@ -1570,11 +1570,17 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 1569 unmodified lines | |||
| 1570 | QVector<VoxelPoint> vertices; | 1570 | QVector<VoxelPoint> vertices; |
| 1571 | QVector<int> indices; | 1571 | QVector<int> indices; |
| 1572 | 1572 | ||
| 1573 | // see http://www.frankpetterson.com/publications/dualcontour/dualcontour.pdf for a description of the | ||
| 1574 | // dual contour algorithm for generating meshes from voxel data using Hermite-tagged edges | ||
| 1573 | const QVector<QRgb>& colorContents = color->getContents(); | 1575 | const QVector<QRgb>& colorContents = color->getContents(); |
| 1574 | const QByteArray& materialContents = material->getContents(); | 1576 | const QByteArray& materialContents = material->getContents(); |
| 1575 | const QVector<QRgb>& hermiteContents = hermite->getContents(); | 1577 | const QVector<QRgb>& hermiteContents = hermite->getContents(); |
| 1576 | int size = color->getSize(); | 1578 | int size = color->getSize(); |
| 1577 | int area = size * size; | 1579 | int area = size * size; |
| 1580 | |||
| 1581 | // number variables such as offset3 and alpha0 in this function correspond to cube corners, where the x, y, and z | ||
| 1582 | // components are represented as bits in the 0, 1, and 2 position, respectively; hence, alpha0 is the value at | ||
| 1583 | // the minimum x, y, and z corner and alpha7 is the value at the maximum x, y, and z | ||
| 1578 | int offset3 = size + 1; | 1584 | int offset3 = size + 1; |
| 1579 | int offset5 = area + 1; | 1585 | int offset5 = area + 1; |
| 1580 | int offset6 = area + size; | 1586 | int offset6 = area + size; |
| @@ -1587,6 +1593,8 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines | |||
| 1587 | 1593 | ||
| 1588 | const char* materialData = materialContents.constData(); | 1594 | const char* materialData = materialContents.constData(); |
| 1589 | 1595 | ||
| 1596 | // as we scan down the cube generating vertices between grid points, we remember the indices of the last | ||
| 1597 | // (element, line, section--x, y, z) so that we can connect generated vertices as quads | ||
| 1590 | int expanded = size + 1; | 1598 | int expanded = size + 1; |
| 1591 | QVector<int> lineIndices(expanded, -1); | 1599 | QVector<int> lineIndices(expanded, -1); |
| 1592 | QVector<int> lastLineIndices(expanded, -1); | 1600 | QVector<int> lastLineIndices(expanded, -1); |
| @@ -1609,6 +1617,9 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 16 unmodified lines | |||
| 1609 | int alpha1 = alpha0, alpha2 = alpha0, alpha4 = alpha0; | 1617 | int alpha1 = alpha0, alpha2 = alpha0, alpha4 = alpha0; |
| 1610 | int alphaTotal = alpha0; | 1618 | int alphaTotal = alpha0; |
| 1611 | int possibleTotal = EIGHT_BIT_MAXIMUM; | 1619 | int possibleTotal = EIGHT_BIT_MAXIMUM; |
| 1620 | |||
| 1621 | // cubes on the edge are two-dimensional: this ensures that their vertices will be shared between | ||
| 1622 | // neighboring blocks, which share only one layer of points | ||
| 1612 | bool middleX = (x != 0 && x != size); | 1623 | bool middleX = (x != 0 && x != size); |
| 1613 | bool middleY = (y != 0 && y != size); | 1624 | bool middleY = (y != 0 && y != size); |
| 1614 | bool middleZ = (z != 0 && z != size); | 1625 | bool middleZ = (z != 0 && z != size); |
| @@ -1653,6 +1664,8 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 38 unmodified lines | |||
| 1653 | } | 1664 | } |
| 1654 | continue; // no corners set/all corners set | 1665 | continue; // no corners set/all corners set |
| 1655 | } | 1666 | } |
| 1667 | // the terrifying conditional code that follows checks each cube edge for a crossing, gathering | ||
| 1668 | // its properties (color, material, normal) if one is present; as before, boundary edges are excluded | ||
| 1656 | int clampedX = qMax(x - 1, 0), clampedY = qMax(y - 1, 0), clampedZ = qMax(z - 1, 0); | 1669 | int clampedX = qMax(x - 1, 0), clampedY = qMax(y - 1, 0), clampedZ = qMax(z - 1, 0); |
| 1657 | const QRgb* hermiteBase = hermiteData + clampedZ * hermiteArea + clampedY * hermiteStride + | 1670 | const QRgb* hermiteBase = hermiteData + clampedZ * hermiteArea + clampedY * hermiteStride + |
| 1658 | clampedX * VoxelHermiteData::EDGE_COUNT; | 1671 | clampedX * VoxelHermiteData::EDGE_COUNT; |
| @@ -1826,6 +1839,8 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 167 unmodified lines | |||
| 1826 | } | 1839 | } |
| 1827 | crossing.point = glm::vec3(0.0f, 0.0f, qAlpha(hermite)); | 1840 | crossing.point = glm::vec3(0.0f, 0.0f, qAlpha(hermite)); |
| 1828 | } | 1841 | } |
| 1842 | // at present, we simply average the properties of each crossing as opposed to finding the vertex that | ||
| 1843 | // minimizes the quadratic error function as described in the reference paper | ||
| 1829 | glm::vec3 center; | 1844 | glm::vec3 center; |
| 1830 | glm::vec3 normal; | 1845 | glm::vec3 normal; |
| 1831 | const int MAX_MATERIALS_PER_VERTEX = 4; | 1846 | const int MAX_MATERIALS_PER_VERTEX = 4; |
| @@ -1840,6 +1855,9 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 8 unmodified lines | |||
| 1840 | red += qRed(crossing.color); | 1855 | red += qRed(crossing.color); |
| 1841 | green += qGreen(crossing.color); | 1856 | green += qGreen(crossing.color); |
| 1842 | blue += qBlue(crossing.color); | 1857 | blue += qBlue(crossing.color); |
| 1858 | |||
| 1859 | // when assigning a material, search for its presence and, if not found, | ||
| 1860 | // place it in the first empty slot | ||
| 1843 | if (crossing.material != 0) { | 1861 | if (crossing.material != 0) { |
| 1844 | for (int j = 0; j < MAX_MATERIALS_PER_VERTEX; j++) { | 1862 | for (int j = 0; j < MAX_MATERIALS_PER_VERTEX; j++) { |
| 1845 | if (materials[j] == crossing.material) { | 1863 | if (materials[j] == crossing.material) { |
| @@ -1871,17 +1889,19 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 25 unmodified lines | |||
| 1871 | int index = vertices.size(); | 1889 | int index = vertices.size(); |
| 1872 | vertices.append(point); | 1890 | vertices.append(point); |
| 1873 | 1891 | ||
| 1892 | // the first x, y, and z are repeated for the boundary edge; past that, we consider generating | ||
| 1893 | // quads for each edge that includes a transition, using indices of previously generated vertices | ||
| 1874 | if (x != 0 && y != 0 && z != 0) { | 1894 | if (x != 0 && y != 0 && z != 0) { |
| 1875 | if (alpha0 != alpha1) { | 1895 | if (alpha0 != alpha1) { |
| 1876 | indices.append(index); | 1896 | indices.append(index); |
| 1877 | int index1 = lastLineIndices.at(x); | 1897 | int index1 = lastLineIndices.at(x); |
| 1878 | int index2 = lastPlaneIndices.at((y - 1) * expanded + x); | 1898 | int index2 = lastPlaneIndices.at((y - 1) * expanded + x); |
| 1879 | int index3 = lastPlaneIndices.at(y * expanded + x); | 1899 | int index3 = lastPlaneIndices.at(y * expanded + x); |
| 1880 | if (alpha0 == 0) { | 1900 | if (alpha0 == 0) { // quad faces negative x |
| 1881 | indices.append(index3); | 1901 | indices.append(index3); |
| 1882 | indices.append(index2); | 1902 | indices.append(index2); |
| 1883 | indices.append(index1); | 1903 | indices.append(index1); |
| 1884 | } else { | 1904 | } else { // quad faces positive x |
| 1885 | indices.append(index1); | 1905 | indices.append(index1); |
| 1886 | indices.append(index2); | 1906 | indices.append(index2); |
| 1887 | indices.append(index3); | 1907 | indices.append(index3); |
| @@ -1893,11 +1913,11 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 5 unmodified lines | |||
| 1893 | int index1 = lastIndex; | 1913 | int index1 = lastIndex; |
| 1894 | int index2 = lastPlaneIndices.at(y * expanded + x - 1); | 1914 | int index2 = lastPlaneIndices.at(y * expanded + x - 1); |
| 1895 | int index3 = lastPlaneIndices.at(y * expanded + x); | 1915 | int index3 = lastPlaneIndices.at(y * expanded + x); |
| 1896 | if (alpha0 == 0) { | 1916 | if (alpha0 == 0) { // quad faces negative y |
| 1897 | indices.append(index1); | 1917 | indices.append(index1); |
| 1898 | indices.append(index2); | 1918 | indices.append(index2); |
| 1899 | indices.append(index3); | 1919 | indices.append(index3); |
| 1900 | } else { | 1920 | } else { // quad faces positive y |
| 1901 | indices.append(index3); | 1921 | indices.append(index3); |
| 1902 | indices.append(index2); | 1922 | indices.append(index2); |
| 1903 | indices.append(index1); | 1923 | indices.append(index1); |
| @@ -1909,11 +1929,11 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 5 unmodified lines | |||
| 1909 | int index1 = lastIndex; | 1929 | int index1 = lastIndex; |
| 1910 | int index2 = lastLineIndices.at(x - 1); | 1930 | int index2 = lastLineIndices.at(x - 1); |
| 1911 | int index3 = lastLineIndices.at(x); | 1931 | int index3 = lastLineIndices.at(x); |
| 1912 | if (alpha0 == 0) { | 1932 | if (alpha0 == 0) { // quad faces negative z |
| 1913 | indices.append(index3); | 1933 | indices.append(index3); |
| 1914 | indices.append(index2); | 1934 | indices.append(index2); |
| 1915 | indices.append(index1); | 1935 | indices.append(index1); |
| 1916 | } else { | 1936 | } else { // quad faces positive z |
| 1917 | indices.append(index1); | 1937 | indices.append(index1); |
| 1918 | indices.append(index2); | 1938 | indices.append(index2); |
| 1919 | indices.append(index3); | 1939 | indices.append(index3); |