Алгоритм марширующих кубов использует таблицу для поиска всех индексов ребер для вершин треугольников для любой заданной конфигурации куба из 256 возможных комбинаций углов («падежей»).Согласно this в простейшем случае, без учета неоднозначных случаев, в каждом случае существует максимум 4 треугольника или, другими словами, 12 вершин треугольника в каждом случае, что означает, что в таблице должно быть 256 * 12 записей.Теперь, когда мы наблюдаем симметрию, что для индекса случая n> 127 запись такая же, как и для случая 255-n, где каждый 2-й и 3-й индекс вершин треугольника поменялся местами, можно сократить размер таблицы пополам до 128 * 12 записей.Может ли кто-нибудь предоставить мне такую минимальную справочную таблицу?
Мне известна таблица (1) , в которой максимум 5 треугольников на случай.Я не знаю, почему 5 вместо 4, вероятно, для неоднозначных случаев?Кроме того, эта таблица не симметрична применяемой перестановке.
Также существует альтернативная таблица (2) с 256 * 12 плюс окончание «-1», которое является именно тем, что яищет, но эта таблица создаст отверстия в поверхности для некоторых случаев, по крайней мере с этим углом и индексацией края .Для этой 2-ой таблицы я не смог найти правильного индексации углов и краев где-либо еще в Интернете.Кто-нибудь знает?
Ниже показан код OpenCL C, который я использовал бы для считывания таблицы с трюком симметрии:
uint marching_cubes(const float3* p, const float* v, const float iso, float3* t) { // input: 8 positions p with 8 values v, isovalue; output: returns number of triangles, 12 triangle vertices t
const uchar triangle_table[128*12] = { // termination value 15
+++ insert table here +++
};
int cube = 0; // determine case index of which vertices are inside of the isosurface
#pragma unroll
for(uint i=0; i<8; i++) cube |= (v[i]<iso)<<i;
if(cube==0 || cube==255) return 0; // cube is entirely inside/outside of the surface
float3 vertex[12]; // find the vertices where the surface intersects the cube
vertex[ 0] = interpolate_vertex(p[0], p[1], v[0], v[1], iso); // calculate vertices on all 12 edges
vertex[ 1] = interpolate_vertex(p[1], p[2], v[1], v[2], iso);
vertex[ 2] = interpolate_vertex(p[2], p[3], v[2], v[3], iso);
vertex[ 3] = interpolate_vertex(p[3], p[0], v[3], v[0], iso);
vertex[ 4] = interpolate_vertex(p[4], p[5], v[4], v[5], iso);
vertex[ 5] = interpolate_vertex(p[5], p[6], v[5], v[6], iso);
vertex[ 6] = interpolate_vertex(p[6], p[7], v[6], v[7], iso);
vertex[ 7] = interpolate_vertex(p[7], p[4], v[7], v[4], iso);
vertex[ 8] = interpolate_vertex(p[0], p[4], v[0], v[4], iso);
vertex[ 9] = interpolate_vertex(p[1], p[5], v[1], v[5], iso);
vertex[10] = interpolate_vertex(p[2], p[6], v[2], v[6], iso);
vertex[11] = interpolate_vertex(p[3], p[7], v[3], v[7], iso);
uint tn=0, lookup; // number of triangles, temporary lookup index
const bool ch = cube<128;
cube = (ch?cube:255-case)*12; // invert index when it is above 127
for(uint i=0; i<12&&triangle_table[cube+i]!=15; i+=3) { // create the triangles
lookup = triangle_table[cube+i+(ch?2:1)]; t[3*tn+2] = vertex[lookup]; // swap triangle points 2 and 3 if case index is above 127
lookup = triangle_table[cube+i+(ch?1:2)]; t[3*tn+1] = vertex[lookup]; // swap triangle points 2 and 3 if case index is above 127
lookup = triangle_table[cube+i ]; t[3*tn++] = vertex[lookup]; // increment triangle number tn
}
return tn; // return number of triangles
}
Редактировать : после сравненияТаблица (1) вместе с таблицей (2) Я понял, что угол & 1020 * индексации действительно одинаков для обеих таблиц.Без трюка с симметрией таблица (1) работает безупречно, а таблица (2), которая строго реализует 14 различных случаев , приводит к образованию отверстий на поверхности.Подстановка записей с 5 треугольниками в таблице (1) с соответствующими записями из таблицы (2) также приведет к дырам.Кажется, что 6-й случай неверен для перевернутых углов, и здесь необходимо 5 треугольников.