Initial commit

This commit is contained in:
Paolo Cignoni 2005-01-19 15:40:44 +00:00
parent 29e46cb2af
commit e820e88dfe
4 changed files with 4389 additions and 0 deletions

View File

@ -0,0 +1,905 @@
/*===========================================================================*\
* *
* IsoEx *
* Copyright (C) 2002 by Computer Graphics Group, RWTH Aachen *
* www.rwth-graphics.de *
* *
*---------------------------------------------------------------------------*
* *
* License *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Library General Public License as published *
* by the Free Software Foundation, version 2. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
* *
\*===========================================================================*/
//== TABLES ==================================================================
int edgeTable[256]=
{
0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0
};
//-----------------------------------------------------------------------------
int triTable[256][2][17] =
{{{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 1, 9, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1}},
{{9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 2, 10, 9, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 10, 9, 8, 3, 2 , -1,-1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 0, 8, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 10 */
{{1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 1, 9, 0, 2, 3,11, -1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 9, 8, 11, 2, 1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 3, 11,10, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 8, 11, 10, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 11,10, 9, 0, 3, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 15 */
{{9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 8, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 4, 7, 3, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1}},
{{4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 7, 3, 1, 9, 4, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 20 */
{{1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 1, 2,10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1}},
{{3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 3, 0, 4, 7, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1}},
{{9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 2,10, 9, 0, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}},
{{2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1, -1},
{1, 6, 7, 3, 2,10, 9, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 25 */
{{11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 5, 2, 0, 4, 7,11,-1,-1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 3, 3, 3, 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1}},
{{4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1, -1},
{2, 4, 4, 2, 1, 9, 11, 11,9,4,7, -1, -1, -1, -1, -1 ,-1}},
{{3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 3, 11,10, 1, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1}},
{{1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1, -1},
{1, 6, 1, 0, 4, 7,11,10, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 30 */
{{4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1, -1},
{2, 3, 5, 4, 7, 8, 0, 3, 11, 10, 9, -1, -1, -1, -1, -1, -1}},
{{4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 4, 7,11,10, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 0, 1, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 35 */
{{8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 3, 1, 5, 4, 8,-1,-1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 1, 2,10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1}},
{{3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 3, 3, 3, 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1}},
{{5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 4, 0, 2,10, 5,-1,-1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1, -1},
{2, 4, 4, 2, 10, 5, 3, 4, 8, 3, 5, -1, -1, -1, -1, -1, -1}},
/* 40 */
{{9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 0, 8, 11, 2, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1}},
{{0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 0, 1, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}},
{{2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1, -1},
{1, 6, 2, 1, 5, 4, 8,11, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1},
{ 2, 4, 3, 3,11,10, 1, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1}},
/* 45 */
{{4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1, -1},
{2, 3, 5, 4, 9, 5, 1, 0, 8,11, 10, -1, -1, -1, -1, -1, -1}},
{{5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1, -1},
{1, 6, 5, 4, 0, 3,11, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 5, 4, 8, 11, 10,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 7, 8, 9, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 5, 7, 3, 0, 9,-1,-1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 50 */
{{0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 1, 5, 7, 8, 0,-1,-1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 3, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 7, 8, 9, 5,10, 1, 2, -1, -1, -1, -1, -1, -1, -1}},
{{10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1, -1},
{ 2, 3, 5,10, 1, 2, 0, 9, 5, 7, 3,-1, -1, -1, -1, -1, -1}},
{{8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1, -1},
{1, 6, 2,10, 5, 7, 8, 0,-1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 55 */
{{2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 2,10, 5, 7, 3,-1,-1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 7, 8, 9, 5, 3,11, 2, -1, -1, -1, -1, -1, -1, -1}},
{{9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1, -1},
{1, 6, 2, 0, 9, 5, 7,11, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1, -1},
{2, 3, 5, 2, 3,11, 8, 0, 1, 5, 7, -1, -1, -1, -1, -1, -1}},
{{11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5,11, 2, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 60 */
{{9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1, -1},
{2, 4, 4, 3,11, 10, 1, 5, 7, 8, 9, -1, -1, -1, -1, -1, -1}},
{{5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1, -1},
{1, 7, 5, 7, 11,10, 1, 0, 9, -1, -1, -1, -1, -1, -1, -1, -1}},
{{11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1, -1},
{1, 7, 11,10,5, 7, 8, 0,3, -1, -1, -1, -1, -1, -1, -1, -1}},
{{11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 4, 5, 7, 11,10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 3,10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 65 */
{{0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1}},
{{9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 1, 9, 8, 3, 5,10, 6, -1, -1, -1, -1, -1, -1, -1}},
{{1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 1, 2, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 1, 2, 6, 5, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1}},
/* 70 */
{{9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 0, 2, 6, 5, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1, -1},
{1, 6, 2, 6, 5, 9, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 2, 3,11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1}},
{{11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1},
{ 2, 4, 3, 0, 8, 11, 2, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1}},
{{0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 3, 3, 3, 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1}},
/* 75 */
{{5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1, -1},
{2, 3, 5, 5,10, 6, 2, 1, 9, 8,11, -1, -1, -1, -1, -1, -1}},
{{6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 5, 1, 3, 11,6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1, -1},
{1, 6, 5, 1, 0, 8,11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1, -1},
{2, 4, 4, 3, 11, 6, 0, 5, 9, 0, 6, -1, -1, -1, -1}},
{{6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 6, 5, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 80 */
{{5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 5,10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1}},
{{4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 4, 7, 3, 0, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1}},
{{1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 3, 3, 3, 1, 9, 0, 5,10, 6, 8, 4, 7, -1, -1, -1, -1}},
{{10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1, -1},
{ 2, 3, 5,10, 6, 5, 9, 4, 7, 3, 1,-1, -1, -1, -1, -1, -1}},
{{6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 1, 2, 6, 5, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1}},
/* 85 */
{{1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1, -1},
{2, 4, 4, 2, 6, 5, 1, 3, 0, 4, 7, -1, -1, -1, -1, -1, -1}},
{{8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1, -1},
{2, 3, 5, 8, 4, 7, 5, 9, 0, 2, 6, -1, -1, -1, -1, -1, -1}},
{{7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1, -1},
{1, 7, 7, 3, 2, 6, 5, 9, 4,-1, -1, -1, -1, -1, -1, -1, -1}},
{{3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 3, 3, 3, 3,11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1}},
{{5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1, -1},
{2, 3, 5, 5,10, 6, 7,11, 2, 0, 4, -1, -1, -1, -1, -1, -1}},
/* 90 */
{{0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1},
{4, 3, 3, 3, 3, 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6}},
{{9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1, -1},
{3, 4, 4, 3, 2, 1, 9,11, 4, 7, 11, 9, 5, 10, 6, -1, -1}},
{{8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1, -1},
{2, 3, 5, 8, 4, 7, 11, 6, 5, 1, 3, -1, -1, -1, -1, -1, -1}},
{{5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1, -1},
{1, 7, 5, 1, 0, 4, 7,11, 6, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1, -1},
{3, 4, 4, 3, 0, 6, 5, 9, 3, 11, 6, 0, 8, 4, 7, -1, -1}},
/* 95 */
{{6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1, -1},
{2, 4, 4, 9, 4, 7, 11, 6, 5, 9, 11,-1, -1, -1, -1, -1, -1}},
{{10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 4, 4, 9, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 4, 9,10, 6, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1}},
{{10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 5, 6, 4, 0, 1, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1, -1},
{1, 6, 1,10, 6, 4, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 100 */
{{1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 2, 6, 4, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1, -1},
{2, 3, 5, 3, 0, 8, 9, 1, 2, 6, 4, -1, -1, -1, -1, -1, -1}},
{{0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 2, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 8, 3, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1, -1},
{ 2, 4, 3, 10, 6, 4, 9,11, 2, 3, -1, -1, -1, -1, -1, -1, -1}},
/* 105 */
{{0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1, -1},
{2, 4, 4, 2, 11, 8, 0, 10, 6, 4, 9, -1, -1, -1, -1, -1, -1}},
{{3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1, -1},
{2, 3, 5, 3,11, 2, 1, 10,6, 4, 0, -1, -1, -1, -1, -1, -1}},
{{6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1, -1},
{1, 7, 6, 4, 8,11, 2, 1,10, -1, -1, -1, -1, -1, -1, -1, -1}},
{{9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1, -1},
{1, 6, 3,11, 6, 4, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1, -1},
{1, 7, 8,11, 6, 4, 9, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 110 */
{{3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 3,11, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 8, 11, 6, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 8, 9,10, 6, 7,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1, -1},
{1, 6, 0, 9, 10, 6, 7, 3, -1,-1,-1, -1, -1, -1, -1, -1, -1}},
{{10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1, -1},
{ 2, 4, 4, 8, 0, 1, 7, 10, 6, 7, 1,-1, -1, -1, -1, -1, -1}},
/* 115 */
{{10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 5, 10, 6, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1, -1},
{1, 6, 1, 2, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1, -1},
{1, 7, 2, 6, 7, 3, 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 7, 8, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 7, 3, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 120 */
{{2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1, -1},
{2, 3, 5, 2, 3,11, 6, 7, 8, 9,10, -1, -1, -1, -1, -1, -1}},
{{2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1, -1},
{1, 7, 2, 0, 9,10,6, 7, 11, -1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1, -1},
{3, 4, 4, 3, 8, 0, 1, 7, 10, 6, 7, 1, 11, 2, 3, -1, -1}},
{{11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1, -1},
{ 2, 4, 4, 11, 2, 1,7, 1, 10, 6, 7,-1, -1, -1, -1, -1, -1}},
{{8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1, -1},
{1, 7, 8, 9, 1, 3, 11, 6, 7,-1, -1, -1, -1, -1, -1, -1, -1}},
/* 125 */
{{0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1}},
{{7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1, -1},
{2, 4, 4, 0, 3,11, 6, 7, 8, 0, 6, -1, -1, -1, -1, -1, -1}},
{{7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 130 */
{{0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1}},
{{8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 1, 9, 8, 3,11, 7, 6, -1, -1, -1, -1, -1, -1, -1}},
{{10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 2, 3, 3,10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 3, 3, 3, 1, 2,10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1}},
{{2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 2, 10, 9, 0, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1}},
/* 135 */
{{6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1, -1},
{2, 3, 5, 6, 11, 7, 3, 2,10, 9, 8, -1, -1, -1, -1, -1, -1}},
{{7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 2, 3, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 6, 2, 0, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 2, 3, 7, 6, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1}},
{{1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1, -1},
{1, 6, 6, 2, 1, 9, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 140 */
{{10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 5, 1, 3, 7, 6,10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1, -1},
{ 2, 4, 4, 10, 1, 7, 6, 8, 7, 1, 0,-1, -1, -1, -1, -1, -1}},
{{0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1, -1},
{1, 6,10, 9, 0, 3, 7, 6,-1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 7, 6, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 6, 11, 8, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 145 */
{{3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 0, 4, 6,11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 6,11, 8, 4, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1}},
{{9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1, -1},
{1, 6, 6,11, 3, 1, 9, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 6, 11, 8, 4, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1, -1},
{2, 3, 5, 1, 2, 10,11, 3,0,4, 6, -1, -1, -1, -1, -1, -1}},
/* 150 */
{{4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1, -1},
{2, 4, 4, 4, 6, 11, 8, 2,10, 9, 0, -1, -1, -1, -1, -1, -1}},
{{10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1, -1},
{1, 7, 10,9, 4, 6, 11, 3, 2, -1, -1, -1, -1, -1, -1, -1, -1}},
{{8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 4, 6, 2, 3, 8,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 4, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1, -1},
{2, 3, 5, 1, 9, 0, 3, 8, 4, 6, 2, -1, -1, -1, -1, -1, -1}},
/* 155 */
{{1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 1, 9, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1, -1},
{1, 6, 1, 3, 8, 4, 6,10, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 5,10, 1,0,4,6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1, -1},
{1, 7, 4, 6, 10, 9, 0,3, 8, -1, -1, -1, -1, -1, -1, -1, -1}},
{{10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 4, 4, 6, 10, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 160 */
{{4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 3, 3, 3, 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1}},
{{5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 0, 1, 5, 4, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}},
{{11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1, -1},
{ 2, 3, 5,11, 7, 6, 4, 8, 3, 1, 5,-1, -1, -1, -1, -1, -1}},
{{9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 3, 3, 3, 9, 5, 4,10, 1, 2, 7, 6, 11, -1, -1, -1, -1}},
/* 165 */
{{6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1, -1},
{4, 3, 3, 3, 3, 6,11, 7, 1, 2,10, 0, 8, 3, 4, 9, 5}},
{{7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1, -1},
{2, 3, 5, 7, 6, 11, 10, 5, 4, 0, 2,-1, -1, -1, -1, -1, -1}},
{{3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1, -1},
{3, 4, 4, 3, 5, 3, 2,10, 4, 8, 3, 5, 6, 11, 7, 6, -1}},
{{7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 4, 3, 2, 3, 7, 6, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1}},
{{9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1, -1},
{2, 3, 5, 9, 5, 4, 8, 7, 6, 2, 0, -1, -1, -1, -1, -1, -1}},
/* 170 */
{{3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1, -1},
{2, 4, 4, 3, 7, 6, 2, 0, 1, 5, 4, -1, -1, -1, -1, -1, -1}},
{{6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1, -1},
{1, 7, 6, 2, 1, 5, 4, 8, 7,-1, -1, -1, -1, -1, -1, -1, -1}},
{{9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1, -1},
{2, 3, 5, 9, 5, 4, 6,10, 1, 3, 7,-1, -1, -1, -1, -1, -1}},
{{1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1, -1},
{3, 4, 4, 3, 0, 8, 7, 1, 6, 10, 1, 7, 9, 5, 4, -1, -1}},
{{4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1, -1},
{1, 7, 4, 0, 3, 7, 6, 10, 5, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 175 */
{{7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1, -1},
{2, 4, 4, 4, 8, 10, 5, 7, 6,10, 8, -1, -1, -1, -1, -1, -1}},
{{6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5,11, 8, 9, 5, 6,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1, -1},
{2, 4, 4, 0, 9, 5, 6, 6,11, 3, 0, -1, -1, -1, -1, -1, -1}},
{{0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1, -1},
{1, 6, 0, 1, 5, 6,11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 6,11, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/*180 */
{{1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1, -1},
{2, 3, 5, 1, 2, 10, 5, 6,11, 8, 9, -1, -1, -1, -1, -1, -1}},
{{0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1, -1},
{3, 4, 4, 3, 11, 3,0, 6, 9, 5, 6, 0, 2, 10, 1, 2, 10}},
{{11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1, -1},
{ 1, 7,11, 8, 0, 2,10, 5, 6,-1, -1, -1, -1, -1, -1, -1, -1}},
{{6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1, -1},
{2, 4, 4, 6,11, 3, 5, 10, 5, 3, 2, -1, -1, -1, -1, -1, -1}},
{{5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1, -1},
{1, 6, 2, 3, 8, 9, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 185 */
{{9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 9, 5, 6, 2, 0,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1, -1},
{1, 7, 1, 5, 6, 2, 3, 8, 0, -1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 1, 5, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1, -1},
{1, 7, 1, 3, 8, 9, 5, 6,10, -1, -1, -1, -1, -1, -1, -1, -1}},
{{10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1, -1},
{ 2, 4, 4, 5, 6, 0, 9, 10, 1, 0, 6, -1, -1, -1, -1, -1, -1}},
/* 190 */
{{0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1}},
{{10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 3,10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 4, 5,10, 11, 7,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1, -1},
{ 2, 4, 3, 5,10,11, 7, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1}},
{{5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1, -1},
{ 2, 4, 3, 5, 10, 11, 7, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1}},
/* 195 */
{{10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1, -1},
{ 2, 4, 4, 10, 11, 7, 5, 1, 9, 8, 3, -1, -1, -1, -1, -1, -1}},
{{11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 5, 7, 5, 1, 2,11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1, -1},
{2, 3, 5, 0, 8, 3, 2,11, 7, 5,1, -1, -1, -1, -1, -1, -1}},
{{9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1, -1},
{1, 6, 2,11, 7, 5, 9, 0,-1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1, -1},
{1, 7, 7, 5, 9, 8, 3, 2,11,-1, -1, -1, -1, -1, -1, -1, -1}},
/* 200 */
{{2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 3, 7, 5,10, 2,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1, -1},
{1, 6, 5,10, 2, 0, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1, -1},
{2, 3, 5, 9, 0, 1, 10, 2, 3, 7, 5, -1, -1, -1, -1, -1, -1}},
{{9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1, -1},
{1, 7, 9, 8, 7, 5,10, 2, 1,-1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 3, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 205 */
{{0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 0, 8, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 9, 0, 3, 7, 5,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 7, 5, 9, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 10,11, 8, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1, -1},
{1, 6, 0, 4, 5,10,11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 210 */
{{0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1, -1},
{2, 3, 5, 0, 1, 9, 4, 5, 10, 11, 8, -1, -1, -1, -1, -1, -1}},
{{10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1, -1},
{ 1, 7,10, 11, 3, 1, 9,4, 5,-1, -1, -1, -1, -1, -1, -1}},
{{2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1, -1},
{1, 6, 2,11, 8, 4, 5, 1,-1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1, -1},
{1, 7, 0, 4, 5, 1, 2, 11, 3,-1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1, -1},
{1, 7, 0, 2,11, 8, 4, 5, 9, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 215 */
{{9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1}},
{{2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1, -1},
{2, 4, 4, 2, 3, 5, 10, 4, 5, 3, 8,-1, -1, -1, -1, -1, -1}},
{{5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 5,10, 2, 0, 4,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1, -1},
{3, 4, 4, 3, 3, 5, 10, 2, 8, 4, 5, 3, 0, 1, 9, -1, -1}},
{{5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1, -1},
{1, 6,10, 2, 1, 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 220 */
{{8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 8, 4, 5, 1, 3,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 0, 4, 5, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1, -1},
{2, 4, 4, 0, 3, 5, 9, 8, 4, 5, 3, -1, -1, -1, -1, -1, -1}},
{{9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 9,10, 11, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 225 */
{{0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1, -1},
{2, 3, 5, 0, 8, 3, 7, 4, 9, 10, 11, -1, -1, -1, -1, -1, -1}},
{{1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1, -1},
{1, 6, 1, 10,11, 7, 4, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1, -1},
{1, 7, 3, 1,10,11, 7, 4, 8, -1, -1, -1, -1, -1, -1, -1, -1}},
{{4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1, -1},
{2, 4, 4, 2, 11, 9, 1, 4, 9, 11, 7, -1, -1, -1, -1, -1, -1}},
{{9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1, -1},
{3, 4, 4, 3, 1, 2, 11, 9, 7, 4, 9,11, 8, 3, 0, 8, 3}},
/* 230 */
{{11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 5, 11, 7, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1, -1},
{ 2, 4, 4, 11, 7, 4, 2, 3, 2, 4, 8,-1, -1, -1, -1, -1, -1}},
{{2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1, -1},
{1, 6, 2, 3, 7, 4, 9,10, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1, -1},
{1, 7, 9,10, 2, 0, 8, 7, 4,-1, -1, -1, -1, -1, -1, -1, -1}},
{{3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1, -1},
{1, 7, 3, 7, 4, 0, 1,10, 2, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 235 */
{{1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 3, 1,10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1}},
{{4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 4, 9, 1, 3, 7,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1, -1},
{2, 4, 4, 8, 7, 1, 0, 4, 9, 1, 7, -1, -1, -1, -1, -1, -1}},
{{4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 3, 7, 4, 0,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 240 */
{{9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 8, 9, 10,11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 3, 0, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 0, 1, 10,11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 3, 1,10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 1, 2, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 245 */
{{3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1, -1},
{2, 4, 4, 2,11, 9, 1, 3, 0, 9, 11, -1, -1, -1, -1, -1,-1}},
{{0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 0, 2,11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 2, 3, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 2, 0, 9,10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
/* 250 */
{{2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1, -1},
{2, 4, 4, 2, 3, 8, 10, 1, 10, 8, 0, -1, -1, -1, -1, -1, -1}},
{{1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 4, 1, 3, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
{{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}
};
//-----------------------------------------------------------------------------
int polyTable[8][16] =
{
{-1},
{-1},
{-1},
{0, 1, 2, -1},
{0, 1, 2, 2, 3, 0, -1},
{0, 1, 2, 0, 2, 4, 4, 2, 3, -1},
{0, 1, 2, 2, 3, 4, 4, 5, 0, 0, 2, 4, -1},
{0, 1, 5, 0, 5, 6, 1, 2, 5, 4, 5, 3, 2, 3, 5, -1}
};
//=============================================================================

View File

@ -0,0 +1,457 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/***************************************************************************/
#ifndef __VCG_EXTENDED_MARCHING_CUBES
#define __VCG_EXTENDED_MARCHING_CUBES
#include <float.h>
#include <assert.h>
#include <vector>
#include <vcg/math/base.h>
#include <vcg/math/matrix.h>
#include <vcg/math/lin_algebra.h>
#include <vcg/simplex/face/topology.h>
#include <vcg/complex/trimesh/update/edges.h>
#include <vcg/complex/trimesh/update/normal.h>
#include <vcg/complex/trimesh/update/topology.h>
#include <vcg/complex/trimesh/allocate.h>
#include <vcg/space/point3.h>
#include "emc_lookup_table.h"
namespace vcg
{
namespace tri
{
// Doxygen documentation
/** \addtogroup trimesh */
/*@{*/
/*
* Cube description:
* 3 ________ 2 _____2__
* /| /| / | /|
* / | / | 11/ 3 10/ |
* 7 /_______ / | /__6_|__ / |1
* | | |6 | | | |
* | 0|__|_____|1 | |__|_0|__|
* | / | / 7 8/ 5 /
* | / | / | / | /9
* |/_______|/ |/___4___|/
* 4 5
*/
//! This class implements the Extended Marching Cubes algorithm.
/*!
* The implementation is enough generic: this class works only on one volume cell for each
* call to <CODE>ProcessCell</CODE>. Using the field value at the cell corners, it adds to the
* mesh the triangles set approximating the surface that cross that cell.
* @param TRIMESH_TYPE (Template parameter) the mesh type that will be constructed
* @param WALKER_TYPE (Template parameter) the class that implements the traversal ordering of the volume.
**/
template<class TRIMESH_TYPE, class WALKER_TYPE>
class ExtendedMarchingCubes
{
public:
#ifdef _WIN64
typedef unsigned __int64 size_t;
#else
typedef _W64 unsigned int size_t;
#endif
typedef typename vcg::tri::Allocator< TRIMESH_TYPE > AllocatorType;
typedef typename TRIMESH_TYPE::ScalarType ScalarType;
typedef typename TRIMESH_TYPE::VertexType VertexType;
typedef typename TRIMESH_TYPE::VertexPointer VertexPointer;
typedef typename TRIMESH_TYPE::VertexIterator VertexIterator;
typedef typename TRIMESH_TYPE::FaceType FaceType;
typedef typename TRIMESH_TYPE::FacePointer FacePointer;
typedef typename TRIMESH_TYPE::FaceIterator FaceIterator;
typedef typename TRIMESH_TYPE::CoordType CoordType;
typedef typename TRIMESH_TYPE::CoordType* CoordPointer;
typedef struct
{
size_t face, edge;
} LightEdge;
/*!
* Constructor
* \param mesh The mesh that will be constructed
* \param volume The volume describing the field
* \param walker The class implementing the traversal policy
* \param angle The feature detection threshold misuring the sharpness of a feature(default is 30 degree)
*/
ExtendedMarchingCubes(TRIMESH_TYPE &mesh, WALKER_TYPE &walker, ScalarType angle=30)
{
_mesh = &mesh;
_walker = &walker;
_featureAngle = vcg::math::ToRad(angle);
_initialized = _finalized = false;
};
/*!
* Execute the initialiazation.
* This method must be executed before the first call to <CODE>ApplyEMC</CODE>
*/
void Initialize()
{
assert(!_initialized && !_finalized);
_featureFlag = VertexType::NewBitFlag();
_initialized = true;
};
/*!
*
* This method must be executed after the last call to <CODE>ApplyEMC</CODE>
*/
void Finalize()
{
assert(_initialized && !_finalized);
FlipEdges();
VertexIterator v_iter = _mesh->vert.begin();
VertexIterator v_end = _mesh->vert.end();
for ( ; v_iter!=v_end; v_iter++)
v_iter->ClearUserBit( _featureFlag );
VertexType::DeleteBitFlag( _featureFlag );
_featureFlag = 0;
_mesh = NULL;
_walker = NULL;
_finalized = true;
};
/*!
* Apply the <I>extended marching cubes</I> algorithm to the volume cell identified by the two points <CODE>min</CODE> and <CODE>max</CODE>.
* All the three coordinates of the first point must be smaller than the respectives three coordinatas of the second point.
* \param min the first point
* \param max the second point
*/
void ProcessCell(const vcg::Point3i &min, const vcg::Point3i &max)
{
assert(_initialized && !_finalized);
assert(min[0]<max[0] && min[1]<max[1] && min[2]<max[2]);
_corners[0].X()=min.X(); _corners[0].Y()=min.Y(); _corners[0].Z()=min.Z();
_corners[1].X()=max.X(); _corners[1].Y()=min.Y(); _corners[1].Z()=min.Z();
_corners[2].X()=max.X(); _corners[2].Y()=max.Y(); _corners[2].Z()=min.Z();
_corners[3].X()=min.X(); _corners[3].Y()=max.Y(); _corners[3].Z()=min.Z();
_corners[4].X()=min.X(); _corners[4].Y()=min.Y(); _corners[4].Z()=max.Z();
_corners[5].X()=max.X(); _corners[5].Y()=min.Y(); _corners[5].Z()=max.Z();
_corners[6].X()=max.X(); _corners[6].Y()=max.Y(); _corners[6].Z()=max.Z();
_corners[7].X()=min.X(); _corners[7].Y()=max.Y(); _corners[7].Z()=max.Z();
unsigned char cubetype = 0;
if ((_field[0] = _walker->V(_corners[0].X(), _corners[0].Y(), _corners[0].Z())) >= 0) cubetype+= 1;
if ((_field[1] = _walker->V(_corners[1].X(), _corners[1].Y(), _corners[1].Z())) >= 0) cubetype+= 2;
if ((_field[2] = _walker->V(_corners[2].X(), _corners[2].Y(), _corners[2].Z())) >= 0) cubetype+= 4;
if ((_field[3] = _walker->V(_corners[3].X(), _corners[3].Y(), _corners[3].Z())) >= 0) cubetype+= 8;
if ((_field[4] = _walker->V(_corners[4].X(), _corners[4].Y(), _corners[4].Z())) >= 0) cubetype+= 16;
if ((_field[5] = _walker->V(_corners[5].X(), _corners[5].Y(), _corners[5].Z())) >= 0) cubetype+= 32;
if ((_field[6] = _walker->V(_corners[6].X(), _corners[6].Y(), _corners[6].Z())) >= 0) cubetype+= 64;
if ((_field[7] = _walker->V(_corners[7].X(), _corners[7].Y(), _corners[7].Z())) >= 0) cubetype+=128;
if (cubetype==0 || cubetype==255)
return;
size_t vertices_idx[12];
memset(vertices_idx, -1, 12*sizeof(size_t));
int code = edgeTable[cubetype];
VertexPointer vp = NULL;
if ( 1&code ) { _walker->GetXIntercept(_corners[0], _corners[1], vp); vertices_idx[ 0] = vp - &_mesh->vert[0]; }
if ( 2&code ) { _walker->GetYIntercept(_corners[1], _corners[2], vp); vertices_idx[ 1] = vp - &_mesh->vert[0]; }
if ( 4&code ) { _walker->GetXIntercept(_corners[3], _corners[2], vp); vertices_idx[ 2] = vp - &_mesh->vert[0]; }
if ( 8&code ) { _walker->GetYIntercept(_corners[0], _corners[3], vp); vertices_idx[ 3] = vp - &_mesh->vert[0]; }
if ( 16&code ) { _walker->GetXIntercept(_corners[4], _corners[5], vp); vertices_idx[ 4] = vp - &_mesh->vert[0]; }
if ( 32&code ) { _walker->GetYIntercept(_corners[5], _corners[6], vp); vertices_idx[ 5] = vp - &_mesh->vert[0]; }
if ( 64&code ) { _walker->GetXIntercept(_corners[7], _corners[6], vp); vertices_idx[ 6] = vp - &_mesh->vert[0]; }
if ( 128&code ) { _walker->GetYIntercept(_corners[4], _corners[7], vp); vertices_idx[ 7] = vp - &_mesh->vert[0]; }
if ( 256&code ) { _walker->GetZIntercept(_corners[0], _corners[4], vp); vertices_idx[ 8] = vp - &_mesh->vert[0]; }
if ( 512&code ) { _walker->GetZIntercept(_corners[1], _corners[5], vp); vertices_idx[ 9] = vp - &_mesh->vert[0]; }
if (1024&code ) { _walker->GetZIntercept(_corners[2], _corners[6], vp); vertices_idx[10] = vp - &_mesh->vert[0]; }
if (2048&code ) { _walker->GetZIntercept(_corners[3], _corners[7], vp); vertices_idx[11] = vp - &_mesh->vert[0]; }
unsigned int m, n, vertices_num;
unsigned int components = triTable[cubetype][1][0];
int *indices = &triTable[cubetype][1][components+1];
std::vector< size_t > vertices_list;
for (m=1; m<=components; m++)
{
// current sheet contains vertices_num vertices
vertices_num = triTable[cubetype][1][m];
// collect vertices
vertices_list.clear();
for (n=0; n<vertices_num; ++n)
vertices_list.push_back( vertices_idx[ indices[n] ] );
VertexPointer feature = FindFeature( vertices_list );
if (feature != NULL) // i.e. is a valid vertex
{
// feature -> create triangle fan around feature vertex
size_t feature_idx = feature - &_mesh->vert[0];
size_t face_idx = _mesh->face.size();
vertices_list.push_back( vertices_list[0] );
AllocatorType::AddFaces(*_mesh, (int) vertices_num);
for (unsigned int j=0; j<vertices_num; ++j, face_idx++)
{
_mesh->face[face_idx].V(0) = &_mesh->vert[ vertices_list[j ] ];
_mesh->face[face_idx].V(1) = &_mesh->vert[ vertices_list[j+1] ];
_mesh->face[face_idx].V(2) = &_mesh->vert[ feature_idx ];
}
}
else
{
// no feature -> old marching cubes triangle table
for (int j=0; polyTable[vertices_num][j] != -1; j+=3)
{
size_t face_idx = _mesh->face.size();
AllocatorType::AddFaces(*_mesh, 1);
_mesh->face[ face_idx].V(0) = &_mesh->vert[ vertices_idx[ indices[ polyTable[vertices_num][j ] ] ] ];
_mesh->face[ face_idx].V(1) = &_mesh->vert[ vertices_idx[ indices[ polyTable[vertices_num][j+1] ] ] ];
_mesh->face[ face_idx].V(2) = &_mesh->vert[ vertices_idx[ indices[ polyTable[vertices_num][j+2] ] ] ];
}
}
indices += vertices_num;
}
}; // end of ApplyEMC
private:
/*!
*/
WALKER_TYPE *_walker;
/*!
*/
TRIMESH_TYPE *_mesh;
/*!
*/
bool _initialized;;
/*!
*/
bool _finalized;
/*!
* The feature detection threshold misuring the sharpness of a feature
*/
ScalarType _featureAngle;
/*!
* The flag used for marking the feature vertices.
*/
int _featureFlag;
/*!
* Array of the 8 corners of the volume cell being processed
*/
vcg::Point3i _corners[8];
/*!
* The field value at the cell corners
*/
ScalarType _field[8];
/*!
* Tests if the surface patch crossing the current cell contains a sharp feature
* \param vertices_idx The list of vertex indices intersecting the edges of the current cell
* \return The pointer to the new Vertex if a feature is detected; NULL otherwise.
*/
VertexPointer FindFeature(const std::vector<size_t> &vertices_idx)
{
unsigned int i, j, rank;
size_t vertices_num = (size_t) vertices_idx.size();
CoordType *points = new CoordType[ vertices_num ];
CoordType *normals = new CoordType[ vertices_num ];
for (i=0; i<vertices_num; i++)
{
points[i] = _mesh->vert[ vertices_idx[i] ].P();
normals[i] = _mesh->vert[ vertices_idx[i] ].N();
}
// move barycenter of points into (0, 0, 0)
CoordType center((ScalarType) 0.0, (ScalarType) 0.0, (ScalarType) 0.0);
for (i=0; i<vertices_num; ++i)
center += points[i];
center /= (ScalarType) vertices_num;
for (i=0; i<vertices_num; ++i)
points[i] -= center;
// normal angle criterion
double c, minC, maxC;
CoordType axis;
for (minC=1.0, i=0; i<vertices_num; ++i)
{
for (j=0; j<vertices_num; ++j)
{
c = normals[i]*normals[j];
if (c < minC)
{
minC = c;
axis = normals[i] ^ normals[j];
}
}
} //end for (minC=1.0, i=0; i<vertNumber; ++i)
if (minC > cos(_featureAngle))
return NULL; // invalid vertex
// ok, we have a feature: is it edge or corner, i.e. rank 2 or 3 ?
axis.Normalize();
for (minC=1.0, maxC=-1.0, i=0; i<vertices_num; ++i)
{
c = axis * normals[i];
if (c < minC) minC = c;
if (c > maxC) maxC = c;
}
c = vcg::math::Max< double >(fabs(minC), fabs(maxC));
c = sqrt(1.0-c*c);
rank = (c > cos(_featureAngle) ? 2 : 3);
// setup linear system (find intersection of tangent planes)
vcg::Matrix<double> A((unsigned int) vertices_num, 3);
double *b = new double[ vertices_num ];
for (i=0; i<vertices_num; ++i)
{
A[i][0] = normals[i][0];
A[i][1] = normals[i][1];
A[i][2] = normals[i][2];
b[i] = (points[i] * normals[i]);
}
// SVD of matrix A
vcg::Matrix<double> V(3, 3);
double *w = new double[vertices_num];
vcg::SingularValueDecomposition< vcg::Matrix<double> >(A, w, V, 100);
// rank == 2 -> suppress smallest singular value
if (rank == 2)
{
double smin = DBL_MAX; // the max value, as defined in <float.h>
unsigned int sminid = 0;
unsigned int srank = vcg::math::Min< unsigned int >(vertices_num, 3u);
for (i=0; i<srank; ++i)
{
if (w[i] < smin)
{
smin = w[i];
sminid = i;
}
}
w[sminid] = 0.0;
}
// SVD backsubstitution -> least squares, least norm solution x
double *x = new double[3];
vcg::SingularValueBacksubstitution< vcg::Matrix<double> >(A, w, V, x, b);
// transform x to world coords
CoordType point((ScalarType) x[0], (ScalarType) x[1], (ScalarType) x[2]);
point += center;
// insert the feature-point
VertexPointer mean_point = &*AllocatorType::AddVertices( *_mesh, 1);
mean_point->SetUserBit(_featureFlag);
mean_point->P() = point;
mean_point->N().Zero();
delete []x;
delete []points;
delete []normals;
return mean_point;
} // end of FindFeature
/*!
* Postprocessing step performed during the finalization tha flip some of the mesh edges.
* The flipping criterion is quite simple: each edge is flipped if it will connect two
* feature samples after the flip.
*/
void FlipEdges()
{
size_t i;
std::vector< LightEdge > edges;
FaceIterator f_iter = _mesh->face.begin();
FaceIterator f_end = _mesh->face.end();
for (i=0; f_iter!=f_end; f_iter++, i++)
{
if (f_iter->V(1) > f_iter->V(0))
{
LightEdge le;
le.face = i;
le.edge = 0;
edges.push_back( le );
}
if (f_iter->V(2) > f_iter->V(1))
{
LightEdge le;
le.face = i;
le.edge = 1;
edges.push_back( LightEdge(le));
}
if (f_iter->V(0) > f_iter->V(2))
{
LightEdge le;
le.face = i;
le.edge = 2;
edges.push_back( le );
}
}
vcg::tri::UpdateTopology< TRIMESH_TYPE >::VertexFace( *_mesh );
vcg::tri::UpdateTopology< TRIMESH_TYPE >::FaceFace( *_mesh );
std::vector< LightEdge >::iterator e_it = edges.begin();
std::vector< LightEdge >::iterator e_end = edges.end();
FacePointer g, f;
int w, z;
for( ; e_it!=e_end; e_it++)
{
f = &_mesh->face[e_it->face];
z = e_it->edge;
if (vcg::face::CheckFlipEdge< FaceType >(*f, z))
{
VertexPointer v0, v1, v2, v3;
v0 = f->V(z);
v1 = f->V1(z);
v2 = f->V2(z);
g = f->FFp(z);
w = f->FFi(z);
v3 = g->V2(w);
bool b0, b1, b2, b3;
b0 = !v0->IsUserBit(_featureFlag);
b1 = !v1->IsUserBit(_featureFlag);
b2 = v2->IsUserBit(_featureFlag);
b3 = v3->IsUserBit(_featureFlag);
if( b0 && b1 && b2 && b3)
vcg::face::FlipEdge< FaceType >(*f, z);
} // end if (vcg::face::CheckFlipEdge< _Face >(*f, z))
} // end for( ; e_it!=e_end; e_it++)
}; //end of FlipEdges
}; // end of class ExtendedMarchingCubes
// /*! @} */
// end of Doxygen documentation
} // end of namespace tri
}; // end of namespace vcg
#endif // __VCG_EXTENDED_MARCHING_CUBES

View File

@ -0,0 +1,705 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/***************************************************************************/
#ifndef __VCG_MARCHING_CUBES
#define __VCG_MARCHING_CUBES
#include <assert.h>
#include <vcg/space/point3.h>
#include <vcg/complex/trimesh/allocate.h>
#include "mc_lookup_table.h"
namespace vcg
{
namespace tri
{
// Doxygen documentation
/** \addtogroup trimesh */
/*@{*/
/*
* Cube description:
* 3 ________ 2 _____2__
* /| /| / | /|
* / | / | 11/ 3 10/ |
* 7 /_______ / | /__6_|__ / |1
* | | |6 | | | |
* | 0|__|_____|1 | |__|_0|__|
* | / | / 7 8/ 5 /
* | / | / | / | /9
* |/_______|/ |/___4___|/
* 4 5
*/
//! This class implements the Marching Cubes algorithm.
/*!
* The implementation is enough generic: this class works only on one volume cell for each
* call to <CODE>ProcessCell</CODE>. Using the field value at the cell corners, it adds to the
* mesh the triangles set approximating the surface that cross that cell. The ambiguities
* are resolved using an enhanced topologically controlled lookup table.
* @param TRIMESH_TYPE (Template parameter) the mesh type that will be constructed
* @param WALKER_TYPE (Template parameter) the class that implement the traversal ordering of the volume
**/
template<class TRIMESH_TYPE, class WALKER_TYPE>
class MarchingCubes
{
public:
enum Dimension {X, Y, Z};
#ifdef _WIN64
typedef unsigned __int64 size_t;
#else
typedef _W64 unsigned int size_t;
#endif
typedef typename vcg::tri::Allocator< TRIMESH_TYPE > AllocatorType;
typedef typename TRIMESH_TYPE::ScalarType ScalarType;
typedef typename TRIMESH_TYPE::VertexType VertexType;
typedef typename TRIMESH_TYPE::VertexPointer VertexPointer;
typedef typename TRIMESH_TYPE::VertexIterator VertexIterator;
typedef typename TRIMESH_TYPE::FaceType FaceType;
typedef typename TRIMESH_TYPE::FacePointer FacePointer;
typedef typename TRIMESH_TYPE::FaceIterator FaceIterator;
typedef typename TRIMESH_TYPE::CoordType CoordType;
typedef typename TRIMESH_TYPE::CoordType* CoordPointer;
/*!
* Constructor
* \param mesh the mesh that will be constructed
* \param walker the class implementing the traversal policy
*/
MarchingCubes(TRIMESH_TYPE &mesh, WALKER_TYPE &walker)
{
_mesh = &mesh;
_walker = &walker;
};
/*!
* Execute the initialiazation.
* This method must be executed before the first call to <CODE>ApplyMC</CODE>
*/
void Initialize()
{
_mesh->Clear();
}; // end of Initialize()
/*!
*
* This method must be executed after the last call to <CODE>ApplyMC</CODE>
*/
void Finalize()
{
_mesh = NULL;
_walker = NULL;
}; // end of Finalize()
/*!
* Apply the <I>marching cubes</I> algorithm to the volume cell identified by the two points <CODE>min</CODE> and <CODE>max</CODE>.
* All the three coordinates of the first point must be smaller than the respectives three coordinatas of the second point.
* \param min the first point
* \param max the second point
*/
void ProcessCell(const vcg::Point3i &min, const vcg::Point3i &max)
{
_case = _subconfig = _config = -1;
assert(min[0]<max[0] && min[1]<max[1] && min[2]<max[2]);
_corners[0].X()=min.X(); _corners[0].Y()=min.Y(); _corners[0].Z()=min.Z();
_corners[1].X()=max.X(); _corners[1].Y()=min.Y(); _corners[1].Z()=min.Z();
_corners[2].X()=max.X(); _corners[2].Y()=max.Y(); _corners[2].Z()=min.Z();
_corners[3].X()=min.X(); _corners[3].Y()=max.Y(); _corners[3].Z()=min.Z();
_corners[4].X()=min.X(); _corners[4].Y()=min.Y(); _corners[4].Z()=max.Z();
_corners[5].X()=max.X(); _corners[5].Y()=min.Y(); _corners[5].Z()=max.Z();
_corners[6].X()=max.X(); _corners[6].Y()=max.Y(); _corners[6].Z()=max.Z();
_corners[7].X()=min.X(); _corners[7].Y()=max.Y(); _corners[7].Z()=max.Z();
for (int i=0; i<8; i++)
_field[i] = _walker->V( _corners[i].X(), _corners[i].Y(), _corners[i].Z() );
unsigned char cubetype = 0;
for (int i=0; i<8; i++)
if (_field[i]>0) cubetype += 1<<i;
_case = cases[cubetype][0];
_config = cases[cubetype][1];
_subconfig = 0;
VertexPointer v12 = NULL;
switch( _case )
{
case 0 : { break ; }
case 1 : { AddTriangles( tiling1[_config], 1 ); break; }
case 2 : { AddTriangles( tiling2[_config], 2 ); break; }
case 3 :
{
if( TestFace( test3[_config]) ) AddTriangles( tiling3_2[_config], 4 ) ; // 3.2
else AddTriangles( tiling3_1[_config], 2 ) ; // 3.1
break ;
}
case 4 :
{
if( TestInterior( test4[_config]) ) AddTriangles( tiling4_1[_config], 2 ) ; // 4.1.1
else AddTriangles( tiling4_2[_config], 6 ) ; // 4.1.2
break ;
}
case 5 : { AddTriangles( tiling5[_config], 3 ); break; }
case 6 :
{
if( TestFace( test6[_config][0]) )
AddTriangles( tiling6_2[_config], 5 ) ; // 6.2
else
{
if( TestInterior( test6[_config][1]) ) AddTriangles( tiling6_1_1[_config], 3 ) ; // 6.1.1
else AddTriangles( tiling6_1_2[_config], 7 ) ; // 6.1.2
}
break ;
}
case 7 :
{
if( TestFace( test7[_config][0] ) ) _subconfig += 1 ;
if( TestFace( test7[_config][1] ) ) _subconfig += 2 ;
if( TestFace( test7[_config][2] ) ) _subconfig += 4 ;
switch( _subconfig )
{
case 0 : { AddTriangles( tiling7_1[_config], 3 ) ; break; }
case 1 : { AddTriangles( tiling7_2[_config][0], 5 ) ; break; }
case 2 : { AddTriangles( tiling7_2[_config][1], 5 ) ; break; }
case 3 : { ComputeCVertex(v12); AddTriangles( tiling7_3[_config][0], 9, v12 ) ; break ; }
case 4 : { AddTriangles( tiling7_2[_config][2], 5 ) ; break ;}
case 5 : { ComputeCVertex(v12); AddTriangles( tiling7_3[_config][1], 9, v12 ) ; break ; }
case 6 : { ComputeCVertex(v12); AddTriangles( tiling7_3[_config][2], 9, v12 ) ; break ; }
case 7 :
{
if( TestInterior( test7[_config][3]) ) AddTriangles( tiling7_4_2[_config], 9 ) ;
else AddTriangles( tiling7_4_1[_config], 5 ) ;
break ;
}
};
break ;
} // end of case 7
case 8 : { AddTriangles( tiling8[_config], 2 ) ; break ;}
case 9 : { AddTriangles( tiling9[_config], 4 ) ; break ;}
case 10 :
{
if( TestFace( test10[_config][0]) )
{
if( TestFace( test10[_config][1]) )
AddTriangles( tiling10_1_1_[_config], 4 ) ; // 10.1.1
else
{
ComputeCVertex(v12);
AddTriangles( tiling10_2[_config], 8, v12 ) ; // 10.2
}
}
else
{
if( TestFace( test10[_config][1]) )
{
ComputeCVertex(v12) ;
AddTriangles( tiling10_2_[_config], 8, v12 ) ; // 10.2
}
else
{
if( TestInterior( test10[_config][2]) ) AddTriangles( tiling10_1_1[_config], 4 ) ; // 10.1.1
else AddTriangles( tiling10_1_2[_config], 8 ) ; // 10.1.2
}
}
break ;
} // end of case 10
case 11 : { AddTriangles( tiling11[_config], 4 ) ; break ; }
case 12 :
{
if( TestFace( test12[_config][0]) )
{
if( TestFace( test12[_config][1]) ) AddTriangles( tiling12_1_1_[_config], 4 ) ; // 12.1.1
else
{
ComputeCVertex(v12) ;
AddTriangles( tiling12_2[_config], 8, v12 ) ; // 12.2
}
}
else
{
if( TestFace( test12[_config][1]) )
{
ComputeCVertex(v12) ;
AddTriangles( tiling12_2_[_config], 8, v12 ) ; // 12.2
}
else
{
if( TestInterior( test12[_config][2]) ) AddTriangles( tiling12_1_1[_config], 4 ) ; // 12.1.1
else AddTriangles( tiling12_1_2[_config], 8 ) ; // 12.1.2
}
}
break ;
} // end of case 12
case 13 :
{
if( TestFace( test13[_config][0] ) ) _subconfig += 1 ;
if( TestFace( test13[_config][1] ) ) _subconfig += 2 ;
if( TestFace( test13[_config][2] ) ) _subconfig += 4 ;
if( TestFace( test13[_config][3] ) ) _subconfig += 8 ;
if( TestFace( test13[_config][4] ) ) _subconfig += 16 ;
if( TestFace( test13[_config][5] ) ) _subconfig += 32 ;
switch( subconfig13[_subconfig] )
{
case 0 : { /* 13.1 */ AddTriangles( tiling13_1[_config] , 4 ) ; break ; }
case 1 : { /* 13.2 */ AddTriangles( tiling13_2[_config][0], 6 ) ; break ; }
case 2 : { /* 13.2 */ AddTriangles( tiling13_2[_config][1], 6 ) ; break ; }
case 3 : { /* 13.2 */ AddTriangles( tiling13_2[_config][2], 6 ) ; break ; }
case 4 : { /* 13.2 */ AddTriangles( tiling13_2[_config][3], 6 ) ; break ; }
case 5 : { /* 13.2 */ AddTriangles( tiling13_2[_config][4], 6 ) ; break ; }
case 6 : { /* 13.2 */ AddTriangles( tiling13_2[_config][5], 6 ) ; break ; }
case 7 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3[_config][ 0], 10, v12 ) ; break ; }
case 8 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3[_config][ 1], 10, v12 ) ; break ; }
case 9 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3[_config][ 2], 10, v12 ) ; break ; }
case 10 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3[_config][ 3], 10, v12 ) ; break ; }
case 11 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3[_config][ 4], 10, v12 ) ; break ; }
case 12 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3[_config][ 5], 10, v12 ) ; break ; }
case 13 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3[_config][ 6], 10, v12 ) ; break ; }
case 14 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3[_config][ 7], 10, v12 ) ; break ; }
case 15 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3[_config][ 8], 10, v12 ) ; break ; }
case 16 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3[_config][ 9], 10, v12 ) ; break ; }
case 17 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3[_config][10], 10, v12 ) ; break ; }
case 18 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3[_config][11], 10, v12 ) ; break ; }
case 19 : { /* 13.4 */ ComputeCVertex(v12); AddTriangles( tiling13_4[_config][ 0], 12, v12 ) ; break ; }
case 20 : { /* 13.4 */ ComputeCVertex(v12); AddTriangles( tiling13_4[_config][ 1], 12, v12 ) ; break ; }
case 21 : { /* 13.4 */ ComputeCVertex(v12); AddTriangles( tiling13_4[_config][ 2], 12, v12 ) ; break ; }
case 22 : { /* 13.4 */ ComputeCVertex(v12); AddTriangles( tiling13_4[_config][ 3], 12, v12 ) ; break ; }
case 23 :
{ /* 13.5 */
_subconfig = 0 ;
if( TestInterior( test13[_config][6] ) ) AddTriangles( tiling13_5_1[_config][0], 6 ) ;
else AddTriangles( tiling13_5_2[_config][0], 10 ) ;
break ;
}
case 24 :
{ /* 13.5 */
_subconfig = 1 ;
if( TestInterior( test13[_config][6] ) ) AddTriangles( tiling13_5_1[_config][1], 6 ) ;
else AddTriangles( tiling13_5_2[_config][1], 10 ) ;
break ;
}
case 25 :
{/* 13.5 */
_subconfig = 2 ;
if( TestInterior( test13[_config][6] ) ) AddTriangles( tiling13_5_1[_config][2], 6 ) ;
else AddTriangles( tiling13_5_2[_config][2], 10 ) ;
break ;
}
case 26 :
{/* 13.5 */
_subconfig = 3 ;
if( TestInterior( test13[_config][6] ) ) AddTriangles( tiling13_5_1[_config][3], 6 ) ;
else AddTriangles( tiling13_5_2[_config][3], 10 ) ;
break ;
}
case 27 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3_[_config][ 0], 10, v12 ) ; break ; }
case 28 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3_[_config][ 1], 10, v12 ) ; break ; }
case 29 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3_[_config][ 2], 10, v12 ) ; break ; }
case 30 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3_[_config][ 3], 10, v12 ) ; break ; }
case 31 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3_[_config][ 4], 10, v12 ) ; break ; }
case 32 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3_[_config][ 5], 10, v12 ) ; break ; }
case 33 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3_[_config][ 6], 10, v12 ) ; break ; }
case 34 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3_[_config][ 7], 10, v12 ) ; break ; }
case 35 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3_[_config][ 8], 10, v12 ) ; break ; }
case 36 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3_[_config][ 9], 10, v12 ) ; break ; }
case 37 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3_[_config][10], 10, v12 ) ; break ; }
case 38 : { /* 13.3 */ ComputeCVertex(v12); AddTriangles( tiling13_3_[_config][11], 10, v12 ) ; break ; }
case 39 : { /* 13.2 */ AddTriangles( tiling13_2_[_config][0], 6 ) ; break ; }
case 40 : { /* 13.2 */ AddTriangles( tiling13_2_[_config][1], 6 ) ; break ; }
case 41 : { /* 13.2 */ AddTriangles( tiling13_2_[_config][2], 6 ) ; break ; }
case 42 : { /* 13.2 */ AddTriangles( tiling13_2_[_config][3], 6 ) ; break ; }
case 43 : { /* 13.2 */ AddTriangles( tiling13_2_[_config][4], 6 ) ; break ; }
case 44 : { /* 13.2 */ AddTriangles( tiling13_2_[_config][5], 6 ) ; break ; }
case 45 : { /* 13.1 */ AddTriangles( tiling13_1_[_config] , 4 ) ; break ; }
default : { /*Impossible case 13*/ assert(false); }
}
break ;
} // end of case 13
case 14 : { AddTriangles( tiling14[_config], 4 ) ; }
break ;
} //end of switch (_case)
}; // end of ApplyMC
private:
/*!
*/
WALKER_TYPE *_walker;
/*!
*/
TRIMESH_TYPE *_mesh;
/*!
* The field value at the cell corners
*/
ScalarType _field[8];
/*!
* Array of the 8 corners of the volume cell being processed
*/
vcg::Point3i _corners[8];
/*!
* Case of the volume cell being processed
*/
unsigned char _case;
/*!
* Configuration of the volume cell being processed
*/
unsigned char _config;
/*!
* Subconfiguration of the volume cell being processed
*/
unsigned char _subconfig;
/*!
* Tests if the components of the tesselation of the cube should be connected
* by the interior of an ambiguous face
*/
inline bool TestFace(signed char face)
{
ScalarType A,B,C,D ;
switch( face )
{
case -1 : case 1 : A = _field[0] ; B = _field[4] ; C = _field[5] ; D = _field[1] ; break ;
case -2 : case 2 : A = _field[1] ; B = _field[5] ; C = _field[6] ; D = _field[2] ; break ;
case -3 : case 3 : A = _field[2] ; B = _field[6] ; C = _field[7] ; D = _field[3] ; break ;
case -4 : case 4 : A = _field[3] ; B = _field[7] ; C = _field[4] ; D = _field[0] ; break ;
case -5 : case 5 : A = _field[0] ; B = _field[3] ; C = _field[2] ; D = _field[1] ; break ;
case -6 : case 6 : A = _field[4] ; B = _field[7] ; C = _field[6] ; D = _field[5] ; break ;
default : assert(false); // Invalid face code
};
return face * A * ( A*C - B*D ) >= 0 ; // face and A invert signs
}; // end of TestFace
/*!
* Tests if the components of the tesselation of the cube should be connected
* through the interior of the cube
*/
inline bool TestInterior(signed char s)
{
ScalarType t, At=0, Bt=0, Ct=0, Dt=0, a, b ;
char test = 0 ;
char edge = -1 ; // reference edge of the triangulation
switch( _case )
{
case 4 :
case 10 :
{
a = (_field[4]-_field[0])*(_field[6]-_field[2]) - (_field[7]-_field[3])*(_field[5]-_field[1]);
b = _field[2]*(_field[4]-_field[0])+_field[0]*(_field[6]-_field[2])-_field[1]*(_field[7]-_field[3])-_field[3]*(_field[5]-_field[1]);
t = - b / (2*a) ;
if( t<0 || t>1 )
return s>0 ;
At = _field[0] + ( _field[4] - _field[0] ) * t ;
Bt = _field[3] + ( _field[7] - _field[3] ) * t ;
Ct = _field[2] + ( _field[6] - _field[2] ) * t ;
Dt = _field[1] + ( _field[5] - _field[1] ) * t ;
break ;
}
case 6 :
case 7 :
case 12 :
case 13 :
switch( _case )
{
case 6 : edge = test6 [_config][2] ; break ;
case 7 : edge = test7 [_config][4] ; break ;
case 12 : edge = test12[_config][3] ; break ;
case 13 : edge = tiling13_5_1[_config][_subconfig][0] ; break ;
}
switch( edge )
{
case 0 :
t = _field[0] / ( _field[0] - _field[1] ) ;
At = 0 ;
Bt = _field[3] + ( _field[2] - _field[3] ) * t ;
Ct = _field[7] + ( _field[6] - _field[7] ) * t ;
Dt = _field[4] + ( _field[5] - _field[4] ) * t ;
break ;
case 1 :
t = _field[1] / ( _field[1] - _field[2] ) ;
At = 0 ;
Bt = _field[0] + ( _field[3] - _field[0] ) * t ;
Ct = _field[4] + ( _field[7] - _field[4] ) * t ;
Dt = _field[5] + ( _field[6] - _field[5] ) * t ;
break ;
case 2 :
t = _field[2] / ( _field[2] - _field[3] ) ;
At = 0 ;
Bt = _field[1] + ( _field[0] - _field[1] ) * t ;
Ct = _field[5] + ( _field[4] - _field[5] ) * t ;
Dt = _field[6] + ( _field[7] - _field[6] ) * t ;
break ;
case 3 :
t = _field[3] / ( _field[3] - _field[0] ) ;
At = 0 ;
Bt = _field[2] + ( _field[1] - _field[2] ) * t ;
Ct = _field[6] + ( _field[5] - _field[6] ) * t ;
Dt = _field[7] + ( _field[4] - _field[7] ) * t ;
break ;
case 4 :
t = _field[4] / ( _field[4] - _field[5] ) ;
At = 0 ;
Bt = _field[7] + ( _field[6] - _field[7] ) * t ;
Ct = _field[3] + ( _field[2] - _field[3] ) * t ;
Dt = _field[0] + ( _field[1] - _field[0] ) * t ;
break ;
case 5 :
t = _field[5] / ( _field[5] - _field[6] ) ;
At = 0 ;
Bt = _field[4] + ( _field[7] - _field[4] ) * t ;
Ct = _field[0] + ( _field[3] - _field[0] ) * t ;
Dt = _field[1] + ( _field[2] - _field[1] ) * t ;
break ;
case 6 :
t = _field[6] / ( _field[6] - _field[7] ) ;
At = 0 ;
Bt = _field[5] + ( _field[4] - _field[5] ) * t ;
Ct = _field[1] + ( _field[0] - _field[1] ) * t ;
Dt = _field[2] + ( _field[3] - _field[2] ) * t ;
break ;
case 7 :
t = _field[7] / ( _field[7] - _field[4] ) ;
At = 0 ;
Bt = _field[6] + ( _field[5] - _field[6] ) * t ;
Ct = _field[2] + ( _field[1] - _field[2] ) * t ;
Dt = _field[3] + ( _field[0] - _field[3] ) * t ;
break ;
case 8 :
t = _field[0] / ( _field[0] - _field[4] ) ;
At = 0 ;
Bt = _field[3] + ( _field[7] - _field[3] ) * t ;
Ct = _field[2] + ( _field[6] - _field[2] ) * t ;
Dt = _field[1] + ( _field[5] - _field[1] ) * t ;
break ;
case 9 :
t = _field[1] / ( _field[1] - _field[5] ) ;
At = 0 ;
Bt = _field[0] + ( _field[4] - _field[0] ) * t ;
Ct = _field[3] + ( _field[7] - _field[3] ) * t ;
Dt = _field[2] + ( _field[6] - _field[2] ) * t ;
break ;
case 10 :
t = _field[2] / ( _field[2] - _field[6] ) ;
At = 0 ;
Bt = _field[1] + ( _field[5] - _field[1] ) * t ;
Ct = _field[0] + ( _field[4] - _field[0] ) * t ;
Dt = _field[3] + ( _field[7] - _field[3] ) * t ;
break ;
case 11 :
t = _field[3] / ( _field[3] - _field[7] ) ;
At = 0 ;
Bt = _field[2] + ( _field[6] - _field[2] ) * t ;
Ct = _field[1] + ( _field[5] - _field[1] ) * t ;
Dt = _field[0] + ( _field[4] - _field[0] ) * t ;
break ;
default: { assert(false); /* Invalid edge */ break ; }
}
break ;
default : assert(false); /* Invalid ambiguous case */ break;
}
if( At >= 0 ) test ++ ;
if( Bt >= 0 ) test += 2 ;
if( Ct >= 0 ) test += 4 ;
if( Dt >= 0 ) test += 8 ;
switch( test )
{
case 0 : return s>0 ;
case 1 : return s>0 ;
case 2 : return s>0 ;
case 3 : return s>0 ;
case 4 : return s>0 ;
case 5 : if( At * Ct < Bt * Dt ) return s>0 ; break ;
case 6 : return s>0 ;
case 7 : return s<0 ;
case 8 : return s>0 ;
case 9 : return s>0 ;
case 10 : if( At * Ct >= Bt * Dt ) return s>0 ; break ;
case 11 : return s<0 ;
case 12 : return s>0 ;
case 13 : return s<0 ;
case 14 : return s<0 ;
case 15 : return s<0 ;
}
return s<0 ;
}; //end of TestInterior
/*!
* Adds a vertex inside the current cube
* \param v The pointer to the new vertex along the edge
*/
inline void ComputeCVertex(VertexPointer &v12)
{
v12 = &*AllocatorType::AddVertices(*_mesh, 1);
v12->P() = CoordType(0.0, 0.0, 0.0);
v12->N() = CoordType(0.0, 0.0, 0.0);
unsigned int count = 0;
VertexPointer v = NULL;
if (_walker->Exist(_corners[0], _corners[1], v) )
{
count++;
v12->P() += v->P();
v12->N() += v->N();
}
if (_walker->Exist(_corners[2], _corners[1], v) )
{
count++;
v12->P() += v->P();
v12->N() += v->N();
}
if (_walker->Exist(_corners[3], _corners[2], v) )
{
count++;
v12->P() += v->P();
v12->N() += v->N();
}
if (_walker->Exist(_corners[3], _corners[0], v) )
{
count++;
v12->P() += v->P();
v12->N() += v->N();
}
if (_walker->Exist(_corners[4], _corners[5], v) )
{
count++;
v12->P() += v->P();
v12->N() += v->N();
}
if (_walker->Exist(_corners[6], _corners[5], v) )
{
count++;
v12->P() += v->P();
v12->N() += v->N();
}
if (_walker->Exist(_corners[7], _corners[6], v) )
{
count++;
v12->P() += v->P();
v12->N() += v->N();
}
if (_walker->Exist(_corners[7], _corners[4], v) )
{
count++;
v12->P() += v->P();
v12->N() += v->N();
}
if (_walker->Exist(_corners[0], _corners[4], v) )
{
count++;
v12->P() += v->P();
v12->N() += v->N();
}
if (_walker->Exist(_corners[1], _corners[5], v) )
{
count++;
v12->P() += v->P();
v12->N() += v->N();
}
if (_walker->Exist(_corners[2], _corners[6], v) )
{
count++;
v12->P() += v->P();
v12->N() += v->N();
}
if (_walker->Exist(_corners[3], _corners[7], v) )
{
count++;
v12->P() += v->P();
v12->N() += v->N();
}
v12->P() /= (float) count;
v12->N().Normalize();
} // end of AddCVertex
/*!
* Adds new triangles to the mesh
* \param vertices_list The list of vertex indices
* \param n The number of triangles that will be added to the mesh
* \param v12 The pointer to the vertex inside the current cell
*/
inline void AddTriangles(const char *vertices_list, char n, VertexPointer v12=NULL)
{
VertexPointer vp = NULL;
size_t face_idx = _mesh->face.size();
size_t v12_idx = -1;
size_t vertices_idx[3];
if (v12 != NULL) v12_idx = v12 - &_mesh->vert[0];
AllocatorType::AddFaces(*_mesh, (int) n);
for (int trig=0; trig<3*n; face_idx++ )
{
vp = NULL;
memset(vertices_idx, -1, 3*sizeof(size_t));
for (int vert=0; vert<3; vert++, trig++) //ok
{
switch ( vertices_list[trig] )
{
case 0: { _walker->GetXIntercept(_corners[0], _corners[1], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
case 1: { _walker->GetYIntercept(_corners[1], _corners[2], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
case 2: { _walker->GetXIntercept(_corners[3], _corners[2], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
case 3: { _walker->GetYIntercept(_corners[0], _corners[3], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
case 4: { _walker->GetXIntercept(_corners[4], _corners[5], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
case 5: { _walker->GetYIntercept(_corners[5], _corners[6], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
case 6: { _walker->GetXIntercept(_corners[7], _corners[6], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
case 7: { _walker->GetYIntercept(_corners[4], _corners[7], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
case 8: { _walker->GetZIntercept(_corners[0], _corners[4], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
case 9: { _walker->GetZIntercept(_corners[1], _corners[5], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
case 10: { _walker->GetZIntercept(_corners[2], _corners[6], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
case 11: { _walker->GetZIntercept(_corners[3], _corners[7], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
case 12: { assert(v12 != NULL); vertices_idx[vert] = v12_idx; break; }
default: { assert(false); /* Invalid edge identifier */ }
} // end of switch
assert(vertices_idx[vert]>=0 && vertices_idx[vert]<_mesh->vert.size());
} // end for (int vert=0 ...)
_mesh->face[face_idx].V(0) = &_mesh->vert[vertices_idx[0]];
_mesh->face[face_idx].V(1) = &_mesh->vert[vertices_idx[1]];
_mesh->face[face_idx].V(2) = &_mesh->vert[vertices_idx[2]];
} // end for (int trig=0...)
}; // end of AddTriangles
}; // end of class MarchingCubes
/*! @} */
//end of Doxygen documentation
}; // end of namespace tri
}; // end of namespace vcg
#endif //__VCG_MARCHING_CUBES

File diff suppressed because it is too large Load Diff