Files
LBPM/analysis/dcel.cpp

589 lines
17 KiB
C++
Raw Normal View History

#include "analysis/dcel.h"
2018-07-27 16:23:39 -04:00
2018-09-10 11:06:20 -04:00
2018-07-30 16:51:37 -04:00
DECL::DECL(){
}
DECL::~DECL(){
2018-09-10 11:09:36 -04:00
TriangleCount=0;
2018-09-10 11:06:20 -04:00
VertexCount=0;
2018-07-30 16:51:37 -04:00
2018-07-27 16:23:39 -04:00
}
2018-09-11 16:01:22 -04:00
int DECL::Face(int index){
2018-09-28 16:20:50 -04:00
return FaceData[index];
2018-09-10 17:29:48 -04:00
}
2018-09-28 16:20:50 -04:00
void DECL::LocalIsosurface(const DoubleArray& A, double value, const int i, const int j, const int k){
2018-07-28 16:03:34 -04:00
Point P,Q;
Point PlaceHolder;
Point C0,C1,C2,C3,C4,C5,C6,C7;
2018-07-30 16:51:37 -04:00
2018-07-28 16:03:34 -04:00
Point VertexList[12];
Point NewVertexList[12];
int LocalRemap[12];
2018-07-30 16:51:37 -04:00
2018-09-28 16:20:50 -04:00
Point cellvertices[20];
std::array<std::array<int,3>,20> Triangles;
2018-07-28 16:03:34 -04:00
// Values from array 'A' at the cube corners
double CubeValues[8];
2018-07-30 16:51:37 -04:00
2018-07-28 16:03:34 -04:00
// Points corresponding to cube corners
C0.x = 0.0; C0.y = 0.0; C0.z = 0.0;
C1.x = 1.0; C1.y = 0.0; C1.z = 0.0;
C2.x = 1.0; C2.y = 1.0; C2.z = 0.0;
C3.x = 0.0; C3.y = 1.0; C3.z = 0.0;
C4.x = 0.0; C4.y = 0.0; C4.z = 1.0;
C5.x = 1.0; C5.y = 0.0; C5.z = 1.0;
C6.x = 1.0; C6.y = 1.0; C6.z = 1.0;
C7.x = 0.0; C7.y = 1.0; C7.z = 1.0;
2018-07-30 16:51:37 -04:00
CubeValues[0] = A(i,j,k) - value;
CubeValues[1] = A(i+1,j,k) - value;
CubeValues[2] = A(i+1,j+1,k) - value;
CubeValues[3] = A(i,j+1,k) - value;
CubeValues[4] = A(i,j,k+1) - value;
CubeValues[5] = A(i+1,j,k+1) - value;
CubeValues[6] = A(i+1,j+1,k+1) - value;
CubeValues[7] = A(i,j+1,k+1) -value;
2018-09-10 11:39:16 -04:00
//printf("Set cube values: %i, %i, %i \n",i,j,k);
2018-09-10 11:15:08 -04:00
2018-07-30 16:51:37 -04:00
//Determine the index into the edge table which
//tells us which vertices are inside of the surface
2018-09-28 16:20:50 -04:00
int CubeIndex = 0;
2018-07-30 16:51:37 -04:00
if (CubeValues[0] < 0.0f) CubeIndex |= 1;
if (CubeValues[1] < 0.0f) CubeIndex |= 2;
if (CubeValues[2] < 0.0f) CubeIndex |= 4;
if (CubeValues[3] < 0.0f) CubeIndex |= 8;
if (CubeValues[4] < 0.0f) CubeIndex |= 16;
if (CubeValues[5] < 0.0f) CubeIndex |= 32;
if (CubeValues[6] < 0.0f) CubeIndex |= 64;
if (CubeValues[7] < 0.0f) CubeIndex |= 128;
//Find the vertices where the surface intersects the cube
if (edgeTable[CubeIndex] & 1){
P = VertexInterp(C0,C1,CubeValues[0],CubeValues[1]);
VertexList[0] = P;
Q = C0;
}
if (edgeTable[CubeIndex] & 2){
P = VertexInterp(C1,C2,CubeValues[1],CubeValues[2]);
VertexList[1] = P;
Q = C1;
}
if (edgeTable[CubeIndex] & 4){
P = VertexInterp(C2,C3,CubeValues[2],CubeValues[3]);
VertexList[2] = P;
Q = C2;
}
if (edgeTable[CubeIndex] & 8){
P = VertexInterp(C3,C0,CubeValues[3],CubeValues[0]);
VertexList[3] = P;
Q = C3;
}
if (edgeTable[CubeIndex] & 16){
P = VertexInterp(C4,C5,CubeValues[4],CubeValues[5]);
VertexList[4] = P;
Q = C4;
}
if (edgeTable[CubeIndex] & 32){
P = VertexInterp(C5,C6,CubeValues[5],CubeValues[6]);
VertexList[5] = P;
Q = C5;
}
if (edgeTable[CubeIndex] & 64){
P = VertexInterp(C6,C7,CubeValues[6],CubeValues[7]);
VertexList[6] = P;
Q = C6;
}
if (edgeTable[CubeIndex] & 128){
P = VertexInterp(C7,C4,CubeValues[7],CubeValues[4]);
VertexList[7] = P;
Q = C7;
}
if (edgeTable[CubeIndex] & 256){
P = VertexInterp(C0,C4,CubeValues[0],CubeValues[4]);
VertexList[8] = P;
Q = C0;
}
if (edgeTable[CubeIndex] & 512){
P = VertexInterp(C1,C5,CubeValues[1],CubeValues[5]);
VertexList[9] = P;
Q = C1;
}
if (edgeTable[CubeIndex] & 1024){
P = VertexInterp(C2,C6,CubeValues[2],CubeValues[6]);
VertexList[10] = P;
Q = C2;
}
if (edgeTable[CubeIndex] & 2048){
P = VertexInterp(C3,C7,CubeValues[3],CubeValues[7]);
VertexList[11] = P;
Q = C3;
}
2018-07-28 16:03:34 -04:00
2018-09-09 23:50:04 -04:00
VertexCount=0;
2018-07-30 16:51:37 -04:00
for (int idx=0;idx<12;idx++)
LocalRemap[idx] = -1;
for (int idx=0;triTable[CubeIndex][idx]!=-1;idx++)
{
if(LocalRemap[triTable[CubeIndex][idx]] == -1)
{
2018-09-09 23:50:04 -04:00
NewVertexList[VertexCount] = VertexList[triTable[CubeIndex][idx]];
LocalRemap[triTable[CubeIndex][idx]] = VertexCount;
VertexCount++;
2018-07-30 16:51:37 -04:00
}
}
2018-09-10 11:15:08 -04:00
2018-09-10 11:24:53 -04:00
//printf("Found %i vertices \n",VertexCount);
2018-07-28 16:03:34 -04:00
2018-09-09 23:50:04 -04:00
for (int idx=0;idx<VertexCount;idx++) {
2018-07-30 16:51:37 -04:00
P = NewVertexList[idx];
//P.x += i;
//P.y += j;
//P.z += k;
2018-09-28 16:20:50 -04:00
cellvertices[idx] = P;
2018-07-30 16:51:37 -04:00
}
TriangleCount = 0;
for (int idx=0;triTable[CubeIndex][idx]!=-1;idx+=3) {
2018-09-28 16:20:50 -04:00
Triangles[TriangleCount][0] = LocalRemap[triTable[CubeIndex][idx+0]];
Triangles[TriangleCount][1] = LocalRemap[triTable[CubeIndex][idx+1]];
Triangles[TriangleCount][2] = LocalRemap[triTable[CubeIndex][idx+2]];
2018-07-30 16:51:37 -04:00
TriangleCount++;
}
2018-09-28 16:20:50 -04:00
int nTris = TriangleCount;
2018-07-30 16:51:37 -04:00
// Now add the local values to the DECL data structure
2018-09-10 11:15:08 -04:00
if (nTris>0){
2018-09-10 17:29:48 -04:00
FaceData.resize(TriangleCount);
//printf("Construct halfedge structure... \n");
//printf(" Construct %i triangles \n",nTris);
2018-09-28 16:20:50 -04:00
halfedge.resize(nTris*3);
2018-09-10 11:15:08 -04:00
int idx_edge=0;
for (int idx=0; idx<TriangleCount; idx++){
2018-09-28 16:20:50 -04:00
int V1 = Triangles[idx][0];
int V2 = Triangles[idx][1];
int V3 = Triangles[idx][2];
FaceData[idx] = idx_edge;
2018-09-10 11:15:08 -04:00
// first edge: V1->V2
halfedge.data(0,idx_edge) = V1; // first vertex
halfedge.data(1,idx_edge) = V2; // second vertex
halfedge.data(2,idx_edge) = idx; // triangle
halfedge.data(3,idx_edge) = -1; // twin
halfedge.data(4,idx_edge) = idx_edge+2; // previous edge
halfedge.data(5,idx_edge) = idx_edge+1; // next edge
idx_edge++;
// second edge: V2->V3
halfedge.data(0,idx_edge) = V2; // first vertex
halfedge.data(1,idx_edge) = V3; // second vertex
halfedge.data(2,idx_edge) = idx; // triangle
halfedge.data(3,idx_edge) = -1; // twin
halfedge.data(4,idx_edge) = idx_edge-1; // previous edge
halfedge.data(5,idx_edge) = idx_edge+1; // next edge
idx_edge++;
// third edge: V3->V1
halfedge.data(0,idx_edge) = V3; // first vertex
halfedge.data(1,idx_edge) = V1; // second vertex
halfedge.data(2,idx_edge) = idx; // triangle
halfedge.data(3,idx_edge) = -1; // twin
halfedge.data(4,idx_edge) = idx_edge-1; // previous edge
halfedge.data(5,idx_edge) = idx_edge-2; // next edge
idx_edge++;
2018-09-10 17:29:48 -04:00
//printf(" ***tri %i ***edge %i *** \n",idx, idx_edge);
2018-09-10 11:15:08 -04:00
}
2018-09-10 11:39:16 -04:00
//printf(" parsing halfedge structure\n");
2018-09-10 11:15:08 -04:00
int EdgeCount=idx_edge;
for (int idx=0; idx<EdgeCount; idx++){
2018-09-11 16:01:22 -04:00
int V1=halfedge.data(0,idx);
int V2=halfedge.data(1,idx);
2018-09-10 11:15:08 -04:00
// Find all the twins within the cube
2018-09-10 11:39:16 -04:00
for (int jdx=0; jdx<EdgeCount; jdx++){
2018-09-10 11:15:08 -04:00
if (halfedge.data(1,jdx) == V1 && halfedge.data(0,jdx) == V2){
// this is the pair
halfedge.data(3,idx) = jdx;
halfedge.data(3,jdx) = idx;
}
if (halfedge.data(1,jdx) == V2 && halfedge.data(0,jdx) == V1 && !(idx==jdx)){
std::printf("WARNING: half edges with identical orientation! \n");
}
}
// Use "ghost" twins if edge is on a cube face
2018-09-28 16:20:50 -04:00
P = cellvertices[V1];
Q = cellvertices[V2];
2018-09-10 11:39:16 -04:00
if (P.x == 0.0 && Q.x == 0.0) halfedge.data(3,idx) = -1; // ghost twin for x=0 face
2018-09-11 16:01:22 -04:00
if (P.x == 1.0 && Q.x == 1.0) halfedge.data(3,idx) = -4; // ghost twin for x=1 face
2018-09-10 11:39:16 -04:00
if (P.y == 0.0 && Q.y == 0.0) halfedge.data(3,idx) = -2; // ghost twin for y=0 face
2018-09-11 16:01:22 -04:00
if (P.y == 1.0 && Q.y == 1.0) halfedge.data(3,idx) = -5; // ghost twin for y=1 face
2018-09-10 11:39:16 -04:00
if (P.z == 0.0 && Q.z == 0.0) halfedge.data(3,idx) = -3; // ghost twin for z=0 face
2018-09-11 16:01:22 -04:00
if (P.z == 1.0 && Q.z == 1.0) halfedge.data(3,idx) = -6; // ghost twin for z=1 face
2018-09-10 11:15:08 -04:00
}
2018-07-30 16:51:37 -04:00
}
2018-09-10 11:15:08 -04:00
2018-07-30 16:51:37 -04:00
// Map vertices to global coordinates
2018-09-09 23:50:04 -04:00
for (int idx=0;idx<VertexCount;idx++) {
2018-09-28 16:20:50 -04:00
P = cellvertices[idx];
2018-07-30 16:51:37 -04:00
P.x += i;
P.y += j;
P.z += k;
2018-09-10 17:29:48 -04:00
vertex.assign(idx,P);
2018-07-30 16:51:37 -04:00
}
2018-07-28 16:03:34 -04:00
}
2018-07-27 16:23:39 -04:00
Point DECL::TriNormal(int edge)
{
2018-09-13 12:39:02 -04:00
Point P,Q,R;
Point U,V,W;
2018-07-27 16:23:39 -04:00
double nx,ny,nz,len;
2018-09-13 05:03:10 -04:00
// at cube faces define outward normal to cube
2018-07-30 16:51:37 -04:00
if (edge == -1){
2018-09-13 12:39:02 -04:00
W.x = -1.0; W.y = 0.0; W.z = 0.0; // x cube face
2018-07-30 16:51:37 -04:00
}
else if (edge == -2){
2018-09-13 12:39:02 -04:00
W.x = 0.0; W.y = -1.0; W.z = 0.0; // y cube face
2018-07-30 16:51:37 -04:00
}
else if (edge == -3){
2018-09-13 12:39:02 -04:00
W.x = 0.0; W.y = 0.0; W.z = -1.0; // z cube face
2018-07-30 16:51:37 -04:00
}
2018-09-11 20:50:13 -04:00
else if (edge == -4){
2018-09-13 12:39:02 -04:00
W.x = 1.0; W.y = 0.0; W.z = 0.0; // x cube face
2018-09-11 16:01:22 -04:00
}
else if (edge == -5){
2018-09-13 12:39:02 -04:00
W.x = 0.0; W.y = 1.0; W.z = 0.0; // y cube face
2018-09-11 16:01:22 -04:00
}
else if (edge == -6){
2018-09-13 12:39:02 -04:00
W.x = 0.0; W.y = 0.0; W.z = 1.0; // z cube face
2018-09-11 16:01:22 -04:00
}
2018-07-27 16:23:39 -04:00
else{
2018-09-13 12:39:02 -04:00
// vertices for triange
int e2 = halfedge.next(edge);
int e3 = halfedge.next(e2);
P=vertex.coords(halfedge.v1(edge));
Q=vertex.coords(halfedge.v1(e2));
R=vertex.coords(halfedge.v1(e3));
// edge vectors
U = Q-P;
V = R-Q;
2018-07-27 16:23:39 -04:00
// normal vector
2018-09-13 12:39:02 -04:00
nx = U.y*V.z - U.z*V.y;
ny = U.z*V.x - U.x*V.z;
nz = U.x*V.y - U.y*V.x;
2018-07-27 16:23:39 -04:00
len = sqrt(nx*nx+ny*ny+nz*nz);
2018-09-13 12:39:02 -04:00
W.x = nx/len; W.y = ny/len; W.z = nz/len;
2018-07-27 16:23:39 -04:00
}
2018-09-13 12:39:02 -04:00
return W;
2018-07-27 16:23:39 -04:00
}
double DECL::EdgeAngle(int edge)
{
double angle;
2018-09-28 16:20:50 -04:00
double dotprod;
2018-09-14 16:34:32 -04:00
Point P,Q,R; // triangle vertices
Point U,V,W; // normal vectors
int e2 = halfedge.next(edge);
int e3 = halfedge.next(e2);
P=vertex.coords(halfedge.v1(edge));
Q=vertex.coords(halfedge.v1(e2));
R=vertex.coords(halfedge.v1(e3));
2018-07-27 16:23:39 -04:00
U = TriNormal(edge);
V = TriNormal(halfedge.twin(edge));
2018-09-13 13:07:59 -04:00
if (halfedge.twin(edge) < 0 ){
2018-09-14 16:34:32 -04:00
// compute edge normal in plane of cube face
2018-09-14 16:39:54 -04:00
W = P - Q; // edge tangent vector
2018-09-28 16:20:50 -04:00
double length = sqrt(W.x*W.x+W.y*W.y+W.z*W.z);
2018-09-14 16:34:32 -04:00
W.x /= length;
W.y /= length;
W.z /= length;
// edge normal within the plane of the cube face
2018-09-28 16:20:50 -04:00
double nx = W.y*V.z - W.z*V.y;
double ny = W.z*V.x - W.x*V.z;
double nz = W.x*V.y - W.y*V.x;
2018-09-15 06:24:00 -04:00
length = sqrt(nx*nx+ny*ny+nz*nz);
2018-09-14 16:34:32 -04:00
// new value for V is this normal vector
2018-09-15 06:24:00 -04:00
V.x = nx/length; V.y = ny/length; V.z = nz/length;
2018-09-14 18:23:04 -04:00
dotprod = U.x*V.x + U.y*V.y + U.z*V.z;
2018-09-14 22:00:32 -04:00
if (dotprod < 0.f){
2018-09-15 11:01:51 -04:00
//printf("negative dot product on face\n");
2018-09-14 22:00:32 -04:00
dotprod=-dotprod;
V.x = -V.x; V.y = -V.y; V.z = -V.z;
}
2018-09-15 09:47:32 -04:00
2018-09-14 22:07:45 -04:00
if (dotprod > 1.f) dotprod=1.f;
2018-09-14 18:23:04 -04:00
angle = acos(dotprod);
2018-09-14 18:21:36 -04:00
/* project onto plane of cube face also works
W = U - dotprod*V;
2018-09-14 15:44:17 -04:00
length = sqrt(W.x*W.x+W.y*W.y+W.z*W.z); // for normalization
dotprod = (U.x*W.x + U.y*W.y + U.z*W.z)/length;
if (dotprod > 1.f) dotprod=1.f;
if (dotprod < -1.f) dotprod=-1.f;
angle = acos(dotprod);
2018-09-15 06:53:21 -04:00
*/
2018-09-13 05:03:10 -04:00
}
2018-09-14 18:23:04 -04:00
else{
dotprod=U.x*V.x + U.y*V.y + U.z*V.z;
if (dotprod > 1.f) dotprod=1.f;
if (dotprod < -1.f) dotprod=-1.f;
2018-09-14 20:45:22 -04:00
angle = 0.5*acos(dotprod);
}
// determine if angle is concave or convex based on edge normal
2018-09-15 06:24:00 -04:00
W.x = (P.y-Q.y)*U.z - (P.z-Q.z)*U.y;
W.y = (P.z-Q.z)*U.x - (P.x-Q.x)*U.z;
W.z = (P.x-Q.x)*U.y - (P.y-Q.y)*U.x;
2018-09-15 06:53:21 -04:00
//length = sqrt(nx*nx+ny*ny+nz*nz);
Point w=0.5*(P+Q)-R;
if (W.x*w.x + W.y*w.y + W.z*w.z < 0.f){
2018-09-15 11:09:39 -04:00
//printf("flip edge normal \n");
2018-09-15 06:53:21 -04:00
W.x = -W.x;
W.y = -W.y;
W.z = -W.z;
}
2018-09-15 09:25:22 -04:00
if (W.x*V.x + W.y*V.y + W.z*V.z > 0.f){
2018-09-14 20:45:22 -04:00
// concave
angle = -angle;
2018-09-13 10:38:26 -04:00
}
2018-09-15 11:01:51 -04:00
//printf("angle=%f,dot=%f (Edge=%i, twin=%i): P={%f, %f, %f}, Q={%f, %f, %f} U={%f, %f, %f}, V={%f, %f, %f}\n",angle,dotprod,edge,halfedge.twin(edge),P.x,P.y,P.z,Q.x,Q.y,Q.z,U.x,U.y,U.z,V.x,V.y,V.z);
2018-07-27 16:23:39 -04:00
return angle;
}
void Isosurface(DoubleArray &A, const double &v)
{
Point P,Q;
Point PlaceHolder;
Point C0,C1,C2,C3,C4,C5,C6,C7;
2018-07-30 16:51:37 -04:00
2018-07-27 16:23:39 -04:00
int TriangleCount;
2018-09-09 23:50:04 -04:00
int VertexCount;
2018-07-27 16:23:39 -04:00
int CubeIndex;
2018-07-30 16:51:37 -04:00
2018-07-27 16:23:39 -04:00
Point VertexList[12];
Point NewVertexList[12];
int LocalRemap[12];
2018-07-30 16:51:37 -04:00
2018-09-28 16:20:50 -04:00
Point cellvertices[20];
std::array<std::array<int,3>,20> Triangles;
Triangles.fill( { 0 } );
2018-07-27 16:23:39 -04:00
// Values from array 'A' at the cube corners
double CubeValues[8];
2018-07-30 16:51:37 -04:00
2018-07-27 16:23:39 -04:00
int Nx = A.size(0);
int Ny = A.size(1);
int Nz = A.size(2);
2018-07-30 16:51:37 -04:00
2018-07-27 16:23:39 -04:00
// Points corresponding to cube corners
C0.x = 0.0; C0.y = 0.0; C0.z = 0.0;
C1.x = 1.0; C1.y = 0.0; C1.z = 0.0;
C2.x = 1.0; C2.y = 1.0; C2.z = 0.0;
C3.x = 0.0; C3.y = 1.0; C3.z = 0.0;
C4.x = 0.0; C4.y = 0.0; C4.z = 1.0;
C5.x = 1.0; C5.y = 0.0; C5.z = 1.0;
C6.x = 1.0; C6.y = 1.0; C6.z = 1.0;
C7.x = 0.0; C7.y = 1.0; C7.z = 1.0;
2018-07-30 16:51:37 -04:00
2018-09-28 16:20:50 -04:00
std::vector<std::array<int,6>> HalfEdge;
2018-07-27 16:23:39 -04:00
for (int k=1; k<Nz-1; k++){
for (int j=1; j<Ny-1; j++){
for (int i=1; i<Nx-1; i++){
// Set the corner values for this cube
CubeValues[0] = A(i,j,k);
CubeValues[1] = A(i+1,j,k);
CubeValues[2] = A(i+1,j+1,k);
CubeValues[3] = A(i,j+1,k);
CubeValues[4] = A(i,j,k+1);
CubeValues[5] = A(i+1,j,k+1);
CubeValues[6] = A(i+1,j+1,k+1);
CubeValues[7] = A(i,j+1,k+1);
//Determine the index into the edge table which
//tells us which vertices are inside of the surface
CubeIndex = 0;
if (CubeValues[0] < 0.0f) CubeIndex |= 1;
if (CubeValues[1] < 0.0f) CubeIndex |= 2;
if (CubeValues[2] < 0.0f) CubeIndex |= 4;
if (CubeValues[3] < 0.0f) CubeIndex |= 8;
if (CubeValues[4] < 0.0f) CubeIndex |= 16;
if (CubeValues[5] < 0.0f) CubeIndex |= 32;
if (CubeValues[6] < 0.0f) CubeIndex |= 64;
if (CubeValues[7] < 0.0f) CubeIndex |= 128;
//Find the vertices where the surface intersects the cube
if (edgeTable[CubeIndex] & 1){
P = VertexInterp(C0,C1,CubeValues[0],CubeValues[1]);
VertexList[0] = P;
Q = C0;
}
if (edgeTable[CubeIndex] & 2){
P = VertexInterp(C1,C2,CubeValues[1],CubeValues[2]);
VertexList[1] = P;
Q = C1;
}
if (edgeTable[CubeIndex] & 4){
P = VertexInterp(C2,C3,CubeValues[2],CubeValues[3]);
VertexList[2] = P;
Q = C2;
}
if (edgeTable[CubeIndex] & 8){
P = VertexInterp(C3,C0,CubeValues[3],CubeValues[0]);
VertexList[3] = P;
Q = C3;
}
if (edgeTable[CubeIndex] & 16){
P = VertexInterp(C4,C5,CubeValues[4],CubeValues[5]);
VertexList[4] = P;
Q = C4;
}
if (edgeTable[CubeIndex] & 32){
P = VertexInterp(C5,C6,CubeValues[5],CubeValues[6]);
VertexList[5] = P;
Q = C5;
}
if (edgeTable[CubeIndex] & 64){
P = VertexInterp(C6,C7,CubeValues[6],CubeValues[7]);
VertexList[6] = P;
Q = C6;
}
if (edgeTable[CubeIndex] & 128){
P = VertexInterp(C7,C4,CubeValues[7],CubeValues[4]);
VertexList[7] = P;
Q = C7;
}
if (edgeTable[CubeIndex] & 256){
P = VertexInterp(C0,C4,CubeValues[0],CubeValues[4]);
VertexList[8] = P;
Q = C0;
}
if (edgeTable[CubeIndex] & 512){
P = VertexInterp(C1,C5,CubeValues[1],CubeValues[5]);
VertexList[9] = P;
Q = C1;
}
if (edgeTable[CubeIndex] & 1024){
P = VertexInterp(C2,C6,CubeValues[2],CubeValues[6]);
VertexList[10] = P;
Q = C2;
}
if (edgeTable[CubeIndex] & 2048){
P = VertexInterp(C3,C7,CubeValues[3],CubeValues[7]);
VertexList[11] = P;
Q = C3;
}
2018-09-09 23:50:04 -04:00
VertexCount=0;
2018-07-27 16:23:39 -04:00
for (int idx=0;idx<12;idx++)
LocalRemap[idx] = -1;
for (int idx=0;triTable[CubeIndex][idx]!=-1;idx++)
{
if(LocalRemap[triTable[CubeIndex][idx]] == -1)
{
2018-09-09 23:50:04 -04:00
NewVertexList[VertexCount] = VertexList[triTable[CubeIndex][idx]];
LocalRemap[triTable[CubeIndex][idx]] = VertexCount;
VertexCount++;
2018-07-27 16:23:39 -04:00
}
}
2018-09-09 23:50:04 -04:00
for (int idx=0;idx<VertexCount;idx++) {
2018-07-27 16:23:39 -04:00
P = NewVertexList[idx];
//P.x += i;
//P.y += j;
//P.z += k;
2018-09-28 16:20:50 -04:00
cellvertices[idx] = P;
2018-07-27 16:23:39 -04:00
}
TriangleCount = 0;
for (int idx=0;triTable[CubeIndex][idx]!=-1;idx+=3) {
2018-09-28 16:20:50 -04:00
Triangles[TriangleCount][0] = LocalRemap[triTable[CubeIndex][idx+0]];
Triangles[TriangleCount][1] = LocalRemap[triTable[CubeIndex][idx+1]];
Triangles[TriangleCount][2] = LocalRemap[triTable[CubeIndex][idx+2]];
2018-07-27 16:23:39 -04:00
TriangleCount++;
}
2018-09-28 16:20:50 -04:00
int nTris = TriangleCount;
2018-07-27 16:23:39 -04:00
// Now add the local values to the DECL data structure
2018-09-28 16:20:50 -04:00
HalfEdge.resize(nTris*3);
2018-07-27 16:23:39 -04:00
int idx_edge=0;
for (int idx=0; idx<TriangleCount; idx++){
2018-09-28 16:20:50 -04:00
int V1 = Triangles[idx][0];
int V2 = Triangles[idx][1];
int V3 = Triangles[idx][2];
2018-07-27 16:23:39 -04:00
// first edge: V1->V2
2018-09-28 16:20:50 -04:00
HalfEdge[idx_edge][0] = V1; // first vertex
HalfEdge[idx_edge][1] = V2; // second vertex
HalfEdge[idx_edge][2] = idx; // triangle
HalfEdge[idx_edge][3] = -1; // twin
HalfEdge[idx_edge][4] = idx_edge+2; // previous edge
HalfEdge[idx_edge][5] = idx_edge+1; // next edge
2018-07-27 16:23:39 -04:00
idx_edge++;
// second edge: V2->V3
2018-09-28 16:20:50 -04:00
HalfEdge[idx_edge][0] = V2; // first vertex
HalfEdge[idx_edge][1] = V3; // second vertex
HalfEdge[idx_edge][2] = idx; // triangle
HalfEdge[idx_edge][3] = -1; // twin
HalfEdge[idx_edge][4] = idx_edge-1; // previous edge
HalfEdge[idx_edge][5] = idx_edge+1; // next edge
2018-07-27 16:23:39 -04:00
idx_edge++;
// third edge: V3->V1
2018-09-28 16:20:50 -04:00
HalfEdge[idx_edge][0] = V3; // first vertex
HalfEdge[idx_edge][1] = V1; // second vertex
HalfEdge[idx_edge][2] = idx; // triangle
HalfEdge[idx_edge][3] = -1; // twin
HalfEdge[idx_edge][4] = idx_edge-1; // previous edge
HalfEdge[idx_edge][5] = idx_edge-2; // next edge
2018-07-27 16:23:39 -04:00
idx_edge++;
}
int EdgeCount=idx_edge;
for (int idx=0; idx<EdgeCount; idx++){
2018-09-28 16:20:50 -04:00
int V1=HalfEdge[idx][0];
int V2=HalfEdge[idx][1];
2018-07-27 16:23:39 -04:00
// Find all the twins within the cube
for (int jdx=0; idx<EdgeCount; jdx++){
2018-09-28 16:20:50 -04:00
if (HalfEdge[jdx][1] == V1 && HalfEdge[jdx][0] == V2){
2018-07-27 16:23:39 -04:00
// this is the pair
2018-09-28 16:20:50 -04:00
HalfEdge[idx][3] = jdx;
HalfEdge[jdx][3] = idx;
2018-07-27 16:23:39 -04:00
}
2018-09-28 16:20:50 -04:00
if (HalfEdge[jdx][1] == V2 && HalfEdge[jdx][0] == V1 && !(idx==jdx)){
2018-07-27 16:23:39 -04:00
std::printf("WARNING: half edges with identical orientation! \n");
}
}
// Use "ghost" twins if edge is on a cube face
2018-09-28 16:20:50 -04:00
P = cellvertices[V1];
Q = cellvertices[V2];
if (P.x == 0.0 && Q.x == 0.0) HalfEdge[idx_edge][3] = -1; // ghost twin for x=0 face
if (P.x == 1.0 && Q.x == 1.0) HalfEdge[idx_edge][3] = -2; // ghost twin for x=1 face
if (P.y == 0.0 && Q.y == 0.0) HalfEdge[idx_edge][3] = -3; // ghost twin for y=0 face
if (P.y == 1.0 && Q.y == 1.0) HalfEdge[idx_edge][3] = -4; // ghost twin for y=1 face
if (P.z == 0.0 && Q.z == 0.0) HalfEdge[idx_edge][3] = -5; // ghost twin for z=0 face
if (P.z == 1.0 && Q.z == 1.0) HalfEdge[idx_edge][3] = -6; // ghost twin for z=1 face
2018-07-27 16:23:39 -04:00
}
// Find all the angles
for (int idx=0; idx<EdgeCount; idx++){
2018-09-28 16:20:50 -04:00
int V1=HalfEdge[idx][0];
int V2=HalfEdge[idx][1];
int T1= HalfEdge[idx_edge][2];
int twin=HalfEdge[idx_edge][3];
2018-09-10 11:09:36 -04:00
if (twin == -1){
}
2018-07-27 16:23:39 -04:00
}
2018-07-30 16:51:37 -04:00
2018-07-27 16:23:39 -04:00
// Map vertices to global coordinates
2018-09-09 23:50:04 -04:00
for (int idx=0;idx<VertexCount;idx++) {
2018-09-28 16:20:50 -04:00
P = cellvertices[idx];
2018-07-27 16:23:39 -04:00
P.x += i;
P.y += j;
P.z += k;
2018-09-28 16:20:50 -04:00
cellvertices[idx] = P;
2018-07-27 16:23:39 -04:00
}
}
}
}
}