ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
This commit is contained in:
@@ -17,32 +17,32 @@
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(INC
|
||||
.
|
||||
intern
|
||||
.
|
||||
intern
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
${EIGEN3_INCLUDE_DIRS}
|
||||
${EIGEN3_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
intern/manifold_table.cpp
|
||||
intern/marching_cubes_table.cpp
|
||||
intern/octree.cpp
|
||||
intern/Projections.cpp
|
||||
intern/manifold_table.cpp
|
||||
intern/marching_cubes_table.cpp
|
||||
intern/octree.cpp
|
||||
intern/Projections.cpp
|
||||
|
||||
intern/cubes.h
|
||||
intern/GeoCommon.h
|
||||
intern/manifold_table.h
|
||||
intern/marching_cubes_table.h
|
||||
intern/MemoryAllocator.h
|
||||
intern/ModelReader.h
|
||||
intern/octree.h
|
||||
intern/Projections.h
|
||||
intern/Queue.h
|
||||
intern/cubes.h
|
||||
intern/GeoCommon.h
|
||||
intern/manifold_table.h
|
||||
intern/marching_cubes_table.h
|
||||
intern/MemoryAllocator.h
|
||||
intern/ModelReader.h
|
||||
intern/octree.h
|
||||
intern/Projections.h
|
||||
intern/Queue.h
|
||||
|
||||
intern/dualcon_c_api.cpp
|
||||
dualcon.h
|
||||
intern/dualcon_c_api.cpp
|
||||
dualcon.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
|
||||
@@ -29,22 +29,22 @@ typedef float (*DualConCo)[3];
|
||||
|
||||
typedef unsigned int (*DualConTri)[3];
|
||||
|
||||
typedef unsigned int (*DualConLoop);
|
||||
typedef unsigned int(*DualConLoop);
|
||||
|
||||
typedef struct DualConInput {
|
||||
DualConLoop mloop;
|
||||
DualConLoop mloop;
|
||||
|
||||
DualConCo co;
|
||||
int co_stride;
|
||||
int totco;
|
||||
DualConCo co;
|
||||
int co_stride;
|
||||
int totco;
|
||||
|
||||
DualConTri looptri;
|
||||
int tri_stride;
|
||||
int tottri;
|
||||
DualConTri looptri;
|
||||
int tri_stride;
|
||||
int tottri;
|
||||
|
||||
int loop_stride;
|
||||
int loop_stride;
|
||||
|
||||
float min[3], max[3];
|
||||
float min[3], max[3];
|
||||
} DualConInput;
|
||||
|
||||
/* callback for allocating memory for output */
|
||||
@@ -55,16 +55,16 @@ typedef void (*DualConAddVert)(void *output, const float co[3]);
|
||||
typedef void (*DualConAddQuad)(void *output, const int vert_indices[4]);
|
||||
|
||||
typedef enum {
|
||||
DUALCON_FLOOD_FILL = 1,
|
||||
DUALCON_FLOOD_FILL = 1,
|
||||
} DualConFlags;
|
||||
|
||||
typedef enum {
|
||||
/* blocky */
|
||||
DUALCON_CENTROID,
|
||||
/* smooth */
|
||||
DUALCON_MASS_POINT,
|
||||
/* keeps sharp edges */
|
||||
DUALCON_SHARP_FEATURES,
|
||||
/* blocky */
|
||||
DUALCON_CENTROID,
|
||||
/* smooth */
|
||||
DUALCON_MASS_POINT,
|
||||
/* keeps sharp edges */
|
||||
DUALCON_SHARP_FEATURES,
|
||||
} DualConMode;
|
||||
|
||||
/* Usage:
|
||||
|
||||
@@ -28,31 +28,29 @@
|
||||
* @author Tao Ju
|
||||
*/
|
||||
|
||||
|
||||
// 3d point with integer coordinates
|
||||
typedef struct {
|
||||
int x, y, z;
|
||||
int x, y, z;
|
||||
} Point3i;
|
||||
|
||||
typedef struct {
|
||||
Point3i begin;
|
||||
Point3i end;
|
||||
Point3i begin;
|
||||
Point3i end;
|
||||
} BoundingBox;
|
||||
|
||||
// triangle that points to three vertices
|
||||
typedef struct {
|
||||
float vt[3][3];
|
||||
float vt[3][3];
|
||||
} Triangle;
|
||||
|
||||
// 3d point with float coordinates
|
||||
typedef struct {
|
||||
float x, y, z;
|
||||
float x, y, z;
|
||||
} Point3f;
|
||||
|
||||
typedef struct {
|
||||
Point3f begin;
|
||||
Point3f end;
|
||||
Point3f begin;
|
||||
Point3f end;
|
||||
} BoundingBoxf;
|
||||
|
||||
|
||||
#endif /* __GEOCOMMON_H__ */
|
||||
#endif /* __GEOCOMMON_H__ */
|
||||
|
||||
@@ -29,29 +29,27 @@
|
||||
* @author Tao Ju
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base class of memory allocators
|
||||
*/
|
||||
class VirtualMemoryAllocator
|
||||
{
|
||||
public:
|
||||
virtual ~VirtualMemoryAllocator() {}
|
||||
class VirtualMemoryAllocator {
|
||||
public:
|
||||
virtual ~VirtualMemoryAllocator()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void *allocate( ) = 0;
|
||||
virtual void deallocate(void *obj) = 0;
|
||||
virtual void destroy( ) = 0;
|
||||
virtual void printInfo( ) = 0;
|
||||
virtual void *allocate() = 0;
|
||||
virtual void deallocate(void *obj) = 0;
|
||||
virtual void destroy() = 0;
|
||||
virtual void printInfo() = 0;
|
||||
|
||||
virtual int getAllocated( ) = 0;
|
||||
virtual int getAll( ) = 0;
|
||||
virtual int getBytes( ) = 0;
|
||||
virtual int getAllocated() = 0;
|
||||
virtual int getAll() = 0;
|
||||
virtual int getBytes() = 0;
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:VirtualMemoryAllocator")
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:VirtualMemoryAllocator")
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -59,167 +57,160 @@ virtual int getBytes( ) = 0;
|
||||
*
|
||||
* Note: there are 4 bytes overhead for each allocated yet unused object.
|
||||
*/
|
||||
template < int N >
|
||||
class MemoryAllocator : public VirtualMemoryAllocator
|
||||
{
|
||||
private:
|
||||
template<int N> class MemoryAllocator : public VirtualMemoryAllocator {
|
||||
private:
|
||||
/// Constants
|
||||
int HEAP_UNIT, HEAP_MASK;
|
||||
|
||||
/// Constants
|
||||
int HEAP_UNIT, HEAP_MASK;
|
||||
/// Data array
|
||||
UCHAR **data;
|
||||
|
||||
/// Data array
|
||||
UCHAR **data;
|
||||
/// Allocation stack
|
||||
UCHAR ***stack;
|
||||
|
||||
/// Allocation stack
|
||||
UCHAR ***stack;
|
||||
/// Number of data blocks
|
||||
int datablocknum;
|
||||
|
||||
/// Number of data blocks
|
||||
int datablocknum;
|
||||
/// Number of stack blocks
|
||||
int stackblocknum;
|
||||
|
||||
/// Number of stack blocks
|
||||
int stackblocknum;
|
||||
/// Size of stack
|
||||
int stacksize;
|
||||
|
||||
/// Size of stack
|
||||
int stacksize;
|
||||
/// Number of available objects on stack
|
||||
int available;
|
||||
|
||||
/// Number of available objects on stack
|
||||
int available;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Allocate a memory block
|
||||
*/
|
||||
void allocateDataBlock( )
|
||||
{
|
||||
// Allocate a data block
|
||||
datablocknum += 1;
|
||||
data = ( UCHAR ** )realloc(data, sizeof (UCHAR *) * datablocknum);
|
||||
data[datablocknum - 1] = ( UCHAR * )malloc(HEAP_UNIT * N);
|
||||
void allocateDataBlock()
|
||||
{
|
||||
// Allocate a data block
|
||||
datablocknum += 1;
|
||||
data = (UCHAR **)realloc(data, sizeof(UCHAR *) * datablocknum);
|
||||
data[datablocknum - 1] = (UCHAR *)malloc(HEAP_UNIT * N);
|
||||
|
||||
// Update allocation stack
|
||||
for (int i = 0; i < HEAP_UNIT; i++)
|
||||
{
|
||||
stack[0][i] = (data[datablocknum - 1] + i * N);
|
||||
}
|
||||
available = HEAP_UNIT;
|
||||
}
|
||||
// Update allocation stack
|
||||
for (int i = 0; i < HEAP_UNIT; i++) {
|
||||
stack[0][i] = (data[datablocknum - 1] + i * N);
|
||||
}
|
||||
available = HEAP_UNIT;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Allocate a stack block, to store more deallocated objects
|
||||
*/
|
||||
void allocateStackBlock( )
|
||||
{
|
||||
// Allocate a stack block
|
||||
stackblocknum += 1;
|
||||
stacksize += HEAP_UNIT;
|
||||
stack = ( UCHAR *** )realloc(stack, sizeof (UCHAR * *) * stackblocknum);
|
||||
stack[stackblocknum - 1] = ( UCHAR ** )malloc(HEAP_UNIT * sizeof (UCHAR *) );
|
||||
}
|
||||
void allocateStackBlock()
|
||||
{
|
||||
// Allocate a stack block
|
||||
stackblocknum += 1;
|
||||
stacksize += HEAP_UNIT;
|
||||
stack = (UCHAR ***)realloc(stack, sizeof(UCHAR **) * stackblocknum);
|
||||
stack[stackblocknum - 1] = (UCHAR **)malloc(HEAP_UNIT * sizeof(UCHAR *));
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
/**
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
MemoryAllocator( )
|
||||
{
|
||||
HEAP_UNIT = 1 << HEAP_BASE;
|
||||
HEAP_MASK = (1 << HEAP_BASE) - 1;
|
||||
MemoryAllocator()
|
||||
{
|
||||
HEAP_UNIT = 1 << HEAP_BASE;
|
||||
HEAP_MASK = (1 << HEAP_BASE) - 1;
|
||||
|
||||
data = ( UCHAR ** )malloc(sizeof(UCHAR *) );
|
||||
data[0] = ( UCHAR * )malloc(HEAP_UNIT * N);
|
||||
datablocknum = 1;
|
||||
data = (UCHAR **)malloc(sizeof(UCHAR *));
|
||||
data[0] = (UCHAR *)malloc(HEAP_UNIT * N);
|
||||
datablocknum = 1;
|
||||
|
||||
stack = ( UCHAR *** )malloc(sizeof (UCHAR * *) );
|
||||
stack[0] = ( UCHAR ** )malloc(HEAP_UNIT * sizeof (UCHAR *) );
|
||||
stackblocknum = 1;
|
||||
stacksize = HEAP_UNIT;
|
||||
available = HEAP_UNIT;
|
||||
stack = (UCHAR ***)malloc(sizeof(UCHAR **));
|
||||
stack[0] = (UCHAR **)malloc(HEAP_UNIT * sizeof(UCHAR *));
|
||||
stackblocknum = 1;
|
||||
stacksize = HEAP_UNIT;
|
||||
available = HEAP_UNIT;
|
||||
|
||||
for (int i = 0; i < HEAP_UNIT; i++)
|
||||
{
|
||||
stack[0][i] = (data[0] + i * N);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < HEAP_UNIT; i++) {
|
||||
stack[0][i] = (data[0] + i * N);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
void destroy( )
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < datablocknum; i++)
|
||||
{
|
||||
free(data[i]);
|
||||
}
|
||||
for (i = 0; i < stackblocknum; i++)
|
||||
{
|
||||
free(stack[i]);
|
||||
}
|
||||
free(data);
|
||||
free(stack);
|
||||
}
|
||||
void destroy()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < datablocknum; i++) {
|
||||
free(data[i]);
|
||||
}
|
||||
for (i = 0; i < stackblocknum; i++) {
|
||||
free(stack[i]);
|
||||
}
|
||||
free(data);
|
||||
free(stack);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Allocation method
|
||||
*/
|
||||
void *allocate( )
|
||||
{
|
||||
if (available == 0)
|
||||
{
|
||||
allocateDataBlock( );
|
||||
}
|
||||
void *allocate()
|
||||
{
|
||||
if (available == 0) {
|
||||
allocateDataBlock();
|
||||
}
|
||||
|
||||
// printf("Allocating %d\n", header[ allocated ]) ;
|
||||
available--;
|
||||
return (void *)stack[available >> HEAP_BASE][available & HEAP_MASK];
|
||||
}
|
||||
// printf("Allocating %d\n", header[ allocated ]) ;
|
||||
available--;
|
||||
return (void *)stack[available >> HEAP_BASE][available & HEAP_MASK];
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* De-allocation method
|
||||
*/
|
||||
void deallocate(void *obj)
|
||||
{
|
||||
if (available == stacksize)
|
||||
{
|
||||
allocateStackBlock( );
|
||||
}
|
||||
void deallocate(void *obj)
|
||||
{
|
||||
if (available == stacksize) {
|
||||
allocateStackBlock();
|
||||
}
|
||||
|
||||
// printf("De-allocating %d\n", ( obj - data ) / N ) ;
|
||||
stack[available >> HEAP_BASE][available & HEAP_MASK] = (UCHAR *)obj;
|
||||
available++;
|
||||
// printf("%d %d\n", allocated, header[ allocated ]) ;
|
||||
}
|
||||
// printf("De-allocating %d\n", ( obj - data ) / N ) ;
|
||||
stack[available >> HEAP_BASE][available & HEAP_MASK] = (UCHAR *)obj;
|
||||
available++;
|
||||
// printf("%d %d\n", allocated, header[ allocated ]) ;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Print information
|
||||
*/
|
||||
void printInfo( )
|
||||
{
|
||||
printf("Bytes: %d Used: %d Allocated: %d Maxfree: %d\n", getBytes(), getAllocated(), getAll(), stacksize);
|
||||
}
|
||||
void printInfo()
|
||||
{
|
||||
printf("Bytes: %d Used: %d Allocated: %d Maxfree: %d\n",
|
||||
getBytes(),
|
||||
getAllocated(),
|
||||
getAll(),
|
||||
stacksize);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Query methods
|
||||
*/
|
||||
int getAllocated( )
|
||||
{
|
||||
return HEAP_UNIT * datablocknum - available;
|
||||
};
|
||||
int getAllocated()
|
||||
{
|
||||
return HEAP_UNIT * datablocknum - available;
|
||||
};
|
||||
|
||||
int getAll( )
|
||||
{
|
||||
return HEAP_UNIT * datablocknum;
|
||||
};
|
||||
int getAll()
|
||||
{
|
||||
return HEAP_UNIT * datablocknum;
|
||||
};
|
||||
|
||||
int getBytes( )
|
||||
{
|
||||
return N;
|
||||
};
|
||||
int getBytes()
|
||||
{
|
||||
return N;
|
||||
};
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:MemoryAllocator")
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:MemoryAllocator")
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif /* __MEMORYALLOCATOR_H__ */
|
||||
#endif /* __MEMORYALLOCATOR_H__ */
|
||||
|
||||
@@ -24,40 +24,37 @@
|
||||
*
|
||||
* @author Tao Ju
|
||||
*/
|
||||
class ModelReader
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
ModelReader(){
|
||||
};
|
||||
class ModelReader {
|
||||
public:
|
||||
/// Constructor
|
||||
ModelReader(){};
|
||||
|
||||
/// Get next triangle
|
||||
virtual Triangle *getNextTriangle( ) = 0;
|
||||
virtual int getNextTriangle(int t[3]) = 0;
|
||||
/// Get next triangle
|
||||
virtual Triangle *getNextTriangle() = 0;
|
||||
virtual int getNextTriangle(int t[3]) = 0;
|
||||
|
||||
/// Get bounding box
|
||||
virtual float getBoundingBox(float origin[3]) = 0;
|
||||
/// Get bounding box
|
||||
virtual float getBoundingBox(float origin[3]) = 0;
|
||||
|
||||
/// Get number of triangles
|
||||
virtual int getNumTriangles( ) = 0;
|
||||
/// Get number of triangles
|
||||
virtual int getNumTriangles() = 0;
|
||||
|
||||
/// Get storage size
|
||||
virtual int getMemory( ) = 0;
|
||||
/// Get storage size
|
||||
virtual int getMemory() = 0;
|
||||
|
||||
/// Reset file reading location
|
||||
virtual void reset( ) = 0;
|
||||
/// Reset file reading location
|
||||
virtual void reset() = 0;
|
||||
|
||||
/// For explicit vertex models
|
||||
virtual int getNumVertices( ) = 0;
|
||||
/// For explicit vertex models
|
||||
virtual int getNumVertices() = 0;
|
||||
|
||||
virtual void getNextVertex(float v[3]) = 0;
|
||||
virtual void getNextVertex(float v[3]) = 0;
|
||||
|
||||
virtual void printInfo( ) = 0;
|
||||
virtual void printInfo() = 0;
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:ModelReader")
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:ModelReader")
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif /* __MODELREADER_H__ */
|
||||
#endif /* __MODELREADER_H__ */
|
||||
|
||||
@@ -22,52 +22,45 @@
|
||||
#include "Projections.h"
|
||||
|
||||
const int vertmap[8][3] = {
|
||||
{0, 0, 0},
|
||||
{0, 0, 1},
|
||||
{0, 1, 0},
|
||||
{0, 1, 1},
|
||||
{1, 0, 0},
|
||||
{1, 0, 1},
|
||||
{1, 1, 0},
|
||||
{1, 1, 1},
|
||||
{0, 0, 0},
|
||||
{0, 0, 1},
|
||||
{0, 1, 0},
|
||||
{0, 1, 1},
|
||||
{1, 0, 0},
|
||||
{1, 0, 1},
|
||||
{1, 1, 0},
|
||||
{1, 1, 1},
|
||||
};
|
||||
|
||||
const int centmap[3][3][3][2] = {
|
||||
{{{0, 0}, {0, 1}, {1, 1}},
|
||||
{{0, 2}, {0, 3}, {1, 3}},
|
||||
{{2, 2}, {2, 3}, {3, 3}}},
|
||||
{{{0, 0}, {0, 1}, {1, 1}}, {{0, 2}, {0, 3}, {1, 3}}, {{2, 2}, {2, 3}, {3, 3}}},
|
||||
|
||||
{{{0, 4}, {0, 5}, {1, 5}},
|
||||
{{0, 6}, {0, 7}, {1, 7}},
|
||||
{{2, 6}, {2, 7}, {3, 7}}},
|
||||
{{{0, 4}, {0, 5}, {1, 5}}, {{0, 6}, {0, 7}, {1, 7}}, {{2, 6}, {2, 7}, {3, 7}}},
|
||||
|
||||
{{{4, 4}, {4, 5}, {5, 5}},
|
||||
{{4, 6}, {4, 7}, {5, 7}},
|
||||
{{6, 6}, {6, 7}, {7, 7}}}
|
||||
};
|
||||
{{{4, 4}, {4, 5}, {5, 5}}, {{4, 6}, {4, 7}, {5, 7}}, {{6, 6}, {6, 7}, {7, 7}}}};
|
||||
|
||||
const int edgemap[12][2] = {
|
||||
{0, 4},
|
||||
{1, 5},
|
||||
{2, 6},
|
||||
{3, 7},
|
||||
{0, 2},
|
||||
{1, 3},
|
||||
{4, 6},
|
||||
{5, 7},
|
||||
{0, 1},
|
||||
{2, 3},
|
||||
{4, 5},
|
||||
{6, 7},
|
||||
{0, 4},
|
||||
{1, 5},
|
||||
{2, 6},
|
||||
{3, 7},
|
||||
{0, 2},
|
||||
{1, 3},
|
||||
{4, 6},
|
||||
{5, 7},
|
||||
{0, 1},
|
||||
{2, 3},
|
||||
{4, 5},
|
||||
{6, 7},
|
||||
};
|
||||
|
||||
const int facemap[6][4] = {
|
||||
{0, 1, 2, 3},
|
||||
{4, 5, 6, 7},
|
||||
{0, 1, 4, 5},
|
||||
{2, 3, 6, 7},
|
||||
{0, 2, 4, 6},
|
||||
{1, 3, 5, 7},
|
||||
{0, 1, 2, 3},
|
||||
{4, 5, 6, 7},
|
||||
{0, 1, 4, 5},
|
||||
{2, 3, 6, 7},
|
||||
{0, 2, 4, 6},
|
||||
{1, 3, 5, 7},
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -75,16 +68,16 @@ const int facemap[6][4] = {
|
||||
*/
|
||||
static void crossProduct(int64_t res[3], const int64_t a[3], const int64_t b[3])
|
||||
{
|
||||
res[0] = a[1] * b[2] - a[2] * b[1];
|
||||
res[1] = a[2] * b[0] - a[0] * b[2];
|
||||
res[2] = a[0] * b[1] - a[1] * b[0];
|
||||
res[0] = a[1] * b[2] - a[2] * b[1];
|
||||
res[1] = a[2] * b[0] - a[0] * b[2];
|
||||
res[2] = a[0] * b[1] - a[1] * b[0];
|
||||
}
|
||||
|
||||
static void crossProduct(double res[3], const double a[3], const double b[3])
|
||||
{
|
||||
res[0] = a[1] * b[2] - a[2] * b[1];
|
||||
res[1] = a[2] * b[0] - a[0] * b[2];
|
||||
res[2] = a[0] * b[1] - a[1] * b[0];
|
||||
res[0] = a[1] * b[2] - a[2] * b[1];
|
||||
res[1] = a[2] * b[0] - a[0] * b[2];
|
||||
res[2] = a[0] * b[1] - a[1] * b[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,18 +85,18 @@ static void crossProduct(double res[3], const double a[3], const double b[3])
|
||||
*/
|
||||
static int64_t dotProduct(const int64_t a[3], const int64_t b[3])
|
||||
{
|
||||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
||||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
||||
}
|
||||
|
||||
static void normalize(double a[3])
|
||||
{
|
||||
double mag = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
|
||||
if (mag > 0) {
|
||||
mag = sqrt(mag);
|
||||
a[0] /= mag;
|
||||
a[1] /= mag;
|
||||
a[2] /= mag;
|
||||
}
|
||||
double mag = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
|
||||
if (mag > 0) {
|
||||
mag = sqrt(mag);
|
||||
a[0] /= mag;
|
||||
a[1] /= mag;
|
||||
a[2] /= mag;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create projection axes for cube+triangle intersection testing.
|
||||
@@ -118,114 +111,115 @@ static void normalize(double a[3])
|
||||
*/
|
||||
static void create_projection_axes(int64_t axes[NUM_AXES][3], const int64_t tri[3][3])
|
||||
{
|
||||
/* Cube face normals */
|
||||
axes[0][0] = 1;
|
||||
axes[0][1] = 0;
|
||||
axes[0][2] = 0;
|
||||
axes[1][0] = 0;
|
||||
axes[1][1] = 1;
|
||||
axes[1][2] = 0;
|
||||
axes[2][0] = 0;
|
||||
axes[2][1] = 0;
|
||||
axes[2][2] = 1;
|
||||
/* Cube face normals */
|
||||
axes[0][0] = 1;
|
||||
axes[0][1] = 0;
|
||||
axes[0][2] = 0;
|
||||
axes[1][0] = 0;
|
||||
axes[1][1] = 1;
|
||||
axes[1][2] = 0;
|
||||
axes[2][0] = 0;
|
||||
axes[2][1] = 0;
|
||||
axes[2][2] = 1;
|
||||
|
||||
/* Get triangle edge vectors */
|
||||
int64_t tri_edges[3][3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++)
|
||||
tri_edges[i][j] = tri[(i + 1) % 3][j] - tri[i][j];
|
||||
}
|
||||
/* Get triangle edge vectors */
|
||||
int64_t tri_edges[3][3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++)
|
||||
tri_edges[i][j] = tri[(i + 1) % 3][j] - tri[i][j];
|
||||
}
|
||||
|
||||
/* Triangle normal */
|
||||
crossProduct(axes[3], tri_edges[0], tri_edges[1]);
|
||||
/* Triangle normal */
|
||||
crossProduct(axes[3], tri_edges[0], tri_edges[1]);
|
||||
|
||||
// Face edges and triangle edges
|
||||
int ct = 4;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
crossProduct(axes[ct], axes[j], tri_edges[i]);
|
||||
ct++;
|
||||
}
|
||||
}
|
||||
// Face edges and triangle edges
|
||||
int ct = 4;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
crossProduct(axes[ct], axes[j], tri_edges[i]);
|
||||
ct++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construction from a cube (axes aligned) and triangle
|
||||
*/
|
||||
CubeTriangleIsect::CubeTriangleIsect(int64_t cube[2][3], int64_t tri[3][3], int64_t /*error*/, int triind)
|
||||
CubeTriangleIsect::CubeTriangleIsect(int64_t cube[2][3],
|
||||
int64_t tri[3][3],
|
||||
int64_t /*error*/,
|
||||
int triind)
|
||||
{
|
||||
int i;
|
||||
inherit = new TriangleProjection;
|
||||
inherit->index = triind;
|
||||
int i;
|
||||
inherit = new TriangleProjection;
|
||||
inherit->index = triind;
|
||||
|
||||
int64_t axes[NUM_AXES][3];
|
||||
create_projection_axes(axes, tri);
|
||||
int64_t axes[NUM_AXES][3];
|
||||
create_projection_axes(axes, tri);
|
||||
|
||||
/* Normalize face normal and store */
|
||||
double dedge1[] = {(double)tri[1][0] - (double)tri[0][0],
|
||||
(double)tri[1][1] - (double)tri[0][1],
|
||||
(double)tri[1][2] - (double)tri[0][2]};
|
||||
double dedge2[] = {(double)tri[2][0] - (double)tri[1][0],
|
||||
(double)tri[2][1] - (double)tri[1][1],
|
||||
(double)tri[2][2] - (double)tri[1][2]};
|
||||
crossProduct(inherit->norm, dedge1, dedge2);
|
||||
normalize(inherit->norm);
|
||||
/* Normalize face normal and store */
|
||||
double dedge1[] = {(double)tri[1][0] - (double)tri[0][0],
|
||||
(double)tri[1][1] - (double)tri[0][1],
|
||||
(double)tri[1][2] - (double)tri[0][2]};
|
||||
double dedge2[] = {(double)tri[2][0] - (double)tri[1][0],
|
||||
(double)tri[2][1] - (double)tri[1][1],
|
||||
(double)tri[2][2] - (double)tri[1][2]};
|
||||
crossProduct(inherit->norm, dedge1, dedge2);
|
||||
normalize(inherit->norm);
|
||||
|
||||
int64_t cubeedge[3][3];
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
cubeedge[i][j] = 0;
|
||||
}
|
||||
cubeedge[i][i] = cube[1][i] - cube[0][i];
|
||||
}
|
||||
int64_t cubeedge[3][3];
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
cubeedge[i][j] = 0;
|
||||
}
|
||||
cubeedge[i][i] = cube[1][i] - cube[0][i];
|
||||
}
|
||||
|
||||
/* Project the cube on to each axis */
|
||||
for (int axis = 0; axis < NUM_AXES; axis++) {
|
||||
CubeProjection &cube_proj = cubeProj[axis];
|
||||
/* Project the cube on to each axis */
|
||||
for (int axis = 0; axis < NUM_AXES; axis++) {
|
||||
CubeProjection &cube_proj = cubeProj[axis];
|
||||
|
||||
/* Origin */
|
||||
cube_proj.origin = dotProduct(axes[axis], cube[0]);
|
||||
/* Origin */
|
||||
cube_proj.origin = dotProduct(axes[axis], cube[0]);
|
||||
|
||||
/* 3 direction vectors */
|
||||
for (i = 0; i < 3; i++)
|
||||
cube_proj.edges[i] = dotProduct(axes[axis], cubeedge[i]);
|
||||
/* 3 direction vectors */
|
||||
for (i = 0; i < 3; i++)
|
||||
cube_proj.edges[i] = dotProduct(axes[axis], cubeedge[i]);
|
||||
|
||||
/* Offsets of 2 ends of cube projection */
|
||||
int64_t max = 0;
|
||||
int64_t min = 0;
|
||||
for (i = 1; i < 8; i++) {
|
||||
int64_t proj = (vertmap[i][0] * cube_proj.edges[0] +
|
||||
vertmap[i][1] * cube_proj.edges[1] +
|
||||
vertmap[i][2] * cube_proj.edges[2]);
|
||||
if (proj > max) {
|
||||
max = proj;
|
||||
}
|
||||
if (proj < min) {
|
||||
min = proj;
|
||||
}
|
||||
}
|
||||
cube_proj.min = min;
|
||||
cube_proj.max = max;
|
||||
/* Offsets of 2 ends of cube projection */
|
||||
int64_t max = 0;
|
||||
int64_t min = 0;
|
||||
for (i = 1; i < 8; i++) {
|
||||
int64_t proj = (vertmap[i][0] * cube_proj.edges[0] + vertmap[i][1] * cube_proj.edges[1] +
|
||||
vertmap[i][2] * cube_proj.edges[2]);
|
||||
if (proj > max) {
|
||||
max = proj;
|
||||
}
|
||||
if (proj < min) {
|
||||
min = proj;
|
||||
}
|
||||
}
|
||||
cube_proj.min = min;
|
||||
cube_proj.max = max;
|
||||
}
|
||||
|
||||
}
|
||||
/* Project the triangle on to each axis */
|
||||
for (int axis = 0; axis < NUM_AXES; axis++) {
|
||||
const int64_t vts[3] = {dotProduct(axes[axis], tri[0]),
|
||||
dotProduct(axes[axis], tri[1]),
|
||||
dotProduct(axes[axis], tri[2])};
|
||||
|
||||
/* Project the triangle on to each axis */
|
||||
for (int axis = 0; axis < NUM_AXES; axis++) {
|
||||
const int64_t vts[3] = {dotProduct(axes[axis], tri[0]),
|
||||
dotProduct(axes[axis], tri[1]),
|
||||
dotProduct(axes[axis], tri[2])};
|
||||
// Triangle
|
||||
inherit->tri_proj[axis][0] = vts[0];
|
||||
inherit->tri_proj[axis][1] = vts[0];
|
||||
for (i = 1; i < 3; i++) {
|
||||
if (vts[i] < inherit->tri_proj[axis][0])
|
||||
inherit->tri_proj[axis][0] = vts[i];
|
||||
|
||||
// Triangle
|
||||
inherit->tri_proj[axis][0] = vts[0];
|
||||
inherit->tri_proj[axis][1] = vts[0];
|
||||
for (i = 1; i < 3; i++) {
|
||||
if (vts[i] < inherit->tri_proj[axis][0])
|
||||
inherit->tri_proj[axis][0] = vts[i];
|
||||
|
||||
if (vts[i] > inherit->tri_proj[axis][1])
|
||||
inherit->tri_proj[axis][1] = vts[i];
|
||||
}
|
||||
}
|
||||
if (vts[i] > inherit->tri_proj[axis][1])
|
||||
inherit->tri_proj[axis][1] = vts[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,67 +228,64 @@ CubeTriangleIsect::CubeTriangleIsect(int64_t cube[2][3], int64_t tri[3][3], int6
|
||||
*/
|
||||
CubeTriangleIsect::CubeTriangleIsect(CubeTriangleIsect *parent)
|
||||
{
|
||||
// Copy inheritable projections
|
||||
this->inherit = parent->inherit;
|
||||
// Copy inheritable projections
|
||||
this->inherit = parent->inherit;
|
||||
|
||||
// Shrink cube projections
|
||||
for (int i = 0; i < NUM_AXES; i++) {
|
||||
cubeProj[i].origin = parent->cubeProj[i].origin;
|
||||
// Shrink cube projections
|
||||
for (int i = 0; i < NUM_AXES; i++) {
|
||||
cubeProj[i].origin = parent->cubeProj[i].origin;
|
||||
|
||||
for (int j = 0; j < 3; j++)
|
||||
cubeProj[i].edges[j] = parent->cubeProj[i].edges[j] >> 1;
|
||||
for (int j = 0; j < 3; j++)
|
||||
cubeProj[i].edges[j] = parent->cubeProj[i].edges[j] >> 1;
|
||||
|
||||
cubeProj[i].min = parent->cubeProj[i].min >> 1;
|
||||
cubeProj[i].max = parent->cubeProj[i].max >> 1;
|
||||
}
|
||||
cubeProj[i].min = parent->cubeProj[i].min >> 1;
|
||||
cubeProj[i].max = parent->cubeProj[i].max >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char CubeTriangleIsect::getBoxMask( )
|
||||
unsigned char CubeTriangleIsect::getBoxMask()
|
||||
{
|
||||
int i, j, k;
|
||||
int bmask[3][2] = {{0, 0}, {0, 0}, {0, 0}};
|
||||
unsigned char boxmask = 0;
|
||||
int64_t child_len = cubeProj[0].edges[0] >> 1;
|
||||
int i, j, k;
|
||||
int bmask[3][2] = {{0, 0}, {0, 0}, {0, 0}};
|
||||
unsigned char boxmask = 0;
|
||||
int64_t child_len = cubeProj[0].edges[0] >> 1;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
int64_t mid = cubeProj[i].origin + child_len;
|
||||
for (i = 0; i < 3; i++) {
|
||||
int64_t mid = cubeProj[i].origin + child_len;
|
||||
|
||||
// Check bounding box
|
||||
if (mid >= inherit->tri_proj[i][0]) {
|
||||
bmask[i][0] = 1;
|
||||
}
|
||||
if (mid < inherit->tri_proj[i][1]) {
|
||||
bmask[i][1] = 1;
|
||||
}
|
||||
// Check bounding box
|
||||
if (mid >= inherit->tri_proj[i][0]) {
|
||||
bmask[i][0] = 1;
|
||||
}
|
||||
if (mid < inherit->tri_proj[i][1]) {
|
||||
bmask[i][1] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Fill in masks
|
||||
int ct = 0;
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (k = 0; k < 2; k++) {
|
||||
boxmask |= ((bmask[0][i] & bmask[1][j] & bmask[2][k]) << ct);
|
||||
ct++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in masks
|
||||
int ct = 0;
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (k = 0; k < 2; k++) {
|
||||
boxmask |= ( (bmask[0][i] & bmask[1][j] & bmask[2][k]) << ct);
|
||||
ct++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return bounding box masks
|
||||
return boxmask;
|
||||
// Return bounding box masks
|
||||
return boxmask;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shifting a cube to a new origin
|
||||
*/
|
||||
void CubeTriangleIsect::shift(int off[3])
|
||||
{
|
||||
for (int i = 0; i < NUM_AXES; i++) {
|
||||
cubeProj[i].origin += (off[0] * cubeProj[i].edges[0] +
|
||||
off[1] * cubeProj[i].edges[1] +
|
||||
off[2] * cubeProj[i].edges[2]);
|
||||
}
|
||||
for (int i = 0; i < NUM_AXES; i++) {
|
||||
cubeProj[i].origin += (off[0] * cubeProj[i].edges[0] + off[1] * cubeProj[i].edges[1] +
|
||||
off[2] * cubeProj[i].edges[2]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -302,75 +293,70 @@ void CubeTriangleIsect::shift(int off[3])
|
||||
*/
|
||||
int CubeTriangleIsect::isIntersecting() const
|
||||
{
|
||||
for (int i = 0; i < NUM_AXES; i++) {
|
||||
/*
|
||||
int64_t proj0 = cubeProj[i][0] +
|
||||
vertmap[inherit->cubeEnds[i][0]][0] * cubeProj[i][1] +
|
||||
vertmap[inherit->cubeEnds[i][0]][1] * cubeProj[i][2] +
|
||||
vertmap[inherit->cubeEnds[i][0]][2] * cubeProj[i][3] ;
|
||||
int64_t proj1 = cubeProj[i][0] +
|
||||
vertmap[inherit->cubeEnds[i][1]][0] * cubeProj[i][1] +
|
||||
vertmap[inherit->cubeEnds[i][1]][1] * cubeProj[i][2] +
|
||||
vertmap[inherit->cubeEnds[i][1]][2] * cubeProj[i][3] ;
|
||||
*/
|
||||
for (int i = 0; i < NUM_AXES; i++) {
|
||||
/*
|
||||
int64_t proj0 = cubeProj[i][0] +
|
||||
vertmap[inherit->cubeEnds[i][0]][0] * cubeProj[i][1] +
|
||||
vertmap[inherit->cubeEnds[i][0]][1] * cubeProj[i][2] +
|
||||
vertmap[inherit->cubeEnds[i][0]][2] * cubeProj[i][3] ;
|
||||
int64_t proj1 = cubeProj[i][0] +
|
||||
vertmap[inherit->cubeEnds[i][1]][0] * cubeProj[i][1] +
|
||||
vertmap[inherit->cubeEnds[i][1]][1] * cubeProj[i][2] +
|
||||
vertmap[inherit->cubeEnds[i][1]][2] * cubeProj[i][3] ;
|
||||
*/
|
||||
|
||||
int64_t proj0 = cubeProj[i].origin + cubeProj[i].min;
|
||||
int64_t proj1 = cubeProj[i].origin + cubeProj[i].max;
|
||||
int64_t proj0 = cubeProj[i].origin + cubeProj[i].min;
|
||||
int64_t proj1 = cubeProj[i].origin + cubeProj[i].max;
|
||||
|
||||
if (proj0 > inherit->tri_proj[i][1] ||
|
||||
proj1 < inherit->tri_proj[i][0]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (proj0 > inherit->tri_proj[i][1] || proj1 < inherit->tri_proj[i][0]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CubeTriangleIsect::isIntersectingPrimary(int edgeInd) const
|
||||
{
|
||||
for (int i = 0; i < NUM_AXES; i++) {
|
||||
for (int i = 0; i < NUM_AXES; i++) {
|
||||
|
||||
int64_t proj0 = cubeProj[i].origin;
|
||||
int64_t proj1 = cubeProj[i].origin + cubeProj[i].edges[edgeInd];
|
||||
int64_t proj0 = cubeProj[i].origin;
|
||||
int64_t proj1 = cubeProj[i].origin + cubeProj[i].edges[edgeInd];
|
||||
|
||||
if (proj0 < proj1) {
|
||||
if (proj0 > inherit->tri_proj[i][1] ||
|
||||
proj1 < inherit->tri_proj[i][0]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (proj1 > inherit->tri_proj[i][1] ||
|
||||
proj0 < inherit->tri_proj[i][0]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (proj0 < proj1) {
|
||||
if (proj0 > inherit->tri_proj[i][1] || proj1 < inherit->tri_proj[i][0]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (proj1 > inherit->tri_proj[i][1] || proj0 < inherit->tri_proj[i][0]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// printf( "Intersecting: %d %d\n", edgemap[edgeInd][0], edgemap[edgeInd][1] ) ;
|
||||
return 1;
|
||||
// printf( "Intersecting: %d %d\n", edgemap[edgeInd][0], edgemap[edgeInd][1] ) ;
|
||||
return 1;
|
||||
}
|
||||
|
||||
float CubeTriangleIsect::getIntersectionPrimary(int edgeInd) const
|
||||
{
|
||||
int i = 3;
|
||||
int i = 3;
|
||||
|
||||
int64_t proj0 = cubeProj[i].origin;
|
||||
int64_t proj1 = cubeProj[i].origin + cubeProj[i].edges[edgeInd];
|
||||
int64_t proj2 = inherit->tri_proj[i][1];
|
||||
int64_t d = proj1 - proj0;
|
||||
double alpha;
|
||||
|
||||
int64_t proj0 = cubeProj[i].origin;
|
||||
int64_t proj1 = cubeProj[i].origin + cubeProj[i].edges[edgeInd];
|
||||
int64_t proj2 = inherit->tri_proj[i][1];
|
||||
int64_t d = proj1 - proj0;
|
||||
double alpha;
|
||||
if (d == 0)
|
||||
alpha = 0.5;
|
||||
else {
|
||||
alpha = (double)((proj2 - proj0)) / (double)d;
|
||||
|
||||
if (d == 0)
|
||||
alpha = 0.5;
|
||||
else {
|
||||
alpha = (double)((proj2 - proj0)) / (double)d;
|
||||
if (alpha < 0 || alpha > 1)
|
||||
alpha = 0.5;
|
||||
}
|
||||
|
||||
if (alpha < 0 || alpha > 1)
|
||||
alpha = 0.5;
|
||||
}
|
||||
|
||||
return (float)alpha;
|
||||
return (float)alpha;
|
||||
}
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
#define GRID_DIMENSION 20
|
||||
|
||||
#if defined(_WIN32) && !(_MSC_VER >= 1900)
|
||||
#define isnan(n) _isnan(n)
|
||||
#define LONG __int64
|
||||
#define int64_t __int64
|
||||
# define isnan(n) _isnan(n)
|
||||
# define LONG __int64
|
||||
# define int64_t __int64
|
||||
#else
|
||||
#include <stdint.h>
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -59,71 +59,70 @@ extern const int facemap[6][4];
|
||||
* Structure for the projections inheritable from parent
|
||||
*/
|
||||
struct TriangleProjection {
|
||||
/// Projections of triangle (min and max)
|
||||
int64_t tri_proj[NUM_AXES][2];
|
||||
/// Projections of triangle (min and max)
|
||||
int64_t tri_proj[NUM_AXES][2];
|
||||
|
||||
/// Normal of the triangle
|
||||
double norm[3];
|
||||
/// Normal of the triangle
|
||||
double norm[3];
|
||||
|
||||
/// Index of polygon
|
||||
int index;
|
||||
/// Index of polygon
|
||||
int index;
|
||||
};
|
||||
|
||||
/* This is a projection for the cube against a single projection
|
||||
axis, see CubeTriangleIsect.cubeProj */
|
||||
struct CubeProjection {
|
||||
int64_t origin;
|
||||
int64_t edges[3];
|
||||
int64_t min, max;
|
||||
int64_t origin;
|
||||
int64_t edges[3];
|
||||
int64_t min, max;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class for projections of cube / triangle vertices on the separating axes
|
||||
*/
|
||||
class CubeTriangleIsect
|
||||
{
|
||||
public:
|
||||
/// Inheritable portion
|
||||
TriangleProjection *inherit;
|
||||
class CubeTriangleIsect {
|
||||
public:
|
||||
/// Inheritable portion
|
||||
TriangleProjection *inherit;
|
||||
|
||||
/// Projections of the cube vertices
|
||||
CubeProjection cubeProj[NUM_AXES];
|
||||
/// Projections of the cube vertices
|
||||
CubeProjection cubeProj[NUM_AXES];
|
||||
|
||||
public:
|
||||
CubeTriangleIsect() {}
|
||||
public:
|
||||
CubeTriangleIsect()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Construction from a cube (axes aligned) and triangle
|
||||
*/
|
||||
CubeTriangleIsect(int64_t cube[2][3], int64_t trig[3][3], int64_t error, int triind);
|
||||
|
||||
/**
|
||||
* Construction from a parent CubeTriangleIsect object and the index of
|
||||
* the children
|
||||
*/
|
||||
CubeTriangleIsect(CubeTriangleIsect *parent);
|
||||
|
||||
unsigned char getBoxMask( );
|
||||
/**
|
||||
* Construction from a cube (axes aligned) and triangle
|
||||
*/
|
||||
CubeTriangleIsect(int64_t cube[2][3], int64_t trig[3][3], int64_t error, int triind);
|
||||
|
||||
/**
|
||||
* Shifting a cube to a new origin
|
||||
*/
|
||||
void shift(int off[3]);
|
||||
/**
|
||||
* Construction from a parent CubeTriangleIsect object and the index of
|
||||
* the children
|
||||
*/
|
||||
CubeTriangleIsect(CubeTriangleIsect *parent);
|
||||
|
||||
/**
|
||||
* Method to test intersection of the triangle and the cube
|
||||
*/
|
||||
int isIntersecting() const;
|
||||
unsigned char getBoxMask();
|
||||
|
||||
int isIntersectingPrimary(int edgeInd) const;
|
||||
/**
|
||||
* Shifting a cube to a new origin
|
||||
*/
|
||||
void shift(int off[3]);
|
||||
|
||||
float getIntersectionPrimary(int edgeInd) const;
|
||||
/**
|
||||
* Method to test intersection of the triangle and the cube
|
||||
*/
|
||||
int isIntersecting() const;
|
||||
|
||||
int isIntersectingPrimary(int edgeInd) const;
|
||||
|
||||
float getIntersectionPrimary(int edgeInd) const;
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:CubeTriangleIsect")
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:CubeTriangleIsect")
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif /* __PROJECTIONS_H__ */
|
||||
#endif /* __PROJECTIONS_H__ */
|
||||
|
||||
@@ -18,85 +18,78 @@
|
||||
#define __QUEUE_H__
|
||||
|
||||
struct gridQueueEle {
|
||||
int x, y, z;
|
||||
UCHAR dir;
|
||||
gridQueueEle *next;
|
||||
int x, y, z;
|
||||
UCHAR dir;
|
||||
gridQueueEle *next;
|
||||
};
|
||||
|
||||
class GridQueue
|
||||
{
|
||||
gridQueueEle *head;
|
||||
gridQueueEle *tail;
|
||||
int numEles;
|
||||
class GridQueue {
|
||||
gridQueueEle *head;
|
||||
gridQueueEle *tail;
|
||||
int numEles;
|
||||
|
||||
public:
|
||||
public:
|
||||
GridQueue()
|
||||
{
|
||||
head = NULL;
|
||||
tail = NULL;
|
||||
numEles = 0;
|
||||
}
|
||||
|
||||
GridQueue( )
|
||||
{
|
||||
head = NULL;
|
||||
tail = NULL;
|
||||
numEles = 0;
|
||||
}
|
||||
gridQueueEle *getHead()
|
||||
{
|
||||
return head;
|
||||
}
|
||||
|
||||
gridQueueEle *getHead( )
|
||||
{
|
||||
return head;
|
||||
}
|
||||
int getNumElements()
|
||||
{
|
||||
return numEles;
|
||||
}
|
||||
|
||||
int getNumElements( )
|
||||
{
|
||||
return numEles;
|
||||
}
|
||||
void pushQueue(int st[3], int dir)
|
||||
{
|
||||
gridQueueEle *ele = new gridQueueEle;
|
||||
ele->x = st[0];
|
||||
ele->y = st[1];
|
||||
ele->z = st[2];
|
||||
ele->dir = (UCHAR)dir;
|
||||
ele->next = NULL;
|
||||
if (head == NULL) {
|
||||
head = ele;
|
||||
}
|
||||
else {
|
||||
tail->next = ele;
|
||||
}
|
||||
tail = ele;
|
||||
numEles++;
|
||||
}
|
||||
|
||||
int popQueue(int st[3], int &dir)
|
||||
{
|
||||
if (head == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pushQueue(int st[3], int dir)
|
||||
{
|
||||
gridQueueEle *ele = new gridQueueEle;
|
||||
ele->x = st[0];
|
||||
ele->y = st[1];
|
||||
ele->z = st[2];
|
||||
ele->dir = (UCHAR) dir;
|
||||
ele->next = NULL;
|
||||
if (head == NULL)
|
||||
{
|
||||
head = ele;
|
||||
}
|
||||
else {
|
||||
tail->next = ele;
|
||||
}
|
||||
tail = ele;
|
||||
numEles++;
|
||||
}
|
||||
st[0] = head->x;
|
||||
st[1] = head->y;
|
||||
st[2] = head->z;
|
||||
dir = (int)(head->dir);
|
||||
|
||||
int popQueue(int st[3], int& dir)
|
||||
{
|
||||
if (head == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
gridQueueEle *temp = head;
|
||||
head = head->next;
|
||||
delete temp;
|
||||
|
||||
st[0] = head->x;
|
||||
st[1] = head->y;
|
||||
st[2] = head->z;
|
||||
dir = (int) (head->dir);
|
||||
if (head == NULL) {
|
||||
tail = NULL;
|
||||
}
|
||||
numEles--;
|
||||
|
||||
gridQueueEle *temp = head;
|
||||
head = head->next;
|
||||
delete temp;
|
||||
|
||||
if (head == NULL)
|
||||
{
|
||||
tail = NULL;
|
||||
}
|
||||
numEles--;
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:GridQueue")
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:GridQueue")
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif /* __QUEUE_H__ */
|
||||
#endif /* __QUEUE_H__ */
|
||||
|
||||
@@ -20,26 +20,24 @@
|
||||
#include "marching_cubes_table.h"
|
||||
|
||||
/* simple wrapper for auto-generated marching cubes data */
|
||||
class Cubes
|
||||
{
|
||||
public:
|
||||
/// Get number of triangles
|
||||
int getNumTriangle(int mask)
|
||||
{
|
||||
return marching_cubes_numtri[mask];
|
||||
}
|
||||
class Cubes {
|
||||
public:
|
||||
/// Get number of triangles
|
||||
int getNumTriangle(int mask)
|
||||
{
|
||||
return marching_cubes_numtri[mask];
|
||||
}
|
||||
|
||||
/// Get a triangle
|
||||
void getTriangle(int mask, int index, int indices[3])
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
indices[i] = marching_cubes_tris[mask][index][i];
|
||||
}
|
||||
/// Get a triangle
|
||||
void getTriangle(int mask, int index, int indices[3])
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
indices[i] = marching_cubes_tris[mask][index][i];
|
||||
}
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:Cubes")
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:Cubes")
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif /* __CUBES_H__ */
|
||||
#endif /* __CUBES_H__ */
|
||||
|
||||
@@ -23,141 +23,139 @@
|
||||
#include <float.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define isnan(n) _isnan(n)
|
||||
# define isnan(n) _isnan(n)
|
||||
#endif
|
||||
|
||||
static void veccopy(float dst[3], const float src[3])
|
||||
{
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[2];
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[2];
|
||||
}
|
||||
|
||||
#define GET_TRI(_mesh, _n) \
|
||||
(*(DualConTri)(((char *)(_mesh)->looptri) + ((_n) * (_mesh)->tri_stride)))
|
||||
(*(DualConTri)(((char *)(_mesh)->looptri) + ((_n) * (_mesh)->tri_stride)))
|
||||
|
||||
#define GET_CO(_mesh, _n) \
|
||||
(*(DualConCo)(((char *)(_mesh)->co) + ((_n) * (_mesh)->co_stride)))
|
||||
#define GET_CO(_mesh, _n) (*(DualConCo)(((char *)(_mesh)->co) + ((_n) * (_mesh)->co_stride)))
|
||||
|
||||
#define GET_LOOP(_mesh, _n) \
|
||||
(*(DualConLoop)(((char *)(_mesh)->mloop) + ((_n) * (_mesh)->loop_stride)))
|
||||
(*(DualConLoop)(((char *)(_mesh)->mloop) + ((_n) * (_mesh)->loop_stride)))
|
||||
|
||||
class DualConInputReader : public ModelReader
|
||||
{
|
||||
private:
|
||||
const DualConInput *input_mesh;
|
||||
int tottri, curtri;
|
||||
float min[3], max[3], maxsize;
|
||||
float scale;
|
||||
public:
|
||||
DualConInputReader(const DualConInput *mesh, float _scale)
|
||||
: input_mesh(mesh), scale(_scale)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
class DualConInputReader : public ModelReader {
|
||||
private:
|
||||
const DualConInput *input_mesh;
|
||||
int tottri, curtri;
|
||||
float min[3], max[3], maxsize;
|
||||
float scale;
|
||||
|
||||
void reset()
|
||||
{
|
||||
curtri = 0;
|
||||
maxsize = 0;
|
||||
tottri = input_mesh->tottri;
|
||||
public:
|
||||
DualConInputReader(const DualConInput *mesh, float _scale) : input_mesh(mesh), scale(_scale)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
veccopy(min, input_mesh->min);
|
||||
veccopy(max, input_mesh->max);
|
||||
void reset()
|
||||
{
|
||||
curtri = 0;
|
||||
maxsize = 0;
|
||||
tottri = input_mesh->tottri;
|
||||
|
||||
/* initialize maxsize */
|
||||
for (int i = 0; i < 3; i++) {
|
||||
float d = max[i] - min[i];
|
||||
if (d > maxsize)
|
||||
maxsize = d;
|
||||
}
|
||||
veccopy(min, input_mesh->min);
|
||||
veccopy(max, input_mesh->max);
|
||||
|
||||
/* redo the bounds */
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
min[i] = (max[i] + min[i]) / 2 - maxsize / 2;
|
||||
max[i] = (max[i] + min[i]) / 2 + maxsize / 2;
|
||||
}
|
||||
/* initialize maxsize */
|
||||
for (int i = 0; i < 3; i++) {
|
||||
float d = max[i] - min[i];
|
||||
if (d > maxsize)
|
||||
maxsize = d;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
min[i] -= maxsize * (1 / scale - 1) / 2;
|
||||
maxsize *= 1 / scale;
|
||||
}
|
||||
/* redo the bounds */
|
||||
for (int i = 0; i < 3; i++) {
|
||||
min[i] = (max[i] + min[i]) / 2 - maxsize / 2;
|
||||
max[i] = (max[i] + min[i]) / 2 + maxsize / 2;
|
||||
}
|
||||
|
||||
Triangle *getNextTriangle()
|
||||
{
|
||||
if (curtri == input_mesh->tottri)
|
||||
return NULL;
|
||||
for (int i = 0; i < 3; i++)
|
||||
min[i] -= maxsize * (1 / scale - 1) / 2;
|
||||
maxsize *= 1 / scale;
|
||||
}
|
||||
|
||||
Triangle *t = new Triangle();
|
||||
Triangle *getNextTriangle()
|
||||
{
|
||||
if (curtri == input_mesh->tottri)
|
||||
return NULL;
|
||||
|
||||
unsigned int *tr = GET_TRI(input_mesh, curtri);
|
||||
veccopy(t->vt[0], GET_CO(input_mesh, GET_LOOP(input_mesh, tr[0])));
|
||||
veccopy(t->vt[1], GET_CO(input_mesh, GET_LOOP(input_mesh, tr[1])));
|
||||
veccopy(t->vt[2], GET_CO(input_mesh, GET_LOOP(input_mesh, tr[2])));
|
||||
Triangle *t = new Triangle();
|
||||
|
||||
curtri++;
|
||||
unsigned int *tr = GET_TRI(input_mesh, curtri);
|
||||
veccopy(t->vt[0], GET_CO(input_mesh, GET_LOOP(input_mesh, tr[0])));
|
||||
veccopy(t->vt[1], GET_CO(input_mesh, GET_LOOP(input_mesh, tr[1])));
|
||||
veccopy(t->vt[2], GET_CO(input_mesh, GET_LOOP(input_mesh, tr[2])));
|
||||
|
||||
/* remove triangle if it contains invalid coords */
|
||||
for (int i = 0; i < 3; i++) {
|
||||
const float *co = t->vt[i];
|
||||
if (isnan(co[0]) || isnan(co[1]) || isnan(co[2])) {
|
||||
delete t;
|
||||
return getNextTriangle();
|
||||
}
|
||||
}
|
||||
curtri++;
|
||||
|
||||
return t;
|
||||
}
|
||||
/* remove triangle if it contains invalid coords */
|
||||
for (int i = 0; i < 3; i++) {
|
||||
const float *co = t->vt[i];
|
||||
if (isnan(co[0]) || isnan(co[1]) || isnan(co[2])) {
|
||||
delete t;
|
||||
return getNextTriangle();
|
||||
}
|
||||
}
|
||||
|
||||
int getNextTriangle(int t[3])
|
||||
{
|
||||
if (curtri == input_mesh->tottri)
|
||||
return 0;
|
||||
return t;
|
||||
}
|
||||
|
||||
unsigned int *tr = GET_TRI(input_mesh, curtri);
|
||||
t[0] = tr[0];
|
||||
t[1] = tr[1];
|
||||
t[2] = tr[2];
|
||||
int getNextTriangle(int t[3])
|
||||
{
|
||||
if (curtri == input_mesh->tottri)
|
||||
return 0;
|
||||
|
||||
curtri++;
|
||||
unsigned int *tr = GET_TRI(input_mesh, curtri);
|
||||
t[0] = tr[0];
|
||||
t[1] = tr[1];
|
||||
t[2] = tr[2];
|
||||
|
||||
return 1;
|
||||
}
|
||||
curtri++;
|
||||
|
||||
int getNumTriangles()
|
||||
{
|
||||
return tottri;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int getNumVertices()
|
||||
{
|
||||
return input_mesh->totco;
|
||||
}
|
||||
int getNumTriangles()
|
||||
{
|
||||
return tottri;
|
||||
}
|
||||
|
||||
float getBoundingBox(float origin[3])
|
||||
{
|
||||
veccopy(origin, min);
|
||||
return maxsize;
|
||||
}
|
||||
int getNumVertices()
|
||||
{
|
||||
return input_mesh->totco;
|
||||
}
|
||||
|
||||
/* output */
|
||||
void getNextVertex(float /*v*/[3])
|
||||
{
|
||||
/* not used */
|
||||
}
|
||||
float getBoundingBox(float origin[3])
|
||||
{
|
||||
veccopy(origin, min);
|
||||
return maxsize;
|
||||
}
|
||||
|
||||
/* stubs */
|
||||
void printInfo() {
|
||||
}
|
||||
int getMemory() {
|
||||
return sizeof(DualConInputReader);
|
||||
}
|
||||
/* output */
|
||||
void getNextVertex(float /*v*/[3])
|
||||
{
|
||||
/* not used */
|
||||
}
|
||||
|
||||
/* stubs */
|
||||
void printInfo()
|
||||
{
|
||||
}
|
||||
int getMemory()
|
||||
{
|
||||
return sizeof(DualConInputReader);
|
||||
}
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:DualConInputReader")
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:DualConInputReader")
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
void *dualcon(const DualConInput *input_mesh,
|
||||
@@ -173,9 +171,8 @@ void *dualcon(const DualConInput *input_mesh,
|
||||
float scale,
|
||||
int depth)
|
||||
{
|
||||
DualConInputReader r(input_mesh, scale);
|
||||
Octree o(&r, alloc_output, add_vert, add_quad,
|
||||
flags, mode, depth, threshold, hermite_num);
|
||||
o.scanConvert();
|
||||
return o.getOutputMesh();
|
||||
DualConInputReader r(input_mesh, scale);
|
||||
Octree o(&r, alloc_output, add_vert, add_quad, flags, mode, depth, threshold, hermite_num);
|
||||
o.scanConvert();
|
||||
return o.getOutputMesh();
|
||||
}
|
||||
|
||||
@@ -16,261 +16,3331 @@
|
||||
|
||||
#include "manifold_table.h"
|
||||
|
||||
const ManifoldIndices manifold_table[256] = {
|
||||
{0, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{3, {{1, 1}, {2, 2}, {3, 3}, {0, 0}, {3, 3}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {3, 3}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
|
||||
{2, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {2, 2}, {0, 0}}},
|
||||
{2, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
|
||||
{3, {{1, 1}, {2, 2}, {0, 0}, {3, 3}, {1, 1}, {3, 3}, {0, 0}, {2, 2}, {1, 1}, {3, 3}, {2, 2}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{2, {{0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 2}, {2, 2}, {2, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {1, 2}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
|
||||
{2, {{1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}}},
|
||||
{3, {{1, 1}, {0, 0}, {2, 2}, {3, 3}, {1, 1}, {3, 3}, {2, 2}, {0, 0}, {1, 1}, {3, 3}, {0, 0}, {2, 2}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {2, 2}}},
|
||||
{2, {{1, 1}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{2, {{1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {1, 1}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}}},
|
||||
{2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 1}}},
|
||||
{2, {{1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {1, 1}}},
|
||||
{2, {{0, 0}, {1, 2}, {1, 1}, {2, 2}, {2, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{2, {{2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 2}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{3, {{1, 1}, {2, 2}, {3, 3}, {0, 0}, {1, 1}, {0, 0}, {3, 3}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {3, 3}}},
|
||||
{2, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {2, 2}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {2, 2}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {2, 2}, {1, 1}}},
|
||||
{2, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {1, 1}}},
|
||||
{2, {{2, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {1, 2}, {1, 1}, {2, 2}}},
|
||||
{3, {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {0, 0}, {3, 3}, {2, 2}, {1, 1}, {0, 0}, {3, 3}, {1, 1}, {2, 2}}},
|
||||
{4, {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 1}, {4, 4}, {3, 3}, {2, 2}, {1, 1}, {4, 4}, {2, 2}, {3, 3}}},
|
||||
{2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {2, 2}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {1, 1}}},
|
||||
{2, {{0, 0}, {0, 0}, {0, 0}, {2, 1}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {1, 2}, {0, 0}, {2, 2}, {1, 1}}},
|
||||
{2, {{1, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {2, 2}, {1, 1}}},
|
||||
{1, {{1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{2, {{2, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 2}, {2, 2}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{2, {{1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}}},
|
||||
{2, {{0, 0}, {1, 1}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}}},
|
||||
{2, {{1, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {2, 1}, {1, 1}, {1, 1}, {0, 0}, {2, 2}}},
|
||||
{2, {{0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {1, 1}, {0, 0}, {2, 2}}},
|
||||
{2, {{1, 1}, {1, 1}, {0, 0}, {2, 2}, {1, 2}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {2, 1}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 2}, {0, 0}, {0, 0}, {2, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
|
||||
{2, {{1, 1}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}}},
|
||||
{2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}}},
|
||||
{2, {{1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}}},
|
||||
{3, {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {2, 2}, {1, 1}, {0, 0}, {3, 3}, {1, 1}, {2, 2}, {0, 0}, {3, 3}}},
|
||||
{2, {{1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {2, 2}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{2, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}}},
|
||||
{3, {{1, 1}, {2, 2}, {0, 0}, {3, 3}, {0, 0}, {2, 2}, {1, 1}, {3, 3}, {2, 2}, {0, 0}, {1, 1}, {3, 3}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{3, {{1, 1}, {0, 0}, {2, 2}, {3, 3}, {2, 2}, {0, 0}, {1, 1}, {3, 3}, {0, 0}, {2, 2}, {1, 1}, {3, 3}}},
|
||||
{2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {1, 1}, {2, 2}}},
|
||||
{4, {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {3, 3}, {2, 2}, {1, 1}, {4, 4}, {2, 2}, {3, 3}, {1, 1}, {4, 4}}},
|
||||
{2, {{0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}}},
|
||||
{2, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {2, 2}}},
|
||||
{2, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {1, 1}, {2, 2}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {2, 2}}},
|
||||
{2, {{0, 0}, {2, 1}, {0, 0}, {0, 0}, {1, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{2, {{0, 0}, {0, 0}, {2, 1}, {0, 0}, {0, 0}, {1, 2}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{2, {{1, 1}, {2, 2}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{2, {{0, 0}, {1, 2}, {2, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {2, 2}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}}},
|
||||
{2, {{1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {2, 2}}},
|
||||
{2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {2, 2}}},
|
||||
{2, {{1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 2}, {2, 2}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{2, {{2, 2}, {1, 1}, {1, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{2, {{1, 1}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {1, 2}, {2, 2}, {0, 0}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 1}}},
|
||||
{2, {{0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {1, 2}, {2, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{2, {{0, 0}, {2, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 2}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{2, {{2, 2}, {1, 2}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 1}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
|
||||
{2, {{2, 2}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 2}, {0, 0}, {0, 0}, {2, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {1, 1}, {2, 2}, {2, 2}, {1, 1}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 2}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 2}, {0, 0}, {2, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {1, 2}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 2}, {2, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{0, 0}, {0, 0}, {2, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 2}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 1}, {2, 2}, {1, 2}, {1, 1}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 2}, {0, 0}, {0, 0}, {2, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {1, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {2, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {1, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}}},
|
||||
{2, {{0, 0}, {0, 0}, {0, 0}, {2, 1}, {2, 2}, {1, 1}, {1, 2}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {2, 1}, {1, 2}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {1, 2}, {2, 1}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 2}, {0, 0}, {0, 0}, {2, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 2}, {2, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{0, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}
|
||||
};
|
||||
const ManifoldIndices manifold_table[256] = {{0,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{3,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{3, 3},
|
||||
{0, 0},
|
||||
{3, 3},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{3, 3},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{3,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{3, 3},
|
||||
{1, 1},
|
||||
{3, 3},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{3, 3},
|
||||
{2, 2},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 2},
|
||||
{2, 2},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 2},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{3,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{3, 3},
|
||||
{1, 1},
|
||||
{3, 3},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{3, 3},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 2}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{3,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{3, 3},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{3, 3},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{3, 3}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{2, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 2},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{3,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{3, 3},
|
||||
{0, 0},
|
||||
{3, 3},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{3, 3},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{4,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{3, 3},
|
||||
{4, 4},
|
||||
{1, 1},
|
||||
{4, 4},
|
||||
{3, 3},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{4, 4},
|
||||
{2, 2},
|
||||
{3, 3}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{2, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 2},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{3,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{3, 3},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{3, 3},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{3, 3}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1}}},
|
||||
{3,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{3, 3},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{3, 3},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{3, 3}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{3,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{3, 3},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{3, 3},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{3, 3}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{4,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{3, 3},
|
||||
{4, 4},
|
||||
{3, 3},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{4, 4},
|
||||
{2, 2},
|
||||
{3, 3},
|
||||
{1, 1},
|
||||
{4, 4}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 2},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{2, 2}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 2},
|
||||
{2, 2}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{2, 2}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{2, 2},
|
||||
{1, 1},
|
||||
{1, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{1, 2},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 2},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 2}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{2,
|
||||
{{2, 2},
|
||||
{1, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2}}},
|
||||
{2,
|
||||
{{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 2},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 2},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{1, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 2},
|
||||
{2, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 2},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{2, 2},
|
||||
{1, 2},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{1, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{2, 2},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{1, 2},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 2},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{1, 2},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 1},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{2,
|
||||
{{0, 0},
|
||||
{1, 2},
|
||||
{2, 1},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{2, 2},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{1,
|
||||
{{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}},
|
||||
{0,
|
||||
{{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}}}};
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
#define __MANIFOLD_TABLE_H__
|
||||
|
||||
typedef struct {
|
||||
int comps;
|
||||
int pairs[12][2];
|
||||
int comps;
|
||||
int pairs[12][2];
|
||||
} ManifoldIndices;
|
||||
|
||||
extern const ManifoldIndices manifold_table[256];
|
||||
|
||||
#endif /* __MANIFOLD_TABLE_H__ */
|
||||
#endif /* __MANIFOLD_TABLE_H__ */
|
||||
|
||||
@@ -18,531 +18,2574 @@
|
||||
|
||||
/* number of triangles in each configuration */
|
||||
const int marching_cubes_numtri[TOTCONF] = {
|
||||
0, 1, 1, 2, 1, 2, 4, 3, 1, 4, 2, 3, 2, 3, 3, 2, 1, 2, 4, 3, 4, 3, 5, 4,
|
||||
6, 5, 5, 4, 5, 4, 4, 3, 1, 4, 2, 3, 6, 5, 5, 4, 4, 5, 3, 4, 5, 4, 4, 3,
|
||||
2, 3, 3, 2, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 1, 4, 6, 5, 2, 3, 5, 4,
|
||||
4, 5, 5, 4, 3, 4, 4, 3, 2, 3, 5, 4, 3, 2, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
|
||||
4, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 3, 4, 4, 3, 4, 3, 3, 2,
|
||||
4, 3, 3, 2, 3, 2, 2, 1, 1, 6, 4, 5, 4, 5, 5, 4, 2, 5, 3, 4, 3, 4, 4, 3,
|
||||
4, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 2, 5, 3, 4, 5, 4, 4, 3,
|
||||
3, 4, 2, 3, 4, 3, 3, 2, 3, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
|
||||
2, 5, 5, 4, 3, 4, 4, 3, 3, 4, 4, 3, 2, 3, 3, 2, 3, 4, 4, 3, 4, 3, 3, 2,
|
||||
4, 3, 3, 2, 3, 2, 2, 1, 3, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
|
||||
2, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0
|
||||
};
|
||||
0, 1, 1, 2, 1, 2, 4, 3, 1, 4, 2, 3, 2, 3, 3, 2, 1, 2, 4, 3, 4, 3, 5, 4, 6, 5, 5, 4, 5,
|
||||
4, 4, 3, 1, 4, 2, 3, 6, 5, 5, 4, 4, 5, 3, 4, 5, 4, 4, 3, 2, 3, 3, 2, 5, 4, 4, 3, 5, 4,
|
||||
4, 3, 4, 3, 3, 2, 1, 4, 6, 5, 2, 3, 5, 4, 4, 5, 5, 4, 3, 4, 4, 3, 2, 3, 5, 4, 3, 2, 4,
|
||||
3, 5, 4, 4, 3, 4, 3, 3, 2, 4, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 3, 4, 4, 3,
|
||||
4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, 1, 6, 4, 5, 4, 5, 5, 4, 2, 5, 3, 4, 3, 4, 4, 3, 4,
|
||||
5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 2, 5, 3, 4, 5, 4, 4, 3, 3, 4, 2, 3, 4, 3,
|
||||
3, 2, 3, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, 2, 5, 5, 4, 3, 4, 4, 3, 3, 4, 4,
|
||||
3, 2, 3, 3, 2, 3, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, 3, 4, 4, 3, 4, 3, 3, 2,
|
||||
4, 3, 3, 2, 3, 2, 2, 1, 2, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
|
||||
|
||||
/* table of triangles in each configuration */
|
||||
const int marching_cubes_tris[TOTCONF][MAX_TRIS][3] = {
|
||||
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 0, 8}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 1, 5}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 0, 1}, {4, 1, 5}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 9, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 8, 9}, {0, 9, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{1, 5, 9}, {1, 9, 2}, {1, 2, 4}, {1, 4, 8}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 1, 5}, {0, 5, 9}, {0, 9, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 3, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 8, 5}, {0, 5, 3}, {0, 3, 9}, {0, 9, 4}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 1, 3}, {8, 3, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 0, 1}, {4, 1, 3}, {4, 3, 9}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 5, 3}, {4, 3, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 8, 5}, {0, 5, 3}, {0, 3, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 1}, {4, 1, 3}, {4, 3, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 1, 3}, {0, 3, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 6, 10}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 4, 6}, {8, 6, 10}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 10, 1}, {6, 1, 5}, {6, 5, 8}, {6, 8, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 6, 10}, {4, 10, 1}, {4, 1, 5}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 0, 4}, {10, 4, 9}, {10, 9, 2}, {10, 2, 6}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 10, 8}, {6, 8, 9}, {6, 9, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 0}, {6, 10, 1}, {6, 1, 5}, {6, 5, 9}, {6, 9, 2},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 10, 1}, {6, 1, 5}, {6, 5, 9}, {6, 9, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 0, 5}, {0, 6, 9}, {9, 5, 0}, {6, 10, 3}, {5, 3, 10},
|
||||
{3, 9, 6}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 8, 5}, {10, 5, 3}, {9, 4, 6}, {6, 10, 3}, {6, 3, 9},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 1, 3}, {9, 8, 0}, {9, 0, 6}, {6, 10, 3}, {6, 3, 9},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 6, 10}, {4, 10, 1}, {4, 1, 3}, {4, 3, 9}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 4, 5}, {3, 2, 6}, {3, 6, 10}, {10, 0, 5}, {10, 5, 3},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 10, 8}, {6, 8, 5}, {6, 5, 3}, {6, 3, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 0}, {6, 10, 1}, {6, 1, 3}, {6, 3, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 10, 1}, {6, 1, 3}, {6, 3, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 7, 1}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 0, 10}, {4, 10, 7}, {4, 7, 1}, {4, 1, 8}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 10, 7}, {8, 7, 5}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 0, 10}, {4, 10, 7}, {4, 7, 5}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 2, 4}, {10, 4, 1}, {7, 2, 10}, {1, 9, 7}, {1, 4, 9},
|
||||
{9, 2, 7}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{1, 8, 9}, {2, 0, 10}, {2, 10, 7}, {7, 1, 9}, {7, 9, 2},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 10}, {7, 5, 9}, {7, 9, 2}, {2, 4, 10}, {2, 10, 7},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 7}, {0, 7, 5}, {0, 5, 9}, {0, 9, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 7, 3}, {10, 3, 9}, {10, 9, 5}, {10, 5, 1}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 5, 1}, {4, 0, 10}, {4, 10, 7}, {4, 7, 3}, {4, 3, 9},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 10, 7}, {8, 7, 3}, {8, 3, 9}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 0, 10}, {4, 10, 7}, {4, 7, 3}, {4, 3, 9}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 5, 1}, {4, 1, 10}, {7, 3, 2}, {2, 4, 10}, {2, 10, 7},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 5, 1}, {0, 10, 7}, {0, 7, 3}, {0, 3, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 10}, {4, 10, 7}, {4, 7, 3}, {4, 3, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 7}, {0, 7, 3}, {0, 3, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 6, 7}, {0, 7, 1}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 4, 6}, {8, 6, 7}, {8, 7, 1}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 0, 6}, {8, 6, 7}, {8, 7, 5}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 6, 7}, {4, 7, 5}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{1, 0, 4}, {1, 4, 9}, {2, 6, 7}, {7, 1, 9}, {7, 9, 2},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 7, 1}, {6, 1, 8}, {6, 8, 9}, {6, 9, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 0}, {6, 7, 5}, {6, 5, 9}, {6, 9, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 7, 5}, {6, 5, 9}, {6, 9, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 1, 0}, {6, 7, 3}, {6, 3, 9}, {9, 5, 0}, {9, 0, 6},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 5, 1}, {4, 6, 7}, {4, 7, 3}, {4, 3, 9}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 0, 6}, {8, 6, 7}, {8, 7, 3}, {8, 3, 9}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 6, 7}, {4, 7, 3}, {4, 3, 9}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 4, 5}, {0, 5, 1}, {6, 7, 3}, {6, 3, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 5, 1}, {6, 7, 3}, {6, 3, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 0}, {6, 7, 3}, {6, 3, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 7, 3}, {6, 3, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 2, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 4, 2}, {8, 2, 11}, {8, 11, 6}, {8, 6, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 1, 6}, {6, 1, 11}, {11, 1, 5}, {2, 11, 5}, {2, 5, 8},
|
||||
{6, 2, 8}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 0, 1}, {5, 4, 2}, {5, 2, 11}, {11, 6, 1}, {11, 1, 5},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 4, 9}, {6, 9, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 0, 8}, {6, 8, 9}, {6, 9, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 4, 8}, {6, 8, 1}, {5, 9, 11}, {11, 6, 1}, {11, 1, 5},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 0, 1}, {6, 1, 5}, {6, 5, 9}, {6, 9, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 2, 9}, {6, 9, 5}, {6, 5, 3}, {6, 3, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 2, 9}, {6, 0, 8}, {6, 8, 5}, {6, 5, 3}, {6, 3, 11},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{2, 9, 8}, {1, 3, 11}, {1, 11, 6}, {6, 2, 8}, {6, 8, 1},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 2, 9}, {6, 0, 1}, {6, 1, 3}, {6, 3, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 4, 5}, {6, 5, 3}, {6, 3, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 0, 8}, {6, 8, 5}, {6, 5, 3}, {6, 3, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 4, 8}, {6, 8, 1}, {6, 1, 3}, {6, 3, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 0, 1}, {6, 1, 3}, {6, 3, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 0, 2}, {10, 2, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 8, 4}, {10, 4, 2}, {10, 2, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 0, 2}, {11, 10, 1}, {11, 1, 5}, {5, 8, 2}, {5, 2, 11},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 1, 5}, {10, 5, 4}, {10, 4, 2}, {10, 2, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 0, 4}, {10, 4, 9}, {10, 9, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 8, 9}, {10, 9, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 0}, {10, 1, 5}, {10, 5, 9}, {10, 9, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 1, 5}, {10, 5, 9}, {10, 9, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 2, 9}, {0, 9, 5}, {3, 11, 10}, {10, 0, 5}, {10, 5, 3},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 2, 9}, {10, 8, 5}, {10, 5, 3}, {10, 3, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 0, 2}, {8, 2, 9}, {10, 1, 3}, {10, 3, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 2, 9}, {10, 1, 3}, {10, 3, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 0, 4}, {10, 4, 5}, {10, 5, 3}, {10, 3, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 8, 5}, {10, 5, 3}, {10, 3, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 0}, {10, 1, 3}, {10, 3, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 1, 3}, {10, 3, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{1, 10, 6}, {1, 6, 2}, {1, 2, 11}, {1, 11, 7}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 6}, {7, 1, 8}, {7, 8, 4}, {7, 4, 2}, {7, 2, 11},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 10, 6}, {8, 6, 2}, {11, 7, 5}, {5, 8, 2}, {5, 2, 11},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 6}, {7, 5, 4}, {7, 4, 2}, {7, 2, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 6, 4}, {9, 11, 7}, {9, 7, 1}, {1, 10, 4}, {1, 4, 9},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 6}, {7, 1, 8}, {7, 8, 9}, {7, 9, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 10}, {4, 10, 6}, {7, 5, 9}, {7, 9, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 6}, {7, 5, 9}, {7, 9, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 1, 10}, {5, 10, 6}, {5, 6, 2}, {5, 2, 9}, {7, 3, 11},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 6}, {8, 5, 1}, {4, 2, 9}, {7, 3, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 10, 6}, {8, 6, 2}, {8, 2, 9}, {7, 3, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 6}, {4, 2, 9}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 6, 4}, {10, 4, 5}, {10, 5, 1}, {7, 3, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 6}, {8, 5, 1}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 10}, {4, 10, 6}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 6}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 1, 0}, {7, 0, 2}, {7, 2, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 1, 8}, {7, 8, 4}, {7, 4, 2}, {7, 2, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 5, 8}, {7, 8, 0}, {7, 0, 2}, {7, 2, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 5, 4}, {7, 4, 2}, {7, 2, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 1, 0}, {7, 0, 4}, {7, 4, 9}, {7, 9, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 1, 8}, {7, 8, 9}, {7, 9, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 0}, {7, 5, 9}, {7, 9, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 5, 9}, {7, 9, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 1, 0}, {5, 0, 2}, {5, 2, 9}, {7, 3, 11}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 5, 1}, {4, 2, 9}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 0, 2}, {8, 2, 9}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 2, 9}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 4, 5}, {0, 5, 1}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 5, 1}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 0}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 3, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 11, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 11, 0}, {7, 0, 8}, {0, 11, 4}, {8, 3, 7}, {11, 3, 4},
|
||||
{3, 8, 4}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 1, 7}, {8, 7, 11}, {8, 11, 3}, {8, 3, 5}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 1, 7}, {0, 7, 11}, {3, 5, 4}, {4, 0, 11}, {4, 11, 3},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 9, 3}, {4, 3, 7}, {4, 7, 11}, {4, 11, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 9, 3}, {8, 3, 7}, {11, 2, 0}, {0, 8, 7}, {0, 7, 11},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 9, 3}, {4, 8, 1}, {4, 1, 7}, {4, 7, 11}, {4, 11, 2},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 9, 3}, {0, 1, 7}, {0, 7, 11}, {0, 11, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 7, 11}, {5, 11, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 5, 7}, {11, 9, 4}, {11, 4, 0}, {0, 8, 7}, {0, 7, 11},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 1, 7}, {8, 7, 11}, {8, 11, 9}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 0, 1}, {4, 1, 7}, {4, 7, 11}, {4, 11, 9}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 5, 7}, {4, 7, 11}, {4, 11, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 8, 5}, {0, 5, 7}, {0, 7, 11}, {0, 11, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 1}, {4, 1, 7}, {4, 7, 11}, {4, 11, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 1, 7}, {0, 7, 11}, {0, 11, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 6, 11}, {0, 11, 3}, {0, 3, 7}, {0, 7, 10}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 10, 8}, {4, 6, 11}, {4, 11, 3}, {3, 7, 8}, {3, 8, 4},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 1, 7}, {5, 8, 0}, {5, 0, 6}, {5, 6, 11}, {5, 11, 3},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 1, 7}, {5, 4, 6}, {5, 6, 11}, {5, 11, 3}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 10, 0}, {7, 0, 4}, {7, 4, 9}, {7, 9, 3}, {6, 11, 2},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 10, 8}, {7, 8, 9}, {7, 9, 3}, {6, 11, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 0}, {10, 1, 7}, {5, 9, 3}, {6, 11, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 1, 7}, {5, 9, 3}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 7, 10}, {5, 10, 0}, {6, 11, 9}, {9, 5, 0}, {9, 0, 6},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 8, 5}, {10, 5, 7}, {4, 6, 11}, {4, 11, 9}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 1, 7}, {8, 0, 6}, {8, 6, 11}, {8, 11, 9}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 1, 7}, {4, 6, 11}, {4, 11, 9}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 0, 4}, {10, 4, 5}, {10, 5, 7}, {6, 11, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 8, 5}, {10, 5, 7}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 0}, {10, 1, 7}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 1, 7}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{1, 10, 11}, {1, 11, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 11}, {3, 1, 8}, {3, 8, 4}, {4, 0, 11}, {4, 11, 3},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 8, 10}, {5, 10, 11}, {5, 11, 3}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 4, 0}, {5, 0, 10}, {5, 10, 11}, {5, 11, 3}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{9, 3, 1}, {10, 11, 2}, {10, 2, 4}, {4, 9, 1}, {4, 1, 10},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{1, 8, 9}, {1, 9, 3}, {0, 10, 11}, {0, 11, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 9, 3}, {4, 8, 10}, {4, 10, 11}, {4, 11, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 9, 3}, {0, 10, 11}, {0, 11, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 1, 10}, {5, 10, 11}, {5, 11, 9}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 5, 1}, {4, 0, 10}, {4, 10, 11}, {4, 11, 9}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 10, 11}, {8, 11, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 0, 10}, {4, 10, 11}, {4, 11, 9}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 5, 1}, {4, 1, 10}, {4, 10, 11}, {4, 11, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 5, 1}, {0, 10, 11}, {0, 11, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 10}, {4, 10, 11}, {4, 11, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 11}, {0, 11, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{1, 0, 6}, {1, 6, 11}, {1, 11, 3}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{1, 8, 4}, {1, 4, 6}, {1, 6, 11}, {1, 11, 3}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 8, 0}, {5, 0, 6}, {5, 6, 11}, {5, 11, 3}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 4, 6}, {5, 6, 11}, {5, 11, 3}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{1, 0, 4}, {1, 4, 9}, {1, 9, 3}, {6, 11, 2}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{1, 8, 9}, {1, 9, 3}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 0}, {5, 9, 3}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 9, 3}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 1, 0}, {5, 0, 6}, {5, 6, 11}, {5, 11, 9}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 5, 1}, {4, 6, 11}, {4, 11, 9}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 0, 6}, {8, 6, 11}, {8, 11, 9}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 6, 11}, {4, 11, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 4, 5}, {0, 5, 1}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 5, 1}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 0}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 11, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 6, 2}, {7, 2, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 6, 0}, {7, 0, 8}, {4, 2, 3}, {3, 7, 8}, {3, 8, 4},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{1, 7, 6}, {2, 3, 5}, {2, 5, 8}, {8, 1, 6}, {8, 6, 2},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 0, 1}, {6, 1, 7}, {5, 4, 2}, {5, 2, 3}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 6, 4}, {7, 4, 9}, {7, 9, 3}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 6, 0}, {7, 0, 8}, {7, 8, 9}, {7, 9, 3}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 4, 8}, {6, 8, 1}, {6, 1, 7}, {5, 9, 3}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 0, 1}, {6, 1, 7}, {5, 9, 3}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 7, 6}, {5, 6, 2}, {5, 2, 9}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 0, 8}, {6, 8, 5}, {6, 5, 7}, {4, 2, 9}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 1, 7}, {8, 7, 6}, {8, 6, 2}, {8, 2, 9}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 0, 1}, {6, 1, 7}, {4, 2, 9}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 4, 5}, {6, 5, 7}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 0, 8}, {6, 8, 5}, {6, 5, 7}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 4, 8}, {6, 8, 1}, {6, 1, 7}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{6, 0, 1}, {6, 1, 7}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 10, 0}, {7, 0, 2}, {7, 2, 3}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 10, 8}, {7, 8, 4}, {7, 4, 2}, {7, 2, 3}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 1, 7}, {5, 8, 0}, {5, 0, 2}, {5, 2, 3}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 1, 7}, {5, 4, 2}, {5, 2, 3}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 10, 0}, {7, 0, 4}, {7, 4, 9}, {7, 9, 3}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{7, 10, 8}, {7, 8, 9}, {7, 9, 3}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 0}, {10, 1, 7}, {5, 9, 3}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 1, 7}, {5, 9, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 7, 10}, {5, 10, 0}, {5, 0, 2}, {5, 2, 9}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 8, 5}, {10, 5, 7}, {4, 2, 9}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 1, 7}, {8, 0, 2}, {8, 2, 9}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 1, 7}, {4, 2, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 0, 4}, {10, 4, 5}, {10, 5, 7}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 8, 5}, {10, 5, 7}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 0}, {10, 1, 7}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 1, 7}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{1, 10, 6}, {1, 6, 2}, {1, 2, 3}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 6}, {1, 8, 4}, {1, 4, 2}, {1, 2, 3}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 8, 10}, {5, 10, 6}, {5, 6, 2}, {5, 2, 3}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 6}, {5, 4, 2}, {5, 2, 3}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{1, 10, 6}, {1, 6, 4}, {1, 4, 9}, {1, 9, 3}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 6}, {1, 8, 9}, {1, 9, 3}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 10}, {4, 10, 6}, {5, 9, 3}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 6}, {5, 9, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 1, 10}, {5, 10, 6}, {5, 6, 2}, {5, 2, 9}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 6}, {8, 5, 1}, {4, 2, 9}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 10, 6}, {8, 6, 2}, {8, 2, 9}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 6}, {4, 2, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{10, 6, 4}, {10, 4, 5}, {10, 5, 1}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 6}, {8, 5, 1}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 10}, {4, 10, 6}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 10, 6}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{1, 0, 2}, {1, 2, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{1, 8, 4}, {1, 4, 2}, {1, 2, 3}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 8, 0}, {5, 0, 2}, {5, 2, 3}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 4, 2}, {5, 2, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{1, 0, 4}, {1, 4, 9}, {1, 9, 3}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{1, 8, 9}, {1, 9, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 0}, {5, 9, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 9, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{5, 1, 0}, {5, 0, 2}, {5, 2, 9}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 5, 1}, {4, 2, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 0, 2}, {8, 2, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 2, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 4, 5}, {0, 5, 1}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{8, 5, 1}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{4, 8, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}
|
||||
};
|
||||
const int marching_cubes_tris[TOTCONF][MAX_TRIS][3] = {{{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 0, 8},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 1, 5},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 0, 1},
|
||||
{4, 1, 5},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 9, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 8, 9},
|
||||
{0, 9, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{1, 5, 9},
|
||||
{1, 9, 2},
|
||||
{1, 2, 4},
|
||||
{1, 4, 8},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 1, 5},
|
||||
{0, 5, 9},
|
||||
{0, 9, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 3, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 8, 5},
|
||||
{0, 5, 3},
|
||||
{0, 3, 9},
|
||||
{0, 9, 4},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 1, 3},
|
||||
{8, 3, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 0, 1},
|
||||
{4, 1, 3},
|
||||
{4, 3, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 5, 3},
|
||||
{4, 3, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 8, 5},
|
||||
{0, 5, 3},
|
||||
{0, 3, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 1},
|
||||
{4, 1, 3},
|
||||
{4, 3, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 1, 3},
|
||||
{0, 3, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 6, 10},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 4, 6},
|
||||
{8, 6, 10},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 10, 1},
|
||||
{6, 1, 5},
|
||||
{6, 5, 8},
|
||||
{6, 8, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 6, 10},
|
||||
{4, 10, 1},
|
||||
{4, 1, 5},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 0, 4},
|
||||
{10, 4, 9},
|
||||
{10, 9, 2},
|
||||
{10, 2, 6},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 10, 8},
|
||||
{6, 8, 9},
|
||||
{6, 9, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 0},
|
||||
{6, 10, 1},
|
||||
{6, 1, 5},
|
||||
{6, 5, 9},
|
||||
{6, 9, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 10, 1},
|
||||
{6, 1, 5},
|
||||
{6, 5, 9},
|
||||
{6, 9, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 0, 5},
|
||||
{0, 6, 9},
|
||||
{9, 5, 0},
|
||||
{6, 10, 3},
|
||||
{5, 3, 10},
|
||||
{3, 9, 6},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 8, 5},
|
||||
{10, 5, 3},
|
||||
{9, 4, 6},
|
||||
{6, 10, 3},
|
||||
{6, 3, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 1, 3},
|
||||
{9, 8, 0},
|
||||
{9, 0, 6},
|
||||
{6, 10, 3},
|
||||
{6, 3, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 6, 10},
|
||||
{4, 10, 1},
|
||||
{4, 1, 3},
|
||||
{4, 3, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 4, 5},
|
||||
{3, 2, 6},
|
||||
{3, 6, 10},
|
||||
{10, 0, 5},
|
||||
{10, 5, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 10, 8},
|
||||
{6, 8, 5},
|
||||
{6, 5, 3},
|
||||
{6, 3, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 0},
|
||||
{6, 10, 1},
|
||||
{6, 1, 3},
|
||||
{6, 3, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 10, 1},
|
||||
{6, 1, 3},
|
||||
{6, 3, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 7, 1},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 0, 10},
|
||||
{4, 10, 7},
|
||||
{4, 7, 1},
|
||||
{4, 1, 8},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 10, 7},
|
||||
{8, 7, 5},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 0, 10},
|
||||
{4, 10, 7},
|
||||
{4, 7, 5},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 2, 4},
|
||||
{10, 4, 1},
|
||||
{7, 2, 10},
|
||||
{1, 9, 7},
|
||||
{1, 4, 9},
|
||||
{9, 2, 7},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{1, 8, 9},
|
||||
{2, 0, 10},
|
||||
{2, 10, 7},
|
||||
{7, 1, 9},
|
||||
{7, 9, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 10},
|
||||
{7, 5, 9},
|
||||
{7, 9, 2},
|
||||
{2, 4, 10},
|
||||
{2, 10, 7},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 7},
|
||||
{0, 7, 5},
|
||||
{0, 5, 9},
|
||||
{0, 9, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 7, 3},
|
||||
{10, 3, 9},
|
||||
{10, 9, 5},
|
||||
{10, 5, 1},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 5, 1},
|
||||
{4, 0, 10},
|
||||
{4, 10, 7},
|
||||
{4, 7, 3},
|
||||
{4, 3, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 10, 7},
|
||||
{8, 7, 3},
|
||||
{8, 3, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 0, 10},
|
||||
{4, 10, 7},
|
||||
{4, 7, 3},
|
||||
{4, 3, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 5, 1},
|
||||
{4, 1, 10},
|
||||
{7, 3, 2},
|
||||
{2, 4, 10},
|
||||
{2, 10, 7},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 5, 1},
|
||||
{0, 10, 7},
|
||||
{0, 7, 3},
|
||||
{0, 3, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 10},
|
||||
{4, 10, 7},
|
||||
{4, 7, 3},
|
||||
{4, 3, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 7},
|
||||
{0, 7, 3},
|
||||
{0, 3, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 6, 7},
|
||||
{0, 7, 1},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 4, 6},
|
||||
{8, 6, 7},
|
||||
{8, 7, 1},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 0, 6},
|
||||
{8, 6, 7},
|
||||
{8, 7, 5},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 6, 7},
|
||||
{4, 7, 5},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{1, 0, 4},
|
||||
{1, 4, 9},
|
||||
{2, 6, 7},
|
||||
{7, 1, 9},
|
||||
{7, 9, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 7, 1},
|
||||
{6, 1, 8},
|
||||
{6, 8, 9},
|
||||
{6, 9, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 0},
|
||||
{6, 7, 5},
|
||||
{6, 5, 9},
|
||||
{6, 9, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 7, 5},
|
||||
{6, 5, 9},
|
||||
{6, 9, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 1, 0},
|
||||
{6, 7, 3},
|
||||
{6, 3, 9},
|
||||
{9, 5, 0},
|
||||
{9, 0, 6},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 5, 1},
|
||||
{4, 6, 7},
|
||||
{4, 7, 3},
|
||||
{4, 3, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 0, 6},
|
||||
{8, 6, 7},
|
||||
{8, 7, 3},
|
||||
{8, 3, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 6, 7},
|
||||
{4, 7, 3},
|
||||
{4, 3, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 4, 5},
|
||||
{0, 5, 1},
|
||||
{6, 7, 3},
|
||||
{6, 3, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 5, 1},
|
||||
{6, 7, 3},
|
||||
{6, 3, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 0},
|
||||
{6, 7, 3},
|
||||
{6, 3, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 7, 3},
|
||||
{6, 3, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 2, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 4, 2},
|
||||
{8, 2, 11},
|
||||
{8, 11, 6},
|
||||
{8, 6, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 1, 6},
|
||||
{6, 1, 11},
|
||||
{11, 1, 5},
|
||||
{2, 11, 5},
|
||||
{2, 5, 8},
|
||||
{6, 2, 8},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 0, 1},
|
||||
{5, 4, 2},
|
||||
{5, 2, 11},
|
||||
{11, 6, 1},
|
||||
{11, 1, 5},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 4, 9},
|
||||
{6, 9, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 0, 8},
|
||||
{6, 8, 9},
|
||||
{6, 9, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 4, 8},
|
||||
{6, 8, 1},
|
||||
{5, 9, 11},
|
||||
{11, 6, 1},
|
||||
{11, 1, 5},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 0, 1},
|
||||
{6, 1, 5},
|
||||
{6, 5, 9},
|
||||
{6, 9, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 2, 9},
|
||||
{6, 9, 5},
|
||||
{6, 5, 3},
|
||||
{6, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 2, 9},
|
||||
{6, 0, 8},
|
||||
{6, 8, 5},
|
||||
{6, 5, 3},
|
||||
{6, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{2, 9, 8},
|
||||
{1, 3, 11},
|
||||
{1, 11, 6},
|
||||
{6, 2, 8},
|
||||
{6, 8, 1},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 2, 9},
|
||||
{6, 0, 1},
|
||||
{6, 1, 3},
|
||||
{6, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 4, 5},
|
||||
{6, 5, 3},
|
||||
{6, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 0, 8},
|
||||
{6, 8, 5},
|
||||
{6, 5, 3},
|
||||
{6, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 4, 8},
|
||||
{6, 8, 1},
|
||||
{6, 1, 3},
|
||||
{6, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 0, 1},
|
||||
{6, 1, 3},
|
||||
{6, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 0, 2},
|
||||
{10, 2, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 8, 4},
|
||||
{10, 4, 2},
|
||||
{10, 2, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 0, 2},
|
||||
{11, 10, 1},
|
||||
{11, 1, 5},
|
||||
{5, 8, 2},
|
||||
{5, 2, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 1, 5},
|
||||
{10, 5, 4},
|
||||
{10, 4, 2},
|
||||
{10, 2, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 0, 4},
|
||||
{10, 4, 9},
|
||||
{10, 9, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 8, 9},
|
||||
{10, 9, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 0},
|
||||
{10, 1, 5},
|
||||
{10, 5, 9},
|
||||
{10, 9, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 1, 5},
|
||||
{10, 5, 9},
|
||||
{10, 9, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 2, 9},
|
||||
{0, 9, 5},
|
||||
{3, 11, 10},
|
||||
{10, 0, 5},
|
||||
{10, 5, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 2, 9},
|
||||
{10, 8, 5},
|
||||
{10, 5, 3},
|
||||
{10, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 0, 2},
|
||||
{8, 2, 9},
|
||||
{10, 1, 3},
|
||||
{10, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 2, 9},
|
||||
{10, 1, 3},
|
||||
{10, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 0, 4},
|
||||
{10, 4, 5},
|
||||
{10, 5, 3},
|
||||
{10, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 8, 5},
|
||||
{10, 5, 3},
|
||||
{10, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 0},
|
||||
{10, 1, 3},
|
||||
{10, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 1, 3},
|
||||
{10, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{1, 10, 6},
|
||||
{1, 6, 2},
|
||||
{1, 2, 11},
|
||||
{1, 11, 7},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 6},
|
||||
{7, 1, 8},
|
||||
{7, 8, 4},
|
||||
{7, 4, 2},
|
||||
{7, 2, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 10, 6},
|
||||
{8, 6, 2},
|
||||
{11, 7, 5},
|
||||
{5, 8, 2},
|
||||
{5, 2, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 6},
|
||||
{7, 5, 4},
|
||||
{7, 4, 2},
|
||||
{7, 2, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 6, 4},
|
||||
{9, 11, 7},
|
||||
{9, 7, 1},
|
||||
{1, 10, 4},
|
||||
{1, 4, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 6},
|
||||
{7, 1, 8},
|
||||
{7, 8, 9},
|
||||
{7, 9, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 10},
|
||||
{4, 10, 6},
|
||||
{7, 5, 9},
|
||||
{7, 9, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 6},
|
||||
{7, 5, 9},
|
||||
{7, 9, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 1, 10},
|
||||
{5, 10, 6},
|
||||
{5, 6, 2},
|
||||
{5, 2, 9},
|
||||
{7, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 6},
|
||||
{8, 5, 1},
|
||||
{4, 2, 9},
|
||||
{7, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 10, 6},
|
||||
{8, 6, 2},
|
||||
{8, 2, 9},
|
||||
{7, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 6},
|
||||
{4, 2, 9},
|
||||
{7, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 6, 4},
|
||||
{10, 4, 5},
|
||||
{10, 5, 1},
|
||||
{7, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 6},
|
||||
{8, 5, 1},
|
||||
{7, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 10},
|
||||
{4, 10, 6},
|
||||
{7, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 6},
|
||||
{7, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 1, 0},
|
||||
{7, 0, 2},
|
||||
{7, 2, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 1, 8},
|
||||
{7, 8, 4},
|
||||
{7, 4, 2},
|
||||
{7, 2, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 5, 8},
|
||||
{7, 8, 0},
|
||||
{7, 0, 2},
|
||||
{7, 2, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 5, 4},
|
||||
{7, 4, 2},
|
||||
{7, 2, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 1, 0},
|
||||
{7, 0, 4},
|
||||
{7, 4, 9},
|
||||
{7, 9, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 1, 8},
|
||||
{7, 8, 9},
|
||||
{7, 9, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 0},
|
||||
{7, 5, 9},
|
||||
{7, 9, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 5, 9},
|
||||
{7, 9, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 1, 0},
|
||||
{5, 0, 2},
|
||||
{5, 2, 9},
|
||||
{7, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 5, 1},
|
||||
{4, 2, 9},
|
||||
{7, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 0, 2},
|
||||
{8, 2, 9},
|
||||
{7, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 2, 9},
|
||||
{7, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 4, 5},
|
||||
{0, 5, 1},
|
||||
{7, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 5, 1},
|
||||
{7, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 0},
|
||||
{7, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 3, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 11, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 11, 0},
|
||||
{7, 0, 8},
|
||||
{0, 11, 4},
|
||||
{8, 3, 7},
|
||||
{11, 3, 4},
|
||||
{3, 8, 4},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 1, 7},
|
||||
{8, 7, 11},
|
||||
{8, 11, 3},
|
||||
{8, 3, 5},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 1, 7},
|
||||
{0, 7, 11},
|
||||
{3, 5, 4},
|
||||
{4, 0, 11},
|
||||
{4, 11, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 9, 3},
|
||||
{4, 3, 7},
|
||||
{4, 7, 11},
|
||||
{4, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 9, 3},
|
||||
{8, 3, 7},
|
||||
{11, 2, 0},
|
||||
{0, 8, 7},
|
||||
{0, 7, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 9, 3},
|
||||
{4, 8, 1},
|
||||
{4, 1, 7},
|
||||
{4, 7, 11},
|
||||
{4, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 9, 3},
|
||||
{0, 1, 7},
|
||||
{0, 7, 11},
|
||||
{0, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 7, 11},
|
||||
{5, 11, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 5, 7},
|
||||
{11, 9, 4},
|
||||
{11, 4, 0},
|
||||
{0, 8, 7},
|
||||
{0, 7, 11},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 1, 7},
|
||||
{8, 7, 11},
|
||||
{8, 11, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 0, 1},
|
||||
{4, 1, 7},
|
||||
{4, 7, 11},
|
||||
{4, 11, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 5, 7},
|
||||
{4, 7, 11},
|
||||
{4, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 8, 5},
|
||||
{0, 5, 7},
|
||||
{0, 7, 11},
|
||||
{0, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 1},
|
||||
{4, 1, 7},
|
||||
{4, 7, 11},
|
||||
{4, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 1, 7},
|
||||
{0, 7, 11},
|
||||
{0, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 6, 11},
|
||||
{0, 11, 3},
|
||||
{0, 3, 7},
|
||||
{0, 7, 10},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 10, 8},
|
||||
{4, 6, 11},
|
||||
{4, 11, 3},
|
||||
{3, 7, 8},
|
||||
{3, 8, 4},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 1, 7},
|
||||
{5, 8, 0},
|
||||
{5, 0, 6},
|
||||
{5, 6, 11},
|
||||
{5, 11, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 1, 7},
|
||||
{5, 4, 6},
|
||||
{5, 6, 11},
|
||||
{5, 11, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 10, 0},
|
||||
{7, 0, 4},
|
||||
{7, 4, 9},
|
||||
{7, 9, 3},
|
||||
{6, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 10, 8},
|
||||
{7, 8, 9},
|
||||
{7, 9, 3},
|
||||
{6, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 0},
|
||||
{10, 1, 7},
|
||||
{5, 9, 3},
|
||||
{6, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 1, 7},
|
||||
{5, 9, 3},
|
||||
{6, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 7, 10},
|
||||
{5, 10, 0},
|
||||
{6, 11, 9},
|
||||
{9, 5, 0},
|
||||
{9, 0, 6},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 8, 5},
|
||||
{10, 5, 7},
|
||||
{4, 6, 11},
|
||||
{4, 11, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 1, 7},
|
||||
{8, 0, 6},
|
||||
{8, 6, 11},
|
||||
{8, 11, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 1, 7},
|
||||
{4, 6, 11},
|
||||
{4, 11, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 0, 4},
|
||||
{10, 4, 5},
|
||||
{10, 5, 7},
|
||||
{6, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 8, 5},
|
||||
{10, 5, 7},
|
||||
{6, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 0},
|
||||
{10, 1, 7},
|
||||
{6, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 1, 7},
|
||||
{6, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{1, 10, 11},
|
||||
{1, 11, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 11},
|
||||
{3, 1, 8},
|
||||
{3, 8, 4},
|
||||
{4, 0, 11},
|
||||
{4, 11, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 8, 10},
|
||||
{5, 10, 11},
|
||||
{5, 11, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 4, 0},
|
||||
{5, 0, 10},
|
||||
{5, 10, 11},
|
||||
{5, 11, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{9, 3, 1},
|
||||
{10, 11, 2},
|
||||
{10, 2, 4},
|
||||
{4, 9, 1},
|
||||
{4, 1, 10},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{1, 8, 9},
|
||||
{1, 9, 3},
|
||||
{0, 10, 11},
|
||||
{0, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 9, 3},
|
||||
{4, 8, 10},
|
||||
{4, 10, 11},
|
||||
{4, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 9, 3},
|
||||
{0, 10, 11},
|
||||
{0, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 1, 10},
|
||||
{5, 10, 11},
|
||||
{5, 11, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 5, 1},
|
||||
{4, 0, 10},
|
||||
{4, 10, 11},
|
||||
{4, 11, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 10, 11},
|
||||
{8, 11, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 0, 10},
|
||||
{4, 10, 11},
|
||||
{4, 11, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 5, 1},
|
||||
{4, 1, 10},
|
||||
{4, 10, 11},
|
||||
{4, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 5, 1},
|
||||
{0, 10, 11},
|
||||
{0, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 10},
|
||||
{4, 10, 11},
|
||||
{4, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 11},
|
||||
{0, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{1, 0, 6},
|
||||
{1, 6, 11},
|
||||
{1, 11, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{1, 8, 4},
|
||||
{1, 4, 6},
|
||||
{1, 6, 11},
|
||||
{1, 11, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 8, 0},
|
||||
{5, 0, 6},
|
||||
{5, 6, 11},
|
||||
{5, 11, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 4, 6},
|
||||
{5, 6, 11},
|
||||
{5, 11, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{1, 0, 4},
|
||||
{1, 4, 9},
|
||||
{1, 9, 3},
|
||||
{6, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{1, 8, 9},
|
||||
{1, 9, 3},
|
||||
{6, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 0},
|
||||
{5, 9, 3},
|
||||
{6, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 9, 3},
|
||||
{6, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 1, 0},
|
||||
{5, 0, 6},
|
||||
{5, 6, 11},
|
||||
{5, 11, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 5, 1},
|
||||
{4, 6, 11},
|
||||
{4, 11, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 0, 6},
|
||||
{8, 6, 11},
|
||||
{8, 11, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 6, 11},
|
||||
{4, 11, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 4, 5},
|
||||
{0, 5, 1},
|
||||
{6, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 5, 1},
|
||||
{6, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 0},
|
||||
{6, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 11, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 6, 2},
|
||||
{7, 2, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 6, 0},
|
||||
{7, 0, 8},
|
||||
{4, 2, 3},
|
||||
{3, 7, 8},
|
||||
{3, 8, 4},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{1, 7, 6},
|
||||
{2, 3, 5},
|
||||
{2, 5, 8},
|
||||
{8, 1, 6},
|
||||
{8, 6, 2},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 0, 1},
|
||||
{6, 1, 7},
|
||||
{5, 4, 2},
|
||||
{5, 2, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 6, 4},
|
||||
{7, 4, 9},
|
||||
{7, 9, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 6, 0},
|
||||
{7, 0, 8},
|
||||
{7, 8, 9},
|
||||
{7, 9, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 4, 8},
|
||||
{6, 8, 1},
|
||||
{6, 1, 7},
|
||||
{5, 9, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 0, 1},
|
||||
{6, 1, 7},
|
||||
{5, 9, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 7, 6},
|
||||
{5, 6, 2},
|
||||
{5, 2, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 0, 8},
|
||||
{6, 8, 5},
|
||||
{6, 5, 7},
|
||||
{4, 2, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 1, 7},
|
||||
{8, 7, 6},
|
||||
{8, 6, 2},
|
||||
{8, 2, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 0, 1},
|
||||
{6, 1, 7},
|
||||
{4, 2, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 4, 5},
|
||||
{6, 5, 7},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 0, 8},
|
||||
{6, 8, 5},
|
||||
{6, 5, 7},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 4, 8},
|
||||
{6, 8, 1},
|
||||
{6, 1, 7},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{6, 0, 1},
|
||||
{6, 1, 7},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 10, 0},
|
||||
{7, 0, 2},
|
||||
{7, 2, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 10, 8},
|
||||
{7, 8, 4},
|
||||
{7, 4, 2},
|
||||
{7, 2, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 1, 7},
|
||||
{5, 8, 0},
|
||||
{5, 0, 2},
|
||||
{5, 2, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 1, 7},
|
||||
{5, 4, 2},
|
||||
{5, 2, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 10, 0},
|
||||
{7, 0, 4},
|
||||
{7, 4, 9},
|
||||
{7, 9, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{7, 10, 8},
|
||||
{7, 8, 9},
|
||||
{7, 9, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 0},
|
||||
{10, 1, 7},
|
||||
{5, 9, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 1, 7},
|
||||
{5, 9, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 7, 10},
|
||||
{5, 10, 0},
|
||||
{5, 0, 2},
|
||||
{5, 2, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 8, 5},
|
||||
{10, 5, 7},
|
||||
{4, 2, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 1, 7},
|
||||
{8, 0, 2},
|
||||
{8, 2, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 1, 7},
|
||||
{4, 2, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 0, 4},
|
||||
{10, 4, 5},
|
||||
{10, 5, 7},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 8, 5},
|
||||
{10, 5, 7},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 0},
|
||||
{10, 1, 7},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 1, 7},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{1, 10, 6},
|
||||
{1, 6, 2},
|
||||
{1, 2, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 6},
|
||||
{1, 8, 4},
|
||||
{1, 4, 2},
|
||||
{1, 2, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 8, 10},
|
||||
{5, 10, 6},
|
||||
{5, 6, 2},
|
||||
{5, 2, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 6},
|
||||
{5, 4, 2},
|
||||
{5, 2, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{1, 10, 6},
|
||||
{1, 6, 4},
|
||||
{1, 4, 9},
|
||||
{1, 9, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 6},
|
||||
{1, 8, 9},
|
||||
{1, 9, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 10},
|
||||
{4, 10, 6},
|
||||
{5, 9, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 6},
|
||||
{5, 9, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 1, 10},
|
||||
{5, 10, 6},
|
||||
{5, 6, 2},
|
||||
{5, 2, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 6},
|
||||
{8, 5, 1},
|
||||
{4, 2, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 10, 6},
|
||||
{8, 6, 2},
|
||||
{8, 2, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 6},
|
||||
{4, 2, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{10, 6, 4},
|
||||
{10, 4, 5},
|
||||
{10, 5, 1},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 6},
|
||||
{8, 5, 1},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 10},
|
||||
{4, 10, 6},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 10, 6},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{1, 0, 2},
|
||||
{1, 2, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{1, 8, 4},
|
||||
{1, 4, 2},
|
||||
{1, 2, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 8, 0},
|
||||
{5, 0, 2},
|
||||
{5, 2, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 4, 2},
|
||||
{5, 2, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{1, 0, 4},
|
||||
{1, 4, 9},
|
||||
{1, 9, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{1, 8, 9},
|
||||
{1, 9, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 0},
|
||||
{5, 9, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 9, 3},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{5, 1, 0},
|
||||
{5, 0, 2},
|
||||
{5, 2, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 5, 1},
|
||||
{4, 2, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 0, 2},
|
||||
{8, 2, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 2, 9},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 4, 5},
|
||||
{0, 5, 1},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{8, 5, 1},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{4, 8, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}}};
|
||||
|
||||
@@ -34,2063 +34,2085 @@
|
||||
|
||||
#if DC_DEBUG
|
||||
/* enable debug printfs */
|
||||
#define dc_printf printf
|
||||
# define dc_printf printf
|
||||
#else
|
||||
/* disable debug printfs */
|
||||
#define dc_printf(...) do {} while (0)
|
||||
# define dc_printf(...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
Octree::Octree(ModelReader *mr,
|
||||
DualConAllocOutput alloc_output_func,
|
||||
DualConAddVert add_vert_func,
|
||||
DualConAddQuad add_quad_func,
|
||||
DualConFlags flags, DualConMode dualcon_mode, int depth,
|
||||
float threshold, float sharpness)
|
||||
: use_flood_fill(flags & DUALCON_FLOOD_FILL),
|
||||
/* note on `use_manifold':
|
||||
DualConFlags flags,
|
||||
DualConMode dualcon_mode,
|
||||
int depth,
|
||||
float threshold,
|
||||
float sharpness)
|
||||
: use_flood_fill(flags & DUALCON_FLOOD_FILL),
|
||||
/* note on `use_manifold':
|
||||
|
||||
After playing around with this option, the only case I could
|
||||
find where this option gives different results is on
|
||||
relatively thin corners. Sometimes along these corners two
|
||||
vertices from separate sides will be placed in the same
|
||||
position, so hole gets filled with a 5-sided face, where two
|
||||
of those vertices are in the same 3D location. If
|
||||
`use_manifold' is disabled, then the modifier doesn't
|
||||
generate two separate vertices so the results end up as all
|
||||
quads.
|
||||
After playing around with this option, the only case I could
|
||||
find where this option gives different results is on
|
||||
relatively thin corners. Sometimes along these corners two
|
||||
vertices from separate sides will be placed in the same
|
||||
position, so hole gets filled with a 5-sided face, where two
|
||||
of those vertices are in the same 3D location. If
|
||||
`use_manifold' is disabled, then the modifier doesn't
|
||||
generate two separate vertices so the results end up as all
|
||||
quads.
|
||||
|
||||
Since the results are just as good with all quads, there
|
||||
doesn't seem any reason to allow this to be toggled in
|
||||
Blender. -nicholasbishop
|
||||
*/
|
||||
use_manifold(false),
|
||||
hermite_num(sharpness),
|
||||
mode(dualcon_mode),
|
||||
alloc_output(alloc_output_func),
|
||||
add_vert(add_vert_func),
|
||||
add_quad(add_quad_func)
|
||||
Since the results are just as good with all quads, there
|
||||
doesn't seem any reason to allow this to be toggled in
|
||||
Blender. -nicholasbishop
|
||||
*/
|
||||
use_manifold(false),
|
||||
hermite_num(sharpness),
|
||||
mode(dualcon_mode),
|
||||
alloc_output(alloc_output_func),
|
||||
add_vert(add_vert_func),
|
||||
add_quad(add_quad_func)
|
||||
{
|
||||
thresh = threshold;
|
||||
reader = mr;
|
||||
dimen = 1 << GRID_DIMENSION;
|
||||
range = reader->getBoundingBox(origin);
|
||||
nodeCount = nodeSpace = 0;
|
||||
maxDepth = depth;
|
||||
mindimen = (dimen >> maxDepth);
|
||||
minshift = (GRID_DIMENSION - maxDepth);
|
||||
buildTable();
|
||||
thresh = threshold;
|
||||
reader = mr;
|
||||
dimen = 1 << GRID_DIMENSION;
|
||||
range = reader->getBoundingBox(origin);
|
||||
nodeCount = nodeSpace = 0;
|
||||
maxDepth = depth;
|
||||
mindimen = (dimen >> maxDepth);
|
||||
minshift = (GRID_DIMENSION - maxDepth);
|
||||
buildTable();
|
||||
|
||||
maxTrianglePerCell = 0;
|
||||
maxTrianglePerCell = 0;
|
||||
|
||||
// Initialize memory
|
||||
// Initialize memory
|
||||
#ifdef IN_VERBOSE_MODE
|
||||
dc_printf("Range: %f origin: %f, %f,%f \n", range, origin[0], origin[1], origin[2]);
|
||||
dc_printf("Initialize memory...\n");
|
||||
dc_printf("Range: %f origin: %f, %f,%f \n", range, origin[0], origin[1], origin[2]);
|
||||
dc_printf("Initialize memory...\n");
|
||||
#endif
|
||||
initMemory();
|
||||
root = (Node *)createInternal(0);
|
||||
initMemory();
|
||||
root = (Node *)createInternal(0);
|
||||
|
||||
// Read MC table
|
||||
// Read MC table
|
||||
#ifdef IN_VERBOSE_MODE
|
||||
dc_printf("Reading contour table...\n");
|
||||
dc_printf("Reading contour table...\n");
|
||||
#endif
|
||||
cubes = new Cubes();
|
||||
|
||||
cubes = new Cubes();
|
||||
}
|
||||
|
||||
Octree::~Octree()
|
||||
{
|
||||
delete cubes;
|
||||
freeMemory();
|
||||
delete cubes;
|
||||
freeMemory();
|
||||
}
|
||||
|
||||
void Octree::scanConvert()
|
||||
{
|
||||
// Scan triangles
|
||||
// Scan triangles
|
||||
#if DC_DEBUG
|
||||
clock_t start, finish;
|
||||
start = clock();
|
||||
clock_t start, finish;
|
||||
start = clock();
|
||||
#endif
|
||||
|
||||
addAllTriangles();
|
||||
resetMinimalEdges();
|
||||
preparePrimalEdgesMask(&root->internal);
|
||||
addAllTriangles();
|
||||
resetMinimalEdges();
|
||||
preparePrimalEdgesMask(&root->internal);
|
||||
|
||||
#if DC_DEBUG
|
||||
finish = clock();
|
||||
dc_printf("Time taken: %f seconds \n",
|
||||
(double)(finish - start) / CLOCKS_PER_SEC);
|
||||
finish = clock();
|
||||
dc_printf("Time taken: %f seconds \n",
|
||||
(double)(finish - start) / CLOCKS_PER_SEC);
|
||||
#endif
|
||||
|
||||
// Generate signs
|
||||
// Find holes
|
||||
// Generate signs
|
||||
// Find holes
|
||||
#if DC_DEBUG
|
||||
dc_printf("Patching...\n");
|
||||
start = clock();
|
||||
dc_printf("Patching...\n");
|
||||
start = clock();
|
||||
#endif
|
||||
trace();
|
||||
trace();
|
||||
#if DC_DEBUG
|
||||
finish = clock();
|
||||
dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
|
||||
finish = clock();
|
||||
dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
|
||||
# ifdef IN_VERBOSE_MODE
|
||||
dc_printf("Holes: %d Average Length: %f Max Length: %d \n",
|
||||
numRings,
|
||||
(float)totRingLengths / (float)numRings,
|
||||
maxRingLength);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Check again
|
||||
int tnumRings = numRings;
|
||||
trace();
|
||||
#ifdef IN_VERBOSE_MODE
|
||||
dc_printf("Holes: %d Average Length: %f Max Length: %d \n", numRings, (float)totRingLengths / (float) numRings, maxRingLength);
|
||||
dc_printf("Holes after patching: %d \n", numRings);
|
||||
#endif
|
||||
numRings = tnumRings;
|
||||
|
||||
#if DC_DEBUG
|
||||
dc_printf("Building signs...\n");
|
||||
start = clock();
|
||||
#endif
|
||||
buildSigns();
|
||||
#if DC_DEBUG
|
||||
finish = clock();
|
||||
dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
|
||||
#endif
|
||||
|
||||
// Check again
|
||||
int tnumRings = numRings;
|
||||
trace();
|
||||
if (use_flood_fill) {
|
||||
/*
|
||||
start = clock();
|
||||
floodFill();
|
||||
// Check again
|
||||
tnumRings = numRings;
|
||||
trace();
|
||||
dc_printf("Holes after filling: %d \n", numRings);
|
||||
numRings = tnumRings;
|
||||
buildSigns();
|
||||
finish = clock();
|
||||
dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
|
||||
*/
|
||||
#if DC_DEBUG
|
||||
start = clock();
|
||||
dc_printf("Removing components...\n");
|
||||
#endif
|
||||
floodFill();
|
||||
buildSigns();
|
||||
// dc_printf("Checking...\n");
|
||||
// floodFill();
|
||||
#if DC_DEBUG
|
||||
finish = clock();
|
||||
dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Output
|
||||
#if DC_DEBUG
|
||||
start = clock();
|
||||
#endif
|
||||
writeOut();
|
||||
#if DC_DEBUG
|
||||
finish = clock();
|
||||
#endif
|
||||
// dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
|
||||
|
||||
// Print info
|
||||
#ifdef IN_VERBOSE_MODE
|
||||
dc_printf("Holes after patching: %d \n", numRings);
|
||||
#endif
|
||||
numRings = tnumRings;
|
||||
|
||||
#if DC_DEBUG
|
||||
dc_printf("Building signs...\n");
|
||||
start = clock();
|
||||
#endif
|
||||
buildSigns();
|
||||
#if DC_DEBUG
|
||||
finish = clock();
|
||||
dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
|
||||
#endif
|
||||
|
||||
if (use_flood_fill) {
|
||||
/*
|
||||
start = clock();
|
||||
floodFill();
|
||||
// Check again
|
||||
tnumRings = numRings;
|
||||
trace();
|
||||
dc_printf("Holes after filling: %d \n", numRings);
|
||||
numRings = tnumRings;
|
||||
buildSigns();
|
||||
finish = clock();
|
||||
dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
|
||||
*/
|
||||
#if DC_DEBUG
|
||||
start = clock();
|
||||
dc_printf("Removing components...\n");
|
||||
#endif
|
||||
floodFill();
|
||||
buildSigns();
|
||||
// dc_printf("Checking...\n");
|
||||
// floodFill();
|
||||
#if DC_DEBUG
|
||||
finish = clock();
|
||||
dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Output
|
||||
#if DC_DEBUG
|
||||
start = clock();
|
||||
#endif
|
||||
writeOut();
|
||||
#if DC_DEBUG
|
||||
finish = clock();
|
||||
#endif
|
||||
// dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
|
||||
|
||||
// Print info
|
||||
#ifdef IN_VERBOSE_MODE
|
||||
printMemUsage();
|
||||
printMemUsage();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Octree::initMemory()
|
||||
{
|
||||
leafalloc[0] = new MemoryAllocator<sizeof(LeafNode)>();
|
||||
leafalloc[1] = new MemoryAllocator<sizeof(LeafNode) + sizeof(float) *EDGE_FLOATS>();
|
||||
leafalloc[2] = new MemoryAllocator<sizeof(LeafNode) + sizeof(float) *EDGE_FLOATS * 2>();
|
||||
leafalloc[3] = new MemoryAllocator<sizeof(LeafNode) + sizeof(float) *EDGE_FLOATS * 3>();
|
||||
leafalloc[0] = new MemoryAllocator<sizeof(LeafNode)>();
|
||||
leafalloc[1] = new MemoryAllocator<sizeof(LeafNode) + sizeof(float) * EDGE_FLOATS>();
|
||||
leafalloc[2] = new MemoryAllocator<sizeof(LeafNode) + sizeof(float) * EDGE_FLOATS * 2>();
|
||||
leafalloc[3] = new MemoryAllocator<sizeof(LeafNode) + sizeof(float) * EDGE_FLOATS * 3>();
|
||||
|
||||
alloc[0] = new MemoryAllocator<sizeof(InternalNode)>();
|
||||
alloc[1] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *)>();
|
||||
alloc[2] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 2>();
|
||||
alloc[3] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 3>();
|
||||
alloc[4] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 4>();
|
||||
alloc[5] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 5>();
|
||||
alloc[6] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 6>();
|
||||
alloc[7] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 7>();
|
||||
alloc[8] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 8>();
|
||||
alloc[0] = new MemoryAllocator<sizeof(InternalNode)>();
|
||||
alloc[1] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *)>();
|
||||
alloc[2] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 2>();
|
||||
alloc[3] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 3>();
|
||||
alloc[4] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 4>();
|
||||
alloc[5] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 5>();
|
||||
alloc[6] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 6>();
|
||||
alloc[7] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 7>();
|
||||
alloc[8] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 8>();
|
||||
}
|
||||
|
||||
void Octree::freeMemory()
|
||||
{
|
||||
for (int i = 0; i < 9; i++) {
|
||||
alloc[i]->destroy();
|
||||
delete alloc[i];
|
||||
}
|
||||
for (int i = 0; i < 9; i++) {
|
||||
alloc[i]->destroy();
|
||||
delete alloc[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
leafalloc[i]->destroy();
|
||||
delete leafalloc[i];
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
leafalloc[i]->destroy();
|
||||
delete leafalloc[i];
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::printMemUsage()
|
||||
{
|
||||
int totalbytes = 0;
|
||||
dc_printf("********* Internal nodes: \n");
|
||||
for (int i = 0; i < 9; i++) {
|
||||
alloc[i]->printInfo();
|
||||
int totalbytes = 0;
|
||||
dc_printf("********* Internal nodes: \n");
|
||||
for (int i = 0; i < 9; i++) {
|
||||
alloc[i]->printInfo();
|
||||
|
||||
totalbytes += alloc[i]->getAll() * alloc[i]->getBytes();
|
||||
}
|
||||
dc_printf("********* Leaf nodes: \n");
|
||||
int totalLeafs = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
leafalloc[i]->printInfo();
|
||||
totalbytes += alloc[i]->getAll() * alloc[i]->getBytes();
|
||||
}
|
||||
dc_printf("********* Leaf nodes: \n");
|
||||
int totalLeafs = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
leafalloc[i]->printInfo();
|
||||
|
||||
totalbytes += leafalloc[i]->getAll() * leafalloc[i]->getBytes();
|
||||
totalLeafs += leafalloc[i]->getAllocated();
|
||||
}
|
||||
totalbytes += leafalloc[i]->getAll() * leafalloc[i]->getBytes();
|
||||
totalLeafs += leafalloc[i]->getAllocated();
|
||||
}
|
||||
|
||||
dc_printf("Total allocated bytes on disk: %d \n", totalbytes);
|
||||
dc_printf("Total leaf nodes: %d\n", totalLeafs);
|
||||
dc_printf("Total allocated bytes on disk: %d \n", totalbytes);
|
||||
dc_printf("Total leaf nodes: %d\n", totalLeafs);
|
||||
}
|
||||
|
||||
void Octree::resetMinimalEdges()
|
||||
{
|
||||
cellProcParity(root, 0, maxDepth);
|
||||
cellProcParity(root, 0, maxDepth);
|
||||
}
|
||||
|
||||
void Octree::addAllTriangles()
|
||||
{
|
||||
Triangle *trian;
|
||||
int count = 0;
|
||||
Triangle *trian;
|
||||
int count = 0;
|
||||
|
||||
#if DC_DEBUG
|
||||
int total = reader->getNumTriangles();
|
||||
int unitcount = 1000;
|
||||
dc_printf("\nScan converting to depth %d...\n", maxDepth);
|
||||
int total = reader->getNumTriangles();
|
||||
int unitcount = 1000;
|
||||
dc_printf("\nScan converting to depth %d...\n", maxDepth);
|
||||
#endif
|
||||
|
||||
srand(0);
|
||||
srand(0);
|
||||
|
||||
while ((trian = reader->getNextTriangle()) != NULL) {
|
||||
// Drop triangles
|
||||
{
|
||||
addTriangle(trian, count);
|
||||
}
|
||||
delete trian;
|
||||
while ((trian = reader->getNextTriangle()) != NULL) {
|
||||
// Drop triangles
|
||||
{
|
||||
addTriangle(trian, count);
|
||||
}
|
||||
delete trian;
|
||||
|
||||
count++;
|
||||
count++;
|
||||
|
||||
#if DC_DEBUG
|
||||
if (count % unitcount == 0) {
|
||||
putchar(13);
|
||||
if (count % unitcount == 0) {
|
||||
putchar(13);
|
||||
|
||||
switch ((count / unitcount) % 4) {
|
||||
case 0: dc_printf("-");
|
||||
break;
|
||||
case 1: dc_printf("/");
|
||||
break;
|
||||
case 2: dc_printf("|");
|
||||
break;
|
||||
case 3: dc_printf("\\");
|
||||
break;
|
||||
}
|
||||
switch ((count / unitcount) % 4) {
|
||||
case 0:
|
||||
dc_printf("-");
|
||||
break;
|
||||
case 1:
|
||||
dc_printf("/");
|
||||
break;
|
||||
case 2:
|
||||
dc_printf("|");
|
||||
break;
|
||||
case 3:
|
||||
dc_printf("\\");
|
||||
break;
|
||||
}
|
||||
|
||||
float percent = (float) count / total;
|
||||
float percent = (float)count / total;
|
||||
|
||||
/*
|
||||
int totbars = 50;
|
||||
int bars =(int)(percent * totbars);
|
||||
for(int i = 0; i < bars; i ++) {
|
||||
putchar(219);
|
||||
}
|
||||
for(i = bars; i < totbars; i ++) {
|
||||
putchar(176);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
int totbars = 50;
|
||||
int bars =(int)(percent * totbars);
|
||||
for(int i = 0; i < bars; i ++) {
|
||||
putchar(219);
|
||||
}
|
||||
for(i = bars; i < totbars; i ++) {
|
||||
putchar(176);
|
||||
}
|
||||
*/
|
||||
|
||||
dc_printf(" %d triangles: ", count);
|
||||
dc_printf(" %f%% complete.", 100 * percent);
|
||||
}
|
||||
dc_printf(" %d triangles: ", count);
|
||||
dc_printf(" %f%% complete.", 100 * percent);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
putchar(13);
|
||||
}
|
||||
putchar(13);
|
||||
}
|
||||
|
||||
/* Prepare a triangle for insertion into the octree; call the other
|
||||
addTriangle() to (recursively) build the octree */
|
||||
void Octree::addTriangle(Triangle *trian, int triind)
|
||||
{
|
||||
int i, j;
|
||||
int i, j;
|
||||
|
||||
/* Project the triangle's coordinates into the grid */
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++)
|
||||
trian->vt[i][j] = dimen * (trian->vt[i][j] - origin[j]) / range;
|
||||
}
|
||||
/* Project the triangle's coordinates into the grid */
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++)
|
||||
trian->vt[i][j] = dimen * (trian->vt[i][j] - origin[j]) / range;
|
||||
}
|
||||
|
||||
/* Generate projections */
|
||||
int64_t cube[2][3] = {{0, 0, 0}, {dimen, dimen, dimen}};
|
||||
int64_t trig[3][3];
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++)
|
||||
trig[i][j] = (int64_t)(trian->vt[i][j]);
|
||||
}
|
||||
/* Generate projections */
|
||||
int64_t cube[2][3] = {{0, 0, 0}, {dimen, dimen, dimen}};
|
||||
int64_t trig[3][3];
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++)
|
||||
trig[i][j] = (int64_t)(trian->vt[i][j]);
|
||||
}
|
||||
|
||||
/* Add triangle to the octree */
|
||||
int64_t errorvec = (int64_t)(0);
|
||||
CubeTriangleIsect *proj = new CubeTriangleIsect(cube, trig, errorvec, triind);
|
||||
root = (Node *)addTriangle(&root->internal, proj, maxDepth);
|
||||
/* Add triangle to the octree */
|
||||
int64_t errorvec = (int64_t)(0);
|
||||
CubeTriangleIsect *proj = new CubeTriangleIsect(cube, trig, errorvec, triind);
|
||||
root = (Node *)addTriangle(&root->internal, proj, maxDepth);
|
||||
|
||||
delete proj->inherit;
|
||||
delete proj;
|
||||
delete proj->inherit;
|
||||
delete proj;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void print_depth(int height, int maxDepth)
|
||||
{
|
||||
for (int i = 0; i < maxDepth - height; i++)
|
||||
printf(" ");
|
||||
for (int i = 0; i < maxDepth - height; i++)
|
||||
printf(" ");
|
||||
}
|
||||
#endif
|
||||
|
||||
InternalNode *Octree::addTriangle(InternalNode *node, CubeTriangleIsect *p, int height)
|
||||
{
|
||||
int i;
|
||||
const int vertdiff[8][3] = {
|
||||
{0, 0, 0},
|
||||
{0, 0, 1},
|
||||
{0, 1, -1},
|
||||
{0, 0, 1},
|
||||
{1, -1, -1},
|
||||
{0, 0, 1},
|
||||
{0, 1, -1},
|
||||
{0, 0, 1}};
|
||||
unsigned char boxmask = p->getBoxMask();
|
||||
CubeTriangleIsect *subp = new CubeTriangleIsect(p);
|
||||
int i;
|
||||
const int vertdiff[8][3] = {
|
||||
{0, 0, 0}, {0, 0, 1}, {0, 1, -1}, {0, 0, 1}, {1, -1, -1}, {0, 0, 1}, {0, 1, -1}, {0, 0, 1}};
|
||||
unsigned char boxmask = p->getBoxMask();
|
||||
CubeTriangleIsect *subp = new CubeTriangleIsect(p);
|
||||
|
||||
int count = 0;
|
||||
int tempdiff[3] = {0, 0, 0};
|
||||
int count = 0;
|
||||
int tempdiff[3] = {0, 0, 0};
|
||||
|
||||
/* Check triangle against each of the input node's children */
|
||||
for (i = 0; i < 8; i++) {
|
||||
tempdiff[0] += vertdiff[i][0];
|
||||
tempdiff[1] += vertdiff[i][1];
|
||||
tempdiff[2] += vertdiff[i][2];
|
||||
/* Check triangle against each of the input node's children */
|
||||
for (i = 0; i < 8; i++) {
|
||||
tempdiff[0] += vertdiff[i][0];
|
||||
tempdiff[1] += vertdiff[i][1];
|
||||
tempdiff[2] += vertdiff[i][2];
|
||||
|
||||
/* Quick pruning using bounding box */
|
||||
if (boxmask & (1 << i)) {
|
||||
subp->shift(tempdiff);
|
||||
tempdiff[0] = tempdiff[1] = tempdiff[2] = 0;
|
||||
/* Quick pruning using bounding box */
|
||||
if (boxmask & (1 << i)) {
|
||||
subp->shift(tempdiff);
|
||||
tempdiff[0] = tempdiff[1] = tempdiff[2] = 0;
|
||||
|
||||
/* Pruning using intersection test */
|
||||
if (subp->isIntersecting()) {
|
||||
if (!node->has_child(i)) {
|
||||
if (height == 1)
|
||||
node = addLeafChild(node, i, count, createLeaf(0));
|
||||
else
|
||||
node = addInternalChild(node, i, count, createInternal(0));
|
||||
}
|
||||
Node *chd = node->get_child(count);
|
||||
/* Pruning using intersection test */
|
||||
if (subp->isIntersecting()) {
|
||||
if (!node->has_child(i)) {
|
||||
if (height == 1)
|
||||
node = addLeafChild(node, i, count, createLeaf(0));
|
||||
else
|
||||
node = addInternalChild(node, i, count, createInternal(0));
|
||||
}
|
||||
Node *chd = node->get_child(count);
|
||||
|
||||
if (node->is_child_leaf(i))
|
||||
node->set_child(count, (Node *)updateCell(&chd->leaf, subp));
|
||||
else
|
||||
node->set_child(count, (Node *)addTriangle(&chd->internal, subp, height - 1));
|
||||
}
|
||||
}
|
||||
if (node->is_child_leaf(i))
|
||||
node->set_child(count, (Node *)updateCell(&chd->leaf, subp));
|
||||
else
|
||||
node->set_child(count, (Node *)addTriangle(&chd->internal, subp, height - 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (node->has_child(i))
|
||||
count++;
|
||||
}
|
||||
if (node->has_child(i))
|
||||
count++;
|
||||
}
|
||||
|
||||
delete subp;
|
||||
delete subp;
|
||||
|
||||
return node;
|
||||
return node;
|
||||
}
|
||||
|
||||
LeafNode *Octree::updateCell(LeafNode *node, CubeTriangleIsect *p)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
// Edge connectivity
|
||||
int mask[3] = {0, 4, 8 };
|
||||
int oldc = 0, newc = 0;
|
||||
float offs[3];
|
||||
float a[3], b[3], c[3];
|
||||
// Edge connectivity
|
||||
int mask[3] = {0, 4, 8};
|
||||
int oldc = 0, newc = 0;
|
||||
float offs[3];
|
||||
float a[3], b[3], c[3];
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (!getEdgeParity(node, mask[i])) {
|
||||
if (p->isIntersectingPrimary(i)) {
|
||||
// actualQuads ++;
|
||||
setEdge(node, mask[i]);
|
||||
offs[newc] = p->getIntersectionPrimary(i);
|
||||
a[newc] = (float) p->inherit->norm[0];
|
||||
b[newc] = (float) p->inherit->norm[1];
|
||||
c[newc] = (float) p->inherit->norm[2];
|
||||
newc++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
offs[newc] = getEdgeOffsetNormal(node, oldc, a[newc], b[newc], c[newc]);
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (!getEdgeParity(node, mask[i])) {
|
||||
if (p->isIntersectingPrimary(i)) {
|
||||
// actualQuads ++;
|
||||
setEdge(node, mask[i]);
|
||||
offs[newc] = p->getIntersectionPrimary(i);
|
||||
a[newc] = (float)p->inherit->norm[0];
|
||||
b[newc] = (float)p->inherit->norm[1];
|
||||
c[newc] = (float)p->inherit->norm[2];
|
||||
newc++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
offs[newc] = getEdgeOffsetNormal(node, oldc, a[newc], b[newc], c[newc]);
|
||||
|
||||
oldc++;
|
||||
newc++;
|
||||
}
|
||||
}
|
||||
oldc++;
|
||||
newc++;
|
||||
}
|
||||
}
|
||||
|
||||
if (newc > oldc) {
|
||||
// New offsets added, update this node
|
||||
node = updateEdgeOffsetsNormals(node, oldc, newc, offs, a, b, c);
|
||||
}
|
||||
if (newc > oldc) {
|
||||
// New offsets added, update this node
|
||||
node = updateEdgeOffsetsNormals(node, oldc, newc, offs, a, b, c);
|
||||
}
|
||||
|
||||
return node;
|
||||
return node;
|
||||
}
|
||||
|
||||
void Octree::preparePrimalEdgesMask(InternalNode *node)
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (node->has_child(i)) {
|
||||
if (node->is_child_leaf(i))
|
||||
createPrimalEdgesMask(&node->get_child(count)->leaf);
|
||||
else
|
||||
preparePrimalEdgesMask(&node->get_child(count)->internal);
|
||||
int count = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (node->has_child(i)) {
|
||||
if (node->is_child_leaf(i))
|
||||
createPrimalEdgesMask(&node->get_child(count)->leaf);
|
||||
else
|
||||
preparePrimalEdgesMask(&node->get_child(count)->internal);
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::trace()
|
||||
{
|
||||
int st[3] = {0, 0, 0, };
|
||||
numRings = 0;
|
||||
totRingLengths = 0;
|
||||
maxRingLength = 0;
|
||||
int st[3] = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
numRings = 0;
|
||||
totRingLengths = 0;
|
||||
maxRingLength = 0;
|
||||
|
||||
PathList *chdpath = NULL;
|
||||
root = trace(root, st, dimen, maxDepth, chdpath);
|
||||
PathList *chdpath = NULL;
|
||||
root = trace(root, st, dimen, maxDepth, chdpath);
|
||||
|
||||
if (chdpath != NULL) {
|
||||
dc_printf("there are incomplete rings.\n");
|
||||
printPaths(chdpath);
|
||||
};
|
||||
if (chdpath != NULL) {
|
||||
dc_printf("there are incomplete rings.\n");
|
||||
printPaths(chdpath);
|
||||
};
|
||||
}
|
||||
|
||||
Node *Octree::trace(Node *newnode, int *st, int len, int depth, PathList *& paths)
|
||||
Node *Octree::trace(Node *newnode, int *st, int len, int depth, PathList *&paths)
|
||||
{
|
||||
len >>= 1;
|
||||
PathList *chdpaths[8];
|
||||
Node *chd[8];
|
||||
int nst[8][3];
|
||||
int i, j;
|
||||
len >>= 1;
|
||||
PathList *chdpaths[8];
|
||||
Node *chd[8];
|
||||
int nst[8][3];
|
||||
int i, j;
|
||||
|
||||
// Get children paths
|
||||
int chdleaf[8];
|
||||
newnode->internal.fill_children(chd, chdleaf);
|
||||
// Get children paths
|
||||
int chdleaf[8];
|
||||
newnode->internal.fill_children(chd, chdleaf);
|
||||
|
||||
// int count = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
nst[i][j] = st[j] + len * vertmap[i][j];
|
||||
}
|
||||
// int count = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
nst[i][j] = st[j] + len * vertmap[i][j];
|
||||
}
|
||||
|
||||
if (chd[i] == NULL || newnode->internal.is_child_leaf(i)) {
|
||||
chdpaths[i] = NULL;
|
||||
}
|
||||
else {
|
||||
trace(chd[i], nst[i], len, depth - 1, chdpaths[i]);
|
||||
}
|
||||
}
|
||||
if (chd[i] == NULL || newnode->internal.is_child_leaf(i)) {
|
||||
chdpaths[i] = NULL;
|
||||
}
|
||||
else {
|
||||
trace(chd[i], nst[i], len, depth - 1, chdpaths[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Get connectors on the faces
|
||||
PathList *conn[12];
|
||||
Node *nf[2];
|
||||
int lf[2];
|
||||
int df[2] = {depth - 1, depth - 1};
|
||||
int *nstf[2];
|
||||
// Get connectors on the faces
|
||||
PathList *conn[12];
|
||||
Node *nf[2];
|
||||
int lf[2];
|
||||
int df[2] = {depth - 1, depth - 1};
|
||||
int *nstf[2];
|
||||
|
||||
newnode->internal.fill_children(chd, chdleaf);
|
||||
newnode->internal.fill_children(chd, chdleaf);
|
||||
|
||||
for (i = 0; i < 12; i++) {
|
||||
int c[2] = {cellProcFaceMask[i][0], cellProcFaceMask[i][1]};
|
||||
for (i = 0; i < 12; i++) {
|
||||
int c[2] = {cellProcFaceMask[i][0], cellProcFaceMask[i][1]};
|
||||
|
||||
for (int j = 0; j < 2; j++) {
|
||||
lf[j] = chdleaf[c[j]];
|
||||
nf[j] = chd[c[j]];
|
||||
nstf[j] = nst[c[j]];
|
||||
}
|
||||
for (int j = 0; j < 2; j++) {
|
||||
lf[j] = chdleaf[c[j]];
|
||||
nf[j] = chd[c[j]];
|
||||
nstf[j] = nst[c[j]];
|
||||
}
|
||||
|
||||
conn[i] = NULL;
|
||||
conn[i] = NULL;
|
||||
|
||||
findPaths((Node **)nf, lf, df, nstf, depth - 1, cellProcFaceMask[i][2], conn[i]);
|
||||
findPaths((Node **)nf, lf, df, nstf, depth - 1, cellProcFaceMask[i][2], conn[i]);
|
||||
|
||||
//if(conn[i]) {
|
||||
// printPath(conn[i]);
|
||||
//}
|
||||
}
|
||||
//if(conn[i]) {
|
||||
// printPath(conn[i]);
|
||||
//}
|
||||
}
|
||||
|
||||
// Connect paths
|
||||
PathList *rings = NULL;
|
||||
combinePaths(chdpaths[0], chdpaths[1], conn[8], rings);
|
||||
combinePaths(chdpaths[2], chdpaths[3], conn[9], rings);
|
||||
combinePaths(chdpaths[4], chdpaths[5], conn[10], rings);
|
||||
combinePaths(chdpaths[6], chdpaths[7], conn[11], rings);
|
||||
// Connect paths
|
||||
PathList *rings = NULL;
|
||||
combinePaths(chdpaths[0], chdpaths[1], conn[8], rings);
|
||||
combinePaths(chdpaths[2], chdpaths[3], conn[9], rings);
|
||||
combinePaths(chdpaths[4], chdpaths[5], conn[10], rings);
|
||||
combinePaths(chdpaths[6], chdpaths[7], conn[11], rings);
|
||||
|
||||
combinePaths(chdpaths[0], chdpaths[2], conn[4], rings);
|
||||
combinePaths(chdpaths[4], chdpaths[6], conn[5], rings);
|
||||
combinePaths(chdpaths[0], NULL, conn[6], rings);
|
||||
combinePaths(chdpaths[4], NULL, conn[7], rings);
|
||||
combinePaths(chdpaths[0], chdpaths[2], conn[4], rings);
|
||||
combinePaths(chdpaths[4], chdpaths[6], conn[5], rings);
|
||||
combinePaths(chdpaths[0], NULL, conn[6], rings);
|
||||
combinePaths(chdpaths[4], NULL, conn[7], rings);
|
||||
|
||||
combinePaths(chdpaths[0], chdpaths[4], conn[0], rings);
|
||||
combinePaths(chdpaths[0], NULL, conn[1], rings);
|
||||
combinePaths(chdpaths[0], NULL, conn[2], rings);
|
||||
combinePaths(chdpaths[0], NULL, conn[3], rings);
|
||||
combinePaths(chdpaths[0], chdpaths[4], conn[0], rings);
|
||||
combinePaths(chdpaths[0], NULL, conn[1], rings);
|
||||
combinePaths(chdpaths[0], NULL, conn[2], rings);
|
||||
combinePaths(chdpaths[0], NULL, conn[3], rings);
|
||||
|
||||
// By now, only chdpaths[0] and rings have contents
|
||||
// By now, only chdpaths[0] and rings have contents
|
||||
|
||||
// Process rings
|
||||
if (rings) {
|
||||
// printPath(rings);
|
||||
// Process rings
|
||||
if (rings) {
|
||||
// printPath(rings);
|
||||
|
||||
/* Let's count first */
|
||||
PathList *trings = rings;
|
||||
while (trings) {
|
||||
numRings++;
|
||||
totRingLengths += trings->length;
|
||||
if (trings->length > maxRingLength) {
|
||||
maxRingLength = trings->length;
|
||||
}
|
||||
trings = trings->next;
|
||||
}
|
||||
/* Let's count first */
|
||||
PathList *trings = rings;
|
||||
while (trings) {
|
||||
numRings++;
|
||||
totRingLengths += trings->length;
|
||||
if (trings->length > maxRingLength) {
|
||||
maxRingLength = trings->length;
|
||||
}
|
||||
trings = trings->next;
|
||||
}
|
||||
|
||||
// printPath(rings);
|
||||
newnode = patch(newnode, st, (len << 1), rings);
|
||||
}
|
||||
// printPath(rings);
|
||||
newnode = patch(newnode, st, (len << 1), rings);
|
||||
}
|
||||
|
||||
// Return incomplete paths
|
||||
paths = chdpaths[0];
|
||||
return newnode;
|
||||
// Return incomplete paths
|
||||
paths = chdpaths[0];
|
||||
return newnode;
|
||||
}
|
||||
|
||||
void Octree::findPaths(Node *node[2], int leaf[2], int depth[2], int *st[2], int maxdep, int dir, PathList *& paths)
|
||||
void Octree::findPaths(
|
||||
Node *node[2], int leaf[2], int depth[2], int *st[2], int maxdep, int dir, PathList *&paths)
|
||||
{
|
||||
if (!(node[0] && node[1])) {
|
||||
return;
|
||||
}
|
||||
if (!(node[0] && node[1])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(leaf[0] && leaf[1])) {
|
||||
// Not at the bottom, recur
|
||||
if (!(leaf[0] && leaf[1])) {
|
||||
// Not at the bottom, recur
|
||||
|
||||
// Fill children nodes
|
||||
int i, j;
|
||||
Node *chd[2][8];
|
||||
int chdleaf[2][8];
|
||||
int nst[2][8][3];
|
||||
// Fill children nodes
|
||||
int i, j;
|
||||
Node *chd[2][8];
|
||||
int chdleaf[2][8];
|
||||
int nst[2][8][3];
|
||||
|
||||
for (j = 0; j < 2; j++) {
|
||||
if (!leaf[j]) {
|
||||
node[j]->internal.fill_children(chd[j], chdleaf[j]);
|
||||
for (j = 0; j < 2; j++) {
|
||||
if (!leaf[j]) {
|
||||
node[j]->internal.fill_children(chd[j], chdleaf[j]);
|
||||
|
||||
int len = (dimen >> (maxDepth - depth[j] + 1));
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (int k = 0; k < 3; k++) {
|
||||
nst[j][i][k] = st[j][k] + len * vertmap[i][k];
|
||||
}
|
||||
}
|
||||
int len = (dimen >> (maxDepth - depth[j] + 1));
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (int k = 0; k < 3; k++) {
|
||||
nst[j][i][k] = st[j][k] + len * vertmap[i][k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// 4 face calls
|
||||
Node *nf[2];
|
||||
int df[2];
|
||||
int lf[2];
|
||||
int *nstf[2];
|
||||
for (i = 0; i < 4; i++) {
|
||||
int c[2] = {faceProcFaceMask[dir][i][0], faceProcFaceMask[dir][i][1]};
|
||||
for (int j = 0; j < 2; j++) {
|
||||
if (leaf[j]) {
|
||||
lf[j] = leaf[j];
|
||||
nf[j] = node[j];
|
||||
df[j] = depth[j];
|
||||
nstf[j] = st[j];
|
||||
}
|
||||
else {
|
||||
lf[j] = chdleaf[j][c[j]];
|
||||
nf[j] = chd[j][c[j]];
|
||||
df[j] = depth[j] - 1;
|
||||
nstf[j] = nst[j][c[j]];
|
||||
}
|
||||
}
|
||||
findPaths(nf, lf, df, nstf, maxdep - 1, faceProcFaceMask[dir][i][2], paths);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// At the bottom, check this face
|
||||
int ind = (depth[0] == maxdep ? 0 : 1);
|
||||
int fcind = 2 * dir + (1 - ind);
|
||||
if (getFaceParity((LeafNode *)node[ind], fcind)) {
|
||||
// Add into path
|
||||
PathElement *ele1 = new PathElement;
|
||||
PathElement *ele2 = new PathElement;
|
||||
|
||||
// 4 face calls
|
||||
Node *nf[2];
|
||||
int df[2];
|
||||
int lf[2];
|
||||
int *nstf[2];
|
||||
for (i = 0; i < 4; i++) {
|
||||
int c[2] = {faceProcFaceMask[dir][i][0], faceProcFaceMask[dir][i][1]};
|
||||
for (int j = 0; j < 2; j++) {
|
||||
if (leaf[j]) {
|
||||
lf[j] = leaf[j];
|
||||
nf[j] = node[j];
|
||||
df[j] = depth[j];
|
||||
nstf[j] = st[j];
|
||||
}
|
||||
else {
|
||||
lf[j] = chdleaf[j][c[j]];
|
||||
nf[j] = chd[j][c[j]];
|
||||
df[j] = depth[j] - 1;
|
||||
nstf[j] = nst[j][c[j]];
|
||||
}
|
||||
}
|
||||
findPaths(nf, lf, df, nstf, maxdep - 1, faceProcFaceMask[dir][i][2], paths);
|
||||
}
|
||||
ele1->pos[0] = st[0][0];
|
||||
ele1->pos[1] = st[0][1];
|
||||
ele1->pos[2] = st[0][2];
|
||||
|
||||
}
|
||||
else {
|
||||
// At the bottom, check this face
|
||||
int ind = (depth[0] == maxdep ? 0 : 1);
|
||||
int fcind = 2 * dir + (1 - ind);
|
||||
if (getFaceParity((LeafNode *)node[ind], fcind)) {
|
||||
// Add into path
|
||||
PathElement *ele1 = new PathElement;
|
||||
PathElement *ele2 = new PathElement;
|
||||
ele2->pos[0] = st[1][0];
|
||||
ele2->pos[1] = st[1][1];
|
||||
ele2->pos[2] = st[1][2];
|
||||
|
||||
ele1->pos[0] = st[0][0];
|
||||
ele1->pos[1] = st[0][1];
|
||||
ele1->pos[2] = st[0][2];
|
||||
ele1->next = ele2;
|
||||
ele2->next = NULL;
|
||||
|
||||
ele2->pos[0] = st[1][0];
|
||||
ele2->pos[1] = st[1][1];
|
||||
ele2->pos[2] = st[1][2];
|
||||
|
||||
ele1->next = ele2;
|
||||
ele2->next = NULL;
|
||||
|
||||
PathList *lst = new PathList;
|
||||
lst->head = ele1;
|
||||
lst->tail = ele2;
|
||||
lst->length = 2;
|
||||
lst->next = paths;
|
||||
paths = lst;
|
||||
|
||||
// int l =(dimen >> maxDepth);
|
||||
}
|
||||
}
|
||||
PathList *lst = new PathList;
|
||||
lst->head = ele1;
|
||||
lst->tail = ele2;
|
||||
lst->length = 2;
|
||||
lst->next = paths;
|
||||
paths = lst;
|
||||
|
||||
// int l =(dimen >> maxDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::combinePaths(PathList *& list1, PathList *list2, PathList *paths, PathList *& rings)
|
||||
void Octree::combinePaths(PathList *&list1, PathList *list2, PathList *paths, PathList *&rings)
|
||||
{
|
||||
// Make new list of paths
|
||||
PathList *nlist = NULL;
|
||||
// Make new list of paths
|
||||
PathList *nlist = NULL;
|
||||
|
||||
// Search for each connectors in paths
|
||||
PathList *tpaths = paths;
|
||||
PathList *tlist, *pre;
|
||||
while (tpaths) {
|
||||
PathList *singlist = tpaths;
|
||||
PathList *templist;
|
||||
tpaths = tpaths->next;
|
||||
singlist->next = NULL;
|
||||
// Search for each connectors in paths
|
||||
PathList *tpaths = paths;
|
||||
PathList *tlist, *pre;
|
||||
while (tpaths) {
|
||||
PathList *singlist = tpaths;
|
||||
PathList *templist;
|
||||
tpaths = tpaths->next;
|
||||
singlist->next = NULL;
|
||||
|
||||
// Look for hookup in list1
|
||||
tlist = list1;
|
||||
pre = NULL;
|
||||
while (tlist) {
|
||||
if ((templist = combineSinglePath(list1, pre, tlist, singlist, NULL, singlist)) != NULL) {
|
||||
singlist = templist;
|
||||
continue;
|
||||
}
|
||||
pre = tlist;
|
||||
tlist = tlist->next;
|
||||
}
|
||||
// Look for hookup in list1
|
||||
tlist = list1;
|
||||
pre = NULL;
|
||||
while (tlist) {
|
||||
if ((templist = combineSinglePath(list1, pre, tlist, singlist, NULL, singlist)) != NULL) {
|
||||
singlist = templist;
|
||||
continue;
|
||||
}
|
||||
pre = tlist;
|
||||
tlist = tlist->next;
|
||||
}
|
||||
|
||||
// Look for hookup in list2
|
||||
tlist = list2;
|
||||
pre = NULL;
|
||||
while (tlist) {
|
||||
if ((templist = combineSinglePath(list2, pre, tlist, singlist, NULL, singlist)) != NULL) {
|
||||
singlist = templist;
|
||||
continue;
|
||||
}
|
||||
pre = tlist;
|
||||
tlist = tlist->next;
|
||||
}
|
||||
// Look for hookup in list2
|
||||
tlist = list2;
|
||||
pre = NULL;
|
||||
while (tlist) {
|
||||
if ((templist = combineSinglePath(list2, pre, tlist, singlist, NULL, singlist)) != NULL) {
|
||||
singlist = templist;
|
||||
continue;
|
||||
}
|
||||
pre = tlist;
|
||||
tlist = tlist->next;
|
||||
}
|
||||
|
||||
// Look for hookup in nlist
|
||||
tlist = nlist;
|
||||
pre = NULL;
|
||||
while (tlist) {
|
||||
if ((templist = combineSinglePath(nlist, pre, tlist, singlist, NULL, singlist)) != NULL) {
|
||||
singlist = templist;
|
||||
continue;
|
||||
}
|
||||
pre = tlist;
|
||||
tlist = tlist->next;
|
||||
}
|
||||
// Look for hookup in nlist
|
||||
tlist = nlist;
|
||||
pre = NULL;
|
||||
while (tlist) {
|
||||
if ((templist = combineSinglePath(nlist, pre, tlist, singlist, NULL, singlist)) != NULL) {
|
||||
singlist = templist;
|
||||
continue;
|
||||
}
|
||||
pre = tlist;
|
||||
tlist = tlist->next;
|
||||
}
|
||||
|
||||
// Add to nlist or rings
|
||||
if (isEqual(singlist->head, singlist->tail)) {
|
||||
PathElement *temp = singlist->head;
|
||||
singlist->head = temp->next;
|
||||
delete temp;
|
||||
singlist->length--;
|
||||
singlist->tail->next = singlist->head;
|
||||
// Add to nlist or rings
|
||||
if (isEqual(singlist->head, singlist->tail)) {
|
||||
PathElement *temp = singlist->head;
|
||||
singlist->head = temp->next;
|
||||
delete temp;
|
||||
singlist->length--;
|
||||
singlist->tail->next = singlist->head;
|
||||
|
||||
singlist->next = rings;
|
||||
rings = singlist;
|
||||
}
|
||||
else {
|
||||
singlist->next = nlist;
|
||||
nlist = singlist;
|
||||
}
|
||||
singlist->next = rings;
|
||||
rings = singlist;
|
||||
}
|
||||
else {
|
||||
singlist->next = nlist;
|
||||
nlist = singlist;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Append list2 and nlist to the end of list1
|
||||
tlist = list1;
|
||||
if (tlist != NULL) {
|
||||
while (tlist->next != NULL) {
|
||||
tlist = tlist->next;
|
||||
}
|
||||
tlist->next = list2;
|
||||
}
|
||||
else {
|
||||
tlist = list2;
|
||||
list1 = list2;
|
||||
}
|
||||
|
||||
if (tlist != NULL) {
|
||||
while (tlist->next != NULL) {
|
||||
tlist = tlist->next;
|
||||
}
|
||||
tlist->next = nlist;
|
||||
}
|
||||
else {
|
||||
tlist = nlist;
|
||||
list1 = nlist;
|
||||
}
|
||||
// Append list2 and nlist to the end of list1
|
||||
tlist = list1;
|
||||
if (tlist != NULL) {
|
||||
while (tlist->next != NULL) {
|
||||
tlist = tlist->next;
|
||||
}
|
||||
tlist->next = list2;
|
||||
}
|
||||
else {
|
||||
tlist = list2;
|
||||
list1 = list2;
|
||||
}
|
||||
|
||||
if (tlist != NULL) {
|
||||
while (tlist->next != NULL) {
|
||||
tlist = tlist->next;
|
||||
}
|
||||
tlist->next = nlist;
|
||||
}
|
||||
else {
|
||||
tlist = nlist;
|
||||
list1 = nlist;
|
||||
}
|
||||
}
|
||||
|
||||
PathList *Octree::combineSinglePath(PathList *& head1, PathList *pre1, PathList *& list1, PathList *& head2, PathList *pre2, PathList *& list2)
|
||||
PathList *Octree::combineSinglePath(PathList *&head1,
|
||||
PathList *pre1,
|
||||
PathList *&list1,
|
||||
PathList *&head2,
|
||||
PathList *pre2,
|
||||
PathList *&list2)
|
||||
{
|
||||
if (isEqual(list1->head, list2->head) || isEqual(list1->tail, list2->tail)) {
|
||||
// Reverse the list
|
||||
if (list1->length < list2->length) {
|
||||
// Reverse list1
|
||||
PathElement *prev = list1->head;
|
||||
PathElement *next = prev->next;
|
||||
prev->next = NULL;
|
||||
while (next != NULL) {
|
||||
PathElement *tnext = next->next;
|
||||
next->next = prev;
|
||||
if (isEqual(list1->head, list2->head) || isEqual(list1->tail, list2->tail)) {
|
||||
// Reverse the list
|
||||
if (list1->length < list2->length) {
|
||||
// Reverse list1
|
||||
PathElement *prev = list1->head;
|
||||
PathElement *next = prev->next;
|
||||
prev->next = NULL;
|
||||
while (next != NULL) {
|
||||
PathElement *tnext = next->next;
|
||||
next->next = prev;
|
||||
|
||||
prev = next;
|
||||
next = tnext;
|
||||
}
|
||||
prev = next;
|
||||
next = tnext;
|
||||
}
|
||||
|
||||
list1->tail = list1->head;
|
||||
list1->head = prev;
|
||||
}
|
||||
else {
|
||||
// Reverse list2
|
||||
PathElement *prev = list2->head;
|
||||
PathElement *next = prev->next;
|
||||
prev->next = NULL;
|
||||
while (next != NULL) {
|
||||
PathElement *tnext = next->next;
|
||||
next->next = prev;
|
||||
list1->tail = list1->head;
|
||||
list1->head = prev;
|
||||
}
|
||||
else {
|
||||
// Reverse list2
|
||||
PathElement *prev = list2->head;
|
||||
PathElement *next = prev->next;
|
||||
prev->next = NULL;
|
||||
while (next != NULL) {
|
||||
PathElement *tnext = next->next;
|
||||
next->next = prev;
|
||||
|
||||
prev = next;
|
||||
next = tnext;
|
||||
}
|
||||
prev = next;
|
||||
next = tnext;
|
||||
}
|
||||
|
||||
list2->tail = list2->head;
|
||||
list2->head = prev;
|
||||
}
|
||||
}
|
||||
list2->tail = list2->head;
|
||||
list2->head = prev;
|
||||
}
|
||||
}
|
||||
|
||||
if (isEqual(list1->head, list2->tail)) {
|
||||
if (isEqual(list1->head, list2->tail)) {
|
||||
|
||||
// Easy case
|
||||
PathElement *temp = list1->head->next;
|
||||
delete list1->head;
|
||||
list2->tail->next = temp;
|
||||
// Easy case
|
||||
PathElement *temp = list1->head->next;
|
||||
delete list1->head;
|
||||
list2->tail->next = temp;
|
||||
|
||||
PathList *nlist = new PathList;
|
||||
nlist->length = list1->length + list2->length - 1;
|
||||
nlist->head = list2->head;
|
||||
nlist->tail = list1->tail;
|
||||
nlist->next = NULL;
|
||||
PathList *nlist = new PathList;
|
||||
nlist->length = list1->length + list2->length - 1;
|
||||
nlist->head = list2->head;
|
||||
nlist->tail = list1->tail;
|
||||
nlist->next = NULL;
|
||||
|
||||
deletePath(head1, pre1, list1);
|
||||
deletePath(head2, pre2, list2);
|
||||
deletePath(head1, pre1, list1);
|
||||
deletePath(head2, pre2, list2);
|
||||
|
||||
return nlist;
|
||||
}
|
||||
else if (isEqual(list1->tail, list2->head)) {
|
||||
// Easy case
|
||||
PathElement *temp = list2->head->next;
|
||||
delete list2->head;
|
||||
list1->tail->next = temp;
|
||||
return nlist;
|
||||
}
|
||||
else if (isEqual(list1->tail, list2->head)) {
|
||||
// Easy case
|
||||
PathElement *temp = list2->head->next;
|
||||
delete list2->head;
|
||||
list1->tail->next = temp;
|
||||
|
||||
PathList *nlist = new PathList;
|
||||
nlist->length = list1->length + list2->length - 1;
|
||||
nlist->head = list1->head;
|
||||
nlist->tail = list2->tail;
|
||||
nlist->next = NULL;
|
||||
PathList *nlist = new PathList;
|
||||
nlist->length = list1->length + list2->length - 1;
|
||||
nlist->head = list1->head;
|
||||
nlist->tail = list2->tail;
|
||||
nlist->next = NULL;
|
||||
|
||||
deletePath(head1, pre1, list1);
|
||||
deletePath(head2, pre2, list2);
|
||||
deletePath(head1, pre1, list1);
|
||||
deletePath(head2, pre2, list2);
|
||||
|
||||
return nlist;
|
||||
}
|
||||
return nlist;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Octree::deletePath(PathList *& head, PathList *pre, PathList *& curr)
|
||||
void Octree::deletePath(PathList *&head, PathList *pre, PathList *&curr)
|
||||
{
|
||||
PathList *temp = curr;
|
||||
curr = temp->next;
|
||||
delete temp;
|
||||
PathList *temp = curr;
|
||||
curr = temp->next;
|
||||
delete temp;
|
||||
|
||||
if (pre == NULL) {
|
||||
head = curr;
|
||||
}
|
||||
else {
|
||||
pre->next = curr;
|
||||
}
|
||||
if (pre == NULL) {
|
||||
head = curr;
|
||||
}
|
||||
else {
|
||||
pre->next = curr;
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::printElement(PathElement *ele)
|
||||
{
|
||||
if (ele != NULL) {
|
||||
dc_printf("(%d %d %d)", ele->pos[0], ele->pos[1], ele->pos[2]);
|
||||
}
|
||||
if (ele != NULL) {
|
||||
dc_printf("(%d %d %d)", ele->pos[0], ele->pos[1], ele->pos[2]);
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::printPath(PathList *path)
|
||||
{
|
||||
PathElement *n = path->head;
|
||||
int same = 0;
|
||||
PathElement *n = path->head;
|
||||
int same = 0;
|
||||
|
||||
#if DC_DEBUG
|
||||
int len = (dimen >> maxDepth);
|
||||
int len = (dimen >> maxDepth);
|
||||
#endif
|
||||
while (n && (same == 0 || n != path->head)) {
|
||||
same++;
|
||||
dc_printf("(%d %d %d)", n->pos[0] / len, n->pos[1] / len, n->pos[2] / len);
|
||||
n = n->next;
|
||||
}
|
||||
while (n && (same == 0 || n != path->head)) {
|
||||
same++;
|
||||
dc_printf("(%d %d %d)", n->pos[0] / len, n->pos[1] / len, n->pos[2] / len);
|
||||
n = n->next;
|
||||
}
|
||||
|
||||
if (n == path->head) {
|
||||
dc_printf(" Ring!\n");
|
||||
}
|
||||
else {
|
||||
dc_printf(" %p end!\n", n);
|
||||
}
|
||||
if (n == path->head) {
|
||||
dc_printf(" Ring!\n");
|
||||
}
|
||||
else {
|
||||
dc_printf(" %p end!\n", n);
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::printPath(PathElement *path)
|
||||
{
|
||||
PathElement *n = path;
|
||||
int same = 0;
|
||||
PathElement *n = path;
|
||||
int same = 0;
|
||||
#if DC_DEBUG
|
||||
int len = (dimen >> maxDepth);
|
||||
int len = (dimen >> maxDepth);
|
||||
#endif
|
||||
while (n && (same == 0 || n != path)) {
|
||||
same++;
|
||||
dc_printf("(%d %d %d)", n->pos[0] / len, n->pos[1] / len, n->pos[2] / len);
|
||||
n = n->next;
|
||||
}
|
||||
|
||||
if (n == path) {
|
||||
dc_printf(" Ring!\n");
|
||||
}
|
||||
else {
|
||||
dc_printf(" %p end!\n", n);
|
||||
}
|
||||
while (n && (same == 0 || n != path)) {
|
||||
same++;
|
||||
dc_printf("(%d %d %d)", n->pos[0] / len, n->pos[1] / len, n->pos[2] / len);
|
||||
n = n->next;
|
||||
}
|
||||
|
||||
if (n == path) {
|
||||
dc_printf(" Ring!\n");
|
||||
}
|
||||
else {
|
||||
dc_printf(" %p end!\n", n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Octree::printPaths(PathList *path)
|
||||
{
|
||||
PathList *iter = path;
|
||||
int i = 0;
|
||||
while (iter != NULL) {
|
||||
dc_printf("Path %d:\n", i);
|
||||
printPath(iter);
|
||||
iter = iter->next;
|
||||
i++;
|
||||
}
|
||||
PathList *iter = path;
|
||||
int i = 0;
|
||||
while (iter != NULL) {
|
||||
dc_printf("Path %d:\n", i);
|
||||
printPath(iter);
|
||||
iter = iter->next;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
Node *Octree::patch(Node *newnode, int st[3], int len, PathList *rings)
|
||||
{
|
||||
#ifdef IN_DEBUG_MODE
|
||||
dc_printf("Call to PATCH with rings: \n");
|
||||
printPaths(rings);
|
||||
dc_printf("Call to PATCH with rings: \n");
|
||||
printPaths(rings);
|
||||
#endif
|
||||
|
||||
/* Do nothing but couting
|
||||
PathList* tlist = rings;
|
||||
PathList* ttlist;
|
||||
PathElement* telem, * ttelem;
|
||||
while(tlist!= NULL) {
|
||||
// printPath(tlist);
|
||||
numRings ++;
|
||||
totRingLengths += tlist->length;
|
||||
if(tlist->length > maxRingLength) {
|
||||
maxRingLength = tlist->length;
|
||||
}
|
||||
ttlist = tlist;
|
||||
tlist = tlist->next;
|
||||
}
|
||||
return node;
|
||||
*/
|
||||
/* Do nothing but couting
|
||||
PathList* tlist = rings;
|
||||
PathList* ttlist;
|
||||
PathElement* telem, * ttelem;
|
||||
while(tlist!= NULL) {
|
||||
// printPath(tlist);
|
||||
numRings ++;
|
||||
totRingLengths += tlist->length;
|
||||
if(tlist->length > maxRingLength) {
|
||||
maxRingLength = tlist->length;
|
||||
}
|
||||
ttlist = tlist;
|
||||
tlist = tlist->next;
|
||||
}
|
||||
return node;
|
||||
*/
|
||||
|
||||
/* Pass onto separate calls in each direction */
|
||||
if (len == mindimen) {
|
||||
dc_printf("Error! should have no list by now.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Pass onto separate calls in each direction */
|
||||
if (len == mindimen) {
|
||||
dc_printf("Error! should have no list by now.\n");
|
||||
exit(0);
|
||||
}
|
||||
// YZ plane
|
||||
PathList *xlists[2];
|
||||
newnode = patchSplit(newnode, st, len, rings, 0, xlists[0], xlists[1]);
|
||||
|
||||
// YZ plane
|
||||
PathList *xlists[2];
|
||||
newnode = patchSplit(newnode, st, len, rings, 0, xlists[0], xlists[1]);
|
||||
// XZ plane
|
||||
PathList *ylists[4];
|
||||
newnode = patchSplit(newnode, st, len, xlists[0], 1, ylists[0], ylists[1]);
|
||||
newnode = patchSplit(newnode, st, len, xlists[1], 1, ylists[2], ylists[3]);
|
||||
|
||||
// XZ plane
|
||||
PathList *ylists[4];
|
||||
newnode = patchSplit(newnode, st, len, xlists[0], 1, ylists[0], ylists[1]);
|
||||
newnode = patchSplit(newnode, st, len, xlists[1], 1, ylists[2], ylists[3]);
|
||||
// XY plane
|
||||
PathList *zlists[8];
|
||||
newnode = patchSplit(newnode, st, len, ylists[0], 2, zlists[0], zlists[1]);
|
||||
newnode = patchSplit(newnode, st, len, ylists[1], 2, zlists[2], zlists[3]);
|
||||
newnode = patchSplit(newnode, st, len, ylists[2], 2, zlists[4], zlists[5]);
|
||||
newnode = patchSplit(newnode, st, len, ylists[3], 2, zlists[6], zlists[7]);
|
||||
|
||||
// XY plane
|
||||
PathList *zlists[8];
|
||||
newnode = patchSplit(newnode, st, len, ylists[0], 2, zlists[0], zlists[1]);
|
||||
newnode = patchSplit(newnode, st, len, ylists[1], 2, zlists[2], zlists[3]);
|
||||
newnode = patchSplit(newnode, st, len, ylists[2], 2, zlists[4], zlists[5]);
|
||||
newnode = patchSplit(newnode, st, len, ylists[3], 2, zlists[6], zlists[7]);
|
||||
// Recur
|
||||
len >>= 1;
|
||||
int count = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (zlists[i] != NULL) {
|
||||
int nori[3] = {
|
||||
st[0] + len * vertmap[i][0], st[1] + len * vertmap[i][1], st[2] + len * vertmap[i][2]};
|
||||
patch(newnode->internal.get_child(count), nori, len, zlists[i]);
|
||||
}
|
||||
|
||||
// Recur
|
||||
len >>= 1;
|
||||
int count = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (zlists[i] != NULL) {
|
||||
int nori[3] = {
|
||||
st[0] + len * vertmap[i][0],
|
||||
st[1] + len * vertmap[i][1],
|
||||
st[2] + len * vertmap[i][2]
|
||||
};
|
||||
patch(newnode->internal.get_child(count), nori, len, zlists[i]);
|
||||
}
|
||||
|
||||
if (newnode->internal.has_child(i)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (newnode->internal.has_child(i)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
#ifdef IN_DEBUG_MODE
|
||||
dc_printf("Return from PATCH\n");
|
||||
dc_printf("Return from PATCH\n");
|
||||
#endif
|
||||
return newnode;
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
|
||||
Node *Octree::patchSplit(Node *newnode, int st[3], int len, PathList *rings,
|
||||
int dir, PathList *& nrings1, PathList *& nrings2)
|
||||
Node *Octree::patchSplit(Node *newnode,
|
||||
int st[3],
|
||||
int len,
|
||||
PathList *rings,
|
||||
int dir,
|
||||
PathList *&nrings1,
|
||||
PathList *&nrings2)
|
||||
{
|
||||
#ifdef IN_DEBUG_MODE
|
||||
dc_printf("Call to PATCHSPLIT with direction %d and rings: \n", dir);
|
||||
printPaths(rings);
|
||||
dc_printf("Call to PATCHSPLIT with direction %d and rings: \n", dir);
|
||||
printPaths(rings);
|
||||
#endif
|
||||
|
||||
nrings1 = NULL;
|
||||
nrings2 = NULL;
|
||||
PathList *tmp;
|
||||
while (rings != NULL) {
|
||||
// Process this ring
|
||||
newnode = patchSplitSingle(newnode, st, len, rings->head, dir, nrings1, nrings2);
|
||||
nrings1 = NULL;
|
||||
nrings2 = NULL;
|
||||
PathList *tmp;
|
||||
while (rings != NULL) {
|
||||
// Process this ring
|
||||
newnode = patchSplitSingle(newnode, st, len, rings->head, dir, nrings1, nrings2);
|
||||
|
||||
// Delete this ring from the group
|
||||
tmp = rings;
|
||||
rings = rings->next;
|
||||
delete tmp;
|
||||
}
|
||||
// Delete this ring from the group
|
||||
tmp = rings;
|
||||
rings = rings->next;
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
#ifdef IN_DEBUG_MODE
|
||||
dc_printf("Return from PATCHSPLIT with \n");
|
||||
dc_printf("Rings gourp 1:\n");
|
||||
printPaths(nrings1);
|
||||
dc_printf("Rings group 2:\n");
|
||||
printPaths(nrings2);
|
||||
dc_printf("Return from PATCHSPLIT with \n");
|
||||
dc_printf("Rings gourp 1:\n");
|
||||
printPaths(nrings1);
|
||||
dc_printf("Rings group 2:\n");
|
||||
printPaths(nrings2);
|
||||
#endif
|
||||
|
||||
return newnode;
|
||||
return newnode;
|
||||
}
|
||||
|
||||
Node *Octree::patchSplitSingle(Node *newnode, int st[3], int len, PathElement *head, int dir, PathList *& nrings1, PathList *& nrings2)
|
||||
Node *Octree::patchSplitSingle(Node *newnode,
|
||||
int st[3],
|
||||
int len,
|
||||
PathElement *head,
|
||||
int dir,
|
||||
PathList *&nrings1,
|
||||
PathList *&nrings2)
|
||||
{
|
||||
#ifdef IN_DEBUG_MODE
|
||||
dc_printf("Call to PATCHSPLITSINGLE with direction %d and path: \n", dir);
|
||||
printPath(head);
|
||||
dc_printf("Call to PATCHSPLITSINGLE with direction %d and path: \n", dir);
|
||||
printPath(head);
|
||||
#endif
|
||||
|
||||
if (head == NULL) {
|
||||
if (head == NULL) {
|
||||
#ifdef IN_DEBUG_MODE
|
||||
dc_printf("Return from PATCHSPLITSINGLE with head==NULL.\n");
|
||||
dc_printf("Return from PATCHSPLITSINGLE with head==NULL.\n");
|
||||
#endif
|
||||
return newnode;
|
||||
}
|
||||
else {
|
||||
// printPath(head);
|
||||
}
|
||||
return newnode;
|
||||
}
|
||||
else {
|
||||
// printPath(head);
|
||||
}
|
||||
|
||||
// Walk along the ring to find pair of intersections
|
||||
PathElement *pre1 = NULL;
|
||||
PathElement *pre2 = NULL;
|
||||
int side = findPair(head, st[dir] + len / 2, dir, pre1, pre2);
|
||||
// Walk along the ring to find pair of intersections
|
||||
PathElement *pre1 = NULL;
|
||||
PathElement *pre2 = NULL;
|
||||
int side = findPair(head, st[dir] + len / 2, dir, pre1, pre2);
|
||||
|
||||
/*
|
||||
if(pre1 == pre2) {
|
||||
int edgelen =(dimen >> maxDepth);
|
||||
dc_printf("Location: %d %d %d Direction: %d Reso: %d\n", st[0]/edgelen, st[1]/edgelen, st[2]/edgelen, dir, len/edgelen);
|
||||
printPath(head);
|
||||
exit(0);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if(pre1 == pre2) {
|
||||
int edgelen =(dimen >> maxDepth);
|
||||
dc_printf("Location: %d %d %d Direction: %d Reso: %d\n", st[0]/edgelen, st[1]/edgelen, st[2]/edgelen, dir, len/edgelen);
|
||||
printPath(head);
|
||||
exit(0);
|
||||
}
|
||||
*/
|
||||
|
||||
if (side) {
|
||||
// Entirely on one side
|
||||
PathList *nring = new PathList();
|
||||
nring->head = head;
|
||||
if (side) {
|
||||
// Entirely on one side
|
||||
PathList *nring = new PathList();
|
||||
nring->head = head;
|
||||
|
||||
if (side == -1) {
|
||||
nring->next = nrings1;
|
||||
nrings1 = nring;
|
||||
}
|
||||
else {
|
||||
nring->next = nrings2;
|
||||
nrings2 = nring;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Break into two parts
|
||||
PathElement *nxt1 = pre1->next;
|
||||
PathElement *nxt2 = pre2->next;
|
||||
pre1->next = nxt2;
|
||||
pre2->next = nxt1;
|
||||
if (side == -1) {
|
||||
nring->next = nrings1;
|
||||
nrings1 = nring;
|
||||
}
|
||||
else {
|
||||
nring->next = nrings2;
|
||||
nrings2 = nring;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Break into two parts
|
||||
PathElement *nxt1 = pre1->next;
|
||||
PathElement *nxt2 = pre2->next;
|
||||
pre1->next = nxt2;
|
||||
pre2->next = nxt1;
|
||||
|
||||
newnode = connectFace(newnode, st, len, dir, pre1, pre2);
|
||||
newnode = connectFace(newnode, st, len, dir, pre1, pre2);
|
||||
|
||||
if (isEqual(pre1, pre1->next)) {
|
||||
if (pre1 == pre1->next) {
|
||||
delete pre1;
|
||||
pre1 = NULL;
|
||||
}
|
||||
else {
|
||||
PathElement *temp = pre1->next;
|
||||
pre1->next = temp->next;
|
||||
delete temp;
|
||||
}
|
||||
}
|
||||
if (isEqual(pre2, pre2->next)) {
|
||||
if (pre2 == pre2->next) {
|
||||
delete pre2;
|
||||
pre2 = NULL;
|
||||
}
|
||||
else {
|
||||
PathElement *temp = pre2->next;
|
||||
pre2->next = temp->next;
|
||||
delete temp;
|
||||
}
|
||||
}
|
||||
if (isEqual(pre1, pre1->next)) {
|
||||
if (pre1 == pre1->next) {
|
||||
delete pre1;
|
||||
pre1 = NULL;
|
||||
}
|
||||
else {
|
||||
PathElement *temp = pre1->next;
|
||||
pre1->next = temp->next;
|
||||
delete temp;
|
||||
}
|
||||
}
|
||||
if (isEqual(pre2, pre2->next)) {
|
||||
if (pre2 == pre2->next) {
|
||||
delete pre2;
|
||||
pre2 = NULL;
|
||||
}
|
||||
else {
|
||||
PathElement *temp = pre2->next;
|
||||
pre2->next = temp->next;
|
||||
delete temp;
|
||||
}
|
||||
}
|
||||
|
||||
compressRing(pre1);
|
||||
compressRing(pre2);
|
||||
compressRing(pre1);
|
||||
compressRing(pre2);
|
||||
|
||||
// Recur
|
||||
newnode = patchSplitSingle(newnode, st, len, pre1, dir, nrings1, nrings2);
|
||||
newnode = patchSplitSingle(newnode, st, len, pre2, dir, nrings1, nrings2);
|
||||
|
||||
}
|
||||
// Recur
|
||||
newnode = patchSplitSingle(newnode, st, len, pre1, dir, nrings1, nrings2);
|
||||
newnode = patchSplitSingle(newnode, st, len, pre2, dir, nrings1, nrings2);
|
||||
}
|
||||
|
||||
#ifdef IN_DEBUG_MODE
|
||||
dc_printf("Return from PATCHSPLITSINGLE with \n");
|
||||
dc_printf("Rings gourp 1:\n");
|
||||
printPaths(nrings1);
|
||||
dc_printf("Rings group 2:\n");
|
||||
printPaths(nrings2);
|
||||
dc_printf("Return from PATCHSPLITSINGLE with \n");
|
||||
dc_printf("Rings gourp 1:\n");
|
||||
printPaths(nrings1);
|
||||
dc_printf("Rings group 2:\n");
|
||||
printPaths(nrings2);
|
||||
#endif
|
||||
|
||||
return newnode;
|
||||
return newnode;
|
||||
}
|
||||
|
||||
Node *Octree::connectFace(Node *newnode, int st[3], int len, int dir,
|
||||
PathElement *f1, PathElement *f2)
|
||||
Node *Octree::connectFace(
|
||||
Node *newnode, int st[3], int len, int dir, PathElement *f1, PathElement *f2)
|
||||
{
|
||||
#ifdef IN_DEBUG_MODE
|
||||
dc_printf("Call to CONNECTFACE with direction %d and length %d path: \n", dir, len);
|
||||
dc_printf("Path(low side): \n");
|
||||
printPath(f1);
|
||||
// checkPath(f1);
|
||||
dc_printf("Path(high side): \n");
|
||||
printPath(f2);
|
||||
// checkPath(f2);
|
||||
dc_printf("Call to CONNECTFACE with direction %d and length %d path: \n", dir, len);
|
||||
dc_printf("Path(low side): \n");
|
||||
printPath(f1);
|
||||
// checkPath(f1);
|
||||
dc_printf("Path(high side): \n");
|
||||
printPath(f2);
|
||||
// checkPath(f2);
|
||||
#endif
|
||||
|
||||
// Setup 2D
|
||||
int pos = st[dir] + len / 2;
|
||||
int xdir = (dir + 1) % 3;
|
||||
int ydir = (dir + 2) % 3;
|
||||
// Setup 2D
|
||||
int pos = st[dir] + len / 2;
|
||||
int xdir = (dir + 1) % 3;
|
||||
int ydir = (dir + 2) % 3;
|
||||
|
||||
// Use existing intersections on f1 and f2
|
||||
int x1, y1, x2, y2;
|
||||
float p1, q1, p2, q2;
|
||||
// Use existing intersections on f1 and f2
|
||||
int x1, y1, x2, y2;
|
||||
float p1, q1, p2, q2;
|
||||
|
||||
getFacePoint(f2->next, dir, x1, y1, p1, q1);
|
||||
getFacePoint(f2, dir, x2, y2, p2, q2);
|
||||
getFacePoint(f2->next, dir, x1, y1, p1, q1);
|
||||
getFacePoint(f2, dir, x2, y2, p2, q2);
|
||||
|
||||
float dx = x2 + p2 - x1 - p1;
|
||||
float dy = y2 + q2 - y1 - q1;
|
||||
float dx = x2 + p2 - x1 - p1;
|
||||
float dy = y2 + q2 - y1 - q1;
|
||||
|
||||
// Do adapted Bresenham line drawing
|
||||
float rx = p1, ry = q1;
|
||||
int incx = 1, incy = 1;
|
||||
int lx = x1, ly = y1;
|
||||
int hx = x2, hy = y2;
|
||||
int choice;
|
||||
if (x2 < x1) {
|
||||
incx = -1;
|
||||
rx = 1 - rx;
|
||||
lx = x2;
|
||||
hx = x1;
|
||||
}
|
||||
if (y2 < y1) {
|
||||
incy = -1;
|
||||
ry = 1 - ry;
|
||||
ly = y2;
|
||||
hy = y1;
|
||||
}
|
||||
// Do adapted Bresenham line drawing
|
||||
float rx = p1, ry = q1;
|
||||
int incx = 1, incy = 1;
|
||||
int lx = x1, ly = y1;
|
||||
int hx = x2, hy = y2;
|
||||
int choice;
|
||||
if (x2 < x1) {
|
||||
incx = -1;
|
||||
rx = 1 - rx;
|
||||
lx = x2;
|
||||
hx = x1;
|
||||
}
|
||||
if (y2 < y1) {
|
||||
incy = -1;
|
||||
ry = 1 - ry;
|
||||
ly = y2;
|
||||
hy = y1;
|
||||
}
|
||||
|
||||
float sx = dx * incx;
|
||||
float sy = dy * incy;
|
||||
float sx = dx * incx;
|
||||
float sy = dy * incy;
|
||||
|
||||
int ori[3];
|
||||
ori[dir] = pos / mindimen;
|
||||
ori[xdir] = x1;
|
||||
ori[ydir] = y1;
|
||||
int walkdir;
|
||||
int inc;
|
||||
float alpha;
|
||||
int ori[3];
|
||||
ori[dir] = pos / mindimen;
|
||||
ori[xdir] = x1;
|
||||
ori[ydir] = y1;
|
||||
int walkdir;
|
||||
int inc;
|
||||
float alpha;
|
||||
|
||||
PathElement *curEleN = f1;
|
||||
PathElement *curEleP = f2->next;
|
||||
Node *nodeN = NULL, *nodeP = NULL;
|
||||
LeafNode *curN = locateLeaf(&newnode->internal, len, f1->pos);
|
||||
LeafNode *curP = locateLeaf(&newnode->internal, len, f2->next->pos);
|
||||
if (curN == NULL || curP == NULL) {
|
||||
exit(0);
|
||||
}
|
||||
int stN[3], stP[3];
|
||||
int lenN, lenP;
|
||||
PathElement *curEleN = f1;
|
||||
PathElement *curEleP = f2->next;
|
||||
Node *nodeN = NULL, *nodeP = NULL;
|
||||
LeafNode *curN = locateLeaf(&newnode->internal, len, f1->pos);
|
||||
LeafNode *curP = locateLeaf(&newnode->internal, len, f2->next->pos);
|
||||
if (curN == NULL || curP == NULL) {
|
||||
exit(0);
|
||||
}
|
||||
int stN[3], stP[3];
|
||||
int lenN, lenP;
|
||||
|
||||
/* Unused code, leaving for posterity
|
||||
/* Unused code, leaving for posterity
|
||||
|
||||
float stpt[3], edpt[3];
|
||||
stpt[dir] = edpt[dir] =(float) pos;
|
||||
stpt[xdir] =(x1 + p1) * mindimen;
|
||||
stpt[ydir] =(y1 + q1) * mindimen;
|
||||
edpt[xdir] =(x2 + p2) * mindimen;
|
||||
edpt[ydir] =(y2 + q2) * mindimen;
|
||||
*/
|
||||
while (ori[xdir] != x2 || ori[ydir] != y2) {
|
||||
int next;
|
||||
if (sy * (1 - rx) > sx * (1 - ry)) {
|
||||
choice = 1;
|
||||
next = ori[ydir] + incy;
|
||||
if (next < ly || next > hy) {
|
||||
choice = 4;
|
||||
next = ori[xdir] + incx;
|
||||
}
|
||||
}
|
||||
else {
|
||||
choice = 2;
|
||||
next = ori[xdir] + incx;
|
||||
if (next < lx || next > hx) {
|
||||
choice = 3;
|
||||
next = ori[ydir] + incy;
|
||||
}
|
||||
}
|
||||
float stpt[3], edpt[3];
|
||||
stpt[dir] = edpt[dir] =(float) pos;
|
||||
stpt[xdir] =(x1 + p1) * mindimen;
|
||||
stpt[ydir] =(y1 + q1) * mindimen;
|
||||
edpt[xdir] =(x2 + p2) * mindimen;
|
||||
edpt[ydir] =(y2 + q2) * mindimen;
|
||||
*/
|
||||
while (ori[xdir] != x2 || ori[ydir] != y2) {
|
||||
int next;
|
||||
if (sy * (1 - rx) > sx * (1 - ry)) {
|
||||
choice = 1;
|
||||
next = ori[ydir] + incy;
|
||||
if (next < ly || next > hy) {
|
||||
choice = 4;
|
||||
next = ori[xdir] + incx;
|
||||
}
|
||||
}
|
||||
else {
|
||||
choice = 2;
|
||||
next = ori[xdir] + incx;
|
||||
if (next < lx || next > hx) {
|
||||
choice = 3;
|
||||
next = ori[ydir] + incy;
|
||||
}
|
||||
}
|
||||
|
||||
if (choice & 1) {
|
||||
ori[ydir] = next;
|
||||
if (choice == 1) {
|
||||
rx += (sy == 0 ? 0 : (1 - ry) * sx / sy);
|
||||
ry = 0;
|
||||
}
|
||||
if (choice & 1) {
|
||||
ori[ydir] = next;
|
||||
if (choice == 1) {
|
||||
rx += (sy == 0 ? 0 : (1 - ry) * sx / sy);
|
||||
ry = 0;
|
||||
}
|
||||
|
||||
walkdir = 2;
|
||||
inc = incy;
|
||||
alpha = x2 < x1 ? 1 - rx : rx;
|
||||
}
|
||||
else {
|
||||
ori[xdir] = next;
|
||||
if (choice == 2) {
|
||||
ry += (sx == 0 ? 0 : (1 - rx) * sy / sx);
|
||||
rx = 0;
|
||||
}
|
||||
walkdir = 2;
|
||||
inc = incy;
|
||||
alpha = x2 < x1 ? 1 - rx : rx;
|
||||
}
|
||||
else {
|
||||
ori[xdir] = next;
|
||||
if (choice == 2) {
|
||||
ry += (sx == 0 ? 0 : (1 - rx) * sy / sx);
|
||||
rx = 0;
|
||||
}
|
||||
|
||||
walkdir = 1;
|
||||
inc = incx;
|
||||
alpha = y2 < y1 ? 1 - ry : ry;
|
||||
}
|
||||
walkdir = 1;
|
||||
inc = incx;
|
||||
alpha = y2 < y1 ? 1 - ry : ry;
|
||||
}
|
||||
|
||||
// Get the exact location of the marcher
|
||||
int nori[3] = {ori[0] * mindimen, ori[1] * mindimen, ori[2] * mindimen};
|
||||
float spt[3] = {(float)nori[0], (float)nori[1], (float)nori[2]};
|
||||
spt[(dir + (3 - walkdir)) % 3] += alpha * mindimen;
|
||||
if (inc < 0) {
|
||||
spt[(dir + walkdir) % 3] += mindimen;
|
||||
}
|
||||
|
||||
// dc_printf("new x,y: %d %d\n", ori[xdir] / edgelen, ori[ydir] / edgelen);
|
||||
// dc_printf("nori: %d %d %d alpha: %f walkdir: %d\n", nori[0], nori[1], nori[2], alpha, walkdir);
|
||||
// dc_printf("%f %f %f\n", spt[0], spt[1], spt[2]);
|
||||
|
||||
// Get the exact location of the marcher
|
||||
int nori[3] = {ori[0] * mindimen, ori[1] * mindimen, ori[2] * mindimen};
|
||||
float spt[3] = {(float) nori[0], (float) nori[1], (float) nori[2]};
|
||||
spt[(dir + (3 - walkdir)) % 3] += alpha * mindimen;
|
||||
if (inc < 0) {
|
||||
spt[(dir + walkdir) % 3] += mindimen;
|
||||
}
|
||||
// Locate the current cells on both sides
|
||||
newnode = locateCell(&newnode->internal, st, len, nori, dir, 1, nodeN, stN, lenN);
|
||||
newnode = locateCell(&newnode->internal, st, len, nori, dir, 0, nodeP, stP, lenP);
|
||||
|
||||
// dc_printf("new x,y: %d %d\n", ori[xdir] / edgelen, ori[ydir] / edgelen);
|
||||
// dc_printf("nori: %d %d %d alpha: %f walkdir: %d\n", nori[0], nori[1], nori[2], alpha, walkdir);
|
||||
// dc_printf("%f %f %f\n", spt[0], spt[1], spt[2]);
|
||||
updateParent(&newnode->internal, len, st);
|
||||
|
||||
// Locate the current cells on both sides
|
||||
newnode = locateCell(&newnode->internal, st, len, nori, dir, 1, nodeN, stN, lenN);
|
||||
newnode = locateCell(&newnode->internal, st, len, nori, dir, 0, nodeP, stP, lenP);
|
||||
int flag = 0;
|
||||
// Add the cells to the rings and fill in the patch
|
||||
PathElement *newEleN;
|
||||
if (curEleN->pos[0] != stN[0] || curEleN->pos[1] != stN[1] || curEleN->pos[2] != stN[2]) {
|
||||
if (curEleN->next->pos[0] != stN[0] || curEleN->next->pos[1] != stN[1] ||
|
||||
curEleN->next->pos[2] != stN[2]) {
|
||||
newEleN = new PathElement;
|
||||
newEleN->next = curEleN->next;
|
||||
newEleN->pos[0] = stN[0];
|
||||
newEleN->pos[1] = stN[1];
|
||||
newEleN->pos[2] = stN[2];
|
||||
|
||||
updateParent(&newnode->internal, len, st);
|
||||
curEleN->next = newEleN;
|
||||
}
|
||||
else {
|
||||
newEleN = curEleN->next;
|
||||
}
|
||||
curN = patchAdjacent(&newnode->internal,
|
||||
len,
|
||||
curEleN->pos,
|
||||
curN,
|
||||
newEleN->pos,
|
||||
(LeafNode *)nodeN,
|
||||
walkdir,
|
||||
inc,
|
||||
dir,
|
||||
1,
|
||||
alpha);
|
||||
|
||||
int flag = 0;
|
||||
// Add the cells to the rings and fill in the patch
|
||||
PathElement *newEleN;
|
||||
if (curEleN->pos[0] != stN[0] || curEleN->pos[1] != stN[1] || curEleN->pos[2] != stN[2]) {
|
||||
if (curEleN->next->pos[0] != stN[0] || curEleN->next->pos[1] != stN[1] || curEleN->next->pos[2] != stN[2]) {
|
||||
newEleN = new PathElement;
|
||||
newEleN->next = curEleN->next;
|
||||
newEleN->pos[0] = stN[0];
|
||||
newEleN->pos[1] = stN[1];
|
||||
newEleN->pos[2] = stN[2];
|
||||
curEleN = newEleN;
|
||||
flag++;
|
||||
}
|
||||
|
||||
curEleN->next = newEleN;
|
||||
}
|
||||
else {
|
||||
newEleN = curEleN->next;
|
||||
}
|
||||
curN = patchAdjacent(&newnode->internal, len, curEleN->pos, curN,
|
||||
newEleN->pos, (LeafNode *)nodeN, walkdir,
|
||||
inc, dir, 1, alpha);
|
||||
PathElement *newEleP;
|
||||
if (curEleP->pos[0] != stP[0] || curEleP->pos[1] != stP[1] || curEleP->pos[2] != stP[2]) {
|
||||
if (f2->pos[0] != stP[0] || f2->pos[1] != stP[1] || f2->pos[2] != stP[2]) {
|
||||
newEleP = new PathElement;
|
||||
newEleP->next = curEleP;
|
||||
newEleP->pos[0] = stP[0];
|
||||
newEleP->pos[1] = stP[1];
|
||||
newEleP->pos[2] = stP[2];
|
||||
|
||||
curEleN = newEleN;
|
||||
flag++;
|
||||
}
|
||||
f2->next = newEleP;
|
||||
}
|
||||
else {
|
||||
newEleP = f2;
|
||||
}
|
||||
curP = patchAdjacent(&newnode->internal,
|
||||
len,
|
||||
curEleP->pos,
|
||||
curP,
|
||||
newEleP->pos,
|
||||
(LeafNode *)nodeP,
|
||||
walkdir,
|
||||
inc,
|
||||
dir,
|
||||
0,
|
||||
alpha);
|
||||
|
||||
PathElement *newEleP;
|
||||
if (curEleP->pos[0] != stP[0] || curEleP->pos[1] != stP[1] || curEleP->pos[2] != stP[2]) {
|
||||
if (f2->pos[0] != stP[0] || f2->pos[1] != stP[1] || f2->pos[2] != stP[2]) {
|
||||
newEleP = new PathElement;
|
||||
newEleP->next = curEleP;
|
||||
newEleP->pos[0] = stP[0];
|
||||
newEleP->pos[1] = stP[1];
|
||||
newEleP->pos[2] = stP[2];
|
||||
curEleP = newEleP;
|
||||
flag++;
|
||||
}
|
||||
|
||||
f2->next = newEleP;
|
||||
}
|
||||
else {
|
||||
newEleP = f2;
|
||||
}
|
||||
curP = patchAdjacent(&newnode->internal, len, curEleP->pos, curP,
|
||||
newEleP->pos, (LeafNode *)nodeP, walkdir,
|
||||
inc, dir, 0, alpha);
|
||||
|
||||
|
||||
|
||||
curEleP = newEleP;
|
||||
flag++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
if(flag == 0) {
|
||||
dc_printf("error: non-synchronized patching! at \n");
|
||||
}
|
||||
*/
|
||||
}
|
||||
/*
|
||||
if(flag == 0) {
|
||||
dc_printf("error: non-synchronized patching! at \n");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
#ifdef IN_DEBUG_MODE
|
||||
dc_printf("Return from CONNECTFACE with \n");
|
||||
dc_printf("Path(low side):\n");
|
||||
printPath(f1);
|
||||
checkPath(f1);
|
||||
dc_printf("Path(high side):\n");
|
||||
printPath(f2);
|
||||
checkPath(f2);
|
||||
dc_printf("Return from CONNECTFACE with \n");
|
||||
dc_printf("Path(low side):\n");
|
||||
printPath(f1);
|
||||
checkPath(f1);
|
||||
dc_printf("Path(high side):\n");
|
||||
printPath(f2);
|
||||
checkPath(f2);
|
||||
#endif
|
||||
|
||||
|
||||
return newnode;
|
||||
return newnode;
|
||||
}
|
||||
|
||||
LeafNode *Octree::patchAdjacent(InternalNode *node, int len, int st1[3],
|
||||
LeafNode *leaf1, int st2[3], LeafNode *leaf2,
|
||||
int walkdir, int inc, int dir, int side,
|
||||
LeafNode *Octree::patchAdjacent(InternalNode *node,
|
||||
int len,
|
||||
int st1[3],
|
||||
LeafNode *leaf1,
|
||||
int st2[3],
|
||||
LeafNode *leaf2,
|
||||
int walkdir,
|
||||
int inc,
|
||||
int dir,
|
||||
int side,
|
||||
float alpha)
|
||||
{
|
||||
#ifdef IN_DEBUG_MODE
|
||||
dc_printf("Before patching.\n");
|
||||
printInfo(st1);
|
||||
printInfo(st2);
|
||||
dc_printf("-----------------%d %d %d; %d %d %d\n", st1[0], st2[1], st1[2], st2[0], st2[1], st2[2]);
|
||||
dc_printf("Before patching.\n");
|
||||
printInfo(st1);
|
||||
printInfo(st2);
|
||||
dc_printf(
|
||||
"-----------------%d %d %d; %d %d %d\n", st1[0], st2[1], st1[2], st2[0], st2[1], st2[2]);
|
||||
#endif
|
||||
|
||||
// Get edge index on each leaf
|
||||
int edgedir = (dir + (3 - walkdir)) % 3;
|
||||
int incdir = (dir + walkdir) % 3;
|
||||
int ind1 = (edgedir == 1 ? (dir + 3 - edgedir) % 3 - 1 : 2 - (dir + 3 - edgedir) % 3);
|
||||
int ind2 = (edgedir == 1 ? (incdir + 3 - edgedir) % 3 - 1 : 2 - (incdir + 3 - edgedir) % 3);
|
||||
// Get edge index on each leaf
|
||||
int edgedir = (dir + (3 - walkdir)) % 3;
|
||||
int incdir = (dir + walkdir) % 3;
|
||||
int ind1 = (edgedir == 1 ? (dir + 3 - edgedir) % 3 - 1 : 2 - (dir + 3 - edgedir) % 3);
|
||||
int ind2 = (edgedir == 1 ? (incdir + 3 - edgedir) % 3 - 1 : 2 - (incdir + 3 - edgedir) % 3);
|
||||
|
||||
int eind1 = ((edgedir << 2) | (side << ind1) | ((inc > 0 ? 1 : 0) << ind2));
|
||||
int eind2 = ((edgedir << 2) | (side << ind1) | ((inc > 0 ? 0 : 1) << ind2));
|
||||
int eind1 = ((edgedir << 2) | (side << ind1) | ((inc > 0 ? 1 : 0) << ind2));
|
||||
int eind2 = ((edgedir << 2) | (side << ind1) | ((inc > 0 ? 0 : 1) << ind2));
|
||||
|
||||
#ifdef IN_DEBUG_MODE
|
||||
dc_printf("Index 1: %d Alpha 1: %f Index 2: %d Alpha 2: %f\n", eind1, alpha, eind2, alpha);
|
||||
/*
|
||||
if(alpha < 0 || alpha > 1) {
|
||||
dc_printf("Index 1: %d Alpha 1: %f Index 2: %d Alpha 2: %f\n", eind1, alpha, eind2, alpha);
|
||||
printInfo(st1);
|
||||
printInfo(st2);
|
||||
}
|
||||
*/
|
||||
dc_printf("Index 1: %d Alpha 1: %f Index 2: %d Alpha 2: %f\n", eind1, alpha, eind2, alpha);
|
||||
/*
|
||||
if(alpha < 0 || alpha > 1) {
|
||||
dc_printf("Index 1: %d Alpha 1: %f Index 2: %d Alpha 2: %f\n", eind1, alpha, eind2, alpha);
|
||||
printInfo(st1);
|
||||
printInfo(st2);
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
// Flip edge parity
|
||||
LeafNode *nleaf1 = flipEdge(leaf1, eind1, alpha);
|
||||
LeafNode *nleaf2 = flipEdge(leaf2, eind2, alpha);
|
||||
// Flip edge parity
|
||||
LeafNode *nleaf1 = flipEdge(leaf1, eind1, alpha);
|
||||
LeafNode *nleaf2 = flipEdge(leaf2, eind2, alpha);
|
||||
|
||||
// Update parent link
|
||||
updateParent(node, len, st1, nleaf1);
|
||||
updateParent(node, len, st2, nleaf2);
|
||||
// updateParent(nleaf1, mindimen, st1);
|
||||
// updateParent(nleaf2, mindimen, st2);
|
||||
// Update parent link
|
||||
updateParent(node, len, st1, nleaf1);
|
||||
updateParent(node, len, st2, nleaf2);
|
||||
// updateParent(nleaf1, mindimen, st1);
|
||||
// updateParent(nleaf2, mindimen, st2);
|
||||
|
||||
/*
|
||||
float m[3];
|
||||
dc_printf("Adding new point: %f %f %f\n", spt[0], spt[1], spt[2]);
|
||||
getMinimizer(leaf1, m);
|
||||
dc_printf("Cell %d now has minimizer %f %f %f\n", leaf1, m[0], m[1], m[2]);
|
||||
getMinimizer(leaf2, m);
|
||||
dc_printf("Cell %d now has minimizer %f %f %f\n", leaf2, m[0], m[1], m[2]);
|
||||
*/
|
||||
/*
|
||||
float m[3];
|
||||
dc_printf("Adding new point: %f %f %f\n", spt[0], spt[1], spt[2]);
|
||||
getMinimizer(leaf1, m);
|
||||
dc_printf("Cell %d now has minimizer %f %f %f\n", leaf1, m[0], m[1], m[2]);
|
||||
getMinimizer(leaf2, m);
|
||||
dc_printf("Cell %d now has minimizer %f %f %f\n", leaf2, m[0], m[1], m[2]);
|
||||
*/
|
||||
|
||||
#ifdef IN_DEBUG_MODE
|
||||
dc_printf("After patching.\n");
|
||||
printInfo(st1);
|
||||
printInfo(st2);
|
||||
dc_printf("After patching.\n");
|
||||
printInfo(st1);
|
||||
printInfo(st2);
|
||||
#endif
|
||||
return nleaf2;
|
||||
return nleaf2;
|
||||
}
|
||||
|
||||
Node *Octree::locateCell(InternalNode *node, int st[3], int len, int ori[3], int dir, int side, Node *& rleaf, int rst[3], int& rlen)
|
||||
Node *Octree::locateCell(InternalNode *node,
|
||||
int st[3],
|
||||
int len,
|
||||
int ori[3],
|
||||
int dir,
|
||||
int side,
|
||||
Node *&rleaf,
|
||||
int rst[3],
|
||||
int &rlen)
|
||||
{
|
||||
#ifdef IN_DEBUG_MODE
|
||||
// dc_printf("Call to LOCATECELL with node ");
|
||||
// printNode(node);
|
||||
// dc_printf("Call to LOCATECELL with node ");
|
||||
// printNode(node);
|
||||
#endif
|
||||
|
||||
int i;
|
||||
len >>= 1;
|
||||
int ind = 0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
ind <<= 1;
|
||||
if (i == dir && side == 1) {
|
||||
ind |= (ori[i] <= (st[i] + len) ? 0 : 1);
|
||||
}
|
||||
else {
|
||||
ind |= (ori[i] < (st[i] + len) ? 0 : 1);
|
||||
}
|
||||
}
|
||||
int i;
|
||||
len >>= 1;
|
||||
int ind = 0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
ind <<= 1;
|
||||
if (i == dir && side == 1) {
|
||||
ind |= (ori[i] <= (st[i] + len) ? 0 : 1);
|
||||
}
|
||||
else {
|
||||
ind |= (ori[i] < (st[i] + len) ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef IN_DEBUG_MODE
|
||||
// dc_printf("In LOCATECELL index of ori(%d %d %d) with dir %d side %d in st(%d %d %d, %d) is: %d\n",
|
||||
// ori[0], ori[1], ori[2], dir, side, st[0], st[1], st[2], len, ind);
|
||||
// dc_printf("In LOCATECELL index of ori(%d %d %d) with dir %d side %d in st(%d %d %d, %d) is: %d\n",
|
||||
// ori[0], ori[1], ori[2], dir, side, st[0], st[1], st[2], len, ind);
|
||||
#endif
|
||||
|
||||
rst[0] = st[0] + vertmap[ind][0] * len;
|
||||
rst[1] = st[1] + vertmap[ind][1] * len;
|
||||
rst[2] = st[2] + vertmap[ind][2] * len;
|
||||
rst[0] = st[0] + vertmap[ind][0] * len;
|
||||
rst[1] = st[1] + vertmap[ind][1] * len;
|
||||
rst[2] = st[2] + vertmap[ind][2] * len;
|
||||
|
||||
if (node->has_child(ind)) {
|
||||
int count = node->get_child_count(ind);
|
||||
Node *chd = node->get_child(count);
|
||||
if (node->is_child_leaf(ind)) {
|
||||
rleaf = chd;
|
||||
rlen = len;
|
||||
}
|
||||
else {
|
||||
// Recur
|
||||
node->set_child(count, locateCell(&chd->internal, rst, len, ori, dir, side, rleaf, rst, rlen));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Create a new child here
|
||||
if (len == mindimen) {
|
||||
LeafNode *chd = createLeaf(0);
|
||||
node = addChild(node, ind, (Node *)chd, 1);
|
||||
rleaf = (Node *)chd;
|
||||
rlen = len;
|
||||
}
|
||||
else {
|
||||
// Subdivide the empty cube
|
||||
InternalNode *chd = createInternal(0);
|
||||
node = addChild(node, ind,
|
||||
locateCell(chd, rst, len, ori, dir, side, rleaf, rst, rlen), 0);
|
||||
}
|
||||
}
|
||||
if (node->has_child(ind)) {
|
||||
int count = node->get_child_count(ind);
|
||||
Node *chd = node->get_child(count);
|
||||
if (node->is_child_leaf(ind)) {
|
||||
rleaf = chd;
|
||||
rlen = len;
|
||||
}
|
||||
else {
|
||||
// Recur
|
||||
node->set_child(count,
|
||||
locateCell(&chd->internal, rst, len, ori, dir, side, rleaf, rst, rlen));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Create a new child here
|
||||
if (len == mindimen) {
|
||||
LeafNode *chd = createLeaf(0);
|
||||
node = addChild(node, ind, (Node *)chd, 1);
|
||||
rleaf = (Node *)chd;
|
||||
rlen = len;
|
||||
}
|
||||
else {
|
||||
// Subdivide the empty cube
|
||||
InternalNode *chd = createInternal(0);
|
||||
node = addChild(node, ind, locateCell(chd, rst, len, ori, dir, side, rleaf, rst, rlen), 0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef IN_DEBUG_MODE
|
||||
// dc_printf("Return from LOCATECELL with node ");
|
||||
// printNode(newnode);
|
||||
// dc_printf("Return from LOCATECELL with node ");
|
||||
// printNode(newnode);
|
||||
#endif
|
||||
return (Node *)node;
|
||||
return (Node *)node;
|
||||
}
|
||||
|
||||
void Octree::checkElement(PathElement * /*ele*/)
|
||||
{
|
||||
/*
|
||||
if(ele != NULL && locateLeafCheck(ele->pos) != ele->node) {
|
||||
dc_printf("Screwed! at pos: %d %d %d\n", ele->pos[0]>>minshift, ele->pos[1]>>minshift, ele->pos[2]>>minshift);
|
||||
exit(0);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if(ele != NULL && locateLeafCheck(ele->pos) != ele->node) {
|
||||
dc_printf("Screwed! at pos: %d %d %d\n", ele->pos[0]>>minshift, ele->pos[1]>>minshift, ele->pos[2]>>minshift);
|
||||
exit(0);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void Octree::checkPath(PathElement *path)
|
||||
{
|
||||
PathElement *n = path;
|
||||
int same = 0;
|
||||
while (n && (same == 0 || n != path)) {
|
||||
same++;
|
||||
checkElement(n);
|
||||
n = n->next;
|
||||
}
|
||||
|
||||
PathElement *n = path;
|
||||
int same = 0;
|
||||
while (n && (same == 0 || n != path)) {
|
||||
same++;
|
||||
checkElement(n);
|
||||
n = n->next;
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::testFacePoint(PathElement *e1, PathElement *e2)
|
||||
{
|
||||
int i;
|
||||
PathElement *e = NULL;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (e1->pos[i] != e2->pos[i]) {
|
||||
if (e1->pos[i] < e2->pos[i]) {
|
||||
e = e2;
|
||||
}
|
||||
else {
|
||||
e = e1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
int i;
|
||||
PathElement *e = NULL;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (e1->pos[i] != e2->pos[i]) {
|
||||
if (e1->pos[i] < e2->pos[i]) {
|
||||
e = e2;
|
||||
}
|
||||
else {
|
||||
e = e1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int x, y;
|
||||
float p, q;
|
||||
dc_printf("Test.");
|
||||
getFacePoint(e, i, x, y, p, q);
|
||||
int x, y;
|
||||
float p, q;
|
||||
dc_printf("Test.");
|
||||
getFacePoint(e, i, x, y, p, q);
|
||||
}
|
||||
|
||||
void Octree::getFacePoint(PathElement *leaf, int dir, int& x, int& y, float& p, float& q)
|
||||
void Octree::getFacePoint(PathElement *leaf, int dir, int &x, int &y, float &p, float &q)
|
||||
{
|
||||
// Find average intersections
|
||||
float avg[3] = {0, 0, 0};
|
||||
float off[3];
|
||||
int num = 0, num2 = 0;
|
||||
// Find average intersections
|
||||
float avg[3] = {0, 0, 0};
|
||||
float off[3];
|
||||
int num = 0, num2 = 0;
|
||||
|
||||
LeafNode *leafnode = locateLeaf(leaf->pos);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int edgeind = faceMap[dir * 2][i];
|
||||
int nst[3];
|
||||
for (int j = 0; j < 3; j++) {
|
||||
nst[j] = leaf->pos[j] + mindimen * vertmap[edgemap[edgeind][0]][j];
|
||||
}
|
||||
LeafNode *leafnode = locateLeaf(leaf->pos);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int edgeind = faceMap[dir * 2][i];
|
||||
int nst[3];
|
||||
for (int j = 0; j < 3; j++) {
|
||||
nst[j] = leaf->pos[j] + mindimen * vertmap[edgemap[edgeind][0]][j];
|
||||
}
|
||||
|
||||
if (getEdgeIntersectionByIndex(nst, edgeind / 4, off, 1)) {
|
||||
avg[0] += off[0];
|
||||
avg[1] += off[1];
|
||||
avg[2] += off[2];
|
||||
num++;
|
||||
}
|
||||
if (getEdgeParity(leafnode, edgeind)) {
|
||||
num2++;
|
||||
}
|
||||
}
|
||||
if (num == 0) {
|
||||
dc_printf("Wrong! dir: %d pos: %d %d %d num: %d\n", dir, leaf->pos[0] >> minshift, leaf->pos[1] >> minshift, leaf->pos[2] >> minshift, num2);
|
||||
avg[0] = (float) leaf->pos[0];
|
||||
avg[1] = (float) leaf->pos[1];
|
||||
avg[2] = (float) leaf->pos[2];
|
||||
}
|
||||
else {
|
||||
if (getEdgeIntersectionByIndex(nst, edgeind / 4, off, 1)) {
|
||||
avg[0] += off[0];
|
||||
avg[1] += off[1];
|
||||
avg[2] += off[2];
|
||||
num++;
|
||||
}
|
||||
if (getEdgeParity(leafnode, edgeind)) {
|
||||
num2++;
|
||||
}
|
||||
}
|
||||
if (num == 0) {
|
||||
dc_printf("Wrong! dir: %d pos: %d %d %d num: %d\n",
|
||||
dir,
|
||||
leaf->pos[0] >> minshift,
|
||||
leaf->pos[1] >> minshift,
|
||||
leaf->pos[2] >> minshift,
|
||||
num2);
|
||||
avg[0] = (float)leaf->pos[0];
|
||||
avg[1] = (float)leaf->pos[1];
|
||||
avg[2] = (float)leaf->pos[2];
|
||||
}
|
||||
else {
|
||||
|
||||
avg[0] /= num;
|
||||
avg[1] /= num;
|
||||
avg[2] /= num;
|
||||
avg[0] /= num;
|
||||
avg[1] /= num;
|
||||
avg[2] /= num;
|
||||
|
||||
//avg[0] =(float) leaf->pos[0];
|
||||
//avg[1] =(float) leaf->pos[1];
|
||||
//avg[2] =(float) leaf->pos[2];
|
||||
}
|
||||
//avg[0] =(float) leaf->pos[0];
|
||||
//avg[1] =(float) leaf->pos[1];
|
||||
//avg[2] =(float) leaf->pos[2];
|
||||
}
|
||||
|
||||
int xdir = (dir + 1) % 3;
|
||||
int ydir = (dir + 2) % 3;
|
||||
int xdir = (dir + 1) % 3;
|
||||
int ydir = (dir + 2) % 3;
|
||||
|
||||
float xf = avg[xdir];
|
||||
float yf = avg[ydir];
|
||||
float xf = avg[xdir];
|
||||
float yf = avg[ydir];
|
||||
|
||||
#ifdef IN_DEBUG_MODE
|
||||
// Is it outside?
|
||||
// PathElement* leaf = leaf1->len < leaf2->len ? leaf1 : leaf2;
|
||||
/*
|
||||
float* m =(leaf == leaf1 ? m1 : m2);
|
||||
if(xf < leaf->pos[xdir] ||
|
||||
yf < leaf->pos[ydir] ||
|
||||
xf > leaf->pos[xdir] + leaf->len ||
|
||||
yf > leaf->pos[ydir] + leaf->len) {
|
||||
dc_printf("Outside cube(%d %d %d), %d : %d %d %f %f\n", leaf->pos[0], leaf->pos[1], leaf->pos[2], leaf->len,
|
||||
pos, dir, xf, yf);
|
||||
// Is it outside?
|
||||
// PathElement* leaf = leaf1->len < leaf2->len ? leaf1 : leaf2;
|
||||
/*
|
||||
float* m =(leaf == leaf1 ? m1 : m2);
|
||||
if(xf < leaf->pos[xdir] ||
|
||||
yf < leaf->pos[ydir] ||
|
||||
xf > leaf->pos[xdir] + leaf->len ||
|
||||
yf > leaf->pos[ydir] + leaf->len) {
|
||||
dc_printf("Outside cube(%d %d %d), %d : %d %d %f %f\n", leaf->pos[0], leaf->pos[1], leaf->pos[2], leaf->len,
|
||||
pos, dir, xf, yf);
|
||||
|
||||
// For now, snap to cell
|
||||
xf = m[xdir];
|
||||
yf = m[ydir];
|
||||
}
|
||||
*/
|
||||
// For now, snap to cell
|
||||
xf = m[xdir];
|
||||
yf = m[ydir];
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
if(alpha < 0 || alpha > 1 ||
|
||||
xf < leaf->pos[xdir] || xf > leaf->pos[xdir] + leaf->len ||
|
||||
yf < leaf->pos[ydir] || yf > leaf->pos[ydir] + leaf->len) {
|
||||
dc_printf("Alpha: %f Address: %d and %d\n", alpha, leaf1->node, leaf2->node);
|
||||
dc_printf("GETFACEPOINT result:(%d %d %d) %d min:(%f %f %f);(%d %d %d) %d min:(%f %f %f).\n",
|
||||
leaf1->pos[0], leaf1->pos[1], leaf1->pos[2], leaf1->len, m1[0], m1[1], m1[2],
|
||||
leaf2->pos[0], leaf2->pos[1], leaf2->pos[2], leaf2->len, m2[0], m2[1], m2[2]);
|
||||
dc_printf("Face point at dir %d pos %d: %f %f\n", dir, pos, xf, yf);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if(alpha < 0 || alpha > 1 ||
|
||||
xf < leaf->pos[xdir] || xf > leaf->pos[xdir] + leaf->len ||
|
||||
yf < leaf->pos[ydir] || yf > leaf->pos[ydir] + leaf->len) {
|
||||
dc_printf("Alpha: %f Address: %d and %d\n", alpha, leaf1->node, leaf2->node);
|
||||
dc_printf("GETFACEPOINT result:(%d %d %d) %d min:(%f %f %f);(%d %d %d) %d min:(%f %f %f).\n",
|
||||
leaf1->pos[0], leaf1->pos[1], leaf1->pos[2], leaf1->len, m1[0], m1[1], m1[2],
|
||||
leaf2->pos[0], leaf2->pos[1], leaf2->pos[2], leaf2->len, m2[0], m2[1], m2[2]);
|
||||
dc_printf("Face point at dir %d pos %d: %f %f\n", dir, pos, xf, yf);
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
// Get the integer and float part
|
||||
x = ((leaf->pos[xdir]) >> minshift);
|
||||
y = ((leaf->pos[ydir]) >> minshift);
|
||||
|
||||
// Get the integer and float part
|
||||
x = ((leaf->pos[xdir]) >> minshift);
|
||||
y = ((leaf->pos[ydir]) >> minshift);
|
||||
|
||||
p = (xf - leaf->pos[xdir]) / mindimen;
|
||||
q = (yf - leaf->pos[ydir]) / mindimen;
|
||||
|
||||
p = (xf - leaf->pos[xdir]) / mindimen;
|
||||
q = (yf - leaf->pos[ydir]) / mindimen;
|
||||
|
||||
#ifdef IN_DEBUG_MODE
|
||||
dc_printf("Face point at dir %d : %f %f\n", dir, xf, yf);
|
||||
dc_printf("Face point at dir %d : %f %f\n", dir, xf, yf);
|
||||
#endif
|
||||
}
|
||||
|
||||
int Octree::findPair(PathElement *head, int pos, int dir, PathElement *& pre1, PathElement *& pre2)
|
||||
int Octree::findPair(PathElement *head, int pos, int dir, PathElement *&pre1, PathElement *&pre2)
|
||||
{
|
||||
int side = getSide(head, pos, dir);
|
||||
PathElement *cur = head;
|
||||
PathElement *anchor;
|
||||
PathElement *ppre1, *ppre2;
|
||||
int side = getSide(head, pos, dir);
|
||||
PathElement *cur = head;
|
||||
PathElement *anchor;
|
||||
PathElement *ppre1, *ppre2;
|
||||
|
||||
// Start from this face, find a pair
|
||||
anchor = cur;
|
||||
ppre1 = cur;
|
||||
cur = cur->next;
|
||||
while (cur != anchor && (getSide(cur, pos, dir) == side)) {
|
||||
ppre1 = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
if (cur == anchor) {
|
||||
// No pair found
|
||||
return side;
|
||||
}
|
||||
// Start from this face, find a pair
|
||||
anchor = cur;
|
||||
ppre1 = cur;
|
||||
cur = cur->next;
|
||||
while (cur != anchor && (getSide(cur, pos, dir) == side)) {
|
||||
ppre1 = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
if (cur == anchor) {
|
||||
// No pair found
|
||||
return side;
|
||||
}
|
||||
|
||||
side = getSide(cur, pos, dir);
|
||||
ppre2 = cur;
|
||||
cur = cur->next;
|
||||
while (getSide(cur, pos, dir) == side) {
|
||||
ppre2 = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
side = getSide(cur, pos, dir);
|
||||
ppre2 = cur;
|
||||
cur = cur->next;
|
||||
while (getSide(cur, pos, dir) == side) {
|
||||
ppre2 = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// Switch pre1 and pre2 if we start from the higher side
|
||||
if (side == -1) {
|
||||
cur = ppre1;
|
||||
ppre1 = ppre2;
|
||||
ppre2 = cur;
|
||||
}
|
||||
|
||||
// Switch pre1 and pre2 if we start from the higher side
|
||||
if (side == -1) {
|
||||
cur = ppre1;
|
||||
ppre1 = ppre2;
|
||||
ppre2 = cur;
|
||||
}
|
||||
pre1 = ppre1;
|
||||
pre2 = ppre2;
|
||||
|
||||
pre1 = ppre1;
|
||||
pre2 = ppre2;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Octree::getSide(PathElement *e, int pos, int dir)
|
||||
{
|
||||
return (e->pos[dir] < pos ? -1 : 1);
|
||||
return (e->pos[dir] < pos ? -1 : 1);
|
||||
}
|
||||
|
||||
int Octree::isEqual(PathElement *e1, PathElement *e2)
|
||||
{
|
||||
return (e1->pos[0] == e2->pos[0] && e1->pos[1] == e2->pos[1] && e1->pos[2] == e2->pos[2]);
|
||||
return (e1->pos[0] == e2->pos[0] && e1->pos[1] == e2->pos[1] && e1->pos[2] == e2->pos[2]);
|
||||
}
|
||||
|
||||
void Octree::compressRing(PathElement *& ring)
|
||||
void Octree::compressRing(PathElement *&ring)
|
||||
{
|
||||
if (ring == NULL) {
|
||||
return;
|
||||
}
|
||||
if (ring == NULL) {
|
||||
return;
|
||||
}
|
||||
#ifdef IN_DEBUG_MODE
|
||||
dc_printf("Call to COMPRESSRING with path: \n");
|
||||
printPath(ring);
|
||||
dc_printf("Call to COMPRESSRING with path: \n");
|
||||
printPath(ring);
|
||||
#endif
|
||||
|
||||
PathElement *cur = ring->next->next;
|
||||
PathElement *pre = ring->next;
|
||||
PathElement *prepre = ring;
|
||||
PathElement *anchor = prepre;
|
||||
PathElement *cur = ring->next->next;
|
||||
PathElement *pre = ring->next;
|
||||
PathElement *prepre = ring;
|
||||
PathElement *anchor = prepre;
|
||||
|
||||
do {
|
||||
while (isEqual(cur, prepre)) {
|
||||
// Delete
|
||||
if (cur == prepre) {
|
||||
// The ring has shrinked to a point
|
||||
delete pre;
|
||||
delete cur;
|
||||
anchor = NULL;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
prepre->next = cur->next;
|
||||
delete pre;
|
||||
delete cur;
|
||||
pre = prepre->next;
|
||||
cur = pre->next;
|
||||
anchor = prepre;
|
||||
}
|
||||
}
|
||||
do {
|
||||
while (isEqual(cur, prepre)) {
|
||||
// Delete
|
||||
if (cur == prepre) {
|
||||
// The ring has shrinked to a point
|
||||
delete pre;
|
||||
delete cur;
|
||||
anchor = NULL;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
prepre->next = cur->next;
|
||||
delete pre;
|
||||
delete cur;
|
||||
pre = prepre->next;
|
||||
cur = pre->next;
|
||||
anchor = prepre;
|
||||
}
|
||||
}
|
||||
|
||||
if (anchor == NULL) {
|
||||
break;
|
||||
}
|
||||
if (anchor == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
prepre = pre;
|
||||
pre = cur;
|
||||
cur = cur->next;
|
||||
} while (prepre != anchor);
|
||||
prepre = pre;
|
||||
pre = cur;
|
||||
cur = cur->next;
|
||||
} while (prepre != anchor);
|
||||
|
||||
ring = anchor;
|
||||
ring = anchor;
|
||||
|
||||
#ifdef IN_DEBUG_MODE
|
||||
dc_printf("Return from COMPRESSRING with path: \n");
|
||||
printPath(ring);
|
||||
dc_printf("Return from COMPRESSRING with path: \n");
|
||||
printPath(ring);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Octree::buildSigns()
|
||||
{
|
||||
// First build a lookup table
|
||||
// dc_printf("Building up look up table...\n");
|
||||
int size = 1 << 12;
|
||||
unsigned char table[1 << 12];
|
||||
for (int i = 0; i < size; i++) {
|
||||
table[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < 256; i++) {
|
||||
int ind = 0;
|
||||
for (int j = 11; j >= 0; j--) {
|
||||
ind <<= 1;
|
||||
if (((i >> edgemap[j][0]) & 1) ^ ((i >> edgemap[j][1]) & 1)) {
|
||||
ind |= 1;
|
||||
}
|
||||
}
|
||||
// First build a lookup table
|
||||
// dc_printf("Building up look up table...\n");
|
||||
int size = 1 << 12;
|
||||
unsigned char table[1 << 12];
|
||||
for (int i = 0; i < size; i++) {
|
||||
table[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < 256; i++) {
|
||||
int ind = 0;
|
||||
for (int j = 11; j >= 0; j--) {
|
||||
ind <<= 1;
|
||||
if (((i >> edgemap[j][0]) & 1) ^ ((i >> edgemap[j][1]) & 1)) {
|
||||
ind |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
table[ind] = i;
|
||||
}
|
||||
table[ind] = i;
|
||||
}
|
||||
|
||||
// Next, traverse the grid
|
||||
int sg = 1;
|
||||
int cube[8];
|
||||
buildSigns(table, root, 0, sg, cube);
|
||||
// Next, traverse the grid
|
||||
int sg = 1;
|
||||
int cube[8];
|
||||
buildSigns(table, root, 0, sg, cube);
|
||||
}
|
||||
|
||||
void Octree::buildSigns(unsigned char table[], Node *node, int isLeaf, int sg, int rvalue[8])
|
||||
{
|
||||
if (node == NULL) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
rvalue[i] = sg;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (node == NULL) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
rvalue[i] = sg;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (isLeaf == 0) {
|
||||
// Internal node
|
||||
Node *chd[8];
|
||||
int leaf[8];
|
||||
node->internal.fill_children(chd, leaf);
|
||||
if (isLeaf == 0) {
|
||||
// Internal node
|
||||
Node *chd[8];
|
||||
int leaf[8];
|
||||
node->internal.fill_children(chd, leaf);
|
||||
|
||||
// Get the signs at the corners of the first cube
|
||||
rvalue[0] = sg;
|
||||
int oris[8];
|
||||
buildSigns(table, chd[0], leaf[0], sg, oris);
|
||||
// Get the signs at the corners of the first cube
|
||||
rvalue[0] = sg;
|
||||
int oris[8];
|
||||
buildSigns(table, chd[0], leaf[0], sg, oris);
|
||||
|
||||
// Get the rest
|
||||
int cube[8];
|
||||
for (int i = 1; i < 8; i++) {
|
||||
buildSigns(table, chd[i], leaf[i], oris[i], cube);
|
||||
rvalue[i] = cube[i];
|
||||
}
|
||||
// Get the rest
|
||||
int cube[8];
|
||||
for (int i = 1; i < 8; i++) {
|
||||
buildSigns(table, chd[i], leaf[i], oris[i], cube);
|
||||
rvalue[i] = cube[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Leaf node
|
||||
generateSigns(&node->leaf, table, sg);
|
||||
|
||||
}
|
||||
else {
|
||||
// Leaf node
|
||||
generateSigns(&node->leaf, table, sg);
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
rvalue[i] = getSign(&node->leaf, i);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 8; i++) {
|
||||
rvalue[i] = getSign(&node->leaf, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::floodFill()
|
||||
{
|
||||
// int threshold =(int)((dimen/mindimen) *(dimen/mindimen) * 0.5f);
|
||||
int st[3] = {0, 0, 0};
|
||||
// int threshold =(int)((dimen/mindimen) *(dimen/mindimen) * 0.5f);
|
||||
int st[3] = {0, 0, 0};
|
||||
|
||||
// First, check for largest component
|
||||
// size stored in -threshold
|
||||
clearProcessBits(root, maxDepth);
|
||||
int threshold = floodFill(root, st, dimen, maxDepth, 0);
|
||||
// First, check for largest component
|
||||
// size stored in -threshold
|
||||
clearProcessBits(root, maxDepth);
|
||||
int threshold = floodFill(root, st, dimen, maxDepth, 0);
|
||||
|
||||
// Next remove
|
||||
dc_printf("Largest component: %d\n", threshold);
|
||||
threshold *= thresh;
|
||||
dc_printf("Removing all components smaller than %d\n", threshold);
|
||||
|
||||
int st2[3] = {0, 0, 0};
|
||||
clearProcessBits(root, maxDepth);
|
||||
floodFill(root, st2, dimen, maxDepth, threshold);
|
||||
// Next remove
|
||||
dc_printf("Largest component: %d\n", threshold);
|
||||
threshold *= thresh;
|
||||
dc_printf("Removing all components smaller than %d\n", threshold);
|
||||
|
||||
int st2[3] = {0, 0, 0};
|
||||
clearProcessBits(root, maxDepth);
|
||||
floodFill(root, st2, dimen, maxDepth, threshold);
|
||||
}
|
||||
|
||||
void Octree::clearProcessBits(Node *node, int height)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if (height == 0) {
|
||||
// Leaf cell,
|
||||
for (i = 0; i < 12; i++) {
|
||||
setOutProcess(&node->leaf, i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Internal cell, recur
|
||||
int count = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (node->internal.has_child(i)) {
|
||||
clearProcessBits(node->internal.get_child(count), height - 1);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (height == 0) {
|
||||
// Leaf cell,
|
||||
for (i = 0; i < 12; i++) {
|
||||
setOutProcess(&node->leaf, i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Internal cell, recur
|
||||
int count = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (node->internal.has_child(i)) {
|
||||
clearProcessBits(node->internal.get_child(count), height - 1);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Octree::floodFill(LeafNode *leaf, int st[3], int len, int /*height*/, int threshold)
|
||||
{
|
||||
int i, j;
|
||||
int maxtotal = 0;
|
||||
int i, j;
|
||||
int maxtotal = 0;
|
||||
|
||||
// Leaf cell,
|
||||
int par, inp;
|
||||
// Leaf cell,
|
||||
int par, inp;
|
||||
|
||||
// Test if the leaf has intersection edges
|
||||
for (i = 0; i < 12; i++) {
|
||||
par = getEdgeParity(leaf, i);
|
||||
inp = isInProcess(leaf, i);
|
||||
// Test if the leaf has intersection edges
|
||||
for (i = 0; i < 12; i++) {
|
||||
par = getEdgeParity(leaf, i);
|
||||
inp = isInProcess(leaf, i);
|
||||
|
||||
if (par == 1 && inp == 0) {
|
||||
// Intersection edge, hasn't been processed
|
||||
// Let's start filling
|
||||
GridQueue *queue = new GridQueue();
|
||||
int total = 1;
|
||||
if (par == 1 && inp == 0) {
|
||||
// Intersection edge, hasn't been processed
|
||||
// Let's start filling
|
||||
GridQueue *queue = new GridQueue();
|
||||
int total = 1;
|
||||
|
||||
// Set to in process
|
||||
int mst[3];
|
||||
mst[0] = st[0] + vertmap[edgemap[i][0]][0] * len;
|
||||
mst[1] = st[1] + vertmap[edgemap[i][0]][1] * len;
|
||||
mst[2] = st[2] + vertmap[edgemap[i][0]][2] * len;
|
||||
int mdir = i / 4;
|
||||
setInProcessAll(mst, mdir);
|
||||
// Set to in process
|
||||
int mst[3];
|
||||
mst[0] = st[0] + vertmap[edgemap[i][0]][0] * len;
|
||||
mst[1] = st[1] + vertmap[edgemap[i][0]][1] * len;
|
||||
mst[2] = st[2] + vertmap[edgemap[i][0]][2] * len;
|
||||
int mdir = i / 4;
|
||||
setInProcessAll(mst, mdir);
|
||||
|
||||
// Put this edge into queue
|
||||
queue->pushQueue(mst, mdir);
|
||||
// Put this edge into queue
|
||||
queue->pushQueue(mst, mdir);
|
||||
|
||||
// Queue processing
|
||||
int nst[3], dir;
|
||||
while (queue->popQueue(nst, dir) == 1) {
|
||||
// dc_printf("nst: %d %d %d, dir: %d\n", nst[0]/mindimen, nst[1]/mindimen, nst[2]/mindimen, dir);
|
||||
// locations
|
||||
int stMask[3][3] = {
|
||||
{0, 0 - len, 0 - len},
|
||||
{0 - len, 0, 0 - len},
|
||||
{0 - len, 0 - len, 0}
|
||||
};
|
||||
int cst[2][3];
|
||||
for (j = 0; j < 3; j++) {
|
||||
cst[0][j] = nst[j];
|
||||
cst[1][j] = nst[j] + stMask[dir][j];
|
||||
}
|
||||
// Queue processing
|
||||
int nst[3], dir;
|
||||
while (queue->popQueue(nst, dir) == 1) {
|
||||
// dc_printf("nst: %d %d %d, dir: %d\n", nst[0]/mindimen, nst[1]/mindimen, nst[2]/mindimen, dir);
|
||||
// locations
|
||||
int stMask[3][3] = {{0, 0 - len, 0 - len}, {0 - len, 0, 0 - len}, {0 - len, 0 - len, 0}};
|
||||
int cst[2][3];
|
||||
for (j = 0; j < 3; j++) {
|
||||
cst[0][j] = nst[j];
|
||||
cst[1][j] = nst[j] + stMask[dir][j];
|
||||
}
|
||||
|
||||
// cells
|
||||
LeafNode *cs[2];
|
||||
for (j = 0; j < 2; j++) {
|
||||
cs[j] = locateLeaf(cst[j]);
|
||||
}
|
||||
// cells
|
||||
LeafNode *cs[2];
|
||||
for (j = 0; j < 2; j++) {
|
||||
cs[j] = locateLeaf(cst[j]);
|
||||
}
|
||||
|
||||
// Middle sign
|
||||
int s = getSign(cs[0], 0);
|
||||
// Middle sign
|
||||
int s = getSign(cs[0], 0);
|
||||
|
||||
// Masks
|
||||
int fcCells[4] = {1, 0, 1, 0};
|
||||
int fcEdges[3][4][3] = {
|
||||
{{9, 2, 11}, {8, 1, 10}, {5, 1, 7}, {4, 2, 6}},
|
||||
{{10, 6, 11}, {8, 5, 9}, {1, 5, 3}, {0, 6, 2}},
|
||||
{{6, 10, 7}, {4, 9, 5}, {2, 9, 3}, {0, 10, 1}}
|
||||
};
|
||||
// Masks
|
||||
int fcCells[4] = {1, 0, 1, 0};
|
||||
int fcEdges[3][4][3] = {{{9, 2, 11}, {8, 1, 10}, {5, 1, 7}, {4, 2, 6}},
|
||||
{{10, 6, 11}, {8, 5, 9}, {1, 5, 3}, {0, 6, 2}},
|
||||
{{6, 10, 7}, {4, 9, 5}, {2, 9, 3}, {0, 10, 1}}};
|
||||
|
||||
// Search for neighboring connected intersection edges
|
||||
for (int find = 0; find < 4; find++) {
|
||||
int cind = fcCells[find];
|
||||
int eind, edge;
|
||||
if (s == 0) {
|
||||
// Original order
|
||||
for (eind = 0; eind < 3; eind++) {
|
||||
edge = fcEdges[dir][find][eind];
|
||||
if (getEdgeParity(cs[cind], edge) == 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Inverse order
|
||||
for (eind = 2; eind >= 0; eind--) {
|
||||
edge = fcEdges[dir][find][eind];
|
||||
if (getEdgeParity(cs[cind], edge) == 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Search for neighboring connected intersection edges
|
||||
for (int find = 0; find < 4; find++) {
|
||||
int cind = fcCells[find];
|
||||
int eind, edge;
|
||||
if (s == 0) {
|
||||
// Original order
|
||||
for (eind = 0; eind < 3; eind++) {
|
||||
edge = fcEdges[dir][find][eind];
|
||||
if (getEdgeParity(cs[cind], edge) == 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Inverse order
|
||||
for (eind = 2; eind >= 0; eind--) {
|
||||
edge = fcEdges[dir][find][eind];
|
||||
if (getEdgeParity(cs[cind], edge) == 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (eind == 3 || eind == -1) {
|
||||
dc_printf("Wrong! this is not a consistent sign. %d\n", eind);
|
||||
}
|
||||
else {
|
||||
int est[3];
|
||||
est[0] = cst[cind][0] + vertmap[edgemap[edge][0]][0] * len;
|
||||
est[1] = cst[cind][1] + vertmap[edgemap[edge][0]][1] * len;
|
||||
est[2] = cst[cind][2] + vertmap[edgemap[edge][0]][2] * len;
|
||||
int edir = edge / 4;
|
||||
if (eind == 3 || eind == -1) {
|
||||
dc_printf("Wrong! this is not a consistent sign. %d\n", eind);
|
||||
}
|
||||
else {
|
||||
int est[3];
|
||||
est[0] = cst[cind][0] + vertmap[edgemap[edge][0]][0] * len;
|
||||
est[1] = cst[cind][1] + vertmap[edgemap[edge][0]][1] * len;
|
||||
est[2] = cst[cind][2] + vertmap[edgemap[edge][0]][2] * len;
|
||||
int edir = edge / 4;
|
||||
|
||||
if (isInProcess(cs[cind], edge) == 0) {
|
||||
setInProcessAll(est, edir);
|
||||
queue->pushQueue(est, edir);
|
||||
// dc_printf("Pushed: est: %d %d %d, edir: %d\n", est[0]/len, est[1]/len, est[2]/len, edir);
|
||||
total++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isInProcess(cs[cind], edge) == 0) {
|
||||
setInProcessAll(est, edir);
|
||||
queue->pushQueue(est, edir);
|
||||
// dc_printf("Pushed: est: %d %d %d, edir: %d\n", est[0]/len, est[1]/len, est[2]/len, edir);
|
||||
total++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dc_printf("Size of component: %d ", total);
|
||||
dc_printf("Size of component: %d ", total);
|
||||
|
||||
if (threshold == 0) {
|
||||
// Measuring stage
|
||||
if (total > maxtotal) {
|
||||
maxtotal = total;
|
||||
}
|
||||
dc_printf(".\n");
|
||||
delete queue;
|
||||
continue;
|
||||
}
|
||||
if (threshold == 0) {
|
||||
// Measuring stage
|
||||
if (total > maxtotal) {
|
||||
maxtotal = total;
|
||||
}
|
||||
dc_printf(".\n");
|
||||
delete queue;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (total >= threshold) {
|
||||
dc_printf("Maintained.\n");
|
||||
delete queue;
|
||||
continue;
|
||||
}
|
||||
dc_printf("Less then %d, removing...\n", threshold);
|
||||
if (total >= threshold) {
|
||||
dc_printf("Maintained.\n");
|
||||
delete queue;
|
||||
continue;
|
||||
}
|
||||
dc_printf("Less then %d, removing...\n", threshold);
|
||||
|
||||
// We have to remove this noise
|
||||
// We have to remove this noise
|
||||
|
||||
// Flip parity
|
||||
// setOutProcessAll(mst, mdir);
|
||||
flipParityAll(mst, mdir);
|
||||
// Flip parity
|
||||
// setOutProcessAll(mst, mdir);
|
||||
flipParityAll(mst, mdir);
|
||||
|
||||
// Put this edge into queue
|
||||
queue->pushQueue(mst, mdir);
|
||||
// Put this edge into queue
|
||||
queue->pushQueue(mst, mdir);
|
||||
|
||||
// Queue processing
|
||||
while (queue->popQueue(nst, dir) == 1) {
|
||||
// dc_printf("nst: %d %d %d, dir: %d\n", nst[0]/mindimen, nst[1]/mindimen, nst[2]/mindimen, dir);
|
||||
// locations
|
||||
int stMask[3][3] = {
|
||||
{0, 0 - len, 0 - len},
|
||||
{0 - len, 0, 0 - len},
|
||||
{0 - len, 0 - len, 0}
|
||||
};
|
||||
int cst[2][3];
|
||||
for (j = 0; j < 3; j++) {
|
||||
cst[0][j] = nst[j];
|
||||
cst[1][j] = nst[j] + stMask[dir][j];
|
||||
}
|
||||
// Queue processing
|
||||
while (queue->popQueue(nst, dir) == 1) {
|
||||
// dc_printf("nst: %d %d %d, dir: %d\n", nst[0]/mindimen, nst[1]/mindimen, nst[2]/mindimen, dir);
|
||||
// locations
|
||||
int stMask[3][3] = {{0, 0 - len, 0 - len}, {0 - len, 0, 0 - len}, {0 - len, 0 - len, 0}};
|
||||
int cst[2][3];
|
||||
for (j = 0; j < 3; j++) {
|
||||
cst[0][j] = nst[j];
|
||||
cst[1][j] = nst[j] + stMask[dir][j];
|
||||
}
|
||||
|
||||
// cells
|
||||
LeafNode *cs[2];
|
||||
for (j = 0; j < 2; j++)
|
||||
cs[j] = locateLeaf(cst[j]);
|
||||
// cells
|
||||
LeafNode *cs[2];
|
||||
for (j = 0; j < 2; j++)
|
||||
cs[j] = locateLeaf(cst[j]);
|
||||
|
||||
// Middle sign
|
||||
int s = getSign(cs[0], 0);
|
||||
// Middle sign
|
||||
int s = getSign(cs[0], 0);
|
||||
|
||||
// Masks
|
||||
int fcCells[4] = {1, 0, 1, 0};
|
||||
int fcEdges[3][4][3] = {
|
||||
{{9, 2, 11}, {8, 1, 10}, {5, 1, 7}, {4, 2, 6}},
|
||||
{{10, 6, 11}, {8, 5, 9}, {1, 5, 3}, {0, 6, 2}},
|
||||
{{6, 10, 7}, {4, 9, 5}, {2, 9, 3}, {0, 10, 1}}
|
||||
};
|
||||
// Masks
|
||||
int fcCells[4] = {1, 0, 1, 0};
|
||||
int fcEdges[3][4][3] = {{{9, 2, 11}, {8, 1, 10}, {5, 1, 7}, {4, 2, 6}},
|
||||
{{10, 6, 11}, {8, 5, 9}, {1, 5, 3}, {0, 6, 2}},
|
||||
{{6, 10, 7}, {4, 9, 5}, {2, 9, 3}, {0, 10, 1}}};
|
||||
|
||||
// Search for neighboring connected intersection edges
|
||||
for (int find = 0; find < 4; find++) {
|
||||
int cind = fcCells[find];
|
||||
int eind, edge;
|
||||
if (s == 0) {
|
||||
// Original order
|
||||
for (eind = 0; eind < 3; eind++) {
|
||||
edge = fcEdges[dir][find][eind];
|
||||
if (isInProcess(cs[cind], edge) == 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Inverse order
|
||||
for (eind = 2; eind >= 0; eind--) {
|
||||
edge = fcEdges[dir][find][eind];
|
||||
if (isInProcess(cs[cind], edge) == 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Search for neighboring connected intersection edges
|
||||
for (int find = 0; find < 4; find++) {
|
||||
int cind = fcCells[find];
|
||||
int eind, edge;
|
||||
if (s == 0) {
|
||||
// Original order
|
||||
for (eind = 0; eind < 3; eind++) {
|
||||
edge = fcEdges[dir][find][eind];
|
||||
if (isInProcess(cs[cind], edge) == 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Inverse order
|
||||
for (eind = 2; eind >= 0; eind--) {
|
||||
edge = fcEdges[dir][find][eind];
|
||||
if (isInProcess(cs[cind], edge) == 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (eind == 3 || eind == -1) {
|
||||
dc_printf("Wrong! this is not a consistent sign. %d\n", eind);
|
||||
}
|
||||
else {
|
||||
int est[3];
|
||||
est[0] = cst[cind][0] + vertmap[edgemap[edge][0]][0] * len;
|
||||
est[1] = cst[cind][1] + vertmap[edgemap[edge][0]][1] * len;
|
||||
est[2] = cst[cind][2] + vertmap[edgemap[edge][0]][2] * len;
|
||||
int edir = edge / 4;
|
||||
if (eind == 3 || eind == -1) {
|
||||
dc_printf("Wrong! this is not a consistent sign. %d\n", eind);
|
||||
}
|
||||
else {
|
||||
int est[3];
|
||||
est[0] = cst[cind][0] + vertmap[edgemap[edge][0]][0] * len;
|
||||
est[1] = cst[cind][1] + vertmap[edgemap[edge][0]][1] * len;
|
||||
est[2] = cst[cind][2] + vertmap[edgemap[edge][0]][2] * len;
|
||||
int edir = edge / 4;
|
||||
|
||||
if (getEdgeParity(cs[cind], edge) == 1) {
|
||||
flipParityAll(est, edir);
|
||||
queue->pushQueue(est, edir);
|
||||
// dc_printf("Pushed: est: %d %d %d, edir: %d\n", est[0]/len, est[1]/len, est[2]/len, edir);
|
||||
total++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (getEdgeParity(cs[cind], edge) == 1) {
|
||||
flipParityAll(est, edir);
|
||||
queue->pushQueue(est, edir);
|
||||
// dc_printf("Pushed: est: %d %d %d, edir: %d\n", est[0]/len, est[1]/len, est[2]/len, edir);
|
||||
total++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete queue;
|
||||
}
|
||||
}
|
||||
delete queue;
|
||||
}
|
||||
}
|
||||
|
||||
return maxtotal;
|
||||
return maxtotal;
|
||||
}
|
||||
|
||||
int Octree::floodFill(Node *node, int st[3], int len, int height, int threshold)
|
||||
{
|
||||
int i;
|
||||
int maxtotal = 0;
|
||||
int i;
|
||||
int maxtotal = 0;
|
||||
|
||||
if (height == 0) {
|
||||
maxtotal = floodFill(&node->leaf, st, len, height, threshold);
|
||||
}
|
||||
else {
|
||||
// Internal cell, recur
|
||||
int count = 0;
|
||||
len >>= 1;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (node->internal.has_child(i)) {
|
||||
int nst[3];
|
||||
nst[0] = st[0] + vertmap[i][0] * len;
|
||||
nst[1] = st[1] + vertmap[i][1] * len;
|
||||
nst[2] = st[2] + vertmap[i][2] * len;
|
||||
if (height == 0) {
|
||||
maxtotal = floodFill(&node->leaf, st, len, height, threshold);
|
||||
}
|
||||
else {
|
||||
// Internal cell, recur
|
||||
int count = 0;
|
||||
len >>= 1;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (node->internal.has_child(i)) {
|
||||
int nst[3];
|
||||
nst[0] = st[0] + vertmap[i][0] * len;
|
||||
nst[1] = st[1] + vertmap[i][1] * len;
|
||||
nst[2] = st[2] + vertmap[i][2] * len;
|
||||
|
||||
int d = floodFill(node->internal.get_child(count), nst, len, height - 1, threshold);
|
||||
if (d > maxtotal) {
|
||||
maxtotal = d;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return maxtotal;
|
||||
int d = floodFill(node->internal.get_child(count), nst, len, height - 1, threshold);
|
||||
if (d > maxtotal) {
|
||||
maxtotal = d;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return maxtotal;
|
||||
}
|
||||
|
||||
void Octree::writeOut()
|
||||
{
|
||||
int numQuads = 0;
|
||||
int numVertices = 0;
|
||||
int numEdges = 0;
|
||||
int numQuads = 0;
|
||||
int numVertices = 0;
|
||||
int numEdges = 0;
|
||||
|
||||
countIntersection(root, maxDepth, numQuads, numVertices, numEdges);
|
||||
countIntersection(root, maxDepth, numQuads, numVertices, numEdges);
|
||||
|
||||
dc_printf("Vertices counted: %d Polys counted: %d \n", numVertices, numQuads);
|
||||
output_mesh = alloc_output(numVertices, numQuads);
|
||||
int offset = 0;
|
||||
int st[3] = {0, 0, 0};
|
||||
dc_printf("Vertices counted: %d Polys counted: %d \n", numVertices, numQuads);
|
||||
output_mesh = alloc_output(numVertices, numQuads);
|
||||
int offset = 0;
|
||||
int st[3] = {0, 0, 0};
|
||||
|
||||
// First, output vertices
|
||||
offset = 0;
|
||||
actualVerts = 0;
|
||||
actualQuads = 0;
|
||||
// First, output vertices
|
||||
offset = 0;
|
||||
actualVerts = 0;
|
||||
actualQuads = 0;
|
||||
|
||||
generateMinimizer(root, st, dimen, maxDepth, offset);
|
||||
cellProcContour(root, 0, maxDepth);
|
||||
dc_printf("Vertices written: %d Quads written: %d \n", offset, actualQuads);
|
||||
generateMinimizer(root, st, dimen, maxDepth, offset);
|
||||
cellProcContour(root, 0, maxDepth);
|
||||
dc_printf("Vertices written: %d Quads written: %d \n", offset, actualQuads);
|
||||
}
|
||||
|
||||
void Octree::countIntersection(Node *node, int height, int& nedge, int& ncell, int& nface)
|
||||
void Octree::countIntersection(Node *node, int height, int &nedge, int &ncell, int &nface)
|
||||
{
|
||||
if (height > 0) {
|
||||
int total = node->internal.get_num_children();
|
||||
for (int i = 0; i < total; i++) {
|
||||
countIntersection(node->internal.get_child(i), height - 1, nedge, ncell, nface);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nedge += getNumEdges2(&node->leaf);
|
||||
if (height > 0) {
|
||||
int total = node->internal.get_num_children();
|
||||
for (int i = 0; i < total; i++) {
|
||||
countIntersection(node->internal.get_child(i), height - 1, nedge, ncell, nface);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nedge += getNumEdges2(&node->leaf);
|
||||
|
||||
int smask = getSignMask(&node->leaf);
|
||||
int smask = getSignMask(&node->leaf);
|
||||
|
||||
if (use_manifold) {
|
||||
int comps = manifold_table[smask].comps;
|
||||
ncell += comps;
|
||||
}
|
||||
else {
|
||||
if (smask > 0 && smask < 255) {
|
||||
ncell++;
|
||||
}
|
||||
}
|
||||
if (use_manifold) {
|
||||
int comps = manifold_table[smask].comps;
|
||||
ncell += comps;
|
||||
}
|
||||
else {
|
||||
if (smask > 0 && smask < 255) {
|
||||
ncell++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (getFaceEdgeNum(&node->leaf, i * 2)) {
|
||||
nface++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (getFaceEdgeNum(&node->leaf, i * 2)) {
|
||||
nface++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* from http://eigen.tuxfamily.org/bz/show_bug.cgi?id=257 */
|
||||
@@ -2099,751 +2121,713 @@ void pseudoInverse(const _Matrix_Type_ &a,
|
||||
_Matrix_Type_ &result,
|
||||
double epsilon = std::numeric_limits<typename _Matrix_Type_::Scalar>::epsilon())
|
||||
{
|
||||
Eigen::JacobiSVD< _Matrix_Type_ > svd = a.jacobiSvd(Eigen::ComputeFullU |
|
||||
Eigen::ComputeFullV);
|
||||
Eigen::JacobiSVD<_Matrix_Type_> svd = a.jacobiSvd(Eigen::ComputeFullU | Eigen::ComputeFullV);
|
||||
|
||||
typename _Matrix_Type_::Scalar tolerance = epsilon * std::max(a.cols(),
|
||||
a.rows()) *
|
||||
svd.singularValues().array().abs().maxCoeff();
|
||||
typename _Matrix_Type_::Scalar tolerance = epsilon * std::max(a.cols(), a.rows()) *
|
||||
svd.singularValues().array().abs().maxCoeff();
|
||||
|
||||
result = svd.matrixV() *
|
||||
_Matrix_Type_((svd.singularValues().array().abs() >
|
||||
tolerance).select(svd.singularValues().
|
||||
array().inverse(), 0)).asDiagonal() *
|
||||
svd.matrixU().adjoint();
|
||||
result = svd.matrixV() *
|
||||
_Matrix_Type_((svd.singularValues().array().abs() > tolerance)
|
||||
.select(svd.singularValues().array().inverse(), 0))
|
||||
.asDiagonal() *
|
||||
svd.matrixU().adjoint();
|
||||
}
|
||||
|
||||
static void solve_least_squares(const float halfA[], const float b[],
|
||||
const float midpoint[], float rvalue[])
|
||||
static void solve_least_squares(const float halfA[],
|
||||
const float b[],
|
||||
const float midpoint[],
|
||||
float rvalue[])
|
||||
{
|
||||
/* calculate pseudo-inverse */
|
||||
Eigen::MatrixXf A(3, 3), pinv(3, 3);
|
||||
A << halfA[0], halfA[1], halfA[2],
|
||||
halfA[1], halfA[3], halfA[4],
|
||||
halfA[2], halfA[4], halfA[5];
|
||||
pseudoInverse(A, pinv);
|
||||
/* calculate pseudo-inverse */
|
||||
Eigen::MatrixXf A(3, 3), pinv(3, 3);
|
||||
A << halfA[0], halfA[1], halfA[2], halfA[1], halfA[3], halfA[4], halfA[2], halfA[4], halfA[5];
|
||||
pseudoInverse(A, pinv);
|
||||
|
||||
Eigen::Vector3f b2(b), mp(midpoint), result;
|
||||
b2 = b2 + A * -mp;
|
||||
result = pinv * b2 + mp;
|
||||
Eigen::Vector3f b2(b), mp(midpoint), result;
|
||||
b2 = b2 + A * -mp;
|
||||
result = pinv * b2 + mp;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
rvalue[i] = result(i);
|
||||
for (int i = 0; i < 3; i++)
|
||||
rvalue[i] = result(i);
|
||||
}
|
||||
|
||||
static void mass_point(float mp[3], const float pts[12][3], const int parity[12])
|
||||
{
|
||||
int ec = 0;
|
||||
int ec = 0;
|
||||
|
||||
for (int i = 0; i < 12; i++) {
|
||||
if (parity[i]) {
|
||||
const float *p = pts[i];
|
||||
for (int i = 0; i < 12; i++) {
|
||||
if (parity[i]) {
|
||||
const float *p = pts[i];
|
||||
|
||||
mp[0] += p[0];
|
||||
mp[1] += p[1];
|
||||
mp[2] += p[2];
|
||||
mp[0] += p[0];
|
||||
mp[1] += p[1];
|
||||
mp[2] += p[2];
|
||||
|
||||
ec++;
|
||||
}
|
||||
}
|
||||
ec++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ec == 0) {
|
||||
return;
|
||||
}
|
||||
mp[0] /= ec;
|
||||
mp[1] /= ec;
|
||||
mp[2] /= ec;
|
||||
if (ec == 0) {
|
||||
return;
|
||||
}
|
||||
mp[0] /= ec;
|
||||
mp[1] /= ec;
|
||||
mp[2] /= ec;
|
||||
}
|
||||
|
||||
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 minimize(float rvalue[3],
|
||||
float mp[3],
|
||||
const float pts[12][3],
|
||||
const float norms[12][3],
|
||||
const int parity[12])
|
||||
{
|
||||
float ata[6] = {0, 0, 0, 0, 0, 0};
|
||||
float atb[3] = {0, 0, 0};
|
||||
int ec = 0;
|
||||
float ata[6] = {0, 0, 0, 0, 0, 0};
|
||||
float atb[3] = {0, 0, 0};
|
||||
int ec = 0;
|
||||
|
||||
for (int i = 0; i < 12; i++) {
|
||||
// if(getEdgeParity(leaf, i))
|
||||
if (parity[i]) {
|
||||
const float *norm = norms[i];
|
||||
const float *p = pts[i];
|
||||
for (int i = 0; i < 12; i++) {
|
||||
// if(getEdgeParity(leaf, i))
|
||||
if (parity[i]) {
|
||||
const float *norm = norms[i];
|
||||
const float *p = pts[i];
|
||||
|
||||
// QEF
|
||||
ata[0] += (float)(norm[0] * norm[0]);
|
||||
ata[1] += (float)(norm[0] * norm[1]);
|
||||
ata[2] += (float)(norm[0] * norm[2]);
|
||||
ata[3] += (float)(norm[1] * norm[1]);
|
||||
ata[4] += (float)(norm[1] * norm[2]);
|
||||
ata[5] += (float)(norm[2] * norm[2]);
|
||||
// QEF
|
||||
ata[0] += (float)(norm[0] * norm[0]);
|
||||
ata[1] += (float)(norm[0] * norm[1]);
|
||||
ata[2] += (float)(norm[0] * norm[2]);
|
||||
ata[3] += (float)(norm[1] * norm[1]);
|
||||
ata[4] += (float)(norm[1] * norm[2]);
|
||||
ata[5] += (float)(norm[2] * norm[2]);
|
||||
|
||||
const float pn = p[0] * norm[0] + p[1] * norm[1] + p[2] * norm[2];
|
||||
const float pn = p[0] * norm[0] + p[1] * norm[1] + p[2] * norm[2];
|
||||
|
||||
atb[0] += (float)(norm[0] * pn);
|
||||
atb[1] += (float)(norm[1] * pn);
|
||||
atb[2] += (float)(norm[2] * pn);
|
||||
atb[0] += (float)(norm[0] * pn);
|
||||
atb[1] += (float)(norm[1] * pn);
|
||||
atb[2] += (float)(norm[2] * pn);
|
||||
|
||||
// Minimizer
|
||||
mp[0] += p[0];
|
||||
mp[1] += p[1];
|
||||
mp[2] += p[2];
|
||||
// Minimizer
|
||||
mp[0] += p[0];
|
||||
mp[1] += p[1];
|
||||
mp[2] += p[2];
|
||||
|
||||
ec++;
|
||||
}
|
||||
}
|
||||
ec++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ec == 0) {
|
||||
return;
|
||||
}
|
||||
mp[0] /= ec;
|
||||
mp[1] /= ec;
|
||||
mp[2] /= ec;
|
||||
if (ec == 0) {
|
||||
return;
|
||||
}
|
||||
mp[0] /= ec;
|
||||
mp[1] /= ec;
|
||||
mp[2] /= ec;
|
||||
|
||||
// Solve least squares
|
||||
solve_least_squares(ata, atb, mp, rvalue);
|
||||
// Solve least squares
|
||||
solve_least_squares(ata, atb, mp, rvalue);
|
||||
}
|
||||
|
||||
void Octree::computeMinimizer(const LeafNode *leaf, int st[3], int len,
|
||||
float rvalue[3]) const
|
||||
void Octree::computeMinimizer(const LeafNode *leaf, int st[3], int len, float rvalue[3]) const
|
||||
{
|
||||
// First, gather all edge intersections
|
||||
float pts[12][3], norms[12][3];
|
||||
int parity[12];
|
||||
fillEdgeIntersections(leaf, st, len, pts, norms, parity);
|
||||
// First, gather all edge intersections
|
||||
float pts[12][3], norms[12][3];
|
||||
int parity[12];
|
||||
fillEdgeIntersections(leaf, st, len, pts, norms, parity);
|
||||
|
||||
switch (mode) {
|
||||
case DUALCON_CENTROID:
|
||||
rvalue[0] = (float) st[0] + len / 2;
|
||||
rvalue[1] = (float) st[1] + len / 2;
|
||||
rvalue[2] = (float) st[2] + len / 2;
|
||||
break;
|
||||
switch (mode) {
|
||||
case DUALCON_CENTROID:
|
||||
rvalue[0] = (float)st[0] + len / 2;
|
||||
rvalue[1] = (float)st[1] + len / 2;
|
||||
rvalue[2] = (float)st[2] + len / 2;
|
||||
break;
|
||||
|
||||
case DUALCON_MASS_POINT:
|
||||
rvalue[0] = rvalue[1] = rvalue[2] = 0;
|
||||
mass_point(rvalue, pts, parity);
|
||||
break;
|
||||
case DUALCON_MASS_POINT:
|
||||
rvalue[0] = rvalue[1] = rvalue[2] = 0;
|
||||
mass_point(rvalue, pts, parity);
|
||||
break;
|
||||
|
||||
default: {
|
||||
// Sharp features */
|
||||
default: {
|
||||
// Sharp features */
|
||||
|
||||
// construct QEF and minimizer
|
||||
float mp[3] = {0, 0, 0};
|
||||
minimize(rvalue, mp, pts, norms, parity);
|
||||
// construct QEF and minimizer
|
||||
float mp[3] = {0, 0, 0};
|
||||
minimize(rvalue, mp, pts, norms, parity);
|
||||
|
||||
/* Restraining the location of the minimizer */
|
||||
float nh1 = hermite_num * len;
|
||||
float nh2 = (1 + hermite_num) * len;
|
||||
/* Restraining the location of the minimizer */
|
||||
float nh1 = hermite_num * len;
|
||||
float nh2 = (1 + hermite_num) * len;
|
||||
|
||||
if (rvalue[0] < st[0] - nh1 ||
|
||||
rvalue[1] < st[1] - nh1 ||
|
||||
rvalue[2] < st[2] - nh1 ||
|
||||
if (rvalue[0] < st[0] - nh1 || rvalue[1] < st[1] - nh1 || rvalue[2] < st[2] - nh1 ||
|
||||
|
||||
rvalue[0] > st[0] + nh2 ||
|
||||
rvalue[1] > st[1] + nh2 ||
|
||||
rvalue[2] > st[2] + nh2)
|
||||
{
|
||||
// Use mass point instead
|
||||
rvalue[0] = mp[0];
|
||||
rvalue[1] = mp[1];
|
||||
rvalue[2] = mp[2];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
rvalue[0] > st[0] + nh2 || rvalue[1] > st[1] + nh2 || rvalue[2] > st[2] + nh2) {
|
||||
// Use mass point instead
|
||||
rvalue[0] = mp[0];
|
||||
rvalue[1] = mp[1];
|
||||
rvalue[2] = mp[2];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::generateMinimizer(Node *node, int st[3], int len, int height, int& offset)
|
||||
void Octree::generateMinimizer(Node *node, int st[3], int len, int height, int &offset)
|
||||
{
|
||||
int i, j;
|
||||
int i, j;
|
||||
|
||||
if (height == 0) {
|
||||
// Leaf cell, generate
|
||||
if (height == 0) {
|
||||
// Leaf cell, generate
|
||||
|
||||
// First, find minimizer
|
||||
float rvalue[3];
|
||||
rvalue[0] = (float) st[0] + len / 2;
|
||||
rvalue[1] = (float) st[1] + len / 2;
|
||||
rvalue[2] = (float) st[2] + len / 2;
|
||||
computeMinimizer(&node->leaf, st, len, rvalue);
|
||||
// First, find minimizer
|
||||
float rvalue[3];
|
||||
rvalue[0] = (float)st[0] + len / 2;
|
||||
rvalue[1] = (float)st[1] + len / 2;
|
||||
rvalue[2] = (float)st[2] + len / 2;
|
||||
computeMinimizer(&node->leaf, st, len, rvalue);
|
||||
|
||||
// Update
|
||||
//float fnst[3];
|
||||
for (j = 0; j < 3; j++) {
|
||||
rvalue[j] = rvalue[j] * range / dimen + origin[j];
|
||||
//fnst[j] = st[j] * range / dimen + origin[j];
|
||||
}
|
||||
// Update
|
||||
//float fnst[3];
|
||||
for (j = 0; j < 3; j++) {
|
||||
rvalue[j] = rvalue[j] * range / dimen + origin[j];
|
||||
//fnst[j] = st[j] * range / dimen + origin[j];
|
||||
}
|
||||
|
||||
int mult = 0, smask = getSignMask(&node->leaf);
|
||||
int mult = 0, smask = getSignMask(&node->leaf);
|
||||
|
||||
if (use_manifold) {
|
||||
mult = manifold_table[smask].comps;
|
||||
}
|
||||
else {
|
||||
if (smask > 0 && smask < 255) {
|
||||
mult = 1;
|
||||
}
|
||||
}
|
||||
if (use_manifold) {
|
||||
mult = manifold_table[smask].comps;
|
||||
}
|
||||
else {
|
||||
if (smask > 0 && smask < 255) {
|
||||
mult = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < mult; j++) {
|
||||
add_vert(output_mesh, rvalue);
|
||||
}
|
||||
for (j = 0; j < mult; j++) {
|
||||
add_vert(output_mesh, rvalue);
|
||||
}
|
||||
|
||||
// Store the index
|
||||
setMinimizerIndex(&node->leaf, offset);
|
||||
// Store the index
|
||||
setMinimizerIndex(&node->leaf, offset);
|
||||
|
||||
offset += mult;
|
||||
}
|
||||
else {
|
||||
// Internal cell, recur
|
||||
int count = 0;
|
||||
len >>= 1;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (node->internal.has_child(i)) {
|
||||
int nst[3];
|
||||
nst[0] = st[0] + vertmap[i][0] * len;
|
||||
nst[1] = st[1] + vertmap[i][1] * len;
|
||||
nst[2] = st[2] + vertmap[i][2] * len;
|
||||
offset += mult;
|
||||
}
|
||||
else {
|
||||
// Internal cell, recur
|
||||
int count = 0;
|
||||
len >>= 1;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (node->internal.has_child(i)) {
|
||||
int nst[3];
|
||||
nst[0] = st[0] + vertmap[i][0] * len;
|
||||
nst[1] = st[1] + vertmap[i][1] * len;
|
||||
nst[2] = st[2] + vertmap[i][2] * len;
|
||||
|
||||
generateMinimizer(node->internal.get_child(count),
|
||||
nst, len, height - 1, offset);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
generateMinimizer(node->internal.get_child(count), nst, len, height - 1, offset);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::processEdgeWrite(Node *node[4], int /*depth*/[4], int /*maxdep*/, int dir)
|
||||
{
|
||||
//int color = 0;
|
||||
//int color = 0;
|
||||
|
||||
int i = 3;
|
||||
{
|
||||
if (getEdgeParity((LeafNode *)(node[i]), processEdgeMask[dir][i])) {
|
||||
int flip = 0;
|
||||
int edgeind = processEdgeMask[dir][i];
|
||||
if (getSign((LeafNode *)node[i], edgemap[edgeind][1]) > 0) {
|
||||
flip = 1;
|
||||
}
|
||||
int i = 3;
|
||||
{
|
||||
if (getEdgeParity((LeafNode *)(node[i]), processEdgeMask[dir][i])) {
|
||||
int flip = 0;
|
||||
int edgeind = processEdgeMask[dir][i];
|
||||
if (getSign((LeafNode *)node[i], edgemap[edgeind][1]) > 0) {
|
||||
flip = 1;
|
||||
}
|
||||
|
||||
int num = 0;
|
||||
{
|
||||
int ind[8];
|
||||
if (use_manifold) {
|
||||
int vind[2];
|
||||
int seq[4] = {0, 1, 3, 2};
|
||||
for (int k = 0; k < 4; k++) {
|
||||
getMinimizerIndices((LeafNode *)(node[seq[k]]), processEdgeMask[dir][seq[k]], vind);
|
||||
ind[num] = vind[0];
|
||||
num++;
|
||||
int num = 0;
|
||||
{
|
||||
int ind[8];
|
||||
if (use_manifold) {
|
||||
int vind[2];
|
||||
int seq[4] = {0, 1, 3, 2};
|
||||
for (int k = 0; k < 4; k++) {
|
||||
getMinimizerIndices((LeafNode *)(node[seq[k]]), processEdgeMask[dir][seq[k]], vind);
|
||||
ind[num] = vind[0];
|
||||
num++;
|
||||
|
||||
if (vind[1] != -1) {
|
||||
ind[num] = vind[1];
|
||||
num++;
|
||||
if (flip == 0) {
|
||||
ind[num - 1] = vind[0];
|
||||
ind[num - 2] = vind[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vind[1] != -1) {
|
||||
ind[num] = vind[1];
|
||||
num++;
|
||||
if (flip == 0) {
|
||||
ind[num - 1] = vind[0];
|
||||
ind[num - 2] = vind[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* we don't use the manifold option, but if it is
|
||||
ever enabled again note that it can output
|
||||
non-quads */
|
||||
}
|
||||
else {
|
||||
if (flip) {
|
||||
ind[0] = getMinimizerIndex((LeafNode *)(node[2]));
|
||||
ind[1] = getMinimizerIndex((LeafNode *)(node[3]));
|
||||
ind[2] = getMinimizerIndex((LeafNode *)(node[1]));
|
||||
ind[3] = getMinimizerIndex((LeafNode *)(node[0]));
|
||||
}
|
||||
else {
|
||||
ind[0] = getMinimizerIndex((LeafNode *)(node[0]));
|
||||
ind[1] = getMinimizerIndex((LeafNode *)(node[1]));
|
||||
ind[2] = getMinimizerIndex((LeafNode *)(node[3]));
|
||||
ind[3] = getMinimizerIndex((LeafNode *)(node[2]));
|
||||
}
|
||||
/* we don't use the manifold option, but if it is
|
||||
ever enabled again note that it can output
|
||||
non-quads */
|
||||
}
|
||||
else {
|
||||
if (flip) {
|
||||
ind[0] = getMinimizerIndex((LeafNode *)(node[2]));
|
||||
ind[1] = getMinimizerIndex((LeafNode *)(node[3]));
|
||||
ind[2] = getMinimizerIndex((LeafNode *)(node[1]));
|
||||
ind[3] = getMinimizerIndex((LeafNode *)(node[0]));
|
||||
}
|
||||
else {
|
||||
ind[0] = getMinimizerIndex((LeafNode *)(node[0]));
|
||||
ind[1] = getMinimizerIndex((LeafNode *)(node[1]));
|
||||
ind[2] = getMinimizerIndex((LeafNode *)(node[3]));
|
||||
ind[3] = getMinimizerIndex((LeafNode *)(node[2]));
|
||||
}
|
||||
|
||||
add_quad(output_mesh, ind);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
add_quad(output_mesh, ind);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Octree::edgeProcContour(Node *node[4], int leaf[4], int depth[4], int maxdep, int dir)
|
||||
{
|
||||
if (!(node[0] && node[1] && node[2] && node[3])) {
|
||||
return;
|
||||
}
|
||||
if (leaf[0] && leaf[1] && leaf[2] && leaf[3]) {
|
||||
processEdgeWrite(node, depth, maxdep, dir);
|
||||
}
|
||||
else {
|
||||
int i, j;
|
||||
Node *chd[4][8];
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
|
||||
node[j]->internal.get_child(
|
||||
node[j]->internal.get_child_count(i)) : NULL;
|
||||
}
|
||||
}
|
||||
if (!(node[0] && node[1] && node[2] && node[3])) {
|
||||
return;
|
||||
}
|
||||
if (leaf[0] && leaf[1] && leaf[2] && leaf[3]) {
|
||||
processEdgeWrite(node, depth, maxdep, dir);
|
||||
}
|
||||
else {
|
||||
int i, j;
|
||||
Node *chd[4][8];
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
|
||||
node[j]->internal.get_child(node[j]->internal.get_child_count(i)) :
|
||||
NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// 2 edge calls
|
||||
Node *ne[4];
|
||||
int le[4];
|
||||
int de[4];
|
||||
for (i = 0; i < 2; i++) {
|
||||
int c[4] = {edgeProcEdgeMask[dir][i][0],
|
||||
edgeProcEdgeMask[dir][i][1],
|
||||
edgeProcEdgeMask[dir][i][2],
|
||||
edgeProcEdgeMask[dir][i][3]};
|
||||
// 2 edge calls
|
||||
Node *ne[4];
|
||||
int le[4];
|
||||
int de[4];
|
||||
for (i = 0; i < 2; i++) {
|
||||
int c[4] = {edgeProcEdgeMask[dir][i][0],
|
||||
edgeProcEdgeMask[dir][i][1],
|
||||
edgeProcEdgeMask[dir][i][2],
|
||||
edgeProcEdgeMask[dir][i][3]};
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (leaf[j]) {
|
||||
le[j] = leaf[j];
|
||||
ne[j] = node[j];
|
||||
de[j] = depth[j];
|
||||
}
|
||||
else {
|
||||
le[j] = node[j]->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[j][c[j]];
|
||||
de[j] = depth[j] - 1;
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (leaf[j]) {
|
||||
le[j] = leaf[j];
|
||||
ne[j] = node[j];
|
||||
de[j] = depth[j];
|
||||
}
|
||||
else {
|
||||
le[j] = node[j]->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[j][c[j]];
|
||||
de[j] = depth[j] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
edgeProcContour(ne, le, de, maxdep - 1, edgeProcEdgeMask[dir][i][4]);
|
||||
}
|
||||
|
||||
}
|
||||
edgeProcContour(ne, le, de, maxdep - 1, edgeProcEdgeMask[dir][i][4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::faceProcContour(Node *node[2], int leaf[2], int depth[2], int maxdep, int dir)
|
||||
{
|
||||
if (!(node[0] && node[1])) {
|
||||
return;
|
||||
}
|
||||
if (!(node[0] && node[1])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(leaf[0] && leaf[1])) {
|
||||
int i, j;
|
||||
// Fill children nodes
|
||||
Node *chd[2][8];
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
|
||||
node[j]->internal.get_child(
|
||||
node[j]->internal.get_child_count(i)) : NULL;
|
||||
}
|
||||
}
|
||||
if (!(leaf[0] && leaf[1])) {
|
||||
int i, j;
|
||||
// Fill children nodes
|
||||
Node *chd[2][8];
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
|
||||
node[j]->internal.get_child(node[j]->internal.get_child_count(i)) :
|
||||
NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// 4 face calls
|
||||
Node *nf[2];
|
||||
int df[2];
|
||||
int lf[2];
|
||||
for (i = 0; i < 4; i++) {
|
||||
int c[2] = {faceProcFaceMask[dir][i][0], faceProcFaceMask[dir][i][1]};
|
||||
for (int j = 0; j < 2; j++) {
|
||||
if (leaf[j]) {
|
||||
lf[j] = leaf[j];
|
||||
nf[j] = node[j];
|
||||
df[j] = depth[j];
|
||||
}
|
||||
else {
|
||||
lf[j] = node[j]->internal.is_child_leaf(c[j]);
|
||||
nf[j] = chd[j][c[j]];
|
||||
df[j] = depth[j] - 1;
|
||||
}
|
||||
}
|
||||
faceProcContour(nf, lf, df, maxdep - 1, faceProcFaceMask[dir][i][2]);
|
||||
}
|
||||
// 4 face calls
|
||||
Node *nf[2];
|
||||
int df[2];
|
||||
int lf[2];
|
||||
for (i = 0; i < 4; i++) {
|
||||
int c[2] = {faceProcFaceMask[dir][i][0], faceProcFaceMask[dir][i][1]};
|
||||
for (int j = 0; j < 2; j++) {
|
||||
if (leaf[j]) {
|
||||
lf[j] = leaf[j];
|
||||
nf[j] = node[j];
|
||||
df[j] = depth[j];
|
||||
}
|
||||
else {
|
||||
lf[j] = node[j]->internal.is_child_leaf(c[j]);
|
||||
nf[j] = chd[j][c[j]];
|
||||
df[j] = depth[j] - 1;
|
||||
}
|
||||
}
|
||||
faceProcContour(nf, lf, df, maxdep - 1, faceProcFaceMask[dir][i][2]);
|
||||
}
|
||||
|
||||
// 4 edge calls
|
||||
int orders[2][4] = {{0, 0, 1, 1}, {0, 1, 0, 1}};
|
||||
Node *ne[4];
|
||||
int le[4];
|
||||
int de[4];
|
||||
// 4 edge calls
|
||||
int orders[2][4] = {{0, 0, 1, 1}, {0, 1, 0, 1}};
|
||||
Node *ne[4];
|
||||
int le[4];
|
||||
int de[4];
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
int c[4] = {faceProcEdgeMask[dir][i][1], faceProcEdgeMask[dir][i][2],
|
||||
faceProcEdgeMask[dir][i][3], faceProcEdgeMask[dir][i][4]};
|
||||
int *order = orders[faceProcEdgeMask[dir][i][0]];
|
||||
for (i = 0; i < 4; i++) {
|
||||
int c[4] = {faceProcEdgeMask[dir][i][1],
|
||||
faceProcEdgeMask[dir][i][2],
|
||||
faceProcEdgeMask[dir][i][3],
|
||||
faceProcEdgeMask[dir][i][4]};
|
||||
int *order = orders[faceProcEdgeMask[dir][i][0]];
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (leaf[order[j]]) {
|
||||
le[j] = leaf[order[j]];
|
||||
ne[j] = node[order[j]];
|
||||
de[j] = depth[order[j]];
|
||||
}
|
||||
else {
|
||||
le[j] = node[order[j]]->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[order[j]][c[j]];
|
||||
de[j] = depth[order[j]] - 1;
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (leaf[order[j]]) {
|
||||
le[j] = leaf[order[j]];
|
||||
ne[j] = node[order[j]];
|
||||
de[j] = depth[order[j]];
|
||||
}
|
||||
else {
|
||||
le[j] = node[order[j]]->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[order[j]][c[j]];
|
||||
de[j] = depth[order[j]] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
edgeProcContour(ne, le, de, maxdep - 1, faceProcEdgeMask[dir][i][5]);
|
||||
}
|
||||
}
|
||||
edgeProcContour(ne, le, de, maxdep - 1, faceProcEdgeMask[dir][i][5]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Octree::cellProcContour(Node *node, int leaf, int depth)
|
||||
{
|
||||
if (node == NULL) {
|
||||
return;
|
||||
}
|
||||
if (node == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!leaf) {
|
||||
int i;
|
||||
if (!leaf) {
|
||||
int i;
|
||||
|
||||
// Fill children nodes
|
||||
Node *chd[8];
|
||||
for (i = 0; i < 8; i++) {
|
||||
chd[i] = ((!leaf) && node->internal.has_child(i)) ?
|
||||
node->internal.get_child(node->internal.get_child_count(i)) : NULL;
|
||||
}
|
||||
// Fill children nodes
|
||||
Node *chd[8];
|
||||
for (i = 0; i < 8; i++) {
|
||||
chd[i] = ((!leaf) && node->internal.has_child(i)) ?
|
||||
node->internal.get_child(node->internal.get_child_count(i)) :
|
||||
NULL;
|
||||
}
|
||||
|
||||
// 8 Cell calls
|
||||
for (i = 0; i < 8; i++) {
|
||||
cellProcContour(chd[i], node->internal.is_child_leaf(i), depth - 1);
|
||||
}
|
||||
// 8 Cell calls
|
||||
for (i = 0; i < 8; i++) {
|
||||
cellProcContour(chd[i], node->internal.is_child_leaf(i), depth - 1);
|
||||
}
|
||||
|
||||
// 12 face calls
|
||||
Node *nf[2];
|
||||
int lf[2];
|
||||
int df[2] = {depth - 1, depth - 1};
|
||||
for (i = 0; i < 12; i++) {
|
||||
int c[2] = {cellProcFaceMask[i][0], cellProcFaceMask[i][1]};
|
||||
// 12 face calls
|
||||
Node *nf[2];
|
||||
int lf[2];
|
||||
int df[2] = {depth - 1, depth - 1};
|
||||
for (i = 0; i < 12; i++) {
|
||||
int c[2] = {cellProcFaceMask[i][0], cellProcFaceMask[i][1]};
|
||||
|
||||
lf[0] = node->internal.is_child_leaf(c[0]);
|
||||
lf[1] = node->internal.is_child_leaf(c[1]);
|
||||
lf[0] = node->internal.is_child_leaf(c[0]);
|
||||
lf[1] = node->internal.is_child_leaf(c[1]);
|
||||
|
||||
nf[0] = chd[c[0]];
|
||||
nf[1] = chd[c[1]];
|
||||
nf[0] = chd[c[0]];
|
||||
nf[1] = chd[c[1]];
|
||||
|
||||
faceProcContour(nf, lf, df, depth - 1, cellProcFaceMask[i][2]);
|
||||
}
|
||||
faceProcContour(nf, lf, df, depth - 1, cellProcFaceMask[i][2]);
|
||||
}
|
||||
|
||||
// 6 edge calls
|
||||
Node *ne[4];
|
||||
int le[4];
|
||||
int de[4] = {depth - 1, depth - 1, depth - 1, depth - 1};
|
||||
for (i = 0; i < 6; i++) {
|
||||
int c[4] = {cellProcEdgeMask[i][0], cellProcEdgeMask[i][1], cellProcEdgeMask[i][2], cellProcEdgeMask[i][3]};
|
||||
// 6 edge calls
|
||||
Node *ne[4];
|
||||
int le[4];
|
||||
int de[4] = {depth - 1, depth - 1, depth - 1, depth - 1};
|
||||
for (i = 0; i < 6; i++) {
|
||||
int c[4] = {cellProcEdgeMask[i][0],
|
||||
cellProcEdgeMask[i][1],
|
||||
cellProcEdgeMask[i][2],
|
||||
cellProcEdgeMask[i][3]};
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
le[j] = node->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[c[j]];
|
||||
}
|
||||
|
||||
edgeProcContour(ne, le, de, depth - 1, cellProcEdgeMask[i][4]);
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < 4; j++) {
|
||||
le[j] = node->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[c[j]];
|
||||
}
|
||||
|
||||
edgeProcContour(ne, le, de, depth - 1, cellProcEdgeMask[i][4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::processEdgeParity(LeafNode *node[4], int /*depth*/[4], int /*maxdep*/, int dir)
|
||||
{
|
||||
int con = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
// Minimal cell
|
||||
// if(op == 0)
|
||||
{
|
||||
if (getEdgeParity(node[i], processEdgeMask[dir][i])) {
|
||||
con = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (con == 1) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
setEdge(node[i], processEdgeMask[dir][i]);
|
||||
}
|
||||
}
|
||||
int con = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
// Minimal cell
|
||||
// if(op == 0)
|
||||
{
|
||||
if (getEdgeParity(node[i], processEdgeMask[dir][i])) {
|
||||
con = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (con == 1) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
setEdge(node[i], processEdgeMask[dir][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::edgeProcParity(Node *node[4], int leaf[4], int depth[4], int maxdep, int dir)
|
||||
{
|
||||
if (!(node[0] && node[1] && node[2] && node[3])) {
|
||||
return;
|
||||
}
|
||||
if (leaf[0] && leaf[1] && leaf[2] && leaf[3]) {
|
||||
processEdgeParity((LeafNode **)node, depth, maxdep, dir);
|
||||
}
|
||||
else {
|
||||
int i, j;
|
||||
Node *chd[4][8];
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
|
||||
node[j]->internal.get_child( node[j]->internal.get_child_count(i)) : NULL;
|
||||
}
|
||||
}
|
||||
if (!(node[0] && node[1] && node[2] && node[3])) {
|
||||
return;
|
||||
}
|
||||
if (leaf[0] && leaf[1] && leaf[2] && leaf[3]) {
|
||||
processEdgeParity((LeafNode **)node, depth, maxdep, dir);
|
||||
}
|
||||
else {
|
||||
int i, j;
|
||||
Node *chd[4][8];
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
|
||||
node[j]->internal.get_child(node[j]->internal.get_child_count(i)) :
|
||||
NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// 2 edge calls
|
||||
Node *ne[4];
|
||||
int le[4];
|
||||
int de[4];
|
||||
for (i = 0; i < 2; i++) {
|
||||
int c[4] = {edgeProcEdgeMask[dir][i][0],
|
||||
edgeProcEdgeMask[dir][i][1],
|
||||
edgeProcEdgeMask[dir][i][2],
|
||||
edgeProcEdgeMask[dir][i][3]};
|
||||
// 2 edge calls
|
||||
Node *ne[4];
|
||||
int le[4];
|
||||
int de[4];
|
||||
for (i = 0; i < 2; i++) {
|
||||
int c[4] = {edgeProcEdgeMask[dir][i][0],
|
||||
edgeProcEdgeMask[dir][i][1],
|
||||
edgeProcEdgeMask[dir][i][2],
|
||||
edgeProcEdgeMask[dir][i][3]};
|
||||
|
||||
// int allleaf = 1;
|
||||
for (int j = 0; j < 4; j++) {
|
||||
// int allleaf = 1;
|
||||
for (int j = 0; j < 4; j++) {
|
||||
|
||||
if (leaf[j]) {
|
||||
le[j] = leaf[j];
|
||||
ne[j] = node[j];
|
||||
de[j] = depth[j];
|
||||
}
|
||||
else {
|
||||
le[j] = node[j]->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[j][c[j]];
|
||||
de[j] = depth[j] - 1;
|
||||
if (leaf[j]) {
|
||||
le[j] = leaf[j];
|
||||
ne[j] = node[j];
|
||||
de[j] = depth[j];
|
||||
}
|
||||
else {
|
||||
le[j] = node[j]->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[j][c[j]];
|
||||
de[j] = depth[j] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
edgeProcParity(ne, le, de, maxdep - 1, edgeProcEdgeMask[dir][i][4]);
|
||||
}
|
||||
|
||||
}
|
||||
edgeProcParity(ne, le, de, maxdep - 1, edgeProcEdgeMask[dir][i][4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::faceProcParity(Node *node[2], int leaf[2], int depth[2], int maxdep, int dir)
|
||||
{
|
||||
if (!(node[0] && node[1])) {
|
||||
return;
|
||||
}
|
||||
if (!(node[0] && node[1])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(leaf[0] && leaf[1])) {
|
||||
int i, j;
|
||||
// Fill children nodes
|
||||
Node *chd[2][8];
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
|
||||
node[j]->internal.get_child(
|
||||
node[j]->internal.get_child_count(i)) : NULL;
|
||||
}
|
||||
}
|
||||
if (!(leaf[0] && leaf[1])) {
|
||||
int i, j;
|
||||
// Fill children nodes
|
||||
Node *chd[2][8];
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
|
||||
node[j]->internal.get_child(node[j]->internal.get_child_count(i)) :
|
||||
NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// 4 face calls
|
||||
Node *nf[2];
|
||||
int df[2];
|
||||
int lf[2];
|
||||
for (i = 0; i < 4; i++) {
|
||||
int c[2] = {faceProcFaceMask[dir][i][0], faceProcFaceMask[dir][i][1]};
|
||||
for (int j = 0; j < 2; j++) {
|
||||
if (leaf[j]) {
|
||||
lf[j] = leaf[j];
|
||||
nf[j] = node[j];
|
||||
df[j] = depth[j];
|
||||
}
|
||||
else {
|
||||
lf[j] = node[j]->internal.is_child_leaf(c[j]);
|
||||
nf[j] = chd[j][c[j]];
|
||||
df[j] = depth[j] - 1;
|
||||
}
|
||||
}
|
||||
faceProcParity(nf, lf, df, maxdep - 1, faceProcFaceMask[dir][i][2]);
|
||||
}
|
||||
// 4 face calls
|
||||
Node *nf[2];
|
||||
int df[2];
|
||||
int lf[2];
|
||||
for (i = 0; i < 4; i++) {
|
||||
int c[2] = {faceProcFaceMask[dir][i][0], faceProcFaceMask[dir][i][1]};
|
||||
for (int j = 0; j < 2; j++) {
|
||||
if (leaf[j]) {
|
||||
lf[j] = leaf[j];
|
||||
nf[j] = node[j];
|
||||
df[j] = depth[j];
|
||||
}
|
||||
else {
|
||||
lf[j] = node[j]->internal.is_child_leaf(c[j]);
|
||||
nf[j] = chd[j][c[j]];
|
||||
df[j] = depth[j] - 1;
|
||||
}
|
||||
}
|
||||
faceProcParity(nf, lf, df, maxdep - 1, faceProcFaceMask[dir][i][2]);
|
||||
}
|
||||
|
||||
// 4 edge calls
|
||||
int orders[2][4] = {{0, 0, 1, 1}, {0, 1, 0, 1}};
|
||||
Node *ne[4];
|
||||
int le[4];
|
||||
int de[4];
|
||||
// 4 edge calls
|
||||
int orders[2][4] = {{0, 0, 1, 1}, {0, 1, 0, 1}};
|
||||
Node *ne[4];
|
||||
int le[4];
|
||||
int de[4];
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
int c[4] = {faceProcEdgeMask[dir][i][1], faceProcEdgeMask[dir][i][2],
|
||||
faceProcEdgeMask[dir][i][3], faceProcEdgeMask[dir][i][4]};
|
||||
int *order = orders[faceProcEdgeMask[dir][i][0]];
|
||||
for (i = 0; i < 4; i++) {
|
||||
int c[4] = {faceProcEdgeMask[dir][i][1],
|
||||
faceProcEdgeMask[dir][i][2],
|
||||
faceProcEdgeMask[dir][i][3],
|
||||
faceProcEdgeMask[dir][i][4]};
|
||||
int *order = orders[faceProcEdgeMask[dir][i][0]];
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (leaf[order[j]]) {
|
||||
le[j] = leaf[order[j]];
|
||||
ne[j] = node[order[j]];
|
||||
de[j] = depth[order[j]];
|
||||
}
|
||||
else {
|
||||
le[j] = node[order[j]]->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[order[j]][c[j]];
|
||||
de[j] = depth[order[j]] - 1;
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (leaf[order[j]]) {
|
||||
le[j] = leaf[order[j]];
|
||||
ne[j] = node[order[j]];
|
||||
de[j] = depth[order[j]];
|
||||
}
|
||||
else {
|
||||
le[j] = node[order[j]]->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[order[j]][c[j]];
|
||||
de[j] = depth[order[j]] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
edgeProcParity(ne, le, de, maxdep - 1, faceProcEdgeMask[dir][i][5]);
|
||||
}
|
||||
}
|
||||
edgeProcParity(ne, le, de, maxdep - 1, faceProcEdgeMask[dir][i][5]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Octree::cellProcParity(Node *node, int leaf, int depth)
|
||||
{
|
||||
if (node == NULL) {
|
||||
return;
|
||||
}
|
||||
if (node == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!leaf) {
|
||||
int i;
|
||||
if (!leaf) {
|
||||
int i;
|
||||
|
||||
// Fill children nodes
|
||||
Node *chd[8];
|
||||
for (i = 0; i < 8; i++) {
|
||||
chd[i] = ((!leaf) && node->internal.has_child(i)) ?
|
||||
node->internal.get_child(node->internal.get_child_count(i)) : NULL;
|
||||
}
|
||||
// Fill children nodes
|
||||
Node *chd[8];
|
||||
for (i = 0; i < 8; i++) {
|
||||
chd[i] = ((!leaf) && node->internal.has_child(i)) ?
|
||||
node->internal.get_child(node->internal.get_child_count(i)) :
|
||||
NULL;
|
||||
}
|
||||
|
||||
// 8 Cell calls
|
||||
for (i = 0; i < 8; i++) {
|
||||
cellProcParity(chd[i], node->internal.is_child_leaf(i), depth - 1);
|
||||
}
|
||||
// 8 Cell calls
|
||||
for (i = 0; i < 8; i++) {
|
||||
cellProcParity(chd[i], node->internal.is_child_leaf(i), depth - 1);
|
||||
}
|
||||
|
||||
// 12 face calls
|
||||
Node *nf[2];
|
||||
int lf[2];
|
||||
int df[2] = {depth - 1, depth - 1};
|
||||
for (i = 0; i < 12; i++) {
|
||||
int c[2] = {cellProcFaceMask[i][0], cellProcFaceMask[i][1]};
|
||||
// 12 face calls
|
||||
Node *nf[2];
|
||||
int lf[2];
|
||||
int df[2] = {depth - 1, depth - 1};
|
||||
for (i = 0; i < 12; i++) {
|
||||
int c[2] = {cellProcFaceMask[i][0], cellProcFaceMask[i][1]};
|
||||
|
||||
lf[0] = node->internal.is_child_leaf(c[0]);
|
||||
lf[1] = node->internal.is_child_leaf(c[1]);
|
||||
lf[0] = node->internal.is_child_leaf(c[0]);
|
||||
lf[1] = node->internal.is_child_leaf(c[1]);
|
||||
|
||||
nf[0] = chd[c[0]];
|
||||
nf[1] = chd[c[1]];
|
||||
nf[0] = chd[c[0]];
|
||||
nf[1] = chd[c[1]];
|
||||
|
||||
faceProcParity(nf, lf, df, depth - 1, cellProcFaceMask[i][2]);
|
||||
}
|
||||
faceProcParity(nf, lf, df, depth - 1, cellProcFaceMask[i][2]);
|
||||
}
|
||||
|
||||
// 6 edge calls
|
||||
Node *ne[4];
|
||||
int le[4];
|
||||
int de[4] = {depth - 1, depth - 1, depth - 1, depth - 1};
|
||||
for (i = 0; i < 6; i++) {
|
||||
int c[4] = {cellProcEdgeMask[i][0], cellProcEdgeMask[i][1], cellProcEdgeMask[i][2], cellProcEdgeMask[i][3]};
|
||||
// 6 edge calls
|
||||
Node *ne[4];
|
||||
int le[4];
|
||||
int de[4] = {depth - 1, depth - 1, depth - 1, depth - 1};
|
||||
for (i = 0; i < 6; i++) {
|
||||
int c[4] = {cellProcEdgeMask[i][0],
|
||||
cellProcEdgeMask[i][1],
|
||||
cellProcEdgeMask[i][2],
|
||||
cellProcEdgeMask[i][3]};
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
le[j] = node->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[c[j]];
|
||||
}
|
||||
|
||||
edgeProcParity(ne, le, de, depth - 1, cellProcEdgeMask[i][4]);
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < 4; j++) {
|
||||
le[j] = node->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[c[j]];
|
||||
}
|
||||
|
||||
edgeProcParity(ne, le, de, depth - 1, cellProcEdgeMask[i][4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* definitions for global arrays */
|
||||
const int edgemask[3] = {5, 3, 6};
|
||||
|
||||
const int faceMap[6][4] = {
|
||||
{4, 8, 5, 9},
|
||||
{6, 10, 7, 11},
|
||||
{0, 8, 1, 10},
|
||||
{2, 9, 3, 11},
|
||||
{0, 4, 2, 6},
|
||||
{1, 5, 3, 7},
|
||||
{4, 8, 5, 9},
|
||||
{6, 10, 7, 11},
|
||||
{0, 8, 1, 10},
|
||||
{2, 9, 3, 11},
|
||||
{0, 4, 2, 6},
|
||||
{1, 5, 3, 7},
|
||||
};
|
||||
|
||||
const int cellProcFaceMask[12][3] = {
|
||||
{0, 4, 0},
|
||||
{1, 5, 0},
|
||||
{2, 6, 0},
|
||||
{3, 7, 0},
|
||||
{0, 2, 1},
|
||||
{4, 6, 1},
|
||||
{1, 3, 1},
|
||||
{5, 7, 1},
|
||||
{0, 1, 2},
|
||||
{2, 3, 2},
|
||||
{4, 5, 2},
|
||||
{6, 7, 2},
|
||||
{0, 4, 0},
|
||||
{1, 5, 0},
|
||||
{2, 6, 0},
|
||||
{3, 7, 0},
|
||||
{0, 2, 1},
|
||||
{4, 6, 1},
|
||||
{1, 3, 1},
|
||||
{5, 7, 1},
|
||||
{0, 1, 2},
|
||||
{2, 3, 2},
|
||||
{4, 5, 2},
|
||||
{6, 7, 2},
|
||||
};
|
||||
|
||||
const int cellProcEdgeMask[6][5] = {
|
||||
{0, 1, 2, 3, 0},
|
||||
{4, 5, 6, 7, 0},
|
||||
{0, 4, 1, 5, 1},
|
||||
{2, 6, 3, 7, 1},
|
||||
{0, 2, 4, 6, 2},
|
||||
{1, 3, 5, 7, 2},
|
||||
{0, 1, 2, 3, 0},
|
||||
{4, 5, 6, 7, 0},
|
||||
{0, 4, 1, 5, 1},
|
||||
{2, 6, 3, 7, 1},
|
||||
{0, 2, 4, 6, 2},
|
||||
{1, 3, 5, 7, 2},
|
||||
};
|
||||
|
||||
const int faceProcFaceMask[3][4][3] = {
|
||||
{{4, 0, 0},
|
||||
{5, 1, 0},
|
||||
{6, 2, 0},
|
||||
{7, 3, 0}},
|
||||
{{2, 0, 1},
|
||||
{6, 4, 1},
|
||||
{3, 1, 1},
|
||||
{7, 5, 1}},
|
||||
{{1, 0, 2},
|
||||
{3, 2, 2},
|
||||
{5, 4, 2},
|
||||
{7, 6, 2}}
|
||||
};
|
||||
const int faceProcFaceMask[3][4][3] = {{{4, 0, 0}, {5, 1, 0}, {6, 2, 0}, {7, 3, 0}},
|
||||
{{2, 0, 1}, {6, 4, 1}, {3, 1, 1}, {7, 5, 1}},
|
||||
{{1, 0, 2}, {3, 2, 2}, {5, 4, 2}, {7, 6, 2}}};
|
||||
|
||||
const int faceProcEdgeMask[3][4][6] = {
|
||||
{{1, 4, 0, 5, 1, 1},
|
||||
{1, 6, 2, 7, 3, 1},
|
||||
{0, 4, 6, 0, 2, 2},
|
||||
{0, 5, 7, 1, 3, 2}},
|
||||
{{0, 2, 3, 0, 1, 0},
|
||||
{0, 6, 7, 4, 5, 0},
|
||||
{1, 2, 0, 6, 4, 2},
|
||||
{1, 3, 1, 7, 5, 2}},
|
||||
{{1, 1, 0, 3, 2, 0},
|
||||
{1, 5, 4, 7, 6, 0},
|
||||
{0, 1, 5, 0, 4, 1},
|
||||
{0, 3, 7, 2, 6, 1}}
|
||||
};
|
||||
{{1, 4, 0, 5, 1, 1}, {1, 6, 2, 7, 3, 1}, {0, 4, 6, 0, 2, 2}, {0, 5, 7, 1, 3, 2}},
|
||||
{{0, 2, 3, 0, 1, 0}, {0, 6, 7, 4, 5, 0}, {1, 2, 0, 6, 4, 2}, {1, 3, 1, 7, 5, 2}},
|
||||
{{1, 1, 0, 3, 2, 0}, {1, 5, 4, 7, 6, 0}, {0, 1, 5, 0, 4, 1}, {0, 3, 7, 2, 6, 1}}};
|
||||
|
||||
const int edgeProcEdgeMask[3][2][5] = {
|
||||
{{3, 2, 1, 0, 0},
|
||||
{7, 6, 5, 4, 0}},
|
||||
{{5, 1, 4, 0, 1},
|
||||
{7, 3, 6, 2, 1}},
|
||||
{{6, 4, 2, 0, 2},
|
||||
{7, 5, 3, 1, 2}},
|
||||
{{3, 2, 1, 0, 0}, {7, 6, 5, 4, 0}},
|
||||
{{5, 1, 4, 0, 1}, {7, 3, 6, 2, 1}},
|
||||
{{6, 4, 2, 0, 2}, {7, 5, 3, 1, 2}},
|
||||
};
|
||||
|
||||
const int processEdgeMask[3][4] = {
|
||||
{3, 2, 1, 0},
|
||||
{7, 5, 6, 4},
|
||||
{11, 10, 9, 8},
|
||||
{3, 2, 1, 0},
|
||||
{7, 5, 6, 4},
|
||||
{11, 10, 9, 8},
|
||||
};
|
||||
|
||||
const int dirCell[3][4][3] = {
|
||||
{{0, -1, -1},
|
||||
{0, -1, 0},
|
||||
{0, 0, -1},
|
||||
{0, 0, 0}},
|
||||
{{-1, 0, -1},
|
||||
{-1, 0, 0},
|
||||
{0, 0, -1},
|
||||
{0, 0, 0}},
|
||||
{{-1, -1, 0},
|
||||
{-1, 0, 0},
|
||||
{0, -1, 0},
|
||||
{0, 0, 0}}
|
||||
};
|
||||
const int dirCell[3][4][3] = {{{0, -1, -1}, {0, -1, 0}, {0, 0, -1}, {0, 0, 0}},
|
||||
{{-1, 0, -1}, {-1, 0, 0}, {0, 0, -1}, {0, 0, 0}},
|
||||
{{-1, -1, 0}, {-1, 0, 0}, {0, -1, 0}, {0, 0, 0}}};
|
||||
|
||||
const int dirEdge[3][4] = {
|
||||
{3, 2, 1, 0},
|
||||
{7, 6, 5, 4},
|
||||
{11, 10, 9, 8},
|
||||
{3, 2, 1, 0},
|
||||
{7, 6, 5, 4},
|
||||
{11, 10, 9, 8},
|
||||
};
|
||||
|
||||
int InternalNode::numChildrenTable[256];
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
* @author Tao Ju
|
||||
*/
|
||||
|
||||
|
||||
/* Global defines */
|
||||
// Uncomment to see debug information
|
||||
// #define IN_DEBUG_MODE
|
||||
@@ -53,98 +52,97 @@ union Node;
|
||||
struct LeafNode;
|
||||
|
||||
struct InternalNode {
|
||||
/* Initialized in Octree::BuildTable */
|
||||
static int numChildrenTable[256];
|
||||
static int childrenCountTable[256][8];
|
||||
static int childrenIndexTable[256][8];
|
||||
/* Initialized in Octree::BuildTable */
|
||||
static int numChildrenTable[256];
|
||||
static int childrenCountTable[256][8];
|
||||
static int childrenIndexTable[256][8];
|
||||
|
||||
/* Bit N indicates whether child N exists or not */
|
||||
unsigned char has_child_bitfield;
|
||||
/* Bit N indicates whether child N is a leaf or not */
|
||||
unsigned char child_is_leaf_bitfield;
|
||||
/* Bit N indicates whether child N exists or not */
|
||||
unsigned char has_child_bitfield;
|
||||
/* Bit N indicates whether child N is a leaf or not */
|
||||
unsigned char child_is_leaf_bitfield;
|
||||
|
||||
/* Can have up to eight children */
|
||||
Node *children[0];
|
||||
/* Can have up to eight children */
|
||||
Node *children[0];
|
||||
|
||||
/// Test if child is leaf
|
||||
int is_child_leaf(int index) const
|
||||
{
|
||||
return (child_is_leaf_bitfield >> index) & 1;
|
||||
}
|
||||
/// Test if child is leaf
|
||||
int is_child_leaf(int index) const
|
||||
{
|
||||
return (child_is_leaf_bitfield >> index) & 1;
|
||||
}
|
||||
|
||||
/// If child index exists
|
||||
int has_child(int index) const
|
||||
{
|
||||
return (has_child_bitfield >> index) & 1;
|
||||
}
|
||||
/// If child index exists
|
||||
int has_child(int index) const
|
||||
{
|
||||
return (has_child_bitfield >> index) & 1;
|
||||
}
|
||||
|
||||
/// Get the pointer to child index
|
||||
Node *get_child(int count)
|
||||
{
|
||||
return children[count];
|
||||
}
|
||||
/// Get the pointer to child index
|
||||
Node *get_child(int count)
|
||||
{
|
||||
return children[count];
|
||||
}
|
||||
|
||||
const Node *get_child(int count) const
|
||||
{
|
||||
return children[count];
|
||||
}
|
||||
const Node *get_child(int count) const
|
||||
{
|
||||
return children[count];
|
||||
}
|
||||
|
||||
/// Get total number of children
|
||||
int get_num_children() const
|
||||
{
|
||||
return numChildrenTable[has_child_bitfield];
|
||||
}
|
||||
/// Get total number of children
|
||||
int get_num_children() const
|
||||
{
|
||||
return numChildrenTable[has_child_bitfield];
|
||||
}
|
||||
|
||||
/// Get the count of children
|
||||
int get_child_count(int index) const
|
||||
{
|
||||
return childrenCountTable[has_child_bitfield][index];
|
||||
}
|
||||
int get_child_index(int count)
|
||||
{
|
||||
return childrenIndexTable[has_child_bitfield][count];
|
||||
}
|
||||
const int *get_child_counts() const
|
||||
{
|
||||
return childrenCountTable[has_child_bitfield];
|
||||
}
|
||||
/// Get the count of children
|
||||
int get_child_count(int index) const
|
||||
{
|
||||
return childrenCountTable[has_child_bitfield][index];
|
||||
}
|
||||
int get_child_index(int count)
|
||||
{
|
||||
return childrenIndexTable[has_child_bitfield][count];
|
||||
}
|
||||
const int *get_child_counts() const
|
||||
{
|
||||
return childrenCountTable[has_child_bitfield];
|
||||
}
|
||||
|
||||
/// Get all children
|
||||
void fill_children(Node *children[8], int leaf[8])
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
leaf[i] = is_child_leaf(i);
|
||||
if (has_child(i)) {
|
||||
children[i] = get_child(count);
|
||||
count++;
|
||||
}
|
||||
else {
|
||||
children[i] = NULL;
|
||||
leaf[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Get all children
|
||||
void fill_children(Node *children[8], int leaf[8])
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
leaf[i] = is_child_leaf(i);
|
||||
if (has_child(i)) {
|
||||
children[i] = get_child(count);
|
||||
count++;
|
||||
}
|
||||
else {
|
||||
children[i] = NULL;
|
||||
leaf[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the child pointer
|
||||
void set_child(int count, Node *chd)
|
||||
{
|
||||
children[count] = chd;
|
||||
}
|
||||
void set_internal_child(int index, int count, InternalNode *chd)
|
||||
{
|
||||
set_child(count, (Node *)chd);
|
||||
has_child_bitfield |= (1 << index);
|
||||
}
|
||||
void set_leaf_child(int index, int count, LeafNode *chd)
|
||||
{
|
||||
set_child(count, (Node *)chd);
|
||||
has_child_bitfield |= (1 << index);
|
||||
child_is_leaf_bitfield |= (1 << index);
|
||||
}
|
||||
/// Sets the child pointer
|
||||
void set_child(int count, Node *chd)
|
||||
{
|
||||
children[count] = chd;
|
||||
}
|
||||
void set_internal_child(int index, int count, InternalNode *chd)
|
||||
{
|
||||
set_child(count, (Node *)chd);
|
||||
has_child_bitfield |= (1 << index);
|
||||
}
|
||||
void set_leaf_child(int index, int count, LeafNode *chd)
|
||||
{
|
||||
set_child(count, (Node *)chd);
|
||||
has_child_bitfield |= (1 << index);
|
||||
child_is_leaf_bitfield |= (1 << index);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Bits order
|
||||
*
|
||||
@@ -157,27 +155,27 @@ struct InternalNode {
|
||||
* Byte 5: edge intersections(4 bytes per inter, or 12 bytes if USE_HERMIT)
|
||||
*/
|
||||
struct LeafNode /* TODO: remove this attribute once everything is fixed */ {
|
||||
unsigned short edge_parity : 12;
|
||||
unsigned short primary_edge_intersections : 3;
|
||||
unsigned short edge_parity : 12;
|
||||
unsigned short primary_edge_intersections : 3;
|
||||
|
||||
/* XXX: maybe actually unused? */
|
||||
unsigned short in_process : 1;
|
||||
/* XXX: maybe actually unused? */
|
||||
unsigned short in_process : 1;
|
||||
|
||||
/* bitfield */
|
||||
char signs;
|
||||
/* bitfield */
|
||||
char signs;
|
||||
|
||||
int minimizer_index;
|
||||
int minimizer_index;
|
||||
|
||||
unsigned short flood_fill;
|
||||
unsigned short flood_fill;
|
||||
|
||||
float edge_intersections[0];
|
||||
float edge_intersections[0];
|
||||
};
|
||||
|
||||
/* Doesn't get directly allocated anywhere, just used for passing
|
||||
pointers to nodes that could be internal or leaf. */
|
||||
union Node {
|
||||
InternalNode internal;
|
||||
LeafNode leaf;
|
||||
InternalNode internal;
|
||||
LeafNode leaf;
|
||||
};
|
||||
|
||||
/* Global variables */
|
||||
@@ -197,1195 +195,1209 @@ extern const int dirEdge[3][4];
|
||||
*/
|
||||
|
||||
struct PathElement {
|
||||
// Origin
|
||||
int pos[3];
|
||||
// Origin
|
||||
int pos[3];
|
||||
|
||||
// link
|
||||
PathElement *next;
|
||||
// link
|
||||
PathElement *next;
|
||||
};
|
||||
|
||||
struct PathList {
|
||||
// Head
|
||||
PathElement *head;
|
||||
PathElement *tail;
|
||||
// Head
|
||||
PathElement *head;
|
||||
PathElement *tail;
|
||||
|
||||
// Length of the list
|
||||
int length;
|
||||
// Length of the list
|
||||
int length;
|
||||
|
||||
// Next list
|
||||
PathList *next;
|
||||
// Next list
|
||||
PathList *next;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class for building and processing an octree
|
||||
*/
|
||||
class Octree
|
||||
{
|
||||
class Octree {
|
||||
public:
|
||||
/* Public members */
|
||||
/* Public members */
|
||||
|
||||
/// Memory allocators
|
||||
VirtualMemoryAllocator *alloc[9];
|
||||
VirtualMemoryAllocator *leafalloc[4];
|
||||
/// Memory allocators
|
||||
VirtualMemoryAllocator *alloc[9];
|
||||
VirtualMemoryAllocator *leafalloc[4];
|
||||
|
||||
/// Root node
|
||||
Node *root;
|
||||
/// Root node
|
||||
Node *root;
|
||||
|
||||
/// Model reader
|
||||
ModelReader *reader;
|
||||
/// Model reader
|
||||
ModelReader *reader;
|
||||
|
||||
/// Marching cubes table
|
||||
Cubes *cubes;
|
||||
/// Marching cubes table
|
||||
Cubes *cubes;
|
||||
|
||||
/// Length of grid
|
||||
int dimen;
|
||||
int mindimen, minshift;
|
||||
/// Length of grid
|
||||
int dimen;
|
||||
int mindimen, minshift;
|
||||
|
||||
/// Maximum depth
|
||||
int maxDepth;
|
||||
/// Maximum depth
|
||||
int maxDepth;
|
||||
|
||||
/// The lower corner of the bounding box and the size
|
||||
float origin[3];
|
||||
float range;
|
||||
/// The lower corner of the bounding box and the size
|
||||
float origin[3];
|
||||
float range;
|
||||
|
||||
/// Counting information
|
||||
int nodeCount;
|
||||
int nodeSpace;
|
||||
int nodeCounts[9];
|
||||
/// Counting information
|
||||
int nodeCount;
|
||||
int nodeSpace;
|
||||
int nodeCounts[9];
|
||||
|
||||
int actualQuads, actualVerts;
|
||||
int actualQuads, actualVerts;
|
||||
|
||||
PathList *ringList;
|
||||
PathList *ringList;
|
||||
|
||||
int maxTrianglePerCell;
|
||||
int outType; // 0 for OFF, 1 for PLY, 2 for VOL
|
||||
int maxTrianglePerCell;
|
||||
int outType; // 0 for OFF, 1 for PLY, 2 for VOL
|
||||
|
||||
// For flood filling
|
||||
int use_flood_fill;
|
||||
float thresh;
|
||||
// For flood filling
|
||||
int use_flood_fill;
|
||||
float thresh;
|
||||
|
||||
int use_manifold;
|
||||
int use_manifold;
|
||||
|
||||
float hermite_num;
|
||||
float hermite_num;
|
||||
|
||||
DualConMode mode;
|
||||
DualConMode mode;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Construtor
|
||||
*/
|
||||
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);
|
||||
/**
|
||||
* Construtor
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Octree();
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Octree();
|
||||
|
||||
/**
|
||||
* Scan convert
|
||||
*/
|
||||
void scanConvert();
|
||||
/**
|
||||
* Scan convert
|
||||
*/
|
||||
void scanConvert();
|
||||
|
||||
void *getOutputMesh() {
|
||||
return output_mesh;
|
||||
}
|
||||
void *getOutputMesh()
|
||||
{
|
||||
return output_mesh;
|
||||
}
|
||||
|
||||
private:
|
||||
/* Helper functions */
|
||||
/* Helper functions */
|
||||
|
||||
/**
|
||||
* Initialize memory allocators
|
||||
*/
|
||||
void initMemory();
|
||||
/**
|
||||
* Initialize memory allocators
|
||||
*/
|
||||
void initMemory();
|
||||
|
||||
/**
|
||||
* Release memory
|
||||
*/
|
||||
void freeMemory();
|
||||
/**
|
||||
* Release memory
|
||||
*/
|
||||
void freeMemory();
|
||||
|
||||
/**
|
||||
* Print memory usage
|
||||
*/
|
||||
void printMemUsage();
|
||||
/**
|
||||
* Print memory usage
|
||||
*/
|
||||
void printMemUsage();
|
||||
|
||||
/**
|
||||
* Methods to set / restore minimum edges
|
||||
*/
|
||||
void resetMinimalEdges();
|
||||
|
||||
/**
|
||||
* Methods to set / restore minimum edges
|
||||
*/
|
||||
void resetMinimalEdges();
|
||||
void cellProcParity(Node *node, int leaf, int depth);
|
||||
void faceProcParity(Node *node[2], int leaf[2], int depth[2], int maxdep, int dir);
|
||||
void edgeProcParity(Node *node[4], int leaf[4], int depth[4], int maxdep, int dir);
|
||||
|
||||
void cellProcParity(Node *node, int leaf, int depth);
|
||||
void faceProcParity(Node * node[2], int leaf[2], int depth[2], int maxdep, int dir);
|
||||
void edgeProcParity(Node * node[4], int leaf[4], int depth[4], int maxdep, int dir);
|
||||
void processEdgeParity(LeafNode *node[4], int depths[4], int maxdep, int dir);
|
||||
|
||||
void processEdgeParity(LeafNode * node[4], int depths[4], int maxdep, int dir);
|
||||
/**
|
||||
* Add triangles to the tree
|
||||
*/
|
||||
void addAllTriangles();
|
||||
void addTriangle(Triangle *trian, int triind);
|
||||
InternalNode *addTriangle(InternalNode *node, CubeTriangleIsect *p, int height);
|
||||
|
||||
/**
|
||||
* Add triangles to the tree
|
||||
*/
|
||||
void addAllTriangles();
|
||||
void addTriangle(Triangle *trian, int triind);
|
||||
InternalNode *addTriangle(InternalNode *node, CubeTriangleIsect *p, int height);
|
||||
/**
|
||||
* Method to update minimizer in a cell: update edge intersections instead
|
||||
*/
|
||||
LeafNode *updateCell(LeafNode *node, CubeTriangleIsect *p);
|
||||
|
||||
/**
|
||||
* Method to update minimizer in a cell: update edge intersections instead
|
||||
*/
|
||||
LeafNode *updateCell(LeafNode *node, CubeTriangleIsect *p);
|
||||
/* Routines to detect and patch holes */
|
||||
int numRings;
|
||||
int totRingLengths;
|
||||
int maxRingLength;
|
||||
|
||||
/* Routines to detect and patch holes */
|
||||
int numRings;
|
||||
int totRingLengths;
|
||||
int maxRingLength;
|
||||
/**
|
||||
* Entry routine.
|
||||
*/
|
||||
void trace();
|
||||
/**
|
||||
* Trace the given node, find patches and fill them in
|
||||
*/
|
||||
Node *trace(Node *node, int *st, int len, int depth, PathList *&paths);
|
||||
/**
|
||||
* Look for path on the face and add to paths
|
||||
*/
|
||||
void findPaths(
|
||||
Node *node[2], int leaf[2], int depth[2], int *st[2], int maxdep, int dir, PathList *&paths);
|
||||
/**
|
||||
* Combine two list1 and list2 into list1 using connecting paths list3,
|
||||
* while closed paths are appended to rings
|
||||
*/
|
||||
void combinePaths(PathList *&list1, PathList *list2, PathList *paths, PathList *&rings);
|
||||
/**
|
||||
* Helper function: combine current paths in list1 and list2 to a single path and append to list3
|
||||
*/
|
||||
PathList *combineSinglePath(PathList *&head1,
|
||||
PathList *pre1,
|
||||
PathList *&list1,
|
||||
PathList *&head2,
|
||||
PathList *pre2,
|
||||
PathList *&list2);
|
||||
|
||||
/**
|
||||
* Entry routine.
|
||||
*/
|
||||
void trace();
|
||||
/**
|
||||
* Trace the given node, find patches and fill them in
|
||||
*/
|
||||
Node *trace(Node *node, int *st, int len, int depth, PathList *& paths);
|
||||
/**
|
||||
* Look for path on the face and add to paths
|
||||
*/
|
||||
void findPaths(Node * node[2], int leaf[2], int depth[2], int *st[2], int maxdep, int dir, PathList * &paths);
|
||||
/**
|
||||
* Combine two list1 and list2 into list1 using connecting paths list3,
|
||||
* while closed paths are appended to rings
|
||||
*/
|
||||
void combinePaths(PathList *& list1, PathList *list2, PathList *paths, PathList *& rings);
|
||||
/**
|
||||
* Helper function: combine current paths in list1 and list2 to a single path and append to list3
|
||||
*/
|
||||
PathList *combineSinglePath(PathList *& head1, PathList *pre1, PathList *& list1, PathList *& head2, PathList *pre2, PathList *& list2);
|
||||
/**
|
||||
* Functions to patch rings in a node
|
||||
*/
|
||||
Node *patch(Node *node, int st[3], int len, PathList *rings);
|
||||
Node *patchSplit(Node *node,
|
||||
int st[3],
|
||||
int len,
|
||||
PathList *rings,
|
||||
int dir,
|
||||
PathList *&nrings1,
|
||||
PathList *&nrings2);
|
||||
Node *patchSplitSingle(Node *node,
|
||||
int st[3],
|
||||
int len,
|
||||
PathElement *head,
|
||||
int dir,
|
||||
PathList *&nrings1,
|
||||
PathList *&nrings2);
|
||||
Node *connectFace(Node *node, int st[3], int len, int dir, PathElement *f1, PathElement *f2);
|
||||
Node *locateCell(InternalNode *node,
|
||||
int st[3],
|
||||
int len,
|
||||
int ori[3],
|
||||
int dir,
|
||||
int side,
|
||||
Node *&rleaf,
|
||||
int rst[3],
|
||||
int &rlen);
|
||||
void compressRing(PathElement *&ring);
|
||||
void getFacePoint(PathElement *leaf, int dir, int &x, int &y, float &p, float &q);
|
||||
LeafNode *patchAdjacent(InternalNode *node,
|
||||
int len,
|
||||
int st1[3],
|
||||
LeafNode *leaf1,
|
||||
int st2[3],
|
||||
LeafNode *leaf2,
|
||||
int walkdir,
|
||||
int inc,
|
||||
int dir,
|
||||
int side,
|
||||
float alpha);
|
||||
int findPair(PathElement *head, int pos, int dir, PathElement *&pre1, PathElement *&pre2);
|
||||
int getSide(PathElement *e, int pos, int dir);
|
||||
int isEqual(PathElement *e1, PathElement *e2);
|
||||
void preparePrimalEdgesMask(InternalNode *node);
|
||||
void testFacePoint(PathElement *e1, PathElement *e2);
|
||||
|
||||
/**
|
||||
* Functions to patch rings in a node
|
||||
*/
|
||||
Node *patch(Node *node, int st[3], int len, PathList * rings);
|
||||
Node *patchSplit(Node *node, int st[3], int len, PathList * rings, int dir, PathList * &nrings1, PathList * &nrings2);
|
||||
Node *patchSplitSingle(Node *node, int st[3], int len, PathElement *head, int dir, PathList * &nrings1, PathList * &nrings2);
|
||||
Node *connectFace(Node *node, int st[3], int len, int dir, PathElement * f1, PathElement * f2);
|
||||
Node *locateCell(InternalNode *node, int st[3], int len, int ori[3], int dir, int side, Node * &rleaf, int rst[3], int& rlen);
|
||||
void compressRing(PathElement *& ring);
|
||||
void getFacePoint(PathElement *leaf, int dir, int& x, int& y, float& p, float& q);
|
||||
LeafNode *patchAdjacent(InternalNode *node, int len, int st1[3], LeafNode * leaf1, int st2[3], LeafNode * leaf2, int walkdir, int inc, int dir, int side, float alpha);
|
||||
int findPair(PathElement *head, int pos, int dir, PathElement *& pre1, PathElement *& pre2);
|
||||
int getSide(PathElement *e, int pos, int dir);
|
||||
int isEqual(PathElement *e1, PathElement *e2);
|
||||
void preparePrimalEdgesMask(InternalNode *node);
|
||||
void testFacePoint(PathElement *e1, PathElement *e2);
|
||||
/**
|
||||
* Path-related functions
|
||||
*/
|
||||
void deletePath(PathList *&head, PathList *pre, PathList *&curr);
|
||||
void printPath(PathList *path);
|
||||
void printPath(PathElement *path);
|
||||
void printElement(PathElement *ele);
|
||||
void printPaths(PathList *path);
|
||||
void checkElement(PathElement *ele);
|
||||
void checkPath(PathElement *path);
|
||||
|
||||
/**
|
||||
* Path-related functions
|
||||
*/
|
||||
void deletePath(PathList *& head, PathList *pre, PathList *& curr);
|
||||
void printPath(PathList *path);
|
||||
void printPath(PathElement *path);
|
||||
void printElement(PathElement *ele);
|
||||
void printPaths(PathList *path);
|
||||
void checkElement(PathElement *ele);
|
||||
void checkPath(PathElement *path);
|
||||
/**
|
||||
* Routines to build signs to create a partitioned volume
|
||||
*(after patching rings)
|
||||
*/
|
||||
void buildSigns();
|
||||
void buildSigns(unsigned char table[], Node *node, int isLeaf, int sg, int rvalue[8]);
|
||||
|
||||
/************************************************************************/
|
||||
/* To remove disconnected components */
|
||||
/************************************************************************/
|
||||
void floodFill();
|
||||
void clearProcessBits(Node *node, int height);
|
||||
int floodFill(LeafNode *leaf, int st[3], int len, int height, int threshold);
|
||||
int floodFill(Node *node, int st[3], int len, int height, int threshold);
|
||||
|
||||
/**
|
||||
* Routines to build signs to create a partitioned volume
|
||||
*(after patching rings)
|
||||
*/
|
||||
void buildSigns();
|
||||
void buildSigns(unsigned char table[], Node * node, int isLeaf, int sg, int rvalue[8]);
|
||||
/**
|
||||
* Write out polygon file
|
||||
*/
|
||||
void writeOut();
|
||||
|
||||
/************************************************************************/
|
||||
/* To remove disconnected components */
|
||||
/************************************************************************/
|
||||
void floodFill();
|
||||
void clearProcessBits(Node *node, int height);
|
||||
int floodFill(LeafNode *leaf, int st[3], int len, int height, int threshold);
|
||||
int floodFill(Node *node, int st[3], int len, int height, int threshold);
|
||||
void countIntersection(Node *node, int height, int &nedge, int &ncell, int &nface);
|
||||
void generateMinimizer(Node *node, int st[3], int len, int height, int &offset);
|
||||
void computeMinimizer(const LeafNode *leaf, int st[3], int len, float rvalue[3]) const;
|
||||
/**
|
||||
* Traversal functions to generate polygon model
|
||||
* op: 0 for counting, 1 for writing OBJ, 2 for writing OFF, 3 for writing PLY
|
||||
*/
|
||||
void cellProcContour(Node *node, int leaf, int depth);
|
||||
void faceProcContour(Node *node[2], int leaf[2], int depth[2], int maxdep, int dir);
|
||||
void edgeProcContour(Node *node[4], int leaf[4], int depth[4], int maxdep, int dir);
|
||||
void processEdgeWrite(Node *node[4], int depths[4], int maxdep, int dir);
|
||||
|
||||
/**
|
||||
* Write out polygon file
|
||||
*/
|
||||
void writeOut();
|
||||
|
||||
void countIntersection(Node *node, int height, int& nedge, int& ncell, int& nface);
|
||||
void generateMinimizer(Node *node, int st[3], int len, int height, int& offset);
|
||||
void computeMinimizer(const LeafNode * leaf, int st[3], int len,
|
||||
float rvalue[3]) const;
|
||||
/**
|
||||
* Traversal functions to generate polygon model
|
||||
* op: 0 for counting, 1 for writing OBJ, 2 for writing OFF, 3 for writing PLY
|
||||
*/
|
||||
void cellProcContour(Node *node, int leaf, int depth);
|
||||
void faceProcContour(Node * node[2], int leaf[2], int depth[2], int maxdep, int dir);
|
||||
void edgeProcContour(Node * node[4], int leaf[4], int depth[4], int maxdep, int dir);
|
||||
void processEdgeWrite(Node * node[4], int depths[4], int maxdep, int dir);
|
||||
|
||||
/* output callbacks/data */
|
||||
DualConAllocOutput alloc_output;
|
||||
DualConAddVert add_vert;
|
||||
DualConAddQuad add_quad;
|
||||
void *output_mesh;
|
||||
/* output callbacks/data */
|
||||
DualConAllocOutput alloc_output;
|
||||
DualConAddVert add_vert;
|
||||
DualConAddQuad add_quad;
|
||||
void *output_mesh;
|
||||
|
||||
private:
|
||||
/************ Operators for all nodes ************/
|
||||
|
||||
/// Lookup table
|
||||
int numEdgeTable[8];
|
||||
int edgeCountTable[8][3];
|
||||
|
||||
/// Build up lookup table
|
||||
void buildTable()
|
||||
{
|
||||
for (int i = 0; i < 256; i++) {
|
||||
InternalNode::numChildrenTable[i] = 0;
|
||||
int count = 0;
|
||||
for (int j = 0; j < 8; j++) {
|
||||
InternalNode::numChildrenTable[i] += ((i >> j) & 1);
|
||||
InternalNode::childrenCountTable[i][j] = count;
|
||||
InternalNode::childrenIndexTable[i][count] = j;
|
||||
count += ((i >> j) & 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
numEdgeTable[i] = 0;
|
||||
int count = 0;
|
||||
for (int j = 0; j < 3; j++) {
|
||||
numEdgeTable[i] += ((i >> j) & 1);
|
||||
edgeCountTable[i][j] = count;
|
||||
count += ((i >> j) & 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int getSign(Node *node, int height, int index)
|
||||
{
|
||||
if (height == 0) {
|
||||
return getSign(&node->leaf, index);
|
||||
}
|
||||
else {
|
||||
if (node->internal.has_child(index)) {
|
||||
return getSign(node->internal.get_child(node->internal.get_child_count(index)),
|
||||
height - 1,
|
||||
index);
|
||||
}
|
||||
else {
|
||||
return getSign(node->internal.get_child(0),
|
||||
height - 1,
|
||||
7 - node->internal.get_child_index(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************ Operators for leaf nodes ************/
|
||||
|
||||
void printInfo(int st[3])
|
||||
{
|
||||
printf("INFO AT: %d %d %d\n", st[0] >> minshift, st[1] >> minshift, st[2] >> minshift);
|
||||
LeafNode *leaf = (LeafNode *)locateLeafCheck(st);
|
||||
if (leaf)
|
||||
printInfo(leaf);
|
||||
else
|
||||
printf("Leaf not exists!\n");
|
||||
}
|
||||
|
||||
void printInfo(const LeafNode *leaf)
|
||||
{
|
||||
/*
|
||||
printf("Edge mask: ");
|
||||
for(int i = 0; i < 12; i ++)
|
||||
{
|
||||
printf("%d ", getEdgeParity(leaf, i));
|
||||
}
|
||||
printf("\n");
|
||||
printf("Stored edge mask: ");
|
||||
for(i = 0; i < 3; i ++)
|
||||
{
|
||||
printf("%d ", getStoredEdgesParity(leaf, i));
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
printf("Sign mask: ");
|
||||
for (int i = 0; i < 8; i++) {
|
||||
printf("%d ", getSign(leaf, i));
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
|
||||
/// Retrieve signs
|
||||
int getSign(const LeafNode *leaf, int index)
|
||||
{
|
||||
return ((leaf->signs >> index) & 1);
|
||||
}
|
||||
|
||||
/// Set sign
|
||||
void setSign(LeafNode *leaf, int index)
|
||||
{
|
||||
leaf->signs |= (1 << index);
|
||||
}
|
||||
|
||||
void setSign(LeafNode *leaf, int index, int sign)
|
||||
{
|
||||
leaf->signs &= (~(1 << index));
|
||||
leaf->signs |= ((sign & 1) << index);
|
||||
}
|
||||
|
||||
int getSignMask(const LeafNode *leaf) const
|
||||
{
|
||||
return leaf->signs;
|
||||
}
|
||||
|
||||
void setInProcessAll(int st[3], int dir)
|
||||
{
|
||||
int nst[3], eind;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
nst[0] = st[0] + dirCell[dir][i][0] * mindimen;
|
||||
nst[1] = st[1] + dirCell[dir][i][1] * mindimen;
|
||||
nst[2] = st[2] + dirCell[dir][i][2] * mindimen;
|
||||
eind = dirEdge[dir][i];
|
||||
|
||||
LeafNode *cell = locateLeafCheck(nst);
|
||||
assert(cell);
|
||||
|
||||
setInProcess(cell, eind);
|
||||
}
|
||||
}
|
||||
|
||||
void flipParityAll(int st[3], int dir)
|
||||
{
|
||||
int nst[3], eind;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
nst[0] = st[0] + dirCell[dir][i][0] * mindimen;
|
||||
nst[1] = st[1] + dirCell[dir][i][1] * mindimen;
|
||||
nst[2] = st[2] + dirCell[dir][i][2] * mindimen;
|
||||
eind = dirEdge[dir][i];
|
||||
|
||||
LeafNode *cell = locateLeaf(nst);
|
||||
flipEdge(cell, eind);
|
||||
}
|
||||
}
|
||||
|
||||
void setInProcess(LeafNode *leaf, int eind)
|
||||
{
|
||||
assert(eind >= 0 && eind <= 11);
|
||||
|
||||
leaf->flood_fill |= (1 << eind);
|
||||
}
|
||||
|
||||
void setOutProcess(LeafNode *leaf, int eind)
|
||||
{
|
||||
assert(eind >= 0 && eind <= 11);
|
||||
|
||||
leaf->flood_fill &= ~(1 << eind);
|
||||
}
|
||||
|
||||
int isInProcess(LeafNode *leaf, int eind)
|
||||
{
|
||||
assert(eind >= 0 && eind <= 11);
|
||||
|
||||
return (leaf->flood_fill >> eind) & 1;
|
||||
}
|
||||
|
||||
/// Generate signs at the corners from the edge parity
|
||||
void generateSigns(LeafNode *leaf, unsigned char table[], int start)
|
||||
{
|
||||
leaf->signs = table[leaf->edge_parity];
|
||||
|
||||
if ((start ^ leaf->signs) & 1) {
|
||||
leaf->signs = ~(leaf->signs);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get edge parity
|
||||
int getEdgeParity(const LeafNode *leaf, int index) const
|
||||
{
|
||||
assert(index >= 0 && index <= 11);
|
||||
|
||||
return (leaf->edge_parity >> index) & 1;
|
||||
}
|
||||
|
||||
/// Get edge parity on a face
|
||||
int getFaceParity(LeafNode *leaf, int index)
|
||||
{
|
||||
int a = getEdgeParity(leaf, faceMap[index][0]) +
|
||||
getEdgeParity(leaf, faceMap[index][1]) +
|
||||
getEdgeParity(leaf, faceMap[index][2]) +
|
||||
getEdgeParity(leaf, faceMap[index][3]);
|
||||
return (a & 1);
|
||||
}
|
||||
int getFaceEdgeNum(LeafNode *leaf, int index)
|
||||
{
|
||||
int a = getEdgeParity(leaf, faceMap[index][0]) +
|
||||
getEdgeParity(leaf, faceMap[index][1]) +
|
||||
getEdgeParity(leaf, faceMap[index][2]) +
|
||||
getEdgeParity(leaf, faceMap[index][3]);
|
||||
return a;
|
||||
}
|
||||
|
||||
/// Set edge parity
|
||||
void flipEdge(LeafNode *leaf, int index)
|
||||
{
|
||||
assert(index >= 0 && index <= 11);
|
||||
|
||||
leaf->edge_parity ^= (1 << index);
|
||||
}
|
||||
|
||||
/// Set 1
|
||||
void setEdge(LeafNode *leaf, int index)
|
||||
{
|
||||
assert(index >= 0 && index <= 11);
|
||||
|
||||
leaf->edge_parity |= (1 << index);
|
||||
}
|
||||
|
||||
/// Set 0
|
||||
void resetEdge(LeafNode *leaf, int index)
|
||||
{
|
||||
assert(index >= 0 && index <= 11);
|
||||
|
||||
leaf->edge_parity &= ~(1 << index);
|
||||
}
|
||||
|
||||
/// Flipping with a new intersection offset
|
||||
void createPrimalEdgesMask(LeafNode *leaf)
|
||||
{
|
||||
leaf->primary_edge_intersections = getPrimalEdgesMask2(leaf);
|
||||
}
|
||||
|
||||
void setStoredEdgesParity(LeafNode *leaf, int pindex)
|
||||
{
|
||||
assert(pindex <= 2 && pindex >= 0);
|
||||
|
||||
leaf->primary_edge_intersections |= (1 << pindex);
|
||||
}
|
||||
|
||||
int getStoredEdgesParity(const LeafNode *leaf, int pindex) const
|
||||
{
|
||||
assert(pindex <= 2 && pindex >= 0);
|
||||
|
||||
return (leaf->primary_edge_intersections >> pindex) & 1;
|
||||
}
|
||||
|
||||
LeafNode *flipEdge(LeafNode *leaf, int index, float alpha)
|
||||
{
|
||||
flipEdge(leaf, index);
|
||||
|
||||
if ((index & 3) == 0) {
|
||||
int ind = index / 4;
|
||||
if (getEdgeParity(leaf, index) && !getStoredEdgesParity(leaf, ind)) {
|
||||
// Create a new node
|
||||
int num = getNumEdges(leaf) + 1;
|
||||
setStoredEdgesParity(leaf, ind);
|
||||
int count = getEdgeCount(leaf, ind);
|
||||
LeafNode *nleaf = createLeaf(num);
|
||||
*nleaf = *leaf;
|
||||
|
||||
setEdgeOffset(nleaf, alpha, count);
|
||||
|
||||
if (num > 1) {
|
||||
float *pts = leaf->edge_intersections;
|
||||
float *npts = nleaf->edge_intersections;
|
||||
for (int i = 0; i < count; i++) {
|
||||
for (int j = 0; j < EDGE_FLOATS; j++) {
|
||||
npts[i * EDGE_FLOATS + j] = pts[i * EDGE_FLOATS + j];
|
||||
}
|
||||
}
|
||||
for (int i = count + 1; i < num; i++) {
|
||||
for (int j = 0; j < EDGE_FLOATS; j++) {
|
||||
npts[i * EDGE_FLOATS + j] = pts[(i - 1) * EDGE_FLOATS + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
removeLeaf(num - 1, (LeafNode *)leaf);
|
||||
leaf = nleaf;
|
||||
}
|
||||
}
|
||||
|
||||
return leaf;
|
||||
}
|
||||
|
||||
/// Update parent link
|
||||
void updateParent(InternalNode *node, int len, int st[3], LeafNode *leaf)
|
||||
{
|
||||
// First, locate the parent
|
||||
int count;
|
||||
InternalNode *parent = locateParent(node, len, st, count);
|
||||
|
||||
// Update
|
||||
parent->set_child(count, (Node *)leaf);
|
||||
}
|
||||
|
||||
void updateParent(InternalNode *node, int len, int st[3])
|
||||
{
|
||||
if (len == dimen) {
|
||||
root = (Node *)node;
|
||||
return;
|
||||
}
|
||||
|
||||
// First, locate the parent
|
||||
int count;
|
||||
InternalNode *parent = locateParent(len, st, count);
|
||||
|
||||
// UPdate
|
||||
parent->set_child(count, (Node *)node);
|
||||
}
|
||||
|
||||
/// Find edge intersection on a given edge
|
||||
int getEdgeIntersectionByIndex(int st[3], int index, float pt[3], int check) const
|
||||
{
|
||||
// First, locat the leaf
|
||||
const LeafNode *leaf;
|
||||
if (check) {
|
||||
leaf = locateLeafCheck(st);
|
||||
}
|
||||
else {
|
||||
leaf = locateLeaf(st);
|
||||
}
|
||||
|
||||
if (leaf && getStoredEdgesParity(leaf, index)) {
|
||||
float off = getEdgeOffset(leaf, getEdgeCount(leaf, index));
|
||||
pt[0] = (float) st[0];
|
||||
pt[1] = (float) st[1];
|
||||
pt[2] = (float) st[2];
|
||||
pt[index] += off * mindimen;
|
||||
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieve number of edges intersected
|
||||
int getPrimalEdgesMask(const LeafNode *leaf) const
|
||||
{
|
||||
return leaf->primary_edge_intersections;
|
||||
}
|
||||
|
||||
int getPrimalEdgesMask2(LeafNode *leaf)
|
||||
{
|
||||
return (((leaf->edge_parity & 0x1) >> 0) |
|
||||
((leaf->edge_parity & 0x10) >> 3) |
|
||||
((leaf->edge_parity & 0x100) >> 6));
|
||||
}
|
||||
|
||||
/// Get the count for a primary edge
|
||||
int getEdgeCount(const LeafNode *leaf, int index) const
|
||||
{
|
||||
return edgeCountTable[getPrimalEdgesMask(leaf)][index];
|
||||
}
|
||||
int getNumEdges(LeafNode *leaf)
|
||||
{
|
||||
return numEdgeTable[getPrimalEdgesMask(leaf)];
|
||||
}
|
||||
|
||||
int getNumEdges2(LeafNode *leaf)
|
||||
{
|
||||
return numEdgeTable[getPrimalEdgesMask2(leaf)];
|
||||
}
|
||||
|
||||
/// Set edge intersection
|
||||
void setEdgeOffset(LeafNode *leaf, float pt, int count)
|
||||
{
|
||||
float *pts = leaf->edge_intersections;
|
||||
pts[EDGE_FLOATS * count] = pt;
|
||||
pts[EDGE_FLOATS * count + 1] = 0;
|
||||
pts[EDGE_FLOATS * count + 2] = 0;
|
||||
pts[EDGE_FLOATS * count + 3] = 0;
|
||||
}
|
||||
|
||||
/// Set multiple edge intersections
|
||||
void setEdgeOffsets(LeafNode *leaf, float pt[3], int len)
|
||||
{
|
||||
float *pts = leaf->edge_intersections;
|
||||
for (int i = 0; i < len; i++) {
|
||||
pts[i] = pt[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieve edge intersection
|
||||
float getEdgeOffset(const LeafNode *leaf, int count) const
|
||||
{
|
||||
return leaf->edge_intersections[4 * count];
|
||||
}
|
||||
|
||||
/// Update method
|
||||
LeafNode *updateEdgeOffsets(LeafNode *leaf, int oldlen, int newlen, float offs[3])
|
||||
{
|
||||
// First, create a new leaf node
|
||||
LeafNode *nleaf = createLeaf(newlen);
|
||||
*nleaf = *leaf;
|
||||
|
||||
// Next, fill in the offsets
|
||||
setEdgeOffsets(nleaf, offs, newlen);
|
||||
|
||||
// Finally, delete the old leaf
|
||||
removeLeaf(oldlen, leaf);
|
||||
|
||||
return nleaf;
|
||||
}
|
||||
|
||||
/// Set minimizer index
|
||||
void setMinimizerIndex(LeafNode *leaf, int index)
|
||||
{
|
||||
leaf->minimizer_index = index;
|
||||
}
|
||||
|
||||
/// Get minimizer index
|
||||
int getMinimizerIndex(LeafNode *leaf)
|
||||
{
|
||||
return leaf->minimizer_index;
|
||||
}
|
||||
|
||||
int getMinimizerIndex(LeafNode *leaf, int eind)
|
||||
{
|
||||
int add = manifold_table[getSignMask(leaf)].pairs[eind][0] - 1;
|
||||
assert(add >= 0);
|
||||
return leaf->minimizer_index + add;
|
||||
}
|
||||
|
||||
void getMinimizerIndices(LeafNode *leaf, int eind, int inds[2])
|
||||
{
|
||||
const int *add = manifold_table[getSignMask(leaf)].pairs[eind];
|
||||
inds[0] = leaf->minimizer_index + add[0] - 1;
|
||||
if (add[0] == add[1]) {
|
||||
inds[1] = -1;
|
||||
}
|
||||
else {
|
||||
inds[1] = leaf->minimizer_index + add[1] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Set edge intersection
|
||||
void setEdgeOffsetNormal(LeafNode *leaf, float pt, float a, float b, float c, int count)
|
||||
{
|
||||
float *pts = leaf->edge_intersections;
|
||||
pts[4 * count] = pt;
|
||||
pts[4 * count + 1] = a;
|
||||
pts[4 * count + 2] = b;
|
||||
pts[4 * count + 3] = c;
|
||||
}
|
||||
|
||||
float getEdgeOffsetNormal(LeafNode *leaf, int count, float& a, float& b, float& c)
|
||||
{
|
||||
float *pts = leaf->edge_intersections;
|
||||
a = pts[4 * count + 1];
|
||||
b = pts[4 * count + 2];
|
||||
c = pts[4 * count + 3];
|
||||
return pts[4 * count];
|
||||
}
|
||||
|
||||
/// Set multiple edge intersections
|
||||
void setEdgeOffsetsNormals(LeafNode *leaf, const float pt[],
|
||||
const float a[], const float b[],
|
||||
const float c[], int len)
|
||||
{
|
||||
float *pts = leaf->edge_intersections;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (pt[i] > 1 || pt[i] < 0) {
|
||||
printf("\noffset: %f\n", pt[i]);
|
||||
}
|
||||
pts[i * 4] = pt[i];
|
||||
pts[i * 4 + 1] = a[i];
|
||||
pts[i * 4 + 2] = b[i];
|
||||
pts[i * 4 + 3] = c[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieve complete edge intersection
|
||||
void getEdgeIntersectionByIndex(const LeafNode *leaf, int index, int st[3],
|
||||
int len, float pt[3], float nm[3]) const
|
||||
{
|
||||
int count = getEdgeCount(leaf, index);
|
||||
const float *pts = leaf->edge_intersections;
|
||||
|
||||
float off = pts[4 * count];
|
||||
|
||||
pt[0] = (float) st[0];
|
||||
pt[1] = (float) st[1];
|
||||
pt[2] = (float) st[2];
|
||||
pt[index] += (off * len);
|
||||
|
||||
nm[0] = pts[4 * count + 1];
|
||||
nm[1] = pts[4 * count + 2];
|
||||
nm[2] = pts[4 * count + 3];
|
||||
}
|
||||
|
||||
float getEdgeOffsetNormalByIndex(LeafNode *leaf, int index, float nm[3])
|
||||
{
|
||||
int count = getEdgeCount(leaf, index);
|
||||
float *pts = leaf->edge_intersections;
|
||||
|
||||
float off = pts[4 * count];
|
||||
|
||||
nm[0] = pts[4 * count + 1];
|
||||
nm[1] = pts[4 * count + 2];
|
||||
nm[2] = pts[4 * count + 3];
|
||||
|
||||
return off;
|
||||
}
|
||||
|
||||
void fillEdgeIntersections(const LeafNode *leaf, int st[3], int len,
|
||||
float pts[12][3], float norms[12][3]) const
|
||||
{
|
||||
int i;
|
||||
// int stt[3] = {0, 0, 0};
|
||||
|
||||
// The three primal edges are easy
|
||||
int pmask[3] = {0, 4, 8};
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (getEdgeParity(leaf, pmask[i])) {
|
||||
// getEdgeIntersectionByIndex(leaf, i, stt, 1, pts[pmask[i]], norms[pmask[i]]);
|
||||
getEdgeIntersectionByIndex(leaf, i, st, len, pts[pmask[i]], norms[pmask[i]]);
|
||||
}
|
||||
}
|
||||
|
||||
// 3 face adjacent cubes
|
||||
int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
|
||||
int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
|
||||
for (i = 0; i < 3; i++) {
|
||||
int e1 = getEdgeParity(leaf, fmask[i][0]);
|
||||
int e2 = getEdgeParity(leaf, fmask[i][1]);
|
||||
if (e1 || e2) {
|
||||
int nst[3] = {st[0], st[1], st[2]};
|
||||
nst[i] += len;
|
||||
// int nstt[3] = {0, 0, 0};
|
||||
// nstt[i] += 1;
|
||||
const LeafNode *node = locateLeaf(nst);
|
||||
|
||||
if (e1) {
|
||||
// getEdgeIntersectionByIndex(node, femask[i][0], nstt, 1, pts[fmask[i][0]], norms[fmask[i][0]]);
|
||||
getEdgeIntersectionByIndex(node, femask[i][0], nst, len, pts[fmask[i][0]], norms[fmask[i][0]]);
|
||||
}
|
||||
if (e2) {
|
||||
// getEdgeIntersectionByIndex(node, femask[i][1], nstt, 1, pts[fmask[i][1]], norms[fmask[i][1]]);
|
||||
getEdgeIntersectionByIndex(node, femask[i][1], nst, len, pts[fmask[i][1]], norms[fmask[i][1]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 edge adjacent cubes
|
||||
int emask[3] = {3, 7, 11};
|
||||
int eemask[3] = {0, 1, 2};
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (getEdgeParity(leaf, emask[i])) {
|
||||
int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
|
||||
nst[i] -= len;
|
||||
// int nstt[3] = {1, 1, 1};
|
||||
// nstt[i] -= 1;
|
||||
const LeafNode *node = locateLeaf(nst);
|
||||
|
||||
// getEdgeIntersectionByIndex(node, eemask[i], nstt, 1, pts[emask[i]], norms[emask[i]]);
|
||||
getEdgeIntersectionByIndex(node, eemask[i], nst, len, pts[emask[i]], norms[emask[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void fillEdgeIntersections(const LeafNode *leaf, int st[3], int len,
|
||||
float pts[12][3], float norms[12][3],
|
||||
int parity[12]) const
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 12; i++) {
|
||||
parity[i] = 0;
|
||||
}
|
||||
// int stt[3] = {0, 0, 0};
|
||||
|
||||
// The three primal edges are easy
|
||||
int pmask[3] = {0, 4, 8};
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (getStoredEdgesParity(leaf, i)) {
|
||||
// getEdgeIntersectionByIndex(leaf, i, stt, 1, pts[pmask[i]], norms[pmask[i]]);
|
||||
getEdgeIntersectionByIndex(leaf, i, st, len, pts[pmask[i]], norms[pmask[i]]);
|
||||
parity[pmask[i]] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 3 face adjacent cubes
|
||||
int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
|
||||
int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
|
||||
for (i = 0; i < 3; i++) {
|
||||
{
|
||||
int nst[3] = {st[0], st[1], st[2]};
|
||||
nst[i] += len;
|
||||
// int nstt[3] = {0, 0, 0};
|
||||
// nstt[i] += 1;
|
||||
const LeafNode *node = locateLeafCheck(nst);
|
||||
if (node == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int e1 = getStoredEdgesParity(node, femask[i][0]);
|
||||
int e2 = getStoredEdgesParity(node, femask[i][1]);
|
||||
|
||||
if (e1) {
|
||||
// getEdgeIntersectionByIndex(node, femask[i][0], nstt, 1, pts[fmask[i][0]], norms[fmask[i][0]]);
|
||||
getEdgeIntersectionByIndex(node, femask[i][0], nst, len, pts[fmask[i][0]], norms[fmask[i][0]]);
|
||||
parity[fmask[i][0]] = 1;
|
||||
}
|
||||
if (e2) {
|
||||
// getEdgeIntersectionByIndex(node, femask[i][1], nstt, 1, pts[fmask[i][1]], norms[fmask[i][1]]);
|
||||
getEdgeIntersectionByIndex(node, femask[i][1], nst, len, pts[fmask[i][1]], norms[fmask[i][1]]);
|
||||
parity[fmask[i][1]] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 edge adjacent cubes
|
||||
int emask[3] = {3, 7, 11};
|
||||
int eemask[3] = {0, 1, 2};
|
||||
for (i = 0; i < 3; i++) {
|
||||
// if(getEdgeParity(leaf, emask[i]))
|
||||
{
|
||||
int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
|
||||
nst[i] -= len;
|
||||
// int nstt[3] = {1, 1, 1};
|
||||
// nstt[i] -= 1;
|
||||
const LeafNode *node = locateLeafCheck(nst);
|
||||
if (node == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (getStoredEdgesParity(node, eemask[i])) {
|
||||
// getEdgeIntersectionByIndex(node, eemask[i], nstt, 1, pts[emask[i]], norms[emask[i]]);
|
||||
getEdgeIntersectionByIndex(node, eemask[i], nst, len, pts[emask[i]], norms[emask[i]]);
|
||||
parity[emask[i]] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fillEdgeOffsetsNormals(LeafNode *leaf, int st[3], int len, float pts[12], float norms[12][3], int parity[12])
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 12; i++) {
|
||||
parity[i] = 0;
|
||||
}
|
||||
// int stt[3] = {0, 0, 0};
|
||||
|
||||
// The three primal edges are easy
|
||||
int pmask[3] = {0, 4, 8};
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (getStoredEdgesParity(leaf, i)) {
|
||||
pts[pmask[i]] = getEdgeOffsetNormalByIndex(leaf, i, norms[pmask[i]]);
|
||||
parity[pmask[i]] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 3 face adjacent cubes
|
||||
int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
|
||||
int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
|
||||
for (i = 0; i < 3; i++) {
|
||||
{
|
||||
int nst[3] = {st[0], st[1], st[2]};
|
||||
nst[i] += len;
|
||||
// int nstt[3] = {0, 0, 0};
|
||||
// nstt[i] += 1;
|
||||
LeafNode *node = locateLeafCheck(nst);
|
||||
if (node == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int e1 = getStoredEdgesParity(node, femask[i][0]);
|
||||
int e2 = getStoredEdgesParity(node, femask[i][1]);
|
||||
|
||||
if (e1) {
|
||||
pts[fmask[i][0]] = getEdgeOffsetNormalByIndex(node, femask[i][0], norms[fmask[i][0]]);
|
||||
parity[fmask[i][0]] = 1;
|
||||
}
|
||||
if (e2) {
|
||||
pts[fmask[i][1]] = getEdgeOffsetNormalByIndex(node, femask[i][1], norms[fmask[i][1]]);
|
||||
parity[fmask[i][1]] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 edge adjacent cubes
|
||||
int emask[3] = {3, 7, 11};
|
||||
int eemask[3] = {0, 1, 2};
|
||||
for (i = 0; i < 3; i++) {
|
||||
// if(getEdgeParity(leaf, emask[i]))
|
||||
{
|
||||
int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
|
||||
nst[i] -= len;
|
||||
// int nstt[3] = {1, 1, 1};
|
||||
// nstt[i] -= 1;
|
||||
LeafNode *node = locateLeafCheck(nst);
|
||||
if (node == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (getStoredEdgesParity(node, eemask[i])) {
|
||||
pts[emask[i]] = getEdgeOffsetNormalByIndex(node, eemask[i], norms[emask[i]]);
|
||||
parity[emask[i]] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Update method
|
||||
LeafNode *updateEdgeOffsetsNormals(LeafNode *leaf, int oldlen, int newlen, float offs[3], float a[3], float b[3], float c[3])
|
||||
{
|
||||
// First, create a new leaf node
|
||||
LeafNode *nleaf = createLeaf(newlen);
|
||||
*nleaf = *leaf;
|
||||
|
||||
// Next, fill in the offsets
|
||||
setEdgeOffsetsNormals(nleaf, offs, a, b, c, newlen);
|
||||
|
||||
// Finally, delete the old leaf
|
||||
removeLeaf(oldlen, leaf);
|
||||
|
||||
return nleaf;
|
||||
}
|
||||
|
||||
/// Locate a leaf
|
||||
/// WARNING: assuming this leaf already exists!
|
||||
|
||||
LeafNode *locateLeaf(int st[3])
|
||||
{
|
||||
Node *node = (Node *)root;
|
||||
for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
|
||||
int index = (((st[0] >> i) & 1) << 2) |
|
||||
(((st[1] >> i) & 1) << 1) |
|
||||
(((st[2] >> i) & 1));
|
||||
node = node->internal.get_child(node->internal.get_child_count(index));
|
||||
}
|
||||
|
||||
return &node->leaf;
|
||||
}
|
||||
|
||||
const LeafNode *locateLeaf(int st[3]) const
|
||||
{
|
||||
const Node *node = root;
|
||||
for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
|
||||
int index = (((st[0] >> i) & 1) << 2) |
|
||||
(((st[1] >> i) & 1) << 1) |
|
||||
(((st[2] >> i) & 1));
|
||||
node = node->internal.get_child(node->internal.get_child_count(index));
|
||||
}
|
||||
|
||||
return &node->leaf;
|
||||
}
|
||||
|
||||
LeafNode *locateLeaf(InternalNode *parent, int len, int st[3])
|
||||
{
|
||||
Node *node = (Node *)parent;
|
||||
int index;
|
||||
for (int i = len / 2; i >= mindimen; i >>= 1) {
|
||||
index = (((st[0] & i) ? 4 : 0) |
|
||||
((st[1] & i) ? 2 : 0) |
|
||||
((st[2] & i) ? 1 : 0));
|
||||
node = node->internal.get_child(node->internal.get_child_count(index));
|
||||
}
|
||||
|
||||
return &node->leaf;
|
||||
}
|
||||
|
||||
LeafNode *locateLeafCheck(int st[3])
|
||||
{
|
||||
Node *node = (Node *)root;
|
||||
for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
|
||||
int index = (((st[0] >> i) & 1) << 2) |
|
||||
(((st[1] >> i) & 1) << 1) |
|
||||
(((st[2] >> i) & 1));
|
||||
if (!node->internal.has_child(index)) {
|
||||
return NULL;
|
||||
}
|
||||
node = node->internal.get_child(node->internal.get_child_count(index));
|
||||
}
|
||||
|
||||
return &node->leaf;
|
||||
}
|
||||
|
||||
const LeafNode *locateLeafCheck(int st[3]) const
|
||||
{
|
||||
const Node *node = root;
|
||||
for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
|
||||
int index = (((st[0] >> i) & 1) << 2) |
|
||||
(((st[1] >> i) & 1) << 1) |
|
||||
(((st[2] >> i) & 1));
|
||||
if (!node->internal.has_child(index)) {
|
||||
return NULL;
|
||||
}
|
||||
node = node->internal.get_child(node->internal.get_child_count(index));
|
||||
}
|
||||
|
||||
return &node->leaf;
|
||||
}
|
||||
|
||||
InternalNode *locateParent(int len, int st[3], int& count)
|
||||
{
|
||||
InternalNode *node = (InternalNode *)root;
|
||||
InternalNode *pre = NULL;
|
||||
int index = 0;
|
||||
for (int i = dimen / 2; i >= len; i >>= 1) {
|
||||
index = (((st[0] & i) ? 4 : 0) |
|
||||
((st[1] & i) ? 2 : 0) |
|
||||
((st[2] & i) ? 1 : 0));
|
||||
pre = node;
|
||||
node = &node->get_child(node->get_child_count(index))->internal;
|
||||
}
|
||||
|
||||
count = pre->get_child_count(index);
|
||||
return pre;
|
||||
}
|
||||
|
||||
InternalNode *locateParent(InternalNode *parent, int len, int st[3], int& count)
|
||||
{
|
||||
InternalNode *node = parent;
|
||||
InternalNode *pre = NULL;
|
||||
int index = 0;
|
||||
for (int i = len / 2; i >= mindimen; i >>= 1) {
|
||||
index = (((st[0] & i) ? 4 : 0) |
|
||||
((st[1] & i) ? 2 : 0) |
|
||||
((st[2] & i) ? 1 : 0));
|
||||
pre = node;
|
||||
node = &node->get_child(node->get_child_count(index))->internal;
|
||||
}
|
||||
|
||||
count = pre->get_child_count(index);
|
||||
return pre;
|
||||
}
|
||||
|
||||
/************ Operators for internal nodes ************/
|
||||
|
||||
|
||||
/// Add a kid to an existing internal node
|
||||
InternalNode *addChild(InternalNode *node, int index, Node *child, int aLeaf)
|
||||
{
|
||||
// Create new internal node
|
||||
int num = node->get_num_children();
|
||||
InternalNode *rnode = createInternal(num + 1);
|
||||
|
||||
// Establish children
|
||||
int i;
|
||||
int count1 = 0, count2 = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (i == index) {
|
||||
if (aLeaf) {
|
||||
rnode->set_leaf_child(i, count2, &child->leaf);
|
||||
}
|
||||
else {
|
||||
rnode->set_internal_child(i, count2, &child->internal);
|
||||
}
|
||||
count2++;
|
||||
}
|
||||
else if (node->has_child(i)) {
|
||||
if (node->is_child_leaf(i)) {
|
||||
rnode->set_leaf_child(i, count2, &node->get_child(count1)->leaf);
|
||||
}
|
||||
else {
|
||||
rnode->set_internal_child(i, count2, &node->get_child(count1)->internal);
|
||||
}
|
||||
count1++;
|
||||
count2++;
|
||||
}
|
||||
}
|
||||
|
||||
removeInternal(num, node);
|
||||
return rnode;
|
||||
}
|
||||
|
||||
/// Allocate a node
|
||||
InternalNode *createInternal(int length)
|
||||
{
|
||||
InternalNode *inode = (InternalNode *)alloc[length]->allocate();
|
||||
inode->has_child_bitfield = 0;
|
||||
inode->child_is_leaf_bitfield = 0;
|
||||
return inode;
|
||||
}
|
||||
|
||||
LeafNode *createLeaf(int length)
|
||||
{
|
||||
assert(length <= 3);
|
||||
|
||||
LeafNode *lnode = (LeafNode *)leafalloc[length]->allocate();
|
||||
lnode->edge_parity = 0;
|
||||
lnode->primary_edge_intersections = 0;
|
||||
lnode->signs = 0;
|
||||
|
||||
return lnode;
|
||||
}
|
||||
|
||||
void removeInternal(int num, InternalNode *node)
|
||||
{
|
||||
alloc[num]->deallocate(node);
|
||||
}
|
||||
|
||||
void removeLeaf(int num, LeafNode *leaf)
|
||||
{
|
||||
assert(num >= 0 && num <= 3);
|
||||
leafalloc[num]->deallocate(leaf);
|
||||
}
|
||||
|
||||
/// Add a leaf (by creating a new par node with the leaf added)
|
||||
InternalNode *addLeafChild(InternalNode *par, int index, int count,
|
||||
LeafNode *leaf)
|
||||
{
|
||||
int num = par->get_num_children() + 1;
|
||||
InternalNode *npar = createInternal(num);
|
||||
*npar = *par;
|
||||
|
||||
if (num == 1) {
|
||||
npar->set_leaf_child(index, 0, leaf);
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
npar->set_child(i, par->get_child(i));
|
||||
}
|
||||
npar->set_leaf_child(index, count, leaf);
|
||||
for (i = count + 1; i < num; i++) {
|
||||
npar->set_child(i, par->get_child(i - 1));
|
||||
}
|
||||
}
|
||||
|
||||
removeInternal(num - 1, par);
|
||||
return npar;
|
||||
}
|
||||
|
||||
InternalNode *addInternalChild(InternalNode *par, int index, int count,
|
||||
InternalNode *node)
|
||||
{
|
||||
int num = par->get_num_children() + 1;
|
||||
InternalNode *npar = createInternal(num);
|
||||
*npar = *par;
|
||||
|
||||
if (num == 1) {
|
||||
npar->set_internal_child(index, 0, node);
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
npar->set_child(i, par->get_child(i));
|
||||
}
|
||||
npar->set_internal_child(index, count, node);
|
||||
for (i = count + 1; i < num; i++) {
|
||||
npar->set_child(i, par->get_child(i - 1));
|
||||
}
|
||||
}
|
||||
|
||||
removeInternal(num - 1, par);
|
||||
return npar;
|
||||
}
|
||||
/************ Operators for all nodes ************/
|
||||
|
||||
/// Lookup table
|
||||
int numEdgeTable[8];
|
||||
int edgeCountTable[8][3];
|
||||
|
||||
/// Build up lookup table
|
||||
void buildTable()
|
||||
{
|
||||
for (int i = 0; i < 256; i++) {
|
||||
InternalNode::numChildrenTable[i] = 0;
|
||||
int count = 0;
|
||||
for (int j = 0; j < 8; j++) {
|
||||
InternalNode::numChildrenTable[i] += ((i >> j) & 1);
|
||||
InternalNode::childrenCountTable[i][j] = count;
|
||||
InternalNode::childrenIndexTable[i][count] = j;
|
||||
count += ((i >> j) & 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
numEdgeTable[i] = 0;
|
||||
int count = 0;
|
||||
for (int j = 0; j < 3; j++) {
|
||||
numEdgeTable[i] += ((i >> j) & 1);
|
||||
edgeCountTable[i][j] = count;
|
||||
count += ((i >> j) & 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int getSign(Node *node, int height, int index)
|
||||
{
|
||||
if (height == 0) {
|
||||
return getSign(&node->leaf, index);
|
||||
}
|
||||
else {
|
||||
if (node->internal.has_child(index)) {
|
||||
return getSign(
|
||||
node->internal.get_child(node->internal.get_child_count(index)), height - 1, index);
|
||||
}
|
||||
else {
|
||||
return getSign(
|
||||
node->internal.get_child(0), height - 1, 7 - node->internal.get_child_index(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************ Operators for leaf nodes ************/
|
||||
|
||||
void printInfo(int st[3])
|
||||
{
|
||||
printf("INFO AT: %d %d %d\n", st[0] >> minshift, st[1] >> minshift, st[2] >> minshift);
|
||||
LeafNode *leaf = (LeafNode *)locateLeafCheck(st);
|
||||
if (leaf)
|
||||
printInfo(leaf);
|
||||
else
|
||||
printf("Leaf not exists!\n");
|
||||
}
|
||||
|
||||
void printInfo(const LeafNode *leaf)
|
||||
{
|
||||
/*
|
||||
printf("Edge mask: ");
|
||||
for(int i = 0; i < 12; i ++)
|
||||
{
|
||||
printf("%d ", getEdgeParity(leaf, i));
|
||||
}
|
||||
printf("\n");
|
||||
printf("Stored edge mask: ");
|
||||
for(i = 0; i < 3; i ++)
|
||||
{
|
||||
printf("%d ", getStoredEdgesParity(leaf, i));
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
printf("Sign mask: ");
|
||||
for (int i = 0; i < 8; i++) {
|
||||
printf("%d ", getSign(leaf, i));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/// Retrieve signs
|
||||
int getSign(const LeafNode *leaf, int index)
|
||||
{
|
||||
return ((leaf->signs >> index) & 1);
|
||||
}
|
||||
|
||||
/// Set sign
|
||||
void setSign(LeafNode *leaf, int index)
|
||||
{
|
||||
leaf->signs |= (1 << index);
|
||||
}
|
||||
|
||||
void setSign(LeafNode *leaf, int index, int sign)
|
||||
{
|
||||
leaf->signs &= (~(1 << index));
|
||||
leaf->signs |= ((sign & 1) << index);
|
||||
}
|
||||
|
||||
int getSignMask(const LeafNode *leaf) const
|
||||
{
|
||||
return leaf->signs;
|
||||
}
|
||||
|
||||
void setInProcessAll(int st[3], int dir)
|
||||
{
|
||||
int nst[3], eind;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
nst[0] = st[0] + dirCell[dir][i][0] * mindimen;
|
||||
nst[1] = st[1] + dirCell[dir][i][1] * mindimen;
|
||||
nst[2] = st[2] + dirCell[dir][i][2] * mindimen;
|
||||
eind = dirEdge[dir][i];
|
||||
|
||||
LeafNode *cell = locateLeafCheck(nst);
|
||||
assert(cell);
|
||||
|
||||
setInProcess(cell, eind);
|
||||
}
|
||||
}
|
||||
|
||||
void flipParityAll(int st[3], int dir)
|
||||
{
|
||||
int nst[3], eind;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
nst[0] = st[0] + dirCell[dir][i][0] * mindimen;
|
||||
nst[1] = st[1] + dirCell[dir][i][1] * mindimen;
|
||||
nst[2] = st[2] + dirCell[dir][i][2] * mindimen;
|
||||
eind = dirEdge[dir][i];
|
||||
|
||||
LeafNode *cell = locateLeaf(nst);
|
||||
flipEdge(cell, eind);
|
||||
}
|
||||
}
|
||||
|
||||
void setInProcess(LeafNode *leaf, int eind)
|
||||
{
|
||||
assert(eind >= 0 && eind <= 11);
|
||||
|
||||
leaf->flood_fill |= (1 << eind);
|
||||
}
|
||||
|
||||
void setOutProcess(LeafNode *leaf, int eind)
|
||||
{
|
||||
assert(eind >= 0 && eind <= 11);
|
||||
|
||||
leaf->flood_fill &= ~(1 << eind);
|
||||
}
|
||||
|
||||
int isInProcess(LeafNode *leaf, int eind)
|
||||
{
|
||||
assert(eind >= 0 && eind <= 11);
|
||||
|
||||
return (leaf->flood_fill >> eind) & 1;
|
||||
}
|
||||
|
||||
/// Generate signs at the corners from the edge parity
|
||||
void generateSigns(LeafNode *leaf, unsigned char table[], int start)
|
||||
{
|
||||
leaf->signs = table[leaf->edge_parity];
|
||||
|
||||
if ((start ^ leaf->signs) & 1) {
|
||||
leaf->signs = ~(leaf->signs);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get edge parity
|
||||
int getEdgeParity(const LeafNode *leaf, int index) const
|
||||
{
|
||||
assert(index >= 0 && index <= 11);
|
||||
|
||||
return (leaf->edge_parity >> index) & 1;
|
||||
}
|
||||
|
||||
/// Get edge parity on a face
|
||||
int getFaceParity(LeafNode *leaf, int index)
|
||||
{
|
||||
int a = getEdgeParity(leaf, faceMap[index][0]) + getEdgeParity(leaf, faceMap[index][1]) +
|
||||
getEdgeParity(leaf, faceMap[index][2]) + getEdgeParity(leaf, faceMap[index][3]);
|
||||
return (a & 1);
|
||||
}
|
||||
int getFaceEdgeNum(LeafNode *leaf, int index)
|
||||
{
|
||||
int a = getEdgeParity(leaf, faceMap[index][0]) + getEdgeParity(leaf, faceMap[index][1]) +
|
||||
getEdgeParity(leaf, faceMap[index][2]) + getEdgeParity(leaf, faceMap[index][3]);
|
||||
return a;
|
||||
}
|
||||
|
||||
/// Set edge parity
|
||||
void flipEdge(LeafNode *leaf, int index)
|
||||
{
|
||||
assert(index >= 0 && index <= 11);
|
||||
|
||||
leaf->edge_parity ^= (1 << index);
|
||||
}
|
||||
|
||||
/// Set 1
|
||||
void setEdge(LeafNode *leaf, int index)
|
||||
{
|
||||
assert(index >= 0 && index <= 11);
|
||||
|
||||
leaf->edge_parity |= (1 << index);
|
||||
}
|
||||
|
||||
/// Set 0
|
||||
void resetEdge(LeafNode *leaf, int index)
|
||||
{
|
||||
assert(index >= 0 && index <= 11);
|
||||
|
||||
leaf->edge_parity &= ~(1 << index);
|
||||
}
|
||||
|
||||
/// Flipping with a new intersection offset
|
||||
void createPrimalEdgesMask(LeafNode *leaf)
|
||||
{
|
||||
leaf->primary_edge_intersections = getPrimalEdgesMask2(leaf);
|
||||
}
|
||||
|
||||
void setStoredEdgesParity(LeafNode *leaf, int pindex)
|
||||
{
|
||||
assert(pindex <= 2 && pindex >= 0);
|
||||
|
||||
leaf->primary_edge_intersections |= (1 << pindex);
|
||||
}
|
||||
|
||||
int getStoredEdgesParity(const LeafNode *leaf, int pindex) const
|
||||
{
|
||||
assert(pindex <= 2 && pindex >= 0);
|
||||
|
||||
return (leaf->primary_edge_intersections >> pindex) & 1;
|
||||
}
|
||||
|
||||
LeafNode *flipEdge(LeafNode *leaf, int index, float alpha)
|
||||
{
|
||||
flipEdge(leaf, index);
|
||||
|
||||
if ((index & 3) == 0) {
|
||||
int ind = index / 4;
|
||||
if (getEdgeParity(leaf, index) && !getStoredEdgesParity(leaf, ind)) {
|
||||
// Create a new node
|
||||
int num = getNumEdges(leaf) + 1;
|
||||
setStoredEdgesParity(leaf, ind);
|
||||
int count = getEdgeCount(leaf, ind);
|
||||
LeafNode *nleaf = createLeaf(num);
|
||||
*nleaf = *leaf;
|
||||
|
||||
setEdgeOffset(nleaf, alpha, count);
|
||||
|
||||
if (num > 1) {
|
||||
float *pts = leaf->edge_intersections;
|
||||
float *npts = nleaf->edge_intersections;
|
||||
for (int i = 0; i < count; i++) {
|
||||
for (int j = 0; j < EDGE_FLOATS; j++) {
|
||||
npts[i * EDGE_FLOATS + j] = pts[i * EDGE_FLOATS + j];
|
||||
}
|
||||
}
|
||||
for (int i = count + 1; i < num; i++) {
|
||||
for (int j = 0; j < EDGE_FLOATS; j++) {
|
||||
npts[i * EDGE_FLOATS + j] = pts[(i - 1) * EDGE_FLOATS + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
removeLeaf(num - 1, (LeafNode *)leaf);
|
||||
leaf = nleaf;
|
||||
}
|
||||
}
|
||||
|
||||
return leaf;
|
||||
}
|
||||
|
||||
/// Update parent link
|
||||
void updateParent(InternalNode *node, int len, int st[3], LeafNode *leaf)
|
||||
{
|
||||
// First, locate the parent
|
||||
int count;
|
||||
InternalNode *parent = locateParent(node, len, st, count);
|
||||
|
||||
// Update
|
||||
parent->set_child(count, (Node *)leaf);
|
||||
}
|
||||
|
||||
void updateParent(InternalNode *node, int len, int st[3])
|
||||
{
|
||||
if (len == dimen) {
|
||||
root = (Node *)node;
|
||||
return;
|
||||
}
|
||||
|
||||
// First, locate the parent
|
||||
int count;
|
||||
InternalNode *parent = locateParent(len, st, count);
|
||||
|
||||
// UPdate
|
||||
parent->set_child(count, (Node *)node);
|
||||
}
|
||||
|
||||
/// Find edge intersection on a given edge
|
||||
int getEdgeIntersectionByIndex(int st[3], int index, float pt[3], int check) const
|
||||
{
|
||||
// First, locat the leaf
|
||||
const LeafNode *leaf;
|
||||
if (check) {
|
||||
leaf = locateLeafCheck(st);
|
||||
}
|
||||
else {
|
||||
leaf = locateLeaf(st);
|
||||
}
|
||||
|
||||
if (leaf && getStoredEdgesParity(leaf, index)) {
|
||||
float off = getEdgeOffset(leaf, getEdgeCount(leaf, index));
|
||||
pt[0] = (float)st[0];
|
||||
pt[1] = (float)st[1];
|
||||
pt[2] = (float)st[2];
|
||||
pt[index] += off * mindimen;
|
||||
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieve number of edges intersected
|
||||
int getPrimalEdgesMask(const LeafNode *leaf) const
|
||||
{
|
||||
return leaf->primary_edge_intersections;
|
||||
}
|
||||
|
||||
int getPrimalEdgesMask2(LeafNode *leaf)
|
||||
{
|
||||
return (((leaf->edge_parity & 0x1) >> 0) | ((leaf->edge_parity & 0x10) >> 3) |
|
||||
((leaf->edge_parity & 0x100) >> 6));
|
||||
}
|
||||
|
||||
/// Get the count for a primary edge
|
||||
int getEdgeCount(const LeafNode *leaf, int index) const
|
||||
{
|
||||
return edgeCountTable[getPrimalEdgesMask(leaf)][index];
|
||||
}
|
||||
int getNumEdges(LeafNode *leaf)
|
||||
{
|
||||
return numEdgeTable[getPrimalEdgesMask(leaf)];
|
||||
}
|
||||
|
||||
int getNumEdges2(LeafNode *leaf)
|
||||
{
|
||||
return numEdgeTable[getPrimalEdgesMask2(leaf)];
|
||||
}
|
||||
|
||||
/// Set edge intersection
|
||||
void setEdgeOffset(LeafNode *leaf, float pt, int count)
|
||||
{
|
||||
float *pts = leaf->edge_intersections;
|
||||
pts[EDGE_FLOATS * count] = pt;
|
||||
pts[EDGE_FLOATS * count + 1] = 0;
|
||||
pts[EDGE_FLOATS * count + 2] = 0;
|
||||
pts[EDGE_FLOATS * count + 3] = 0;
|
||||
}
|
||||
|
||||
/// Set multiple edge intersections
|
||||
void setEdgeOffsets(LeafNode *leaf, float pt[3], int len)
|
||||
{
|
||||
float *pts = leaf->edge_intersections;
|
||||
for (int i = 0; i < len; i++) {
|
||||
pts[i] = pt[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieve edge intersection
|
||||
float getEdgeOffset(const LeafNode *leaf, int count) const
|
||||
{
|
||||
return leaf->edge_intersections[4 * count];
|
||||
}
|
||||
|
||||
/// Update method
|
||||
LeafNode *updateEdgeOffsets(LeafNode *leaf, int oldlen, int newlen, float offs[3])
|
||||
{
|
||||
// First, create a new leaf node
|
||||
LeafNode *nleaf = createLeaf(newlen);
|
||||
*nleaf = *leaf;
|
||||
|
||||
// Next, fill in the offsets
|
||||
setEdgeOffsets(nleaf, offs, newlen);
|
||||
|
||||
// Finally, delete the old leaf
|
||||
removeLeaf(oldlen, leaf);
|
||||
|
||||
return nleaf;
|
||||
}
|
||||
|
||||
/// Set minimizer index
|
||||
void setMinimizerIndex(LeafNode *leaf, int index)
|
||||
{
|
||||
leaf->minimizer_index = index;
|
||||
}
|
||||
|
||||
/// Get minimizer index
|
||||
int getMinimizerIndex(LeafNode *leaf)
|
||||
{
|
||||
return leaf->minimizer_index;
|
||||
}
|
||||
|
||||
int getMinimizerIndex(LeafNode *leaf, int eind)
|
||||
{
|
||||
int add = manifold_table[getSignMask(leaf)].pairs[eind][0] - 1;
|
||||
assert(add >= 0);
|
||||
return leaf->minimizer_index + add;
|
||||
}
|
||||
|
||||
void getMinimizerIndices(LeafNode *leaf, int eind, int inds[2])
|
||||
{
|
||||
const int *add = manifold_table[getSignMask(leaf)].pairs[eind];
|
||||
inds[0] = leaf->minimizer_index + add[0] - 1;
|
||||
if (add[0] == add[1]) {
|
||||
inds[1] = -1;
|
||||
}
|
||||
else {
|
||||
inds[1] = leaf->minimizer_index + add[1] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// Set edge intersection
|
||||
void setEdgeOffsetNormal(LeafNode *leaf, float pt, float a, float b, float c, int count)
|
||||
{
|
||||
float *pts = leaf->edge_intersections;
|
||||
pts[4 * count] = pt;
|
||||
pts[4 * count + 1] = a;
|
||||
pts[4 * count + 2] = b;
|
||||
pts[4 * count + 3] = c;
|
||||
}
|
||||
|
||||
float getEdgeOffsetNormal(LeafNode *leaf, int count, float &a, float &b, float &c)
|
||||
{
|
||||
float *pts = leaf->edge_intersections;
|
||||
a = pts[4 * count + 1];
|
||||
b = pts[4 * count + 2];
|
||||
c = pts[4 * count + 3];
|
||||
return pts[4 * count];
|
||||
}
|
||||
|
||||
/// Set multiple edge intersections
|
||||
void setEdgeOffsetsNormals(
|
||||
LeafNode *leaf, const float pt[], const float a[], const float b[], const float c[], int len)
|
||||
{
|
||||
float *pts = leaf->edge_intersections;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (pt[i] > 1 || pt[i] < 0) {
|
||||
printf("\noffset: %f\n", pt[i]);
|
||||
}
|
||||
pts[i * 4] = pt[i];
|
||||
pts[i * 4 + 1] = a[i];
|
||||
pts[i * 4 + 2] = b[i];
|
||||
pts[i * 4 + 3] = c[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieve complete edge intersection
|
||||
void getEdgeIntersectionByIndex(
|
||||
const LeafNode *leaf, int index, int st[3], int len, float pt[3], float nm[3]) const
|
||||
{
|
||||
int count = getEdgeCount(leaf, index);
|
||||
const float *pts = leaf->edge_intersections;
|
||||
|
||||
float off = pts[4 * count];
|
||||
|
||||
pt[0] = (float)st[0];
|
||||
pt[1] = (float)st[1];
|
||||
pt[2] = (float)st[2];
|
||||
pt[index] += (off * len);
|
||||
|
||||
nm[0] = pts[4 * count + 1];
|
||||
nm[1] = pts[4 * count + 2];
|
||||
nm[2] = pts[4 * count + 3];
|
||||
}
|
||||
|
||||
float getEdgeOffsetNormalByIndex(LeafNode *leaf, int index, float nm[3])
|
||||
{
|
||||
int count = getEdgeCount(leaf, index);
|
||||
float *pts = leaf->edge_intersections;
|
||||
|
||||
float off = pts[4 * count];
|
||||
|
||||
nm[0] = pts[4 * count + 1];
|
||||
nm[1] = pts[4 * count + 2];
|
||||
nm[2] = pts[4 * count + 3];
|
||||
|
||||
return off;
|
||||
}
|
||||
|
||||
void fillEdgeIntersections(
|
||||
const LeafNode *leaf, int st[3], int len, float pts[12][3], float norms[12][3]) const
|
||||
{
|
||||
int i;
|
||||
// int stt[3] = {0, 0, 0};
|
||||
|
||||
// The three primal edges are easy
|
||||
int pmask[3] = {0, 4, 8};
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (getEdgeParity(leaf, pmask[i])) {
|
||||
// getEdgeIntersectionByIndex(leaf, i, stt, 1, pts[pmask[i]], norms[pmask[i]]);
|
||||
getEdgeIntersectionByIndex(leaf, i, st, len, pts[pmask[i]], norms[pmask[i]]);
|
||||
}
|
||||
}
|
||||
|
||||
// 3 face adjacent cubes
|
||||
int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
|
||||
int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
|
||||
for (i = 0; i < 3; i++) {
|
||||
int e1 = getEdgeParity(leaf, fmask[i][0]);
|
||||
int e2 = getEdgeParity(leaf, fmask[i][1]);
|
||||
if (e1 || e2) {
|
||||
int nst[3] = {st[0], st[1], st[2]};
|
||||
nst[i] += len;
|
||||
// int nstt[3] = {0, 0, 0};
|
||||
// nstt[i] += 1;
|
||||
const LeafNode *node = locateLeaf(nst);
|
||||
|
||||
if (e1) {
|
||||
// getEdgeIntersectionByIndex(node, femask[i][0], nstt, 1, pts[fmask[i][0]], norms[fmask[i][0]]);
|
||||
getEdgeIntersectionByIndex(
|
||||
node, femask[i][0], nst, len, pts[fmask[i][0]], norms[fmask[i][0]]);
|
||||
}
|
||||
if (e2) {
|
||||
// getEdgeIntersectionByIndex(node, femask[i][1], nstt, 1, pts[fmask[i][1]], norms[fmask[i][1]]);
|
||||
getEdgeIntersectionByIndex(
|
||||
node, femask[i][1], nst, len, pts[fmask[i][1]], norms[fmask[i][1]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 edge adjacent cubes
|
||||
int emask[3] = {3, 7, 11};
|
||||
int eemask[3] = {0, 1, 2};
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (getEdgeParity(leaf, emask[i])) {
|
||||
int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
|
||||
nst[i] -= len;
|
||||
// int nstt[3] = {1, 1, 1};
|
||||
// nstt[i] -= 1;
|
||||
const LeafNode *node = locateLeaf(nst);
|
||||
|
||||
// getEdgeIntersectionByIndex(node, eemask[i], nstt, 1, pts[emask[i]], norms[emask[i]]);
|
||||
getEdgeIntersectionByIndex(node, eemask[i], nst, len, pts[emask[i]], norms[emask[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fillEdgeIntersections(const LeafNode *leaf,
|
||||
int st[3],
|
||||
int len,
|
||||
float pts[12][3],
|
||||
float norms[12][3],
|
||||
int parity[12]) const
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 12; i++) {
|
||||
parity[i] = 0;
|
||||
}
|
||||
// int stt[3] = {0, 0, 0};
|
||||
|
||||
// The three primal edges are easy
|
||||
int pmask[3] = {0, 4, 8};
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (getStoredEdgesParity(leaf, i)) {
|
||||
// getEdgeIntersectionByIndex(leaf, i, stt, 1, pts[pmask[i]], norms[pmask[i]]);
|
||||
getEdgeIntersectionByIndex(leaf, i, st, len, pts[pmask[i]], norms[pmask[i]]);
|
||||
parity[pmask[i]] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 3 face adjacent cubes
|
||||
int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
|
||||
int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
|
||||
for (i = 0; i < 3; i++) {
|
||||
{
|
||||
int nst[3] = {st[0], st[1], st[2]};
|
||||
nst[i] += len;
|
||||
// int nstt[3] = {0, 0, 0};
|
||||
// nstt[i] += 1;
|
||||
const LeafNode *node = locateLeafCheck(nst);
|
||||
if (node == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int e1 = getStoredEdgesParity(node, femask[i][0]);
|
||||
int e2 = getStoredEdgesParity(node, femask[i][1]);
|
||||
|
||||
if (e1) {
|
||||
// getEdgeIntersectionByIndex(node, femask[i][0], nstt, 1, pts[fmask[i][0]], norms[fmask[i][0]]);
|
||||
getEdgeIntersectionByIndex(
|
||||
node, femask[i][0], nst, len, pts[fmask[i][0]], norms[fmask[i][0]]);
|
||||
parity[fmask[i][0]] = 1;
|
||||
}
|
||||
if (e2) {
|
||||
// getEdgeIntersectionByIndex(node, femask[i][1], nstt, 1, pts[fmask[i][1]], norms[fmask[i][1]]);
|
||||
getEdgeIntersectionByIndex(
|
||||
node, femask[i][1], nst, len, pts[fmask[i][1]], norms[fmask[i][1]]);
|
||||
parity[fmask[i][1]] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 edge adjacent cubes
|
||||
int emask[3] = {3, 7, 11};
|
||||
int eemask[3] = {0, 1, 2};
|
||||
for (i = 0; i < 3; i++) {
|
||||
// if(getEdgeParity(leaf, emask[i]))
|
||||
{
|
||||
int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
|
||||
nst[i] -= len;
|
||||
// int nstt[3] = {1, 1, 1};
|
||||
// nstt[i] -= 1;
|
||||
const LeafNode *node = locateLeafCheck(nst);
|
||||
if (node == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (getStoredEdgesParity(node, eemask[i])) {
|
||||
// getEdgeIntersectionByIndex(node, eemask[i], nstt, 1, pts[emask[i]], norms[emask[i]]);
|
||||
getEdgeIntersectionByIndex(node, eemask[i], nst, len, pts[emask[i]], norms[emask[i]]);
|
||||
parity[emask[i]] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fillEdgeOffsetsNormals(
|
||||
LeafNode *leaf, int st[3], int len, float pts[12], float norms[12][3], int parity[12])
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 12; i++) {
|
||||
parity[i] = 0;
|
||||
}
|
||||
// int stt[3] = {0, 0, 0};
|
||||
|
||||
// The three primal edges are easy
|
||||
int pmask[3] = {0, 4, 8};
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (getStoredEdgesParity(leaf, i)) {
|
||||
pts[pmask[i]] = getEdgeOffsetNormalByIndex(leaf, i, norms[pmask[i]]);
|
||||
parity[pmask[i]] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 3 face adjacent cubes
|
||||
int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
|
||||
int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
|
||||
for (i = 0; i < 3; i++) {
|
||||
{
|
||||
int nst[3] = {st[0], st[1], st[2]};
|
||||
nst[i] += len;
|
||||
// int nstt[3] = {0, 0, 0};
|
||||
// nstt[i] += 1;
|
||||
LeafNode *node = locateLeafCheck(nst);
|
||||
if (node == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int e1 = getStoredEdgesParity(node, femask[i][0]);
|
||||
int e2 = getStoredEdgesParity(node, femask[i][1]);
|
||||
|
||||
if (e1) {
|
||||
pts[fmask[i][0]] = getEdgeOffsetNormalByIndex(node, femask[i][0], norms[fmask[i][0]]);
|
||||
parity[fmask[i][0]] = 1;
|
||||
}
|
||||
if (e2) {
|
||||
pts[fmask[i][1]] = getEdgeOffsetNormalByIndex(node, femask[i][1], norms[fmask[i][1]]);
|
||||
parity[fmask[i][1]] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 edge adjacent cubes
|
||||
int emask[3] = {3, 7, 11};
|
||||
int eemask[3] = {0, 1, 2};
|
||||
for (i = 0; i < 3; i++) {
|
||||
// if(getEdgeParity(leaf, emask[i]))
|
||||
{
|
||||
int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
|
||||
nst[i] -= len;
|
||||
// int nstt[3] = {1, 1, 1};
|
||||
// nstt[i] -= 1;
|
||||
LeafNode *node = locateLeafCheck(nst);
|
||||
if (node == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (getStoredEdgesParity(node, eemask[i])) {
|
||||
pts[emask[i]] = getEdgeOffsetNormalByIndex(node, eemask[i], norms[emask[i]]);
|
||||
parity[emask[i]] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Update method
|
||||
LeafNode *updateEdgeOffsetsNormals(
|
||||
LeafNode *leaf, int oldlen, int newlen, float offs[3], float a[3], float b[3], float c[3])
|
||||
{
|
||||
// First, create a new leaf node
|
||||
LeafNode *nleaf = createLeaf(newlen);
|
||||
*nleaf = *leaf;
|
||||
|
||||
// Next, fill in the offsets
|
||||
setEdgeOffsetsNormals(nleaf, offs, a, b, c, newlen);
|
||||
|
||||
// Finally, delete the old leaf
|
||||
removeLeaf(oldlen, leaf);
|
||||
|
||||
return nleaf;
|
||||
}
|
||||
|
||||
/// Locate a leaf
|
||||
/// WARNING: assuming this leaf already exists!
|
||||
|
||||
LeafNode *locateLeaf(int st[3])
|
||||
{
|
||||
Node *node = (Node *)root;
|
||||
for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
|
||||
int index = (((st[0] >> i) & 1) << 2) | (((st[1] >> i) & 1) << 1) | (((st[2] >> i) & 1));
|
||||
node = node->internal.get_child(node->internal.get_child_count(index));
|
||||
}
|
||||
|
||||
return &node->leaf;
|
||||
}
|
||||
|
||||
const LeafNode *locateLeaf(int st[3]) const
|
||||
{
|
||||
const Node *node = root;
|
||||
for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
|
||||
int index = (((st[0] >> i) & 1) << 2) | (((st[1] >> i) & 1) << 1) | (((st[2] >> i) & 1));
|
||||
node = node->internal.get_child(node->internal.get_child_count(index));
|
||||
}
|
||||
|
||||
return &node->leaf;
|
||||
}
|
||||
|
||||
LeafNode *locateLeaf(InternalNode *parent, int len, int st[3])
|
||||
{
|
||||
Node *node = (Node *)parent;
|
||||
int index;
|
||||
for (int i = len / 2; i >= mindimen; i >>= 1) {
|
||||
index = (((st[0] & i) ? 4 : 0) | ((st[1] & i) ? 2 : 0) | ((st[2] & i) ? 1 : 0));
|
||||
node = node->internal.get_child(node->internal.get_child_count(index));
|
||||
}
|
||||
|
||||
return &node->leaf;
|
||||
}
|
||||
|
||||
LeafNode *locateLeafCheck(int st[3])
|
||||
{
|
||||
Node *node = (Node *)root;
|
||||
for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
|
||||
int index = (((st[0] >> i) & 1) << 2) | (((st[1] >> i) & 1) << 1) | (((st[2] >> i) & 1));
|
||||
if (!node->internal.has_child(index)) {
|
||||
return NULL;
|
||||
}
|
||||
node = node->internal.get_child(node->internal.get_child_count(index));
|
||||
}
|
||||
|
||||
return &node->leaf;
|
||||
}
|
||||
|
||||
const LeafNode *locateLeafCheck(int st[3]) const
|
||||
{
|
||||
const Node *node = root;
|
||||
for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
|
||||
int index = (((st[0] >> i) & 1) << 2) | (((st[1] >> i) & 1) << 1) | (((st[2] >> i) & 1));
|
||||
if (!node->internal.has_child(index)) {
|
||||
return NULL;
|
||||
}
|
||||
node = node->internal.get_child(node->internal.get_child_count(index));
|
||||
}
|
||||
|
||||
return &node->leaf;
|
||||
}
|
||||
|
||||
InternalNode *locateParent(int len, int st[3], int &count)
|
||||
{
|
||||
InternalNode *node = (InternalNode *)root;
|
||||
InternalNode *pre = NULL;
|
||||
int index = 0;
|
||||
for (int i = dimen / 2; i >= len; i >>= 1) {
|
||||
index = (((st[0] & i) ? 4 : 0) | ((st[1] & i) ? 2 : 0) | ((st[2] & i) ? 1 : 0));
|
||||
pre = node;
|
||||
node = &node->get_child(node->get_child_count(index))->internal;
|
||||
}
|
||||
|
||||
count = pre->get_child_count(index);
|
||||
return pre;
|
||||
}
|
||||
|
||||
InternalNode *locateParent(InternalNode *parent, int len, int st[3], int &count)
|
||||
{
|
||||
InternalNode *node = parent;
|
||||
InternalNode *pre = NULL;
|
||||
int index = 0;
|
||||
for (int i = len / 2; i >= mindimen; i >>= 1) {
|
||||
index = (((st[0] & i) ? 4 : 0) | ((st[1] & i) ? 2 : 0) | ((st[2] & i) ? 1 : 0));
|
||||
pre = node;
|
||||
node = &node->get_child(node->get_child_count(index))->internal;
|
||||
}
|
||||
|
||||
count = pre->get_child_count(index);
|
||||
return pre;
|
||||
}
|
||||
|
||||
/************ Operators for internal nodes ************/
|
||||
|
||||
/// Add a kid to an existing internal node
|
||||
InternalNode *addChild(InternalNode *node, int index, Node *child, int aLeaf)
|
||||
{
|
||||
// Create new internal node
|
||||
int num = node->get_num_children();
|
||||
InternalNode *rnode = createInternal(num + 1);
|
||||
|
||||
// Establish children
|
||||
int i;
|
||||
int count1 = 0, count2 = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (i == index) {
|
||||
if (aLeaf) {
|
||||
rnode->set_leaf_child(i, count2, &child->leaf);
|
||||
}
|
||||
else {
|
||||
rnode->set_internal_child(i, count2, &child->internal);
|
||||
}
|
||||
count2++;
|
||||
}
|
||||
else if (node->has_child(i)) {
|
||||
if (node->is_child_leaf(i)) {
|
||||
rnode->set_leaf_child(i, count2, &node->get_child(count1)->leaf);
|
||||
}
|
||||
else {
|
||||
rnode->set_internal_child(i, count2, &node->get_child(count1)->internal);
|
||||
}
|
||||
count1++;
|
||||
count2++;
|
||||
}
|
||||
}
|
||||
|
||||
removeInternal(num, node);
|
||||
return rnode;
|
||||
}
|
||||
|
||||
/// Allocate a node
|
||||
InternalNode *createInternal(int length)
|
||||
{
|
||||
InternalNode *inode = (InternalNode *)alloc[length]->allocate();
|
||||
inode->has_child_bitfield = 0;
|
||||
inode->child_is_leaf_bitfield = 0;
|
||||
return inode;
|
||||
}
|
||||
|
||||
LeafNode *createLeaf(int length)
|
||||
{
|
||||
assert(length <= 3);
|
||||
|
||||
LeafNode *lnode = (LeafNode *)leafalloc[length]->allocate();
|
||||
lnode->edge_parity = 0;
|
||||
lnode->primary_edge_intersections = 0;
|
||||
lnode->signs = 0;
|
||||
|
||||
return lnode;
|
||||
}
|
||||
|
||||
void removeInternal(int num, InternalNode *node)
|
||||
{
|
||||
alloc[num]->deallocate(node);
|
||||
}
|
||||
|
||||
void removeLeaf(int num, LeafNode *leaf)
|
||||
{
|
||||
assert(num >= 0 && num <= 3);
|
||||
leafalloc[num]->deallocate(leaf);
|
||||
}
|
||||
|
||||
/// Add a leaf (by creating a new par node with the leaf added)
|
||||
InternalNode *addLeafChild(InternalNode *par, int index, int count, LeafNode *leaf)
|
||||
{
|
||||
int num = par->get_num_children() + 1;
|
||||
InternalNode *npar = createInternal(num);
|
||||
*npar = *par;
|
||||
|
||||
if (num == 1) {
|
||||
npar->set_leaf_child(index, 0, leaf);
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
npar->set_child(i, par->get_child(i));
|
||||
}
|
||||
npar->set_leaf_child(index, count, leaf);
|
||||
for (i = count + 1; i < num; i++) {
|
||||
npar->set_child(i, par->get_child(i - 1));
|
||||
}
|
||||
}
|
||||
|
||||
removeInternal(num - 1, par);
|
||||
return npar;
|
||||
}
|
||||
|
||||
InternalNode *addInternalChild(InternalNode *par, int index, int count, InternalNode *node)
|
||||
{
|
||||
int num = par->get_num_children() + 1;
|
||||
InternalNode *npar = createInternal(num);
|
||||
*npar = *par;
|
||||
|
||||
if (num == 1) {
|
||||
npar->set_internal_child(index, 0, node);
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
npar->set_child(i, par->get_child(i));
|
||||
}
|
||||
npar->set_internal_child(index, count, node);
|
||||
for (i = count + 1; i < num; i++) {
|
||||
npar->set_child(i, par->get_child(i - 1));
|
||||
}
|
||||
}
|
||||
|
||||
removeInternal(num - 1, par);
|
||||
return npar;
|
||||
}
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:Octree")
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:Octree")
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* __OCTREE_H__ */
|
||||
#endif /* __OCTREE_H__ */
|
||||
|
||||
Reference in New Issue
Block a user