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 | 1570 | QVector<VoxelPoint> vertices; |
| 1571 | 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 | 1575 | const QVector<QRgb>& colorContents = color->getContents(); |
| 1574 | 1576 | const QByteArray& materialContents = material->getContents(); |
| 1575 | 1577 | const QVector<QRgb>& hermiteContents = hermite->getContents(); |
| 1576 | 1578 | int size = color->getSize(); |
| 1577 | 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 | 1584 | int offset3 = size + 1; |
| 1579 | 1585 | int offset5 = area + 1; |
| 1580 | 1586 | int offset6 = area + size; |
| @@ -1587,6 +1593,8 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines | ||
| 1587 | 1593 | |
| 1588 | 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 | 1598 | int expanded = size + 1; |
| 1591 | 1599 | QVector<int> lineIndices(expanded, -1); |
| 1592 | 1600 | QVector<int> lastLineIndices(expanded, -1); |
| @@ -1609,6 +1617,9 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 16 unmodified lines | ||
| 1609 | 1617 | int alpha1 = alpha0, alpha2 = alpha0, alpha4 = alpha0; |
| 1610 | 1618 | int alphaTotal = alpha0; |
| 1611 | 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 | 1623 | bool middleX = (x != 0 && x != size); |
| 1613 | 1624 | bool middleY = (y != 0 && y != size); |
| 1614 | 1625 | bool middleZ = (z != 0 && z != size); |
| @@ -1653,6 +1664,8 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 38 unmodified lines | ||
| 1653 | 1664 | } |
| 1654 | 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 | 1669 | int clampedX = qMax(x - 1, 0), clampedY = qMax(y - 1, 0), clampedZ = qMax(z - 1, 0); |
| 1657 | 1670 | const QRgb* hermiteBase = hermiteData + clampedZ * hermiteArea + clampedY * hermiteStride + |
| 1658 | 1671 | clampedX * VoxelHermiteData::EDGE_COUNT; |
| @@ -1826,6 +1839,8 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 167 unmodified lines | ||
| 1826 | 1839 | } |
| 1827 | 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 | 1844 | glm::vec3 center; |
| 1830 | 1845 | glm::vec3 normal; |
| 1831 | 1846 | const int MAX_MATERIALS_PER_VERTEX = 4; |
| @@ -1840,6 +1855,9 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 8 unmodified lines | ||
| 1840 | 1855 | red += qRed(crossing.color); |
| 1841 | 1856 | green += qGreen(crossing.color); |
| 1842 | 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 | 1861 | if (crossing.material != 0) { |
| 1844 | 1862 | for (int j = 0; j < MAX_MATERIALS_PER_VERTEX; j++) { |
| 1845 | 1863 | if (materials[j] == crossing.material) { |
| @@ -1871,17 +1889,19 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 25 unmodified lines | ||
| 1871 | 1889 | int index = vertices.size(); |
| 1872 | 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 | 1894 | if (x != 0 && y != 0 && z != 0) { |
| 1875 | 1895 | if (alpha0 != alpha1) { |
| 1876 | 1896 | indices.append(index); |
| 1877 | 1897 | int index1 = lastLineIndices.at(x); |
| 1878 | 1898 | int index2 = lastPlaneIndices.at((y - 1) * expanded + x); |
| 1879 | 1899 | int index3 = lastPlaneIndices.at(y * expanded + x); |
| 1880 | − if (alpha0 == 0) { | |
| 1900 | + if (alpha0 == 0) { // quad faces negative x | |
| 1881 | 1901 | indices.append(index3); |
| 1882 | 1902 | indices.append(index2); |
| 1883 | 1903 | indices.append(index1); |
| 1884 | − } else { | |
| 1904 | + } else { // quad faces positive x | |
| 1885 | 1905 | indices.append(index1); |
| 1886 | 1906 | indices.append(index2); |
| 1887 | 1907 | indices.append(index3); |
| @@ -1893,11 +1913,11 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 5 unmodified lines | ||
| 1893 | 1913 | int index1 = lastIndex; |
| 1894 | 1914 | int index2 = lastPlaneIndices.at(y * expanded + x - 1); |
| 1895 | 1915 | int index3 = lastPlaneIndices.at(y * expanded + x); |
| 1896 | − if (alpha0 == 0) { | |
| 1916 | + if (alpha0 == 0) { // quad faces negative y | |
| 1897 | 1917 | indices.append(index1); |
| 1898 | 1918 | indices.append(index2); |
| 1899 | 1919 | indices.append(index3); |
| 1900 | − } else { | |
| 1920 | + } else { // quad faces positive y | |
| 1901 | 1921 | indices.append(index3); |
| 1902 | 1922 | indices.append(index2); |
| 1903 | 1923 | indices.append(index1); |
| @@ -1909,11 +1929,11 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 5 unmodified lines | ||
| 1909 | 1929 | int index1 = lastIndex; |
| 1910 | 1930 | int index2 = lastLineIndices.at(x - 1); |
| 1911 | 1931 | int index3 = lastLineIndices.at(x); |
| 1912 | − if (alpha0 == 0) { | |
| 1932 | + if (alpha0 == 0) { // quad faces negative z | |
| 1913 | 1933 | indices.append(index3); |
| 1914 | 1934 | indices.append(index2); |
| 1915 | 1935 | indices.append(index1); |
| 1916 | − } else { | |
| 1936 | + } else { // quad faces positive z | |
| 1917 | 1937 | indices.append(index1); |
| 1918 | 1938 | indices.append(index2); |
| 1919 | 1939 | indices.append(index3); |