COMP: cvMeshSurfaceSimplify: moved isosurface algo out to ThirdParty

This commit is contained in:
mattijs
2012-04-04 16:48:46 +01:00
parent cb4a34424b
commit e8b03e3a25
50 changed files with 14 additions and 38672 deletions

View File

@ -0,0 +1,10 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
set -x
if [ -d "${FASTDUALOCTREE_SRC_PATH}" ]
then
wmake
fi
# ----------------------------------------------------------------- end-of-file

View File

@ -4,6 +4,7 @@ MarchingCubes/MarchingCubes.cpp
MarchingCubes/ply.c
*/
/*
MarchingCubes = fastdualoctree_sgp
$(MarchingCubes)/data_access.cpp
@ -14,6 +15,7 @@ $(MarchingCubes)/mc_draw.cpp
$(MarchingCubes)/morton.cpp
$(MarchingCubes)/opt_octree.cpp
$(MarchingCubes)/hash_octree.cpp
*/
cvMeshSurfaceSimplify.C

View File

@ -6,7 +6,7 @@ EXE_INC = \
-DUNIX \
-Wno-old-style-cast \
/* -IMarchingCubes */ \
-I$(MarchingCubes) \
-I$(FASTDUALOCTREE_SRC_PATH) \
-I../conformalVoronoiMesh/lnInclude \
-I$(LIB_SRC)/edgeMesh/lnInclude \
-I$(LIB_SRC)/triSurface/lnInclude \
@ -14,6 +14,7 @@ EXE_INC = \
EXE_LIBS = \
$(CGAL_LIBS) \
-L$(FASTDUALOCTREE_SRC_PATH) -lperf_main \
-lGL \
-lconformalVoronoiMesh \
-ldecompositionMethods -L$(FOAM_LIBBIN)/dummy -lscotchDecomp \

View File

@ -1,96 +0,0 @@
PROJECT(fastDualOctree)
cmake_minimum_required(VERSION 2.8)
#---------------------------------------------------
#----- Dependencies
#---------------------------------------------------
FIND_PACKAGE(OpenGL REQUIRED)
if ( OPENGL_FOUND )
message( "-- OpenGL found. include=${OPENGL_INCLUDE_DIR}" )
include_directories( ${OPENGL_INCLUDE_DIR} )
endif ( OPENGL_FOUND )
FIND_PACKAGE(ZLIB REQUIRED)
if ( ZLIB_FOUND )
message( "-- zlib found. include=${ZLIB_INCLUDE_DIR}" )
include_directories( ${ZLIB_INCLUDE_DIR} )
endif ( ZLIB_FOUND )
FIND_PACKAGE(PNG REQUIRED)
if ( PNG_FOUND )
message( "-- PNG found. include=${PNG_INCLUDE_DIR}" )
include_directories( ${PNG_INCLUDE_DIR} )
endif ( PNG_FOUND )
##-- GLUI dependency
#FIND_PATH(GLUI_INCLUDE_DIR GL/glui.h ~/pub/system/glui-2.36/src/include)
#FIND_LIBRARY(GLUI_LIBRARIES
# NAMES GLUI glui
# GLUT glut
# PATHS /usr/local/lib/
# /usr/lib/
# /opt/graphics/OpenGL/lib
# /usr/openwin/lib
# /usr/shlib
# /usr/X11R6/lib
# ~/pub/system/glui-2.36/src/lib
# )
#if ( GLUI_INCLUDE_DIR )
# message( "-- GL/glui.h found. include=${GLUI_INCLUDE_DIR}" )
# include_directories( ${GLUI_INCLUDE_DIR} )
#else ( GLUI_INCLUDE_DIR )
# message( "-- GL/glui.h not found." )
#endif ( GLUI_INCLUDE_DIR )
#if ( GLUI_LIBRARIES )
# message( "-- libglui found. include=${GLUI_LIBRARIES}" )
#else( GLUI_LIBRARIES )
# message( "-- libglui not found." )
#endif ( GLUI_LIBRARIES )
#---------------------------------------------------
# -- Environement variables
#---------------------------------------------------
if (UNIX)
add_definitions(-DUNIX)
endif (UNIX)
if (WIN32)
add_definitions(-DWIN32)
endif (WIN32)
if (APPLE)
add_definitions(-DAPPLE)
endif (APPLE)
#---------------------------------------------------
# -- SRCs
#---------------------------------------------------
SET(Perf_SRC ${Perf_SRC}
data_access.cpp
hash_octree.cpp
mc_draw.cpp
opt_octree.cpp
fparser.cpp
leaf_octree.cpp
mem_octree.cpp
fpoptimizer.cpp
MarchingCubes.cpp
morton.cpp
ptr_octree.cpp
)
#SET(VIZ_SRC ${VIZ_SRC}
# viz_glui_cmdline.cpp
# viz_glui_controls.cpp
# viz_glui_draws.cpp
# viz_glui_export.cpp
# viz_glui_mouse.cpp
#)
add_executable(perf_main perf_main ${Perf_SRC})
target_link_libraries(perf_main ${OPENGL_LIBRARIES} ${ZLIB_LIBRARIES})
#add_executable(viz_glui_main viz_glui_main ${Perf_SRC} ${VIZ_SRC} )
#target_link_libraries(viz_glui_main ${OPENGL_LIBRARIES} ${ZLIB_LIBRARIES} ${PNG_LIBRARIES} ${GLUI_LIBRARIES})

View File

@ -1,850 +0,0 @@
/**
* @file MarchingCubes.cpp
* @author Thomas Lewiner <thomas.lewiner@polytechnique.org>
* @author Math Dept, PUC-Rio
* @version 0.2
* @date 12/08/2002
*
* @brief MarchingCubes Algorithm
*/
//________________________________________________
#if !defined(WIN32) || defined(__CYGWIN__)
#pragma implementation
#endif // WIN32
#include <math.h>
#include <time.h>
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>
#include <float.h>
#include "MarchingCubes.h"
#include "LookUpTable.h"
// step size of the arrays of vertices and triangles
#define ALLOC_SIZE 65536
//_____________________________________________________________________________
// print cube for debug
void MarchingCubes::print_cube() { printf( "\t%f %f %f %f %f %f %f %f\n", _cube[0], _cube[1], _cube[2], _cube[3], _cube[4], _cube[5], _cube[6], _cube[7]) ; }
//_____________________________________________________________________________
//_____________________________________________________________________________
// Constructor
MarchingCubes::MarchingCubes() :
//-----------------------------------------------------------------------------
_originalMC(true),
_nverts (0),
_ntrigs (0),
_Nverts (0),
_Ntrigs (0),
_vertices (( Point *)NULL),
_triangles ((Triangle*)NULL)
{}
//_____________________________________________________________________________
//_____________________________________________________________________________
// Destructor
MarchingCubes::~MarchingCubes()
//-----------------------------------------------------------------------------
{
clean_all() ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// main algorithm
bool MarchingCubes::tesselate_cube( real iso )
//-----------------------------------------------------------------------------
{
for( int p = 0 ; p < 8 ; ++p )
{
real &v = _cube[p] ;
v -= iso ;
if( fabs( v ) < R_EPSILON ) v = R_EPSILON ;
// printf( "%d - %+0.2f\t", (int)_indexes[p], v ) ;
}
// printf( "\n" ) ;
if( !compute_intersection_points() ) return false ;
_lut_entry = 0 ;
for( int p = 0 ; p < 8 ; ++p )
{
if( _cube[p] > 0 ) _lut_entry += 1 << p ;
}
return process_cube( ) ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// init all structures (must set sizes before call)
void MarchingCubes::init_all ()
//-----------------------------------------------------------------------------
{
_nverts = _ntrigs = 0 ;
_Nverts = _Ntrigs = ALLOC_SIZE ;
_vertices = new Point [_Nverts] ;
_triangles = new Triangle[_Ntrigs] ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// clean temporary structures
void MarchingCubes::clean_temps()
//-----------------------------------------------------------------------------
{
_stored_vertices.clear() ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// clean all structures
void MarchingCubes::clean_all()
//-----------------------------------------------------------------------------
{
clean_temps() ;
delete [] _vertices ;
delete [] _triangles ;
_vertices = (Point *)NULL ;
_triangles = (Triangle *)NULL ;
_nverts = _ntrigs = 0 ;
_Nverts = _Ntrigs = 0 ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
//_____________________________________________________________________________
//_____________________________________________________________________________
// Compute the intersection points
bool MarchingCubes::compute_intersection_points()
//-----------------------------------------------------------------------------
{
bool res = false ;
res |= add_vertex( 0,1 ) ;
res |= add_vertex( 1,2 ) ;
res |= add_vertex( 2,3 ) ;
res |= add_vertex( 3,0 ) ;
res |= add_vertex( 4,5 ) ;
res |= add_vertex( 5,6 ) ;
res |= add_vertex( 6,7 ) ;
res |= add_vertex( 7,4 ) ;
res |= add_vertex( 0,4 ) ;
res |= add_vertex( 1,5 ) ;
res |= add_vertex( 2,6 ) ;
res |= add_vertex( 3,7 ) ;
return res ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// Test a face
// if face>0 return true if the face contains a part of the surface
bool MarchingCubes::test_face( schar face )
//-----------------------------------------------------------------------------
{
real A,B,C,D ;
switch( face )
{
case -1 : case 1 : A = _cube[0] ; B = _cube[4] ; C = _cube[5] ; D = _cube[1] ; break ;
case -2 : case 2 : A = _cube[1] ; B = _cube[5] ; C = _cube[6] ; D = _cube[2] ; break ;
case -3 : case 3 : A = _cube[2] ; B = _cube[6] ; C = _cube[7] ; D = _cube[3] ; break ;
case -4 : case 4 : A = _cube[3] ; B = _cube[7] ; C = _cube[4] ; D = _cube[0] ; break ;
case -5 : case 5 : A = _cube[0] ; B = _cube[3] ; C = _cube[2] ; D = _cube[1] ; break ;
case -6 : case 6 : A = _cube[4] ; B = _cube[7] ; C = _cube[6] ; D = _cube[5] ; break ;
default : printf( "Invalid face code %d\n", face ) ; print_cube() ; A = B = C = D = 0 ;
};
if( fabs( A*C - B*D ) < R_EPSILON )
return face >= 0 ;
return face * A * ( A*C - B*D ) >= 0 ; // face and A invert signs
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// Test the interior of a cube
// if s == 7, return true if the interior is empty
// if s ==-7, return false if the interior is empty
bool MarchingCubes::test_interior( schar s )
//-----------------------------------------------------------------------------
{
real 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 :
case 13 :
a = ( _cube[4] - _cube[0] ) * ( _cube[6] - _cube[2] ) - ( _cube[7] - _cube[3] ) * ( _cube[5] - _cube[1] ) ;
b = _cube[2] * ( _cube[4] - _cube[0] ) + _cube[0] * ( _cube[6] - _cube[2] )
- _cube[1] * ( _cube[7] - _cube[3] ) - _cube[3] * ( _cube[5] - _cube[1] ) ;
t = - b / (2*a) ;
if( t<0 || t>1 ) return s>0 ;
At = _cube[0] + ( _cube[4] - _cube[0] ) * t ;
Bt = _cube[3] + ( _cube[7] - _cube[3] ) * t ;
Ct = _cube[2] + ( _cube[6] - _cube[2] ) * t ;
Dt = _cube[1] + ( _cube[5] - _cube[1] ) * t ;
break ;
case 6 :
case 7 :
case 12 :
switch( _case )
{
case 6 : edge = test6 [_config][2] ; break ;
case 7 : edge = test7 [_config][4] ; break ;
case 12 : edge = test12[_config][3] ; break ;
}
switch( edge )
{
case 0 :
t = _cube[0] / ( _cube[0] - _cube[1] ) ;
At = 0 ;
Bt = _cube[3] + ( _cube[2] - _cube[3] ) * t ;
Ct = _cube[7] + ( _cube[6] - _cube[7] ) * t ;
Dt = _cube[4] + ( _cube[5] - _cube[4] ) * t ;
break ;
case 1 :
t = _cube[1] / ( _cube[1] - _cube[2] ) ;
At = 0 ;
Bt = _cube[0] + ( _cube[3] - _cube[0] ) * t ;
Ct = _cube[4] + ( _cube[7] - _cube[4] ) * t ;
Dt = _cube[5] + ( _cube[6] - _cube[5] ) * t ;
break ;
case 2 :
t = _cube[2] / ( _cube[2] - _cube[3] ) ;
At = 0 ;
Bt = _cube[1] + ( _cube[0] - _cube[1] ) * t ;
Ct = _cube[5] + ( _cube[4] - _cube[5] ) * t ;
Dt = _cube[6] + ( _cube[7] - _cube[6] ) * t ;
break ;
case 3 :
t = _cube[3] / ( _cube[3] - _cube[0] ) ;
At = 0 ;
Bt = _cube[2] + ( _cube[1] - _cube[2] ) * t ;
Ct = _cube[6] + ( _cube[5] - _cube[6] ) * t ;
Dt = _cube[7] + ( _cube[4] - _cube[7] ) * t ;
break ;
case 4 :
t = _cube[4] / ( _cube[4] - _cube[5] ) ;
At = 0 ;
Bt = _cube[7] + ( _cube[6] - _cube[7] ) * t ;
Ct = _cube[3] + ( _cube[2] - _cube[3] ) * t ;
Dt = _cube[0] + ( _cube[1] - _cube[0] ) * t ;
break ;
case 5 :
t = _cube[5] / ( _cube[5] - _cube[6] ) ;
At = 0 ;
Bt = _cube[4] + ( _cube[7] - _cube[4] ) * t ;
Ct = _cube[0] + ( _cube[3] - _cube[0] ) * t ;
Dt = _cube[1] + ( _cube[2] - _cube[1] ) * t ;
break ;
case 6 :
t = _cube[6] / ( _cube[6] - _cube[7] ) ;
At = 0 ;
Bt = _cube[5] + ( _cube[4] - _cube[5] ) * t ;
Ct = _cube[1] + ( _cube[0] - _cube[1] ) * t ;
Dt = _cube[2] + ( _cube[3] - _cube[2] ) * t ;
break ;
case 7 :
t = _cube[7] / ( _cube[7] - _cube[4] ) ;
At = 0 ;
Bt = _cube[6] + ( _cube[5] - _cube[6] ) * t ;
Ct = _cube[2] + ( _cube[1] - _cube[2] ) * t ;
Dt = _cube[3] + ( _cube[0] - _cube[3] ) * t ;
break ;
case 8 :
t = _cube[0] / ( _cube[0] - _cube[4] ) ;
At = 0 ;
Bt = _cube[3] + ( _cube[7] - _cube[3] ) * t ;
Ct = _cube[2] + ( _cube[6] - _cube[2] ) * t ;
Dt = _cube[1] + ( _cube[5] - _cube[1] ) * t ;
break ;
case 9 :
t = _cube[1] / ( _cube[1] - _cube[5] ) ;
At = 0 ;
Bt = _cube[0] + ( _cube[4] - _cube[0] ) * t ;
Ct = _cube[3] + ( _cube[7] - _cube[3] ) * t ;
Dt = _cube[2] + ( _cube[6] - _cube[2] ) * t ;
break ;
case 10 :
t = _cube[2] / ( _cube[2] - _cube[6] ) ;
At = 0 ;
Bt = _cube[1] + ( _cube[5] - _cube[1] ) * t ;
Ct = _cube[0] + ( _cube[4] - _cube[0] ) * t ;
Dt = _cube[3] + ( _cube[7] - _cube[3] ) * t ;
break ;
case 11 :
t = _cube[3] / ( _cube[3] - _cube[7] ) ;
At = 0 ;
Bt = _cube[2] + ( _cube[6] - _cube[2] ) * t ;
Ct = _cube[1] + ( _cube[5] - _cube[1] ) * t ;
Dt = _cube[0] + ( _cube[4] - _cube[0] ) * t ;
break ;
default : printf( "Invalid edge %d\n", edge ) ; print_cube() ; break ;
}
break ;
default : printf( "Invalid ambiguous case %d\n", _case ) ; print_cube() ; 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 < R_EPSILON ) 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 >= R_EPSILON ) 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 ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// Process a unit cube
bool MarchingCubes::process_cube( )
//-----------------------------------------------------------------------------
{
if( _originalMC )
{
char nt = 0 ;
while( casesClassic[_lut_entry][3*nt] != -1 ) nt++ ;
add_triangle( casesClassic[_lut_entry], nt ) ;
return true ;
}
int v12 = -1 ;
_case = cases[_lut_entry][0] ;
_config = cases[_lut_entry][1] ;
_subconfig = 0 ;
switch( _case )
{
case 0 :
break ;
case 1 :
add_triangle( tiling1[_config], 1 ) ;
break ;
case 2 :
add_triangle( tiling2[_config], 2 ) ;
break ;
case 3 :
if( test_face( test3[_config]) )
add_triangle( tiling3_2[_config], 4 ) ; // 3.2
else
add_triangle( tiling3_1[_config], 2 ) ; // 3.1
break ;
case 4 :
if( test_interior( test4[_config]) )
add_triangle( tiling4_1[_config], 2 ) ; // 4.1.1
else
add_triangle( tiling4_2[_config], 6 ) ; // 4.1.2
break ;
case 5 :
add_triangle( tiling5[_config], 3 ) ;
break ;
case 6 :
if( test_face( test6[_config][0]) )
add_triangle( tiling6_2[_config], 5 ) ; // 6.2
else
{
if( test_interior( test6[_config][1]) )
add_triangle( tiling6_1_1[_config], 3 ) ; // 6.1.1
else
{
v12 = add_c_vertex() ;
add_triangle( tiling6_1_2[_config], 9 , v12) ; // 6.1.2
}
}
break ;
case 7 :
if( test_face( test7[_config][0] ) ) _subconfig += 1 ;
if( test_face( test7[_config][1] ) ) _subconfig += 2 ;
if( test_face( test7[_config][2] ) ) _subconfig += 4 ;
switch( _subconfig )
{
case 0 :
add_triangle( tiling7_1[_config], 3 ) ; break ;
case 1 :
add_triangle( tiling7_2[_config][0], 5 ) ; break ;
case 2 :
add_triangle( tiling7_2[_config][1], 5 ) ; break ;
case 3 :
v12 = add_c_vertex() ;
add_triangle( tiling7_3[_config][0], 9, v12 ) ; break ;
case 4 :
add_triangle( tiling7_2[_config][2], 5 ) ; break ;
case 5 :
v12 = add_c_vertex() ;
add_triangle( tiling7_3[_config][1], 9, v12 ) ; break ;
case 6 :
v12 = add_c_vertex() ;
add_triangle( tiling7_3[_config][2], 9, v12 ) ; break ;
case 7 :
if( test_interior( test7[_config][3]) )
add_triangle( tiling7_4_2[_config], 9 ) ;
else
add_triangle( tiling7_4_1[_config], 5 ) ;
break ;
};
break ;
case 8 :
add_triangle( tiling8[_config], 2 ) ;
break ;
case 9 :
add_triangle( tiling9[_config], 4 ) ;
break ;
case 10 :
if( test_face( test10[_config][0]) )
{
if( test_face( test10[_config][1]) )
add_triangle( tiling10_1_1_[_config], 4 ) ; // 10.1.1
else
{
v12 = add_c_vertex() ;
add_triangle( tiling10_2[_config], 8, v12 ) ; // 10.2
}
}
else
{
if( test_face( test10[_config][1]) )
{
v12 = add_c_vertex() ;
add_triangle( tiling10_2_[_config], 8, v12 ) ; // 10.2
}
else
{
if( test_interior( test10[_config][2]) )
add_triangle( tiling10_1_1[_config], 4 ) ; // 10.1.1
else
add_triangle( tiling10_1_2[_config], 8 ) ; // 10.1.2
}
}
break ;
case 11 :
add_triangle( tiling11[_config], 4 ) ;
break ;
case 12 :
if( test_face( test12[_config][0]) )
{
if( test_face( test12[_config][1]) )
add_triangle( tiling12_1_1_[_config], 4 ) ; // 12.1.1
else
{
v12 = add_c_vertex() ;
add_triangle( tiling12_2[_config], 8, v12 ) ; // 12.2
}
}
else
{
if( test_face( test12[_config][1]) )
{
v12 = add_c_vertex() ;
add_triangle( tiling12_2_[_config], 8, v12 ) ; // 12.2
}
else
{
if( test_interior( test12[_config][2]) )
add_triangle( tiling12_1_1[_config], 4 ) ; // 12.1.1
else
add_triangle( tiling12_1_2[_config], 8 ) ; // 12.1.2
}
}
break ;
case 13 :
if( test_face( test13[_config][0] ) ) _subconfig += 1 ;
if( test_face( test13[_config][1] ) ) _subconfig += 2 ;
if( test_face( test13[_config][2] ) ) _subconfig += 4 ;
if( test_face( test13[_config][3] ) ) _subconfig += 8 ;
if( test_face( test13[_config][4] ) ) _subconfig += 16 ;
if( test_face( test13[_config][5] ) ) _subconfig += 32 ;
switch( subconfig13[_subconfig] )
{
case 0 :/* 13.1 */
add_triangle( tiling13_1[_config], 4 ) ; break ;
case 1 :/* 13.2 */
add_triangle( tiling13_2[_config][0], 6 ) ; break ;
case 2 :/* 13.2 */
add_triangle( tiling13_2[_config][1], 6 ) ; break ;
case 3 :/* 13.2 */
add_triangle( tiling13_2[_config][2], 6 ) ; break ;
case 4 :/* 13.2 */
add_triangle( tiling13_2[_config][3], 6 ) ; break ;
case 5 :/* 13.2 */
add_triangle( tiling13_2[_config][4], 6 ) ; break ;
case 6 :/* 13.2 */
add_triangle( tiling13_2[_config][5], 6 ) ; break ;
case 7 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3[_config][0], 10, v12 ) ; break ;
case 8 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3[_config][1], 10, v12 ) ; break ;
case 9 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3[_config][2], 10, v12 ) ; break ;
case 10 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3[_config][3], 10, v12 ) ; break ;
case 11 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3[_config][4], 10, v12 ) ; break ;
case 12 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3[_config][5], 10, v12 ) ; break ;
case 13 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3[_config][6], 10, v12 ) ; break ;
case 14 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3[_config][7], 10, v12 ) ; break ;
case 15 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3[_config][8], 10, v12 ) ; break ;
case 16 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3[_config][9], 10, v12 ) ; break ;
case 17 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3[_config][10], 10, v12 ) ; break ;
case 18 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3[_config][11], 10, v12 ) ; break ;
case 19 :/* 13.4 */
v12 = add_c_vertex() ;
add_triangle( tiling13_4[_config][0], 12, v12 ) ; break ;
case 20 :/* 13.4 */
v12 = add_c_vertex() ;
add_triangle( tiling13_4[_config][1], 12, v12 ) ; break ;
case 21 :/* 13.4 */
v12 = add_c_vertex() ;
add_triangle( tiling13_4[_config][2], 12, v12 ) ; break ;
case 22 :/* 13.4 */
v12 = add_c_vertex() ;
add_triangle( tiling13_4[_config][3], 12, v12 ) ; break ;
case 23 :/* 13.5 */
_subconfig = 0 ;
if( test_interior( test13[_config][6] ) )
add_triangle( tiling13_5_1[_config][0], 6 ) ;
else
add_triangle( tiling13_5_2[_config][0], 10 ) ;
break ;
case 24 :/* 13.5 */
_subconfig = 1 ;
if( test_interior( test13[_config][6] ) )
add_triangle( tiling13_5_1[_config][1], 6 ) ;
else
add_triangle( tiling13_5_2[_config][1], 10 ) ;
break ;
case 25 :/* 13.5 */
_subconfig = 2 ;
if( test_interior( test13[_config][6] ) )
add_triangle( tiling13_5_1[_config][2], 6 ) ;
else
add_triangle( tiling13_5_2[_config][2], 10 ) ;
break ;
case 26 :/* 13.5 */
_subconfig = 3 ;
if( test_interior( test13[_config][6] ) )
add_triangle( tiling13_5_1[_config][3], 6 ) ;
else
add_triangle( tiling13_5_2[_config][3], 10 ) ;
break ;
case 27 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3_[_config][0], 10, v12 ) ; break ;
case 28 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3_[_config][1], 10, v12 ) ; break ;
case 29 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3_[_config][2], 10, v12 ) ; break ;
case 30 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3_[_config][3], 10, v12 ) ; break ;
case 31 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3_[_config][4], 10, v12 ) ; break ;
case 32 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3_[_config][5], 10, v12 ) ; break ;
case 33 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3_[_config][6], 10, v12 ) ; break ;
case 34 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3_[_config][7], 10, v12 ) ; break ;
case 35 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3_[_config][8], 10, v12 ) ; break ;
case 36 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3_[_config][9], 10, v12 ) ; break ;
case 37 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3_[_config][10], 10, v12 ) ; break ;
case 38 :/* 13.3 */
v12 = add_c_vertex() ;
add_triangle( tiling13_3_[_config][11], 10, v12 ) ; break ;
case 39 :/* 13.2 */
add_triangle( tiling13_2_[_config][0], 6 ) ; break ;
case 40 :/* 13.2 */
add_triangle( tiling13_2_[_config][1], 6 ) ; break ;
case 41 :/* 13.2 */
add_triangle( tiling13_2_[_config][2], 6 ) ; break ;
case 42 :/* 13.2 */
add_triangle( tiling13_2_[_config][3], 6 ) ; break ;
case 43 :/* 13.2 */
add_triangle( tiling13_2_[_config][4], 6 ) ; break ;
case 44 :/* 13.2 */
add_triangle( tiling13_2_[_config][5], 6 ) ; break ;
case 45 :/* 13.1 */
add_triangle( tiling13_1_[_config], 4 ) ; break ;
default :
printf("Marching Cubes: Impossible case 13?\n" ) ; print_cube() ;
}
break ;
case 14 :
add_triangle( tiling14[_config], 4 ) ;
break ;
};
return true ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// Adding triangles
void MarchingCubes::add_triangle( const char* trig_, char n, int v12 )
//-----------------------------------------------------------------------------
{
int tv[3] ;
for( int t = 0 ; t < 3*n ; t++ )
{
switch( trig_[t] )
{
case 0 : tv[ t % 3 ] = get_vertex(0,1) ; break ;
case 1 : tv[ t % 3 ] = get_vertex(1,2) ; break ;
case 2 : tv[ t % 3 ] = get_vertex(2,3) ; break ;
case 3 : tv[ t % 3 ] = get_vertex(3,0) ; break ;
case 4 : tv[ t % 3 ] = get_vertex(4,5) ; break ;
case 5 : tv[ t % 3 ] = get_vertex(5,6) ; break ;
case 6 : tv[ t % 3 ] = get_vertex(6,7) ; break ;
case 7 : tv[ t % 3 ] = get_vertex(7,4) ; break ;
case 8 : tv[ t % 3 ] = get_vertex(0,4) ; break ;
case 9 : tv[ t % 3 ] = get_vertex(1,5) ; break ;
case 10 : tv[ t % 3 ] = get_vertex(2,6) ; break ;
case 11 : tv[ t % 3 ] = get_vertex(3,7) ; break ;
case 12 : tv[ t % 3 ] = v12 ; break ;
default : break ;
}
if( tv[t%3] == -1 )
{
printf("Marching Cubes: invalid triangle %d\n", _ntrigs+1) ;
print_cube() ;
}
if( t%3 == 2 )
{
if( _ntrigs >= _Ntrigs )
{
Triangle *temp = _triangles ;
_triangles = new Triangle[ 2*_Ntrigs ] ;
memcpy( _triangles, temp, _Ntrigs*sizeof(Triangle) ) ;
delete[] temp ;
printf("%d allocated triangles\n", _Ntrigs) ;
_Ntrigs *= 2 ;
}
Triangle *T = _triangles + _ntrigs++ ;
T->v1 = tv[0] ;
T->v2 = tv[1] ;
T->v3 = tv[2] ;
}
}
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// Adding vertices
void MarchingCubes::test_vertex_addition()
{
if( _nverts >= _Nverts )
{
Point *temp = _vertices ;
_vertices = new Point [ _Nverts*2 ] ;
memcpy( _vertices, temp, _Nverts*sizeof(Point ) ) ;
delete[] temp ;
printf("%d allocated vertices\n", _Nverts) ;
_Nverts *= 2 ;
}
}
bool MarchingCubes::add_vertex( char i, char j )
//-----------------------------------------------------------------------------
{
real ci = _cube[i] ;
real cj = _cube[j] ;
if( ci * cj >= 0 ) return false ;
Key ki = _indexes[i] ;
Key kj = _indexes[j] ;
std::pair<Key,Key> ij_key = std::make_pair( ki,kj ) ;
if( _stored_vertices.find( ij_key ) != _stored_vertices.end() ) return true ;
test_vertex_addition() ;
Point p ;
_dat_access->interpolate( ci,cj, _space[i],_space[j], p ) ;
_stored_vertices[ ij_key ] = _nverts ;
_stored_vertices[ std::make_pair( kj,ki ) ] = _nverts ;
_vertices[_nverts++] = p ;
return true ;
}
//-----------------------------------------------------------------------------
int MarchingCubes::add_c_vertex( )
//-----------------------------------------------------------------------------
{
test_vertex_addition() ;
Point &vert_ = _vertices[_nverts++] ;
real u = 0 ;
int vid ;
vert_.x() = vert_.y() = vert_.z() = 0 ;
// Computes the average of the intersection points of the cube
vid = get_vertex( 0,1 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; }
vid = get_vertex( 1,2 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; }
vid = get_vertex( 2,3 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; }
vid = get_vertex( 3,0 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; }
vid = get_vertex( 4,5 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; }
vid = get_vertex( 5,6 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; }
vid = get_vertex( 6,7 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; }
vid = get_vertex( 7,4 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; }
vid = get_vertex( 0,4 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; }
vid = get_vertex( 1,5 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; }
vid = get_vertex( 2,6 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; }
vid = get_vertex( 3,7 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; }
vert_ /= u ;
return _nverts-1 ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
//_____________________________________________________________________________
//_____________________________________________________________________________
// OFF ascii exportation
void MarchingCubes::writeOFF(const char *fn )
//-----------------------------------------------------------------------------
{
FILE *fp = fopen( fn, "w" ) ;
int i ;
printf("Marching Cubes::exportOFF(%s)...", fn) ;
fprintf( fp, "OFF\n%d %d 0\n", _nverts, _ntrigs ) ;
for ( i = 0; i < _nverts; i++ )
fprintf( fp, " %f %f %f\n", _vertices[i].x(), _vertices[i].y(), _vertices[i].z() ) ;
printf(" %d vertices written\n", _nverts ) ;
for ( i = 0; i < _ntrigs; i++ )
fprintf( fp, "3 %d %d %d\n", _triangles[i].v1, _triangles[i].v2, _triangles[i].v3 ) ;
fclose( fp ) ;
printf(" %d triangles written\n", _ntrigs ) ;
}
//_____________________________________________________________________________

View File

@ -1,182 +0,0 @@
/**
* @file MarchingCubes.h
* @author Thomas Lewiner <thomas.lewiner@polytechnique.org>
* @author Math Dept, PUC-Rio
* @version 0.2
* @date 12/08/2002
*
* @brief MarchingCubes Algorithm
*/
//________________________________________________
#pragma once
#if !defined(WIN32) || defined(__CYGWIN__)
#pragma interface
#endif // WIN32
#include <map>
#include "morton.h"
#include "point.h"
#include "data_access.h"
//-----------------------------------------------------------------------------
// Triangle structure
/** \struct Triangle "MarchingCubes.h" MarchingCubes
* Indices of the oriented triange vertices
* \brief triangle structure
* \param v1 First vertex index
* \param v2 Second vertex index
* \param v3 Third vertex index
*/
typedef struct
{
int v1,v2,v3 ; /**< Triangle vertices */
} Triangle ;
//_____________________________________________________________________________
//_____________________________________________________________________________
/** Marching Cubes algorithm wrapper */
/** \class MarchingCubes
* \brief Marching Cubes algorithm.
*/
class MarchingCubes
//-----------------------------------------------------------------------------
{
// Constructors
public :
/**
* Main and default constructor
* \brief constructor
*/
MarchingCubes () ;
/** Destructor */
~MarchingCubes() ;
//-----------------------------------------------------------------------------
// Accessors
public :
/** accesses the number of vertices of the generated mesh */
inline const int nverts() const { return _nverts ; }
/** accesses the number of triangles of the generated mesh */
inline const int ntrigs() const { return _ntrigs ; }
/** accesses a specific vertex of the generated mesh */
inline Point * vert( const int i ) const { if( i < 0 || i >= _nverts ) return ( Point *)NULL ; return _vertices + i ; }
/** accesses a specific triangle of the generated mesh */
inline Triangle * trig( const int i ) const { if( i < 0 || i >= _ntrigs ) return (Triangle*)NULL ; return _triangles + i ; }
/** accesses the vertex buffer of the generated mesh */
inline Point *vertices () { return _vertices ; }
/** accesses the triangle buffer of the generated mesh */
inline Triangle *triangles() { return _triangles ; }
/**
* selects wether the algorithm will use the enhanced topologically controlled lookup table or the original MarchingCubes
* \param originalMC true for the original Marching Cubes
*/
inline void set_method ( const bool originalMC = false ) { _originalMC = originalMC ; }
// Data initialization
/** inits all structures (must set sizes before call) : the temporary structures and the mesh buffers */
void init_all () ;
/** clears temporary structures : the grid and the main */
void clean_temps() ;
/** clears all structures : the temporary structures and the mesh buffers */
void clean_all () ;
//-----------------------------------------------------------------------------
// Exportation
public :
/**
* OFF exportation of the generated mesh
* \param fn name of the IV file to create
*/
void writeOFF( const char *fn ) ;
//-----------------------------------------------------------------------------
// Algorithm
public :
/** retrieves the isovalues at the cube vertices */
real *cube () { return _cube ; }
/** retrieves the geometry of the cube */
Point *space () { return _space; }
/** retrieves the indexes of the cube */
Key *indexes() { return _indexes; }
/** retrieves the data accessor */
data_access *&dat_access() { return _dat_access ; }
/**
* Main algorithm
* \param iso isovalue
*/
bool tesselate_cube( real iso ) ;
protected :
/** tesselates one cube */
bool process_cube () ;
/** tests if the components of the tesselation of the cube should be connected by the interior of an ambiguous face */
bool test_face ( schar face ) ;
/** tests if the components of the tesselation of the cube should be connected through the interior of the cube */
bool test_interior( schar s ) ;
//-----------------------------------------------------------------------------
// Operations
protected :
/** computes almost all the vertices of the mesh by interpolation along the cubes edges */
bool compute_intersection_points() ;
/**
* routine to add a triangle to the mesh
* \param trig the code for the triangle as a sequence of edges index
* \param n the number of triangles to produce
* \param v12 the index of the interior vertex to use, if necessary
*/
void add_triangle ( const char* trig, char n, int v12 = -1 ) ;
/** tests and eventually doubles the vertex buffer capacity for a new vertex insertion */
void test_vertex_addition() ;
/** adds a vertex on edge cube[i] cube[j] */
bool add_vertex( char i, char j ) ;
/** gets the vertex of edge cube[i] cube[j] (no check) */
int get_vertex( char i, char j ) { std::map< std::pair< Key,Key >, int >::const_iterator it = _stored_vertices.find( std::make_pair( _indexes[i],_indexes[j] ) ) ; if( it == _stored_vertices.end() ) return -1 ; else return it->second ; }
/** adds a vertex inside the current cube */
int add_c_vertex() ;
/** prints cube for debug */
void print_cube() ;
public:
/** draw the surface using openGL */
void draw_surf() { Triangle *ptr = _triangles ; for( int i = 0 ; i < _ntrigs ; ++i, ++ptr ) { _vertices[ptr->v1].draw() ; _vertices[ptr->v2].draw() ; _vertices[ptr->v3].draw() ; } }
//-----------------------------------------------------------------------------
// Elements
protected :
bool _originalMC ; /**< selects wether the algorithm will use the enhanced topologically controlled lookup table or the original MarchingCubes */
int _nverts ; /**< number of allocated vertices in the vertex buffer */
int _ntrigs ; /**< number of allocated triangles in the triangle buffer */
int _Nverts ; /**< size of the vertex buffer */
int _Ntrigs ; /**< size of the triangle buffer */
Point *_vertices ; /**< vertex buffer */
Triangle *_triangles ; /**< triangle buffer */
std::map< std::pair< Key,Key >, int > _stored_vertices ;
real _cube[8] ; /**< values of the implicit function on the active cube */
Point _space[8] ; /**< coordinates of the active cube */
Key _indexes[8] ; /**< indiexs of the active cube */
uchar _lut_entry ; /**< cube sign representation in [0..255] */
uchar _case ; /**< case of the active cube in [0..15] */
uchar _config ; /**< configuration of the active cube */
uchar _subconfig ; /**< subconfiguration of the active cube */
data_access *_dat_access ; /**< data accessor */
};
//_____________________________________________________________________________

View File

@ -1,123 +0,0 @@
Statistical optimization of octree searches
Fast generation of pointerless octree duals
---------------------------------------------------
Rener Castro, Thomas Lewiner, H<>lio Lopes, Geovan Tavares, Alex Bordignon
Thomas Lewiner, Vin<69>cius Mello, Adelailson Peixoto, Sin<69>sio Pesco, H<>lio Lopes
http://www.matmidia.mat.puc-rio.br/tomlew/publication_page.php?pubkey=octree_cgf
http://www.matmidia.mat.puc-rio.br/tomlew/publication_page.php?pubkey=fastdualoctree_sgp
1. Disclaimer
2. Available code compared to the papers
3. Octrees implementations
4. Morton codes
5. Data
6. Hash table
7. Requirements
Disclaimer
--------------
This code is implements fast searches and the dual generation of static
or dynamic pointer-based or pointerless octrees. It is provided "as is"
and can be used freely. We just ask the users who would use this code to
mention in their academic paper, patent or software documentation the
original articles:
@article{octree_cgf,
author = {Rener Castro and Thomas Lewiner and H<>lio Lopes and Geovan Tavares and Alex Bordignon},
title = {Statistical optimization of octree searches},
year = {2008},
month = {march},
journal = {Computer Graphics Forum},
volume = {27},
number = {6},
pages = {1557--1566},
publisher = {Eurographics},
doi = {10.1111/j.1467-8659.2007.01104.x},
url = {\url{http://www.matmidia.mat.puc-rio.br/tomlew/pdfs/octree_cgf.pdf}}
}
@article{fastdualoctree_sgp,
author = {Thomas Lewiner and Vin<69>cius Mello and Adelailson Peixoto and Sin<69>sio Pesco and H<>lio Lopes},
title = {Fast Generation of Pointerless Octree Duals},
year = {2010},
month = {july},
journal = {Symposium on Geometry Processing 2010},
booktitle = {Computer Graphics Forum},
volume = {29},
number = {5},
pages = {1661--1669},
publisher = {Wiley},
address = {Lyon, France},
url = {\url{http://www.matmidia.mat.puc-rio.br/tomlew/pdfs/fastdualoctree_sgp.pdf}}
}
If you have any comment, correction, question, please feel free to
contact me at : lewiner@gmail.com .
Thank to David Coeurjolly for the code porting to UNIX.
Available code compared to the paper
----------------------------------------------
The code contains simple implementations used to generate the result of
our papers. We stripped down the time measurements (which are platform
specific) and the robust dual marching cubes
(http://www.matmidia.mat.puc-rio.br/tomlew/publication_page.php?pubkey=adaptive_implicit_sibgrapi)
code.
Octrees implementations
------------------------------
The code contains implementations of a pointer-based octree
("ptr_octree.*" files), pointerless octrees with recursive dual
generation ("hash_octree.*"), pointerless octrees with optimized dual
generation for the static strategy representing all the nodes
("opt_octree.*") or only the leaves ("leaf_octree.*"), and the dynamic
strategy ("mem_octree.*"). The octree is chosen at compilation time
through the OCTREE_SWITCH macro.
Morton codes
-----------------
The Morton code operations in dilated integers are all grouped in the
"morton.*" files.
Data
------
The data (implicit function or isogrid) is accessed through the
data_access class. The isogrid must be in "iso" format, i.e. a binary
file with 32-bits integers nx, ny and nz for the size of the grid,
32-bits floats xmin, xmax, ymin<69> for the geometry of the cube, followed
by nx.ny.nz 32-bits floats for the data.
Hash table
-------------
Finally, we made a very simple naive and simple implementations for the
hashtable, in open ("hash_ptr.h") or close ("has_noptr.h") modes. The
parameters of the hash function are chosen at compilation time through
macros defined in the "hash.h" file.
Requirements
------------
The graphical interfaces require the openGL libraries with the GLU, glut
and glui extension, available at http://glui.sourceforge.net/ .
We use Juha Nieminen, Joel Yliluoma's function parser for the implicit
function, and our Marching Cube's implementation
(http://www.matmidia.mat.puc-rio.br/tomlew/publication_page.php?pubkey=marching_cubes_jgt).
Thank you for your interest, and have fun!
http://www.matmidia.mat.puc-rio.br/tomlew/

View File

@ -1,256 +0,0 @@
/**
* \file cube.h
* \author Thomas Lewiner <tomlew@puc-rio.br>
* \author Matmidia Lab, Math Dept, PUC-Rio
* \date 10/01/2010
*
* \brief Simple cube class
*
* Simple cube class
*/
//_____________________________________________________________________________
#pragma once
#include "point.h"
typedef uchar Level ;
extern Level L_INV ;
//_____________________________________________________________________________
/// Simple cube class
class Cube : public Point
{
// Elements
protected :
Level _lv ; ///< cube level (from 0 on): cube corners have coordinates c(xyz) (+/-) (1/2^(lv+1))
//-----------------------------------------------------------------------------
// Constructors
public:
/// Default constructor
Cube( const real &cx_ = R_INV, const real &cy_ = R_INV, const real &cz_ = R_INV, Level lv_ = L_INV )
: Point(cx_,cy_,cz_), _lv(lv_) {}
/// Default constructor
Cube( const Point& c_, Level lv_ = L_INV )
: Point(c_), _lv(lv_) {}
/// Default constructor
Cube( const Cube& c_ )
: Point((const Point&)c_), _lv(c_._lv) {}
/// Destructor
~Cube() {}
/// Assignment operator
Cube &operator= ( const Cube &c )
{ Point::operator=(c) ; _lv = c._lv ; return *this; }
//-----------------------------------------------------------------------------
// Accessors
public:
/// const accessor for point center: x coordinate
real cx() const { return Point::x() ; }
/// accessor for point center: x coordinate
real &cx() { return Point::x() ; }
/// const accessor for point center: y coordinate
real cy() const { return Point::y() ; }
/// accessor for point center: y coordinate
real &cy() { return Point::y() ; }
/// const accessor for point center: z coordinate
real cz() const { return Point::z() ; }
/// accessor for point center: z coordinate
real &cz() { return Point::z() ; }
/// const accessor for a coordinate
real coord( Axis a ) const { return Point::operator[](a) ; }
/// accessor for a coordinate
real &coord( Axis a ) { return Point::operator[](a) ; }
/// const accessor for the cube half size
real sz() const { return (real)1.0 / (2<<_lv) ; }
/// const accessor for cube level
Level lv() const { return _lv ; }
/// accessor for cube level
Level &lv() { return _lv ; }
/// const accessor for cube center: min x coordinate
real xmin() const { return cx() - sz() ; }
/// const accessor for cube center: max x coordinate
real xmax() const { return cx() + sz() ; }
/// const accessor for cube center: min y coordinate
real ymin() const { return cy() - sz() ; }
/// const accessor for cube center: max y coordinate
real ymax() const { return cy() + sz() ; }
/// const accessor for cube center: min z coordinate
real zmin() const { return cz() - sz() ; }
/// const accessor for cube center: max z coordinate
real zmax() const { return cz() + sz() ; }
/// const accessor for cube center: min coordinate
real coordmin( Axis a ) const { return coord(a) - this->sz() ; }
/// const accessor for cube center: max coordinate
real coordmax( Axis a ) const { return coord(a) + this->sz() ; }
//------------------------------------------------
// Test
public :
/// conained
bool contains( const real &x_, const real &y_, const real &z_ ) const
{
real sz_ = sz() ;
return
( fabs(x_-cx()) <= sz_ ) &&
( fabs(y_-cy()) <= sz_ ) &&
( fabs(z_-cz()) <= sz_ ) ;
}
/// conained
bool contains( const Point &p ) const { return contains( p.x(), p.y(), p.z() ) ; }
/// epsilon-conained
bool contains( const real &x_, const real &y_, const real &z_, const real &epsilon ) const
{
real sz_ = sz() + epsilon ;
return
( fabs(x_-cx()) <= sz_ ) &&
( fabs(y_-cy()) <= sz_ ) &&
( fabs(z_-cz()) <= sz_ ) ;
}
/// epsilon-conained
bool contains( const Point &p, const real &epsilon ) const { return contains( p.x(), p.y(), p.z(), epsilon ) ; }
//-----------------------------------------------------------------------------
// Drawing
public:
/// Draws the cube center with opengl
void draw_center () const { ::glVertex3f( (float)x(), (float)y(), (float)z() ) ; }
/// Draws the cube corners with opengl
void draw_corners( real fact = 0.9 ) const
{
const float ix = (const float) x() ;
const float iy = (const float) y() ;
const float iz = (const float) z() ;
const float is = (const float) (fact*sz()) ;
::glVertex3f( ix-is, iy-is, iz-is ) ;
::glVertex3f( ix+is, iy-is, iz-is ) ;
::glVertex3f( ix-is, iy+is, iz-is ) ;
::glVertex3f( ix+is, iy+is, iz-is ) ;
::glVertex3f( ix-is, iy-is, iz+is ) ;
::glVertex3f( ix+is, iy-is, iz+is ) ;
::glVertex3f( ix-is, iy+is, iz+is ) ;
::glVertex3f( ix+is, iy+is, iz+is ) ;
}
/// Draws the cube wire with opengl
void draw_wire ( real fact = 0.9 ) const
{
const float ix = (const float) x() ;
const float iy = (const float) y() ;
const float iz = (const float) z() ;
const float is = (const float) (fact*sz()) ;
::glVertex3f( ix-is, iy-is, iz-is ) ;
::glVertex3f( ix-is, iy+is, iz-is ) ;
::glVertex3f( ix-is, iy-is, iz-is ) ;
::glVertex3f( ix+is, iy-is, iz-is ) ;
::glVertex3f( ix+is, iy-is, iz-is ) ;
::glVertex3f( ix+is, iy+is, iz-is ) ;
::glVertex3f( ix-is, iy+is, iz-is ) ;
::glVertex3f( ix+is, iy+is, iz-is ) ;
::glVertex3f( ix-is, iy-is, iz+is ) ;
::glVertex3f( ix-is, iy+is, iz+is ) ;
::glVertex3f( ix-is, iy-is, iz+is ) ;
::glVertex3f( ix+is, iy-is, iz+is ) ;
::glVertex3f( ix+is, iy-is, iz+is ) ;
::glVertex3f( ix+is, iy+is, iz+is ) ;
::glVertex3f( ix-is, iy+is, iz+is ) ;
::glVertex3f( ix+is, iy+is, iz+is ) ;
::glVertex3f( ix-is, iy-is, iz-is ) ;
::glVertex3f( ix-is, iy-is, iz+is ) ;
::glVertex3f( ix+is, iy-is, iz-is ) ;
::glVertex3f( ix+is, iy-is, iz+is ) ;
::glVertex3f( ix-is, iy+is, iz-is ) ;
::glVertex3f( ix-is, iy+is, iz+is ) ;
::glVertex3f( ix+is, iy+is, iz-is ) ;
::glVertex3f( ix+is, iy+is, iz+is ) ;
}
/// Draws the cube wire with opengl
void draw_fill ( real fact = 0.9 ) const
{
const float ix = (const float) x() ;
const float iy = (const float) y() ;
const float iz = (const float) z() ;
const float is = (const float) (fact*sz()) ;
::glNormal3f(0,0,-1);
::glVertex3f( ix-is, iy-is, iz-is ) ;
::glVertex3f( ix-is, iy+is, iz-is ) ;
::glVertex3f( ix+is, iy+is, iz-is ) ;
::glVertex3f( ix+is, iy-is, iz-is ) ;
::glNormal3f(0,0,1);
::glVertex3f( ix-is, iy-is, iz+is ) ;
::glVertex3f( ix-is, iy+is, iz+is ) ;
::glVertex3f( ix+is, iy+is, iz+is ) ;
::glVertex3f( ix+is, iy-is, iz+is ) ;
::glNormal3f(-1,0,0);
::glVertex3f( ix-is, iy-is, iz-is ) ;
::glVertex3f( ix-is, iy+is, iz-is ) ;
::glVertex3f( ix-is, iy+is, iz+is ) ;
::glVertex3f( ix-is, iy-is, iz+is ) ;
::glNormal3f(1,0,0);
::glVertex3f( ix+is, iy-is, iz-is ) ;
::glVertex3f( ix+is, iy+is, iz-is ) ;
::glVertex3f( ix+is, iy+is, iz+is ) ;
::glVertex3f( ix+is, iy-is, iz+is ) ;
::glNormal3f(0,-1,0);
::glVertex3f( ix-is, iy-is, iz-is ) ;
::glVertex3f( ix-is, iy-is, iz+is ) ;
::glVertex3f( ix+is, iy-is, iz+is ) ;
::glVertex3f( ix+is, iy-is, iz-is ) ;
::glNormal3f(0,1,0);
::glVertex3f( ix-is, iy+is, iz-is ) ;
::glVertex3f( ix-is, iy+is, iz+is ) ;
::glVertex3f( ix+is, iy+is, iz+is ) ;
::glVertex3f( ix+is, iy+is, iz-is ) ;
}
};
//_____________________________________________________________________________
// Invalid cube
extern Cube C_INV ;

View File

@ -1,266 +0,0 @@
/**
* @file data_access.cpp
* \author Thomas Lewiner <thomas.lewiner@polytechnique.org>
* \author Math Dept, PUC-Rio
* \author Matmidia Labs
* \date 14/02/2006
*
* @brief data accesss
*/
//________________________________________________
#ifndef WIN32
#pragma implementation
#endif // WIN32
#include "data_access.h"
//_____________________________________________________________________________
//_____________________________________________________________________________
// data_func
//_____________________________________________________________________________
// crossing data access: parser
void data_func::parse()
//-----------------------------------------------------------------------------
{
if( _formula.empty() )
return ;
std::string vars("x,y,z") ;
int i = _parser.Parse( _formula, vars ) ;
if( _parser.GetParseErrorType() != FunctionParser::FP_NO_ERROR )
printf( "%s\n%s\n% *d\n", _parser.ErrorMsg(), _formula.c_str(), i, 1 ) ;
else
_parser.Optimize() ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// crossing data access
bool data_func::need_refine( const Cube &c )
//-----------------------------------------------------------------------------
{
if( _parser.GetParseErrorType() != FunctionParser::FP_NO_ERROR ) return false ;
int l = c.lv() ;
if( l < 2 ) return true ;
if( l >= _max_level ) return false ;
real cx = c.cx() ;
real cy = c.cy() ;
real cz = c.cz() ;
_v[X] = cx ;
_v[Y] = cy ;
_v[Z] = cz ;
real ref_val = _parser.Eval(_v) - _iso_val ;
if( fabs(ref_val) < R_EPSILON ) return true ;
real sz = c.sz() ;
for( _v[X] = cx-sz ; _v[X] <= cx+sz ; _v[X] += sz )
{
for( _v[Y] = cy-sz ; _v[Y] <= cy+sz ; _v[Y] += sz )
{
for( _v[Z] = cz-sz ; _v[Z] <= cz+sz ; _v[Z] += sz )
{
real val = _parser.Eval(_v) - _iso_val ;
if( ref_val * val < 0 ) return true ;
}
}
}
return false ;
}
//_____________________________________________________________________________
#ifndef BISSEC_ITER
#define BISSEC_ITER 3
#endif // BISSEC_ITER
//_____________________________________________________________________________
// interpolation function
void data_func::interpolate( real ci, real cj, const Point &pi, const Point &pj, Point &p )
//-----------------------------------------------------------------------------
{
real u ;
Point qi = pi ;
Point qj = pj ;
for( int i = 0 ; i < BISSEC_ITER ; ++i )
{
u = ( ci ) / ( ci - cj ) ;
p = ((1-u)*qi) + (u*qj) ;
real c = value_at(p) ;
if( c*ci < 0 )
{
qj = p ;
cj = c ;
}
else if( c*cj < 0 )
{
qi = p ;
ci = c ;
}
else break ;
}
u = ( ci ) / ( ci - cj ) ;
p = ((1-u)*qi) + (u*qj) ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
//_____________________________________________________________________________
// data_file
#include <errno.h>
#include <string.h>
#include <zlib.h>
//_____________________________________________________________________________
// data data access: load file
bool data_file::load_data( const char *fn )
//-----------------------------------------------------------------------------
{
errno = 0;
gzFile isofile = gzopen( fn, "rb" ) ;
if( !isofile )
{
printf( "data_file::load_data couldn't open file %s: %s\n", fn, strerror (errno));
return false ;
}
// read size
unsigned char buf[sizeof(float)] ;
if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ;
_size_x = * (int*)buf ;
if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ;
_size_y = * (int*)buf ;
if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ;
_size_z = * (int*)buf ;
if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ;
float xmin = * (float*)buf ;
if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ;
float xmax = * (float*)buf ;
if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ;
float ymin = * (float*)buf ;
if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ;
float ymax = * (float*)buf ;
if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ;
float zmin = * (float*)buf ;
if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ;
float zmax = * (float*)buf ;
// allocate data
delete [] _data ;
_size_yz = _size_z * _size_y ;
uint total_size = _size_x * _size_yz ;
if( total_size == 0 ) return false ;
// cube fitting
_max_size = _size_x ;
if( _max_size < _size_y ) _max_size = _size_y ;
if( _max_size < _size_z ) _max_size = _size_z ;
Level p = (Level)floor( log(_max_size)/log(2) ) ;
if( _max_size != (1<<p) ) _max_size = 1 << (p+1) ;
_data = new float[ total_size ] ;
if( _data == (float*)NULL ) return false ;
float min_field = FLT_MAX ;
float max_field = -FLT_MAX ;
float *data_ptr = _data ;
for( uint i = 0 ; i < total_size ; ++i, ++data_ptr )
{
if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ;
float v = * (float*) buf ;
*data_ptr = v ;
if( v < min_field ) min_field = v ;
if( v > max_field ) max_field = v ;
}
gzclose( isofile ) ;
printf( "data %s: %dx%dx%d, field originally in [ %f , %f ]\n", fn, (int)_size_x, (int)_size_y, (int)_size_z, min_field, max_field ) ;
// rescale data in [-1.1]
float v_scale = 2.0 / (max_field - min_field) ;
data_ptr = _data ;
for( uint i = 0 ; i < total_size ; ++i, ++data_ptr )
{
*data_ptr = v_scale * ( (*data_ptr) - min_field ) - 1.0 ;
}
// cube scaling
_sx = (xmax - xmin)/_size_x ;
_sy = (ymax - ymin)/_size_y ;
_sz = (zmax - zmin)/_size_z ;
float s = _sx ;
if( s < _sy ) s = _sy ;
if( s < _sz ) s = _sz ;
_sx /= s ;
_sy /= s ;
_sz /= s ;
return true ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// data data access
bool data_file::need_refine( const Cube &c )
//-----------------------------------------------------------------------------
{
int l = c.lv() ;
if( l < 2 ) return true ;
if( l >= _max_level ) return false ;
// ajustar se o dado nao for cubico!
real sz = c.sz() ;
uint i = floor( (c.cx()-sz) * _max_size ) ;
uint iM = ceil ( (c.cx()+sz) * _max_size ) ;
uint j = floor( (c.cy()-sz) * _max_size ) ;
uint jM = ceil ( (c.cy()+sz) * _max_size ) ;
uint k = floor( (c.cz()-sz) * _max_size ) ;
uint kM = ceil ( (c.cz()+sz) * _max_size ) ;
if( iM >= _size_x ) iM = _size_x-1 ;
if( jM >= _size_y ) jM = _size_y-1 ;
if( kM >= _size_z ) kM = _size_z-1 ;
float iso_min = get_data(iM,jM,kM) ;
float iso_max = iso_min ;
for( ; i <= iM ; ++i )
{
for( ; j <= jM ; ++j )
{
for( ; k <= kM ; ++k )
{
float iso = get_data(i,j,k) ;
if( iso_min > iso ) iso_min = iso ;
if( iso_max < iso ) iso_max = iso ;
if( iso_min*iso_max < 0 ) return true ;
}
}
}
return false ;
}
//_____________________________________________________________________________

View File

@ -1,192 +0,0 @@
/**
* @file data_access.h
* \author Thomas Lewiner <thomas.lewiner@polytechnique.org>
* \author Math Dept, PUC-Rio
* \author Matmidia Labs
* \date 14/02/2006
*
* @brief data accesss
*/
//________________________________________________
#pragma once
#ifndef WIN32
#pragma interface
#endif // WIN32
#include <string>
#include <stdio.h>
#include "cube.h"
//_____________________________________________________________________________
/// data access abstract class
class data_access
//_____________________________________________________________________________
{
public :
Level _max_level; ///< maximal level of a cell
real _iso_val; ///< iso value
float _sx ; ///< grid x proportion
float _sy ; ///< grid y proportion
float _sz ; ///< grid z proportion
public :
/// constructor
data_access( Level max_level_ = 4, real iso_val_ = 0.0 ) : _max_level(max_level_), _iso_val(iso_val_), _sx(1.0f), _sy(1.0f), _sz(1.0f) {}
/// destructor
virtual ~data_access() {}
/// test function
virtual bool need_refine( const Cube &c ) = 0 ;
/// data function
virtual real value_at ( const Cube &c ) = 0 ;
/// interpolation function
virtual void interpolate( real ci, real cj, const Point &pi, const Point &pj, Point &p )
{
real u = ( ci ) / ( ci - cj ) ;
p = ((1-u)*pi) + (u*pj) ;
}
} ;
//-----------------------------------------------------------------------------
// may be overridden by the preprocessor
#ifndef RAND_THRES
# define RAND_THRES 0.2
#endif // RAND_THRES
//_____________________________________________________________________________
/// basic data access
class data_rand : public data_access
//-----------------------------------------------------------------------------
{
public:
/// test function
bool need_refine( const Cube &c )
{
int l = c.lv() ;
if( l < 2 ) return true ;
if( l >= _max_level ) return false ;
return value_at(c) > RAND_THRES ;
}
/// data function
real value_at( const Cube &c ) { return ( (real)rand() ) / ( RAND_MAX >> 1 ) - 1.0 ; }
/// interpolation function
void interpolate( real ci, real cj, const Point &pi, const Point &pj, Point &p )
{
real u = ( (real)rand() ) / ( RAND_MAX ) ;
p = ((1-u)*pi) + (u*pj) ;
}
//-----------------------------------------------------------------------------
// Basics
public:
/// default constructor
data_rand( Level max_level_ ) : data_access(max_level_) {}
/// destructor
virtual ~data_rand() {}
} ;
//_____________________________________________________________________________
#include "fptypes.h"
#include "fparser.h"
//_____________________________________________________________________________
/// function crossing data access
class data_func : public data_access
//-----------------------------------------------------------------------------
{
public:
/// implicit function
std::string _formula ;
protected:
double _v[3] ;
FunctionParser _parser ;
protected:
void parse() ;
public:
/// test function
bool need_refine( const Cube &c ) ;
/// data function
real value_at( const Cube &c )
{
if( _parser.GetParseErrorType() != FunctionParser::FP_NO_ERROR ) return false ;
_v[X] = c.cx() ;
_v[Y] = c.cy() ;
_v[Z] = c.cz() ;
real v = _parser.Eval(_v) - _iso_val ;
if( _parser.EvalError() ) return -1.0 ;
return v ;
}
/// interpolation function
void interpolate( real ci, real cj, const Point &pi, const Point &pj, Point &p ) ;
//-----------------------------------------------------------------------------
// Basics
public:
/// default constructor
data_func( Level max_level_, real iso_val_, const std::string &formula_ ) : data_access(max_level_,iso_val_), _formula(formula_) { parse() ; }
/// destructor
virtual ~data_func() {}
} ;
//_____________________________________________________________________________
//_____________________________________________________________________________
/// iso file data access
class data_file : public data_access
//-----------------------------------------------------------------------------
{
public:
uint _size_x ; ///< width of the grid
uint _size_y ; ///< depth of the grid
uint _size_z ; ///< height of the grid
protected:
float *_data ; /**< implicit function values sampled on the grid */
uint _size_yz ; /**< k skip size */
uint _max_size ; /**< bigger side to fit into the cube */
public:
bool load_data ( const char *fn ) ;
bool has_data ( uint i, uint j, uint k ) { return (i < _size_x) && (j < _size_y) && (k < _size_z) ; }
float get_data ( uint i, uint j, uint k ) { return _data[ k + j*_size_z + i*_size_yz] - _iso_val ; }
/// test function
bool need_refine( const Cube &c ) ;
/// data function
real value_at( const Cube &c )
{
uint i = (uint)(c.cx()*_max_size) ;
uint j = (uint)(c.cy()*_max_size) ;
uint k = (uint)(c.cz()*_max_size) ;
if( has_data(i,j,k) ) return (real)get_data(i,j,k) ;
return -1.0 ;
}
// linear interpolation: no specification
//-----------------------------------------------------------------------------
// Basics
public:
/// default constructor
data_file( Level max_level_, real iso_val_, const char *fn ) : data_access(max_level_,iso_val_), _data((float*)NULL) { load_data( fn ) ; }
/// destructor
virtual ~data_file() {}
} ;
//_____________________________________________________________________________

View File

@ -1,292 +0,0 @@
unsigned nameLength = 0;
const unsigned maximumNameLength = 0x80000000U-8;
/*
Due to the manner the identifier lengths are returned from
the readOpcode() function, the maximum supported length for
identifiers is 0x7FFFFFFF bytes. We minus 8 here to add some
buffer, because of the multibyteness of UTF-8.
Function names are limited to 0xFFFF bytes instead, but because
function names that long just are not defined, the point is moot.
*/
const unsigned char* const uptr = (const unsigned char*) input;
typedef signed char schar;
while(likely(nameLength < maximumNameLength))
{
unsigned char byte = uptr[nameLength+0];
/* Handle the common case of A-Za-z first */
if(byte >= 0x40)
{
if(byte < 0x80) // 0x40..0x7F - most common case
{
// Valid characters in 40..7F: A-Za-z_
// Valid bitmask for 40..5F: 01111111111111111111111111100001
// Valid bitmask for 60..7F: 01111111111111111111111111100000
if(sizeof(unsigned long) == 8)
{
const unsigned n = sizeof(unsigned long)*8-32;
// ^ avoids compiler warning when not 64-bit
unsigned long masklow6bits = 1UL << (byte & 0x3F);
if(masklow6bits & ~((1UL << 0) | (0x0FUL << (0x1B ))
| (1UL << n) | (0x1FUL << (0x1B+n))))
{ ++nameLength; continue; }
}
else
{
unsigned masklow5bits = 1 << (byte & 0x1F);
if((masklow5bits & ~(1 | (0x1F << 0x1B))) || byte == '_')
{ ++nameLength; continue; }
}
break;
}
if(byte < 0xF0)
{
if(byte < 0xE0)
{
if(byte < 0xC2) break; // 0x80..0xC1
if(byte == 0xC2 && uptr[nameLength+1]==0xA0) break; // skip nbsp
// C2-DF - next common case when >= 0x40
// Valid sequence: C2-DF 80-BF
if(schar(uptr[nameLength+1]) > schar(0xBF)) break;
nameLength += 2;
continue;
}
if(byte == 0xE0) // E0
{
// Valid sequence: E0 A0-BF 80-BF
if((unsigned char)(uptr[nameLength+1] - 0xA0) > (0xBF-0xA0)) break;
}
else
{
if(byte == 0xED) break; // ED is invalid
// Valid sequence: E1-EC 80-BF 80-BF
// And: EE-EF 80-BF 80-BF
if(byte == 0xE2)
{
// break on various space characters
if(uptr[nameLength+1] == 0x80
&& (schar(uptr[nameLength+2]) <= schar(0x8B)
|| (uptr[nameLength+2] == 0xAF))) break;
if(uptr[nameLength+1] == 0x81
&& uptr[nameLength+2] == 0x9F) break;
} else
if(byte == 0xE3 && uptr[nameLength+1] == 0x80
&& uptr[nameLength+2] == 0x80) break; // this too
if(schar(uptr[nameLength+1]) > schar(0xBF)) break;
}
if(schar(uptr[nameLength+2]) > schar(0xBF)) break;
nameLength += 3;
continue;
}
if(byte == 0xF0) // F0
{
// Valid sequence: F0 90-BF 80-BF 80-BF
if((unsigned char)(uptr[nameLength+1] - 0x90) > (0xBF-0x90)) break;
}
else
{
if(byte > 0xF4) break; // F5-FF are invalid
if(byte == 0xF4) // F4
{
// Valid sequence: F4 80-8F
if(schar(uptr[nameLength+1]) > schar(0x8F)) break;
}
else
{
// F1-F3
// Valid sequence: F1-F3 80-BF 80-BF 80-BF
if(schar(uptr[nameLength+1]) > schar(0xBF)) break;
}
}
if(schar(uptr[nameLength+2]) > schar(0xBF)) break;
if(schar(uptr[nameLength+3]) > schar(0xBF)) break;
nameLength += 4;
continue;
}
if(nameLength > 0)
{
if(sizeof(unsigned long) == 8)
{
// Valid bitmask for 00..1F: 00000000000000000000000000000000
// Valid bitmask for 20..3F: 00000000000000001111111111000000
const unsigned n = sizeof(unsigned long)*8-32;
// ^ avoids compiler warning when not 64-bit
unsigned long masklow6bits = 1UL << byte;
if(masklow6bits & (((1UL << 10)-1UL) << (16+n)))
{ ++nameLength; continue; }
}
else
{
if(byte >= '0' && byte <= '9')
{ ++nameLength; continue; }
}
}
break;
}
/* This function generated with make_function_name_parser.cc */
switch(nameLength)
{
case 2:
/* prefix */if('i' == uptr[0]
&& 'f' == uptr[1]) return Functions[cIf].enabled() ? (cIf<<16) | 0x80000002U : 2;
return 2;
case 3:
/* prefix */switch(uptr[0]) {
case 'a':
/* prefix a */if('b' == uptr[1]
&& 's' == uptr[2]) return Functions[cAbs].enabled() ? (cAbs<<16) | 0x80000003U : 3;
return 3;
case 'c':
/* prefix c */switch(uptr[1]) {
case 'o':
/* prefix co */switch(uptr[2]) {
case 's':
/* prefix cos */return Functions[cCos].enabled() ? (cCos<<16) | 0x80000003U : 3;
case 't':
/* prefix cot */return Functions[cCot].enabled() ? (cCot<<16) | 0x80000003U : 3;
default: return 3; }
case 's':
/* prefix cs */if('c' == uptr[2]) return Functions[cCsc].enabled() ? (cCsc<<16) | 0x80000003U : 3;
return 3;
default: return 3; }
case 'e':
/* prefix e */if('x' == uptr[1]
&& 'p' == uptr[2]) return Functions[cExp].enabled() ? (cExp<<16) | 0x80000003U : 3;
return 3;
case 'i':
/* prefix i */if('n' == uptr[1]
&& 't' == uptr[2]) return Functions[cInt].enabled() ? (cInt<<16) | 0x80000003U : 3;
return 3;
case 'l':
/* prefix l */if('o' == uptr[1]
&& 'g' == uptr[2]) return Functions[cLog].enabled() ? (cLog<<16) | 0x80000003U : 3;
return 3;
case 'm':
/* prefix m */switch(uptr[1]) {
case 'a':
/* prefix ma */if('x' == uptr[2]) return Functions[cMax].enabled() ? (cMax<<16) | 0x80000003U : 3;
return 3;
case 'i':
/* prefix mi */if('n' == uptr[2]) return Functions[cMin].enabled() ? (cMin<<16) | 0x80000003U : 3;
return 3;
default: return 3; }
case 'p':
/* prefix p */if('o' == uptr[1]
&& 'w' == uptr[2]) return Functions[cPow].enabled() ? (cPow<<16) | 0x80000003U : 3;
return 3;
case 's':
/* prefix s */switch(uptr[1]) {
case 'e':
/* prefix se */if('c' == uptr[2]) return Functions[cSec].enabled() ? (cSec<<16) | 0x80000003U : 3;
return 3;
case 'i':
/* prefix si */if('n' == uptr[2]) return Functions[cSin].enabled() ? (cSin<<16) | 0x80000003U : 3;
return 3;
default: return 3; }
case 't':
/* prefix t */if('a' == uptr[1]
&& 'n' == uptr[2]) return Functions[cTan].enabled() ? (cTan<<16) | 0x80000003U : 3;
return 3;
default: return 3; }
case 4:
/* prefix */switch(uptr[0]) {
case 'a':
/* prefix a */switch(uptr[1]) {
case 'c':
/* prefix ac */if('o' == uptr[2]
&& 's' == uptr[3]) return Functions[cAcos].enabled() ? (cAcos<<16) | 0x80000004U : 4;
return 4;
case 's':
/* prefix as */if('i' == uptr[2]
&& 'n' == uptr[3]) return Functions[cAsin].enabled() ? (cAsin<<16) | 0x80000004U : 4;
return 4;
case 't':
/* prefix at */if('a' == uptr[2]
&& 'n' == uptr[3]) return Functions[cAtan].enabled() ? (cAtan<<16) | 0x80000004U : 4;
return 4;
default: return 4; }
case 'c':
/* prefix c */switch(uptr[1]) {
case 'b':
/* prefix cb */if('r' == uptr[2]
&& 't' == uptr[3]) return Functions[cCbrt].enabled() ? (cCbrt<<16) | 0x80000004U : 4;
return 4;
case 'e':
/* prefix ce */if('i' == uptr[2]
&& 'l' == uptr[3]) return Functions[cCeil].enabled() ? (cCeil<<16) | 0x80000004U : 4;
return 4;
case 'o':
/* prefix co */if('s' == uptr[2]
&& 'h' == uptr[3]) return Functions[cCosh].enabled() ? (cCosh<<16) | 0x80000004U : 4;
return 4;
default: return 4; }
case 'e':
/* prefix e */switch(uptr[1]) {
case 'v':
/* prefix ev */if('a' == uptr[2]
&& 'l' == uptr[3]) return Functions[cEval].enabled() ? (cEval<<16) | 0x80000004U : 4;
return 4;
case 'x':
/* prefix ex */if('p' == uptr[2]
&& '2' == uptr[3]) return Functions[cExp2].enabled() ? (cExp2<<16) | 0x80000004U : 4;
return 4;
default: return 4; }
case 'l':
/* prefix l */{static const char tmp[3] = {'o','g','2'};
if(std::memcmp(uptr+1, tmp, 3) == 0) return Functions[cLog2].enabled() ? (cLog2<<16) | 0x80000004U : 4;
return 4; }
case 's':
/* prefix s */switch(uptr[1]) {
case 'i':
/* prefix si */if('n' == uptr[2]
&& 'h' == uptr[3]) return Functions[cSinh].enabled() ? (cSinh<<16) | 0x80000004U : 4;
return 4;
case 'q':
/* prefix sq */if('r' == uptr[2]
&& 't' == uptr[3]) return Functions[cSqrt].enabled() ? (cSqrt<<16) | 0x80000004U : 4;
return 4;
default: return 4; }
case 't':
/* prefix t */{static const char tmp[3] = {'a','n','h'};
if(std::memcmp(uptr+1, tmp, 3) == 0) return Functions[cTanh].enabled() ? (cTanh<<16) | 0x80000004U : 4;
return 4; }
default: return 4; }
case 5:
/* prefix */switch(uptr[0]) {
case 'a':
/* prefix a */switch(uptr[1]) {
case 'c':
/* prefix ac */{static const char tmp[3] = {'o','s','h'};
if(std::memcmp(uptr+2, tmp, 3) == 0) return Functions[cAcosh].enabled() ? (cAcosh<<16) | 0x80000005U : 5;
return 5; }
case 's':
/* prefix as */{static const char tmp[3] = {'i','n','h'};
if(std::memcmp(uptr+2, tmp, 3) == 0) return Functions[cAsinh].enabled() ? (cAsinh<<16) | 0x80000005U : 5;
return 5; }
case 't':
/* prefix at */if('a' == uptr[2]) {
/* prefix ata */if('n' == uptr[3]) {
/* prefix atan */switch(uptr[4]) {
case '2':
/* prefix atan2 */return Functions[cAtan2].enabled() ? (cAtan2<<16) | 0x80000005U : 5;
case 'h':
/* prefix atanh */return Functions[cAtanh].enabled() ? (cAtanh<<16) | 0x80000005U : 5;
default: return 5; }
}return 5;}return 5;default: return 5; }
case 'f':
/* prefix f */{static const char tmp[4] = {'l','o','o','r'};
if(std::memcmp(uptr+1, tmp, 4) == 0) return Functions[cFloor].enabled() ? (cFloor<<16) | 0x80000005U : 5;
return 5; }
case 'l':
/* prefix l */{static const char tmp[4] = {'o','g','1','0'};
if(std::memcmp(uptr+1, tmp, 4) == 0) return Functions[cLog10].enabled() ? (cLog10<<16) | 0x80000005U : 5;
return 5; }
case 't':
/* prefix t */{static const char tmp[4] = {'r','u','n','c'};
if(std::memcmp(uptr+1, tmp, 4) == 0) return Functions[cTrunc].enabled() ? (cTrunc<<16) | 0x80000005U : 5;
return 5; }
default: return 5; }
default: break;
}
return nameLength;

View File

@ -1,159 +0,0 @@
/***************************************************************************\
|* Function Parser for C++ v4.0.3 *|
|*-------------------------------------------------------------------------*|
|* Copyright: Juha Nieminen, Joel Yliluoma *|
\***************************************************************************/
#ifndef ONCE_FPARSER_H_
#define ONCE_FPARSER_H_
#pragma interface
#include <string>
#include <vector>
#ifdef FUNCTIONPARSER_SUPPORT_DEBUG_OUTPUT
#include <iostream>
#endif
#ifdef _MSC_VER
// Visual Studio's warning about missing definitions for the explicit
// FunctionParserBase instantiations is irrelevant here.
#pragma warning(disable : 4661)
#endif
namespace FPoptimizer_CodeTree { class CodeTree; }
template<typename Value_t>
class FunctionParserBase
{
public:
enum ParseErrorType
{
SYNTAX_ERROR=0, MISM_PARENTH, MISSING_PARENTH, EMPTY_PARENTH,
EXPECT_OPERATOR, OUT_OF_MEMORY, UNEXPECTED_ERROR, INVALID_VARS,
ILL_PARAMS_AMOUNT, PREMATURE_EOS, EXPECT_PARENTH_FUNC,
UNKNOWN_IDENTIFIER,
NO_FUNCTION_PARSED_YET,
FP_NO_ERROR
};
typedef Value_t value_type;
int Parse(const char* Function, const std::string& Vars,
bool useDegrees = false);
int Parse(const std::string& Function, const std::string& Vars,
bool useDegrees = false);
void setDelimiterChar(char);
const char* ErrorMsg() const;
inline ParseErrorType GetParseErrorType() const { return parseErrorType; }
Value_t Eval(const Value_t* Vars);
inline int EvalError() const { return evalErrorType; }
bool AddConstant(const std::string& name, Value_t value);
bool AddUnit(const std::string& name, Value_t value);
typedef Value_t (*FunctionPtr)(const Value_t*);
bool AddFunction(const std::string& name,
FunctionPtr, unsigned paramsAmount);
bool AddFunction(const std::string& name, FunctionParserBase&);
bool RemoveIdentifier(const std::string& name);
void Optimize();
int ParseAndDeduceVariables(const std::string& function,
int* amountOfVariablesFound = 0,
bool useDegrees = false);
int ParseAndDeduceVariables(const std::string& function,
std::string& resultVarString,
int* amountOfVariablesFound = 0,
bool useDegrees = false);
int ParseAndDeduceVariables(const std::string& function,
std::vector<std::string>& resultVars,
bool useDegrees = false);
FunctionParserBase();
~FunctionParserBase();
// Copy constructor and assignment operator (implemented using the
// copy-on-write technique for efficiency):
FunctionParserBase(const FunctionParserBase&);
FunctionParserBase& operator=(const FunctionParserBase&);
void ForceDeepCopy();
#ifdef FUNCTIONPARSER_SUPPORT_DEBUG_OUTPUT
// For debugging purposes only:
void PrintByteCode(std::ostream& dest, bool showExpression = true) const;
#endif
//========================================================================
private:
//========================================================================
// Private data:
// ------------
char delimiterChar;
ParseErrorType parseErrorType;
int evalErrorType;
friend class FPoptimizer_CodeTree::CodeTree;
struct Data;
Data* data;
bool useDegreeConversion;
unsigned evalRecursionLevel;
unsigned StackPtr;
const char* errorLocation;
// Private methods:
// ---------------
void CopyOnWrite();
bool CheckRecursiveLinking(const FunctionParserBase*) const;
bool NameExists(const char*, unsigned);
bool ParseVariables(const std::string&);
int ParseFunction(const char*, bool);
const char* SetErrorType(ParseErrorType, const char*);
void AddFunctionOpcode(unsigned);
void AddImmedOpcode(Value_t v);
void incStackPtr();
void CompilePowi(int);
bool TryCompilePowi(Value_t);
const char* CompileIf(const char*);
const char* CompileFunctionParams(const char*, unsigned);
const char* CompileElement(const char*);
const char* CompilePossibleUnit(const char*);
const char* CompilePow(const char*);
const char* CompileUnaryMinus(const char*);
const char* CompileMult(const char*);
const char* CompileAddition(const char*);
const char* CompileComparison(const char*);
const char* CompileAnd(const char*);
const char* CompileExpression(const char*);
inline const char* CompileFunction(const char*, unsigned);
inline const char* CompileParenthesis(const char*);
inline const char* CompileLiteral(const char*);
};
class FunctionParser: public FunctionParserBase<double> {};
class FunctionParser_f: public FunctionParserBase<float> {};
class FunctionParser_ld: public FunctionParserBase<long double> {};
class FunctionParser_li: public FunctionParserBase<long> {};
#endif

View File

@ -1,599 +0,0 @@
/***************************************************************************\
|* Function Parser for C++ v4.0.3 *|
|*-------------------------------------------------------------------------*|
|* Copyright: Juha Nieminen, Joel Yliluoma *|
\***************************************************************************/
// NOTE:
// This file contains only internal types for the function parser library.
// You don't need to include this file in your code. Include "fparser.hh"
// only.
#ifndef ONCE_FPARSER_AUX_H_
#define ONCE_FPARSER_AUX_H_
#include <cmath>
#include <cstring>
#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
#include "mpfr/MpfrFloat.h"
#endif
#ifdef FP_SUPPORT_GMP_INT_TYPE
#include "mpfr/GmpInt.h"
#endif
#ifdef ONCE_FPARSER_H_
namespace FUNCTIONPARSERTYPES
{
//==========================================================================
// Math funcs
//==========================================================================
/* fp_pow() is a wrapper for std::pow()
* that produces an identical value for
* exp(1) ^ 2.0 (0x4000000000000000)
* as exp(2.0) (0x4000000000000000)
* - std::pow() on x86_64
* produces 2.0 (0x3FFFFFFFFFFFFFFF) instead!
* See comments below for other special traits.
*/
template<typename ValueT>
inline ValueT fp_pow_with_exp_log(const ValueT& x, const ValueT& y)
{
// Requirements: x > 0.
return fp_exp(fp_log(x) * y);
}
template<typename ValueT>
inline ValueT fp_powi(ValueT x, unsigned long y)
{
// Requirements: y is non-negative integer.
ValueT result(1);
while(y != 0)
{
if(y & 1) { result *= x; y -= 1; }
else { x *= x; y /= 2; }
}
return result;
}
template<typename ValueT>
ValueT fp_pow(const ValueT& x, const ValueT& y)
{
if(x == ValueT(1)) return ValueT(1);
// y is now zero or positive
if(IsIntegerConst(y))
{
// Use fast binary exponentiation algorithm
// See http://en.wikipedia.org/wiki/Exponentiation_by_squaring
if(y >= ValueT(0))
return fp_powi(x, (long)y);
else
return ValueT(1) / fp_powi(x, -(long)y);
}
if(y >= ValueT(0))
{
// y is now positive. Calculate using exp(log(x)*y).
// See http://en.wikipedia.org/wiki/Exponentiation#Real_powers
if(x > ValueT(0)) return fp_pow_with_exp_log(x, y);
if(x == ValueT(0)) return ValueT(0);
// At this point, y > 0.0 and x is known to be < 0.0,
// because positive and zero cases are already handled.
//
if(!IsIntegerConst(y*ValueT(16)))
return -fp_pow_with_exp_log(-x, y);
// ^This is not technically correct, but it allows
// functions such as cbrt(x^5), that is, x^(5/3),
// to be evaluated when x is negative.
// It is too complicated (and slow) to test whether y
// is a formed from a ratio of an integer to an odd integer.
// (And due to floating point inaccuracy, pointless too.)
// For example, x^1.30769230769... is
// actually x^(17/13), i.e. (x^17) ^ (1/13).
// (-5)^(17/13) gives us now -8.204227562330453.
// To see whether the result is right, we can test the given
// root: (-8.204227562330453)^13 gives us the value of (-5)^17,
// which proves that the expression was correct.
//
// The y*16 check prevents e.g. (-4)^(3/2) from being calculated,
// as it would confuse functioninfo when pow() returns no error
// but sqrt() does when the formula is converted into sqrt(x)*x.
//
// The errors in this approach are:
// (-2)^sqrt(2) should produce NaN
// or actually sqrt(2)I + 2^sqrt(2),
// produces -(2^sqrt(2)) instead.
// (Impact: Neglible)
// Thus, at worst, we're changing a NaN (or complex)
// result into a negative real number result.
}
else
{
// y is negative. Utilize the x^y = 1/(x^-y) identity.
if(x > ValueT(0)) return fp_pow_with_exp_log(ValueT(1) / x, -y);
if(x < ValueT(0))
{
if(!IsIntegerConst(y*ValueT(-16)))
return -fp_pow_with_exp_log(ValueT(-1) / x, -y);
// ^ See comment above.
}
// Remaining case: 0.0 ^ negative number
}
// This is reached when:
// x=0 and y<0
// x<0 and y*16 is either positive or negative integer
// It is used for producing error values and as a safe fallback.
return fp_pow_base(x, y);
}
// -------------------------------------------------------------------------
// double
// -------------------------------------------------------------------------
inline double fp_abs(double x) { return fabs(x); }
inline double fp_acos(double x) { return acos(x); }
inline double fp_asin(double x) { return asin(x); }
inline double fp_atan(double x) { return atan(x); }
inline double fp_atan2(double x, double y) { return atan2(x, y); }
#ifdef FP_SUPPORT_CBRT
inline double fp_cbrt(double x) { return cbrt(x); }
#else
inline double fp_cbrt(double x) { return x>0 ? exp(log( x)/3.0)
: x<0 ? -exp(log(-x)/3.0)
: 0.0; }
#endif
inline double fp_ceil(double x) { return ceil(x); }
inline double fp_cos(double x) { return cos(x); }
inline double fp_cosh(double x) { return cosh(x); }
inline double fp_exp(double x) { return exp(x); }
inline double fp_floor(double x) { return floor(x); }
inline double fp_int(double x) { return floor(x + .5); }
inline double fp_log(double x) { return log(x); }
inline double fp_log10(double x)
{ return log(x) *
0.434294481903251827651128918916605082294397005803666566; }
inline double fp_mod(double x, double y) { return fmod(x, y); }
inline double fp_sin(double x) { return sin(x); }
inline double fp_sinh(double x) { return sinh(x); }
inline double fp_sqrt(double x) { return sqrt(x); }
inline double fp_tan(double x) { return tan(x); }
inline double fp_tanh(double x) { return tanh(x); }
#ifndef FP_SUPPORT_ASINH
inline double fp_asinh(double x) { return log(x + sqrt(x*x + 1.0)); }
inline double fp_acosh(double x) { return log(x + sqrt(x*x - 1.0)); }
inline double fp_atanh(double x) { return log((1.0+x) / (1.0-x)) * 0.5; }
#else
inline double fp_asinh(double x) { return asinh(x); }
inline double fp_acosh(double x) { return acosh(x); }
inline double fp_atanh(double x) { return atanh(x); }
#endif // FP_SUPPORT_ASINH
inline double fp_trunc(double x) { return x<0.0 ? ceil(x) : floor(x); }
inline double fp_pow_base(double x, double y) { return pow(x, y); }
#ifndef FP_SUPPORT_LOG2
inline double fp_log2(double x)
{ return log(x) * 1.4426950408889634073599246810018921374266459541529859; }
#else
inline double fp_log2(double x) { return log2(x); }
#endif // FP_SUPPORT_LOG2
inline double fp_exp2(double x) { return fp_pow(2.0, x); }
#ifdef FP_EPSILON
template<typename Value_t>
inline Value_t fp_epsilon() { return FP_EPSILON; }
#else
template<typename Value_t>
inline Value_t fp_epsilon() { return 0.0; }
#endif
#ifdef FP_EPSILON
inline bool FloatEqual(double a, double b)
{ return fabs(a - b) <= fp_epsilon<double>(); }
#else
inline bool FloatEqual(double a, double b)
{ return a == b; }
#endif // FP_EPSILON
inline bool IsIntegerConst(double a)
{ return FloatEqual(a, (double)(long)a); }
// -------------------------------------------------------------------------
// float
// -------------------------------------------------------------------------
#ifdef FP_SUPPORT_FLOAT_TYPE
inline float fp_abs(float x) { return fabsf(x); }
inline float fp_acos(float x) { return acosf(x); }
inline float fp_asin(float x) { return asinf(x); }
inline float fp_atan(float x) { return atanf(x); }
inline float fp_atan2(float x, float y) { return atan2f(x, y); }
#ifdef FP_SUPPORT_CBRT
inline float fp_cbrt(float x) { return cbrtf(x); }
#else
inline float fp_cbrt(float x) { return x>0 ? expf(logf( x)/3.0f)
: x<0 ? -expf(logf(-x)/3.0f)
: 0.0f; }
#endif
inline float fp_ceil(float x) { return ceilf(x); }
inline float fp_cos(float x) { return cosf(x); }
inline float fp_cosh(float x) { return coshf(x); }
inline float fp_exp(float x) { return expf(x); }
inline float fp_floor(float x) { return floorf(x); }
inline float fp_int(float x) { return floorf(x + .5F); }
inline float fp_log(float x) { return logf(x); }
inline float fp_log10(float x)
{ return logf(x) *
0.434294481903251827651128918916605082294397005803666566F; }
inline float fp_mod(float x, float y) { return fmodf(x, y); }
inline float fp_sin(float x) { return sinf(x); }
inline float fp_sinh(float x) { return sinhf(x); }
inline float fp_sqrt(float x) { return sqrtf(x); }
inline float fp_tan(float x) { return tanf(x); }
inline float fp_tanh(float x) { return tanhf(x); }
#ifndef FP_SUPPORT_ASINH
inline float fp_asinh(float x) { return logf(x + sqrt(x*x + 1.0F)); }
inline float fp_acosh(float x) { return logf(x + sqrt(x*x - 1.0F)); }
inline float fp_atanh(float x) { return logf((1.0F+x) / (1.0F-x)) * 0.5F; }
#else
inline float fp_asinh(float x) { return asinhf(x); }
inline float fp_acosh(float x) { return acoshf(x); }
inline float fp_atanh(float x) { return atanhf(x); }
#endif // FP_SUPPORT_ASINH
inline float fp_trunc(float x) { return x<0.0F ? ceilf(x) : floorf(x); }
inline float fp_pow_base(float x, float y) { return powf(x, y); }
#ifndef FP_SUPPORT_LOG2
inline float fp_log2(float x)
{ return logf(x) *
1.4426950408889634073599246810018921374266459541529859F; }
#else
inline float fp_log2(float x) { return log2f(x); }
#endif // FP_SUPPORT_LOG2
inline float fp_exp2(float x) { return fp_pow(2.0F, x); }
#ifdef FP_EPSILON
template<>
inline float fp_epsilon<float>() { return 1e-6F; }
#else
template<>
inline float fp_epsilon<float>() { return 0.0F; }
#endif
#ifdef FP_EPSILON
inline bool FloatEqual(float a, float b)
{ return fabsf(a - b) <= fp_epsilon<float>(); }
#else
inline bool FloatEqual(float a, float b)
{ return a == b; }
#endif // FP_EPSILON
inline bool IsIntegerConst(float a)
{ return FloatEqual(a, (float)(long)a); }
#endif // FP_SUPPORT_FLOAT_TYPE
// -------------------------------------------------------------------------
// long double
// -------------------------------------------------------------------------
#ifdef FP_SUPPORT_LONG_DOUBLE_TYPE
inline long double fp_abs(long double x) { return fabsl(x); }
inline long double fp_acos(long double x) { return acosl(x); }
inline long double fp_asin(long double x) { return asinl(x); }
inline long double fp_atan(long double x) { return atanl(x); }
inline long double fp_atan2(long double x, long double y)
{ return atan2l(x, y); }
#ifdef FP_SUPPORT_CBRT
inline long double fp_cbrt(long double x) { return cbrtl(x); }
#else
inline long double fp_cbrt(long double x)
{ return x>0 ? expl(logl( x)/3.0l)
: x<0 ? -expl(logl(-x)/3.0l)
: 0.0l; }
#endif
inline long double fp_ceil(long double x) { return ceill(x); }
inline long double fp_cos(long double x) { return cosl(x); }
inline long double fp_cosh(long double x) { return coshl(x); }
inline long double fp_exp(long double x) { return expl(x); }
inline long double fp_floor(long double x) { return floorl(x); }
inline long double fp_int(long double x) { return floorl(x + .5L); }
inline long double fp_log(long double x) { return logl(x); }
inline long double fp_log10(long double x)
{ return logl(x) *
0.434294481903251827651128918916605082294397005803666566L; }
inline long double fp_mod(long double x, long double y)
{ return fmodl(x, y); }
inline long double fp_sin(long double x) { return sinl(x); }
inline long double fp_sinh(long double x) { return sinhl(x); }
inline long double fp_sqrt(long double x) { return sqrtl(x); }
inline long double fp_tan(long double x) { return tanl(x); }
inline long double fp_tanh(long double x) { return tanhl(x); }
#ifndef FP_SUPPORT_ASINH
inline long double fp_asinh(long double x)
{ return logl(x + sqrtl(x*x + 1.0L)); }
inline long double fp_acosh(long double x)
{ return logl(x + sqrtl(x*x - 1.0L)); }
inline long double fp_atanh(long double x)
{ return logl((1.0L+x) / (1.0L-x)) * 0.5L; }
#else
inline long double fp_asinh(long double x) { return asinhl(x); }
inline long double fp_acosh(long double x) { return acoshl(x); }
inline long double fp_atanh(long double x) { return atanhl(x); }
#endif // FP_SUPPORT_ASINH
inline long double fp_trunc(long double x)
{ return x<0.0L ? ceill(x) : floorl(x); }
inline long double fp_pow_base(long double x, long double y)
{ return powl(x, y); }
#ifndef FP_SUPPORT_LOG2
inline long double fp_log2(long double x)
{ return log(x) * 1.4426950408889634073599246810018921374266459541529859L; }
#else
inline long double fp_log2(long double x) { return log2l(x); }
#endif // FP_SUPPORT_LOG2
inline long double fp_exp2(long double x) { return fp_pow(2.0L, x); }
#ifdef FP_EPSILON
inline bool FloatEqual(long double a, long double b)
{ return fabsl(a - b) <= fp_epsilon<double>(); }
#else
inline bool FloatEqual(long double a, long double b)
{ return a == b; }
#endif // FP_EPSILON
inline bool IsIntegerConst(long double a)
{ return FloatEqual(a, (long double)(long)a); }
#endif // FP_SUPPORT_LONG_DOUBLE_TYPE
// -------------------------------------------------------------------------
// Long int
// -------------------------------------------------------------------------
inline long fp_abs(long x) { return x < 0 ? -x : x; }
inline long fp_acos(long) { return 0; }
inline long fp_asin(long) { return 0; }
inline long fp_atan(long) { return 0; }
inline long fp_atan2(long, long) { return 0; }
inline long fp_cbrt(long) { return 0; }
inline long fp_ceil(long x) { return x; }
inline long fp_cos(long) { return 0; }
inline long fp_cosh(long) { return 0; }
inline long fp_exp(long) { return 0; }
inline long fp_floor(long x) { return x; }
inline long fp_int(long x) { return x; }
inline long fp_log(long) { return 0; }
inline long fp_log10(long) { return 0; }
inline long fp_mod(long x, long y) { return x % y; }
inline long fp_pow(long, long) { return 0; }
inline long fp_sin(long) { return 0; }
inline long fp_sinh(long) { return 0; }
inline long fp_sqrt(long) { return 1; }
inline long fp_tan(long) { return 0; }
inline long fp_tanh(long) { return 0; }
inline long fp_asinh(long) { return 0; }
inline long fp_acosh(long) { return 0; }
inline long fp_atanh(long) { return 0; }
inline long fp_trunc(long x) { return x; }
inline long fp_pow_base(long, long) { return 0; }
inline long fp_log2(long) { return 0; }
inline long fp_exp2(long) { return 0; }
template<>
inline long fp_epsilon<long>() { return 0; }
inline bool IsIntegerConst(long) { return true; }
// -------------------------------------------------------------------------
// MpfrFloat
// -------------------------------------------------------------------------
#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
inline MpfrFloat fp_abs(const MpfrFloat& x) { return MpfrFloat::abs(x); }
inline MpfrFloat fp_acos(const MpfrFloat& x) { return MpfrFloat::acos(x); }
inline MpfrFloat fp_asin(const MpfrFloat& x) { return MpfrFloat::asin(x); }
inline MpfrFloat fp_atan(const MpfrFloat& x) { return MpfrFloat::atan(x); }
inline MpfrFloat fp_atan2(const MpfrFloat& x, const MpfrFloat& y) { return MpfrFloat::atan2(x, y); }
inline MpfrFloat fp_cbrt(const MpfrFloat& x) { return MpfrFloat::cbrt(x); }
inline MpfrFloat fp_ceil(const MpfrFloat& x) { return MpfrFloat::ceil(x); }
inline MpfrFloat fp_cos(const MpfrFloat& x) { return MpfrFloat::cos(x); }
inline MpfrFloat fp_cosh(const MpfrFloat& x) { return MpfrFloat::cosh(x); }
inline MpfrFloat fp_exp(const MpfrFloat& x) { return MpfrFloat::exp(x); }
inline MpfrFloat fp_floor(const MpfrFloat& x) { return MpfrFloat::floor(x); }
inline MpfrFloat fp_int(const MpfrFloat& x) { return MpfrFloat::round(x); }
inline MpfrFloat fp_log(const MpfrFloat& x) { return MpfrFloat::log(x); }
inline MpfrFloat fp_log10(const MpfrFloat& x) { return MpfrFloat::log10(x); }
inline MpfrFloat fp_mod(const MpfrFloat& x, const MpfrFloat& y) { return x % y; }
inline MpfrFloat fp_sin(const MpfrFloat& x) { return MpfrFloat::sin(x); }
inline MpfrFloat fp_sinh(const MpfrFloat& x) { return MpfrFloat::sinh(x); }
inline MpfrFloat fp_sqrt(const MpfrFloat& x) { return MpfrFloat::sqrt(x); }
inline MpfrFloat fp_tan(const MpfrFloat& x) { return MpfrFloat::tan(x); }
inline MpfrFloat fp_tanh(const MpfrFloat& x) { return MpfrFloat::tanh(x); }
inline MpfrFloat fp_asinh(const MpfrFloat& x) { return MpfrFloat::asinh(x); }
inline MpfrFloat fp_acosh(const MpfrFloat& x) { return MpfrFloat::acosh(x); }
inline MpfrFloat fp_atanh(const MpfrFloat& x) { return MpfrFloat::atanh(x); }
inline MpfrFloat fp_trunc(const MpfrFloat& x) { return MpfrFloat::trunc(x); }
inline MpfrFloat fp_pow(const MpfrFloat& x, const MpfrFloat& y) { return MpfrFloat::pow(x, y); }
inline MpfrFloat fp_pow_base(const MpfrFloat& x, const MpfrFloat& y) { return MpfrFloat::pow(x, y); }
inline MpfrFloat fp_log2(const MpfrFloat& x) { return MpfrFloat::log2(x); }
inline MpfrFloat fp_exp2(const MpfrFloat& x) { return MpfrFloat::exp2(x); }
inline bool IsIntegerConst(const MpfrFloat& a) { return a.isInteger(); }
template<>
inline MpfrFloat fp_epsilon<MpfrFloat>() { return MpfrFloat::someEpsilon(); }
#endif // FP_SUPPORT_MPFR_FLOAT_TYPE
// -------------------------------------------------------------------------
// GMP int
// -------------------------------------------------------------------------
#ifdef FP_SUPPORT_GMP_INT_TYPE
inline GmpInt fp_abs(GmpInt x) { return GmpInt::abs(x); }
inline GmpInt fp_acos(GmpInt) { return 0; }
inline GmpInt fp_asin(GmpInt) { return 0; }
inline GmpInt fp_atan(GmpInt) { return 0; }
inline GmpInt fp_atan2(GmpInt, GmpInt) { return 0; }
inline GmpInt fp_cbrt(GmpInt) { return 0; }
inline GmpInt fp_ceil(GmpInt x) { return x; }
inline GmpInt fp_cos(GmpInt) { return 0; }
inline GmpInt fp_cosh(GmpInt) { return 0; }
inline GmpInt fp_exp(GmpInt) { return 0; }
inline GmpInt fp_floor(GmpInt x) { return x; }
inline GmpInt fp_int(GmpInt x) { return x; }
inline GmpInt fp_log(GmpInt) { return 0; }
inline GmpInt fp_log10(GmpInt) { return 0; }
inline GmpInt fp_mod(GmpInt x, GmpInt y) { return x % y; }
inline GmpInt fp_pow(GmpInt, GmpInt) { return 0; }
inline GmpInt fp_sin(GmpInt) { return 0; }
inline GmpInt fp_sinh(GmpInt) { return 0; }
inline GmpInt fp_sqrt(GmpInt) { return 0; }
inline GmpInt fp_tan(GmpInt) { return 0; }
inline GmpInt fp_tanh(GmpInt) { return 0; }
inline GmpInt fp_asinh(GmpInt) { return 0; }
inline GmpInt fp_acosh(GmpInt) { return 0; }
inline GmpInt fp_atanh(GmpInt) { return 0; }
inline GmpInt fp_trunc(GmpInt x) { return x; }
inline GmpInt fp_pow_base(GmpInt, GmpInt) { return 0; }
inline GmpInt fp_log2(GmpInt) { return 0; }
inline GmpInt fp_exp2(GmpInt) { return 0; }
template<>
inline GmpInt fp_epsilon<GmpInt>() { return 0; }
inline bool IsIntegerConst(GmpInt) { return true; }
#endif // FP_SUPPORT_GMP_INT_TYPE
// -------------------------------------------------------------------------
// Comparison
// -------------------------------------------------------------------------
#ifdef FP_EPSILON
template<typename Value_t>
inline bool fp_equal(Value_t x, Value_t y)
{ return fp_abs(x - y) <= fp_epsilon<Value_t>(); }
template<typename Value_t>
inline bool fp_nequal(Value_t x, Value_t y)
{ return fp_abs(x - y) > fp_epsilon<Value_t>(); }
template<typename Value_t>
inline bool fp_less(Value_t x, Value_t y)
{ return x < y - fp_epsilon<Value_t>(); }
template<typename Value_t>
inline bool fp_lessOrEq(Value_t x, Value_t y)
{ return x <= y + fp_epsilon<Value_t>(); }
#else // FP_EPSILON
template<typename Value_t>
inline bool fp_equal(Value_t x, Value_t y) { return x == y; }
template<typename Value_t>
inline bool fp_nequal(Value_t x, Value_t y) { return x != y; }
template<typename Value_t>
inline bool fp_less(Value_t x, Value_t y) { return x < y; }
template<typename Value_t>
inline bool fp_lessOrEq(Value_t x, Value_t y) { return x <= y; }
#endif // FP_EPSILON
template<>
inline bool fp_equal<long>(long x, long y) { return x == y; }
template<>
inline bool fp_nequal<long>(long x, long y) { return x != y; }
template<>
inline bool fp_less<long>(long x, long y) { return x < y; }
template<>
inline bool fp_lessOrEq<long>(long x, long y) { return x <= y; }
#ifdef FP_SUPPORT_GMP_INT_TYPE
template<>
inline bool fp_equal<GmpInt>(GmpInt x, GmpInt y) { return x == y; }
template<>
inline bool fp_nequal<GmpInt>(GmpInt x, GmpInt y) { return x != y; }
template<>
inline bool fp_less<GmpInt>(GmpInt x, GmpInt y) { return x < y; }
template<>
inline bool fp_lessOrEq<GmpInt>(GmpInt x, GmpInt y) { return x <= y; }
#endif
} // namespace FUNCTIONPARSERTYPES
#endif // ONCE_FPARSER_H_
#ifndef FP_DISABLE_DOUBLE_TYPE
#define FUNCTIONPARSER_INSTANTIATE_DOUBLE \
template class FunctionParserBase<double>;
#else
#define FUNCTIONPARSER_INSTANTIATE_DOUBLE
#endif
#ifdef FP_SUPPORT_FLOAT_TYPE
#define FUNCTIONPARSER_INSTANTIATE_FLOAT \
template class FunctionParserBase<float>;
#else
#define FUNCTIONPARSER_INSTANTIATE_FLOAT
#endif
#ifdef FP_SUPPORT_LONG_DOUBLE_TYPE
#define FUNCTIONPARSER_INSTANTIATE_LONG_DOUBLE \
template class FunctionParserBase<long double>;
#else
#define FUNCTIONPARSER_INSTANTIATE_LONG_DOUBLE
#endif
#ifdef FP_SUPPORT_LONG_INT_TYPE
#define FUNCTIONPARSER_INSTANTIATE_LONG_INT \
template class FunctionParserBase<long>;
#else
#define FUNCTIONPARSER_INSTANTIATE_LONG_INT
#endif
#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
#define FUNCTIONPARSER_INSTANTIATE_MPFR_FLOAT \
template class FunctionParserBase<MpfrFloat>;
#else
#define FUNCTIONPARSER_INSTANTIATE_MPFR_FLOAT
#endif
#ifdef FP_SUPPORT_GMP_INT_TYPE
#define FUNCTIONPARSER_INSTANTIATE_GMP_INT \
template class FunctionParserBase<GmpInt>;
#else
#define FUNCTIONPARSER_INSTANTIATE_GMP_INT
#endif
/* Add 'FUNCTIONPARSER_INSTANTIATE_TYPES' at the end of all .cc files
containing FunctionParserBase implementations.
*/
#define FUNCTIONPARSER_INSTANTIATE_TYPES \
FUNCTIONPARSER_INSTANTIATE_DOUBLE \
FUNCTIONPARSER_INSTANTIATE_FLOAT \
FUNCTIONPARSER_INSTANTIATE_LONG_DOUBLE \
FUNCTIONPARSER_INSTANTIATE_LONG_INT \
FUNCTIONPARSER_INSTANTIATE_MPFR_FLOAT \
FUNCTIONPARSER_INSTANTIATE_GMP_INT
#endif // ONCE_FPARSER_AUX_H_

View File

@ -1,139 +0,0 @@
/***************************************************************************\
|* Function Parser for C++ v4.0.3 *|
|*-------------------------------------------------------------------------*|
|* Copyright: Juha Nieminen *|
\***************************************************************************/
// Configuration file
// ------------------
/* NOTE:
This file is for the internal use of the function parser only.
You don't need to include this file in your source files, just
include "fparser.hh".
*/
/* Uncomment any of these lines or define them in your compiler settings
to enable the correspondent version of the parser. (These are disabled
by default because they rely on C99 functions, and non-standard libraries
in the case pf MPFR and GMP, and they make compiling needlessly slower
and the resulting binary needlessly larger if they are not used in the
program.)
*/
//#define FP_SUPPORT_FLOAT_TYPE
#define FP_SUPPORT_LONG_DOUBLE_TYPE
//#define FP_SUPPORT_LONG_INT_TYPE
//#define FP_SUPPORT_MPFR_FLOAT_TYPE
//#define FP_SUPPORT_GMP_INT_TYPE
/* Uncomment this line of define it in your compiler settings if you want
to disable compiling the basic double version of the library, in case
one of the above types is used but not the double type. (If the double
type is not used, then disabling it makes compiling faster and the
resulting binary smaller.)
*/
//#define FP_DISABLE_DOUBLE_TYPE
/*
Note that these do not change what FunctionParser supports, they only
change how the function is evaluated, potentially making it faster when
these functions are involved.
These will make the source code use asinh(), acosh(), atanh(), exp2()
and log2().
*/
//#define FP_SUPPORT_TR1_MATH_FUNCS
#ifdef FP_SUPPORT_TR1_MATH_FUNCS
#define FP_SUPPORT_ASINH
#define FP_SUPPORT_EXP2
#define FP_SUPPORT_LOG2
#define FP_SUPPORT_CBRT
#endif
/*
Comment out the following line to enable the eval() function, which can
be used in the function string to recursively call the same function.
Note that enabling this function may be dangerous even if the maximum
recursion level is limited because it is still possible to write functions
using it which take enormous amounts of time to evaluate even though the
maximum recursion is never reached. This may be undesirable in some
applications.
Alternatively you can define the FP_ENABLE_EVAL precompiler constant in
your compiler settings.
*/
#ifndef FP_ENABLE_EVAL
#define FP_DISABLE_EVAL
#endif
/*
Maximum recursion level for eval() calls:
*/
#define FP_EVAL_MAX_REC_LEVEL 1000
/*
Whether to use shortcut evaluation for the & and | operators:
*/
#define FP_DISABLE_SHORTCUT_LOGICAL_EVALUATION
#ifndef FP_DISABLE_SHORTCUT_LOGICAL_EVALUATION
#define FP_ENABLE_SHORTCUT_LOGICAL_EVALUATION
#endif
/*
Whether to enable optimizations that may ignore side effects
of if() calls, such as changing if(x,!y,0) into x&!y.
This is basically the polar opposite of "shortcut logical evaluation".
Disabled by default, because it makes eval() rather unsafe.
*/
#ifdef FP_ENABLE_IGNORE_IF_SIDEEFFECTS
#endif
/*
Comment out the following lines out if you are not going to use the
optimizer and want a slightly smaller library. The Optimize() method
can still be called, but it will not do anything.
If you are unsure, just leave it. It won't slow down the other parts of
the library.
*/
//#define FP_NO_SUPPORT_OPTIMIZER
#ifndef FP_NO_SUPPORT_OPTIMIZER
#define FP_SUPPORT_OPTIMIZER
#endif
/*
Epsilon value used with the comparison operators (must be non-negative):
(Comment it out if you don't want to use epsilon in comparisons. Might
lead to marginally faster evaluation of the comparison operators, but
can introduce inaccuracies in comparisons.)
*/
#define FP_EPSILON 1e-14
/*
No member function of FunctionParser is thread-safe. Most prominently,
Eval() is not thread-safe. By uncommenting one of these lines the Eval()
function can be made thread-safe at the cost of a possible small overhead.
The second version requires that the compiler supports the alloca() function,
which is not standard, but is faster.
*/
//#define FP_USE_THREAD_SAFE_EVAL
//#define FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA
/*
Uncomment (or define in your compiler options) to disable evaluation checks.
(Consult the documentation for details.)
*/
#define FP_NO_EVALUATION_CHECKS
// Temporary settings while double is the only supported type by the optimizer
#ifdef FP_DISABLE_DOUBLE_TYPE
#ifndef FP_NO_SUPPORT_OPTIMIZER
#define FP_NO_SUPPORT_OPTIMIZER
#endif
#undef FP_SUPPORT_OPTIMIZER
#endif

View File

@ -1,267 +0,0 @@
/***************************************************************************\
|* Function Parser for C++ v4.0.3 *|
|*-------------------------------------------------------------------------*|
|* Copyright: Juha Nieminen, Joel Yliluoma *|
\***************************************************************************/
// NOTE:
// This file contains only internal types for the function parser library.
// You don't need to include this file in your code. Include "fparser.hh"
// only.
#ifndef ONCE_FPARSER_TYPES_H_
#define ONCE_FPARSER_TYPES_H_
#include "fpconfig.h"
#include <cstring>
#ifdef ONCE_FPARSER_H_
# include <map>
#endif
namespace FUNCTIONPARSERTYPES
{
enum OPCODE
{
// The order of opcodes in the function list must
// match that which is in the Functions[] array.
cAbs,
cAcos, cAcosh,
cAsin, cAsinh,
cAtan, cAtan2, cAtanh,
cCbrt, cCeil,
cCos, cCosh, cCot, cCsc,
cEval,
cExp, cExp2, cFloor, cIf, cInt, cLog, cLog10, cLog2, cMax, cMin,
cPow, cSec, cSin, cSinh, cSqrt, cTan, cTanh,
cTrunc,
// These do not need any ordering:
// Except that if you change the order of {eq,neq,lt,le,gt,ge}, you
// must also change the order in ConstantFolding_ComparisonOperations().
cImmed, cJump,
cNeg, cAdd, cSub, cMul, cDiv, cMod,
cEqual, cNEqual, cLess, cLessOrEq, cGreater, cGreaterOrEq,
cNot, cAnd, cOr,
cNotNot, /* Protects the double-not sequence from optimizations */
cDeg, cRad, /* Multiplication and division by 180 / pi */
cFCall, cPCall,
#ifdef FP_SUPPORT_OPTIMIZER
cFetch, /* Same as Dup, except with absolute index
* (next value is index) */
cPopNMov, /* cPopNMov(x,y) moves [y] to [x] and deletes anything
* above [x]. Used for disposing of temporaries.
*/
cLog2by, /* log2by(x,y) = log2(x) * y */
#endif
cAbsAnd, /* As cAnd, but assume both operands are absolute values */
cAbsOr, /* As cOr, but assume both operands are absolute values */
cAbsNot, /* As cAbsNot, but assume the operand is an absolute value */
cAbsNotNot, /* As cAbsNotNot, but assume the operand is an absolute value */
cAbsIf, /* As cAbsIf, but assume the 1st operand is an absolute value */
cDup, /* Duplicates the last value in the stack: Push [Stacktop] */
cInv, /* Inverts the last value in the stack (x = 1/x) */
cSqr, /* squares the last operand in the stack, no push/pop */
cRDiv, /* reverse division (not x/y, but y/x) */
cRSub, /* reverse subtraction (not x-y, but y-x) */
cRSqrt, /* inverse square-root (1/sqrt(x)) */
cNop,
VarBegin
};
#ifdef ONCE_FPARSER_H_
struct FuncDefinition
{
enum FunctionFlags
{
Enabled = 0x01,
AngleIn = 0x02,
AngleOut = 0x04,
OkForInt = 0x08
};
#ifdef FUNCTIONPARSER_SUPPORT_DEBUG_OUTPUT
const char name[8];
#else
struct name { } name;
#endif
unsigned params : 8;
unsigned flags : 8;
inline bool enabled() const { return flags != 0; }
inline bool okForInt() const { return (flags & OkForInt) != 0; }
};
#ifndef FP_DISABLE_EVAL
# define FP_EVAL_FUNCTION_ENABLED \
FuncDefinition::Enabled | FuncDefinition::OkForInt
#else
# define FP_EVAL_FUNCTION_ENABLED 0
#endif
#ifdef FUNCTIONPARSER_SUPPORT_DEBUG_OUTPUT
# define FP_FNAME(n) n
#else
# define FP_FNAME(n) {}
#endif
// This list must be in the same order as that in OPCODE enum,
// because the opcode value is used to index this array, and
// the pointer to array element is used for generating the opcode.
const FuncDefinition Functions[]=
{
/*cAbs */ { FP_FNAME("abs"), 1,
FuncDefinition::Enabled | FuncDefinition::OkForInt },
/*cAcos */ { FP_FNAME("acos"), 1,
FuncDefinition::Enabled | FuncDefinition::AngleOut },
/*cAcosh*/ { FP_FNAME("acosh"), 1,
FuncDefinition::Enabled | FuncDefinition::AngleOut },
/*cAsin */ { FP_FNAME("asin"), 1,
FuncDefinition::Enabled | FuncDefinition::AngleOut },
/*cAsinh*/ { FP_FNAME("asinh"), 1,
FuncDefinition::Enabled | FuncDefinition::AngleOut },
/*cAtan */ { FP_FNAME("atan"), 1,
FuncDefinition::Enabled | FuncDefinition::AngleOut },
/*cAtan2*/ { FP_FNAME("atan2"), 2,
FuncDefinition::Enabled | FuncDefinition::AngleOut },
/*cAtanh*/ { FP_FNAME("atanh"), 1, FuncDefinition::Enabled },
/*cCbrt */ { FP_FNAME("cbrt"), 1, FuncDefinition::Enabled },
/*cCeil */ { FP_FNAME("ceil"), 1, FuncDefinition::Enabled },
/*cCos */ { FP_FNAME("cos"), 1,
FuncDefinition::Enabled | FuncDefinition::AngleIn },
/*cCosh */ { FP_FNAME("cosh"), 1,
FuncDefinition::Enabled | FuncDefinition::AngleIn },
/*cCot */ { FP_FNAME("cot"), 1,
FuncDefinition::Enabled | FuncDefinition::AngleIn },
/*cCsc */ { FP_FNAME("csc"), 1,
FuncDefinition::Enabled | FuncDefinition::AngleIn },
/*cEval */ { FP_FNAME("eval"), 0, FP_EVAL_FUNCTION_ENABLED },
/*cExp */ { FP_FNAME("exp"), 1, FuncDefinition::Enabled },
/*cExp2 */ { FP_FNAME("exp2"), 1, FuncDefinition::Enabled },
/*cFloor*/ { FP_FNAME("floor"), 1, FuncDefinition::Enabled },
/*cIf */ { FP_FNAME("if"), 0,
FuncDefinition::Enabled | FuncDefinition::OkForInt },
/*cInt */ { FP_FNAME("int"), 1, FuncDefinition::Enabled },
/*cLog */ { FP_FNAME("log"), 1, FuncDefinition::Enabled },
/*cLog10*/ { FP_FNAME("log10"), 1, FuncDefinition::Enabled },
/*cLog2 */ { FP_FNAME("log2"), 1, FuncDefinition::Enabled },
/*cMax */ { FP_FNAME("max"), 2,
FuncDefinition::Enabled | FuncDefinition::OkForInt },
/*cMin */ { FP_FNAME("min"), 2,
FuncDefinition::Enabled | FuncDefinition::OkForInt },
/*cPow */ { FP_FNAME("pow"), 2, FuncDefinition::Enabled },
/*cSec */ { FP_FNAME("sec"), 1,
FuncDefinition::Enabled | FuncDefinition::AngleIn },
/*cSin */ { FP_FNAME("sin"), 1,
FuncDefinition::Enabled | FuncDefinition::AngleIn },
/*cSinh */ { FP_FNAME("sinh"), 1,
FuncDefinition::Enabled | FuncDefinition::AngleIn },
/*cSqrt */ { FP_FNAME("sqrt"), 1,
FuncDefinition::Enabled },
/*cTan */ { FP_FNAME("tan"), 1,
FuncDefinition::Enabled | FuncDefinition::AngleIn },
/*cTanh */ { FP_FNAME("tanh"), 1,
FuncDefinition::Enabled | FuncDefinition::AngleIn },
/*cTrunc*/ { FP_FNAME("trunc"), 1,
FuncDefinition::Enabled }
};
#undef FP_FNAME
struct NamePtr
{
const char* name;
unsigned nameLength;
NamePtr(const char* n, unsigned l): name(n), nameLength(l) {}
inline bool operator==(const NamePtr& rhs) const
{
return nameLength == rhs.nameLength
&& std::memcmp(name, rhs.name, nameLength) == 0;
}
inline bool operator<(const NamePtr& rhs) const
{
for(unsigned i = 0; i < nameLength; ++i)
{
if(i == rhs.nameLength) return false;
const char c1 = name[i], c2 = rhs.name[i];
if(c1 < c2) return true;
if(c2 < c1) return false;
}
return nameLength < rhs.nameLength;
}
};
template<typename Value_t>
struct NameData
{
enum DataType { CONSTANT, UNIT, FUNC_PTR, PARSER_PTR, VARIABLE };
DataType type;
unsigned index;
Value_t value;
NameData(DataType t, unsigned v) : type(t), index(v), value() { }
NameData(DataType t, Value_t v) : type(t), index(), value(v) { }
NameData() { }
};
template<typename Value_t>
class namePtrsType: public
std::map<
FUNCTIONPARSERTYPES::NamePtr,
FUNCTIONPARSERTYPES::NameData<Value_t>
>
{
};
const unsigned FUNC_AMOUNT = sizeof(Functions)/sizeof(Functions[0]);
#endif // ONCE_FPARSER_H_
}
#ifdef ONCE_FPARSER_H_
#include <vector>
template<typename Value_t>
struct FunctionParserBase<Value_t>::Data
{
unsigned referenceCounter;
unsigned numVariables;
std::string variablesString;
FUNCTIONPARSERTYPES::namePtrsType<Value_t> namePtrs;
struct FuncPtrData
{
union
{
FunctionPtr funcPtr;
FunctionParserBase<Value_t>* parserPtr;
};
unsigned params;
};
std::vector<FuncPtrData> FuncPtrs;
std::vector<FuncPtrData> FuncParsers;
std::vector<unsigned> ByteCode;
std::vector<Value_t> Immed;
#ifndef FP_USE_THREAD_SAFE_EVAL
std::vector<Value_t> Stack;
// Note: When Stack exists,
// Stack.size() and StackSize are mutually redundant.
#endif
unsigned StackSize;
Data();
Data(const Data&);
Data& operator=(const Data&); // not implemented on purpose
~Data();
};
#endif
#include "fpaux.h"
#endif

View File

@ -1,46 +0,0 @@
/**
* @file hash.h
* @author Thomas Lewiner
* @version
* @date
*
* @brief
*
*/
//________________________________________________
#ifndef _HASH_H_
#define _HASH_H_
// may be overridden by the preprocessor
#ifndef USE_HASH_PTR
# define USE_HASH_PTR 1
#endif // USE_HASH_PTR
// may be overridden by the preprocessor
#ifndef HASH_BITS
# define HASH_BITS 22
#endif // HASH_BITS
#ifndef NON_HASH_BITS
# define NON_HASH_BITS 22
#endif // HASH_BITS
#if USE_HASH_PTR
// #define HASH_HAS_ERASE 1
# include "hash_ptr.h"
#else // USE_HASH_PTR
# undef HASH_HAS_ERASE
# include "hash_noptr.h"
#endif // USE_HASH_PTR
#endif // _HASH_H_

View File

@ -1,251 +0,0 @@
/**
* @file hash_noptr.h
* @author Thomas Lewiner
* @version
* @date
*
* @brief Hash table without pointers
*
*/
//________________________________________________
#ifndef _HASH_H_
# error This header should not be included directly! include hash.h instead
#endif // _HASH_H_
#pragma once
#include <stdlib.h> // memset
#include "morton.h"
//_____________________________________________________________________________
// Class hash
template < typename Data > class Hash
//-----------------------------------------------------------------------------
{
public:
typedef uint cntr ;
// static const cntr HASH_BITS = 16 ;
// static const cntr NON_HASH_BITS = 64-HASH_BITS ;
static const cntr HASH_SIZE = ((cntr)1<<HASH_BITS) ;
static const cntr HASH_MASK = HASH_SIZE-1 ;
static const cntr SKIP_MINI = 11 ;
static const cntr SKIP_BITS = 3 ;
static const cntr SKIP_MASK = ((cntr)1<<SKIP_BITS)-1 ;
typedef struct { Key key ; Data data ; } KeyData ;
static KeyData KD_INV ;
protected:
// KeyData _hash[HASH_SIZE] ;
KeyData *_hash ; // allocate dynamically since stack memory is limited
public:
// Constructor & Desctructor
Hash () { _hash = new KeyData[HASH_SIZE] ; reset() ; }
~Hash () { delete [] _hash ; }
void reset() { memset( _hash, KEY_INV, HASH_SIZE*sizeof(KeyData) ) ; KD_INV.key = KEY_INV ; }
inline cntr hash( Key k ) const ;
cntr size() const
{
cntr s = 0 ;
cntr n = HASH_SIZE ;
KeyData *ptr = _hash ;
for( ; n > 0 ; --n, ++ptr )
s += ( ptr->key != KEY_INV ) ;
return s ;
}
bool insert( KeyData d )
{
cntr h = hash( d.key ) ;
KeyData *p = _hash + h ;
const cntr skip = ((d.key>>HASH_BITS) & SKIP_MASK) + SKIP_MINI ;
cntr overflow = skip ;
while( p->key != KEY_INV && p->key != d.key )
{ // collision
h += skip ;
if( h < HASH_SIZE )
p += skip ;
else
{
h &= HASH_MASK ;
p = _hash + h ;
if( !(overflow--) )
return false ;
}
}
*p = d ;
return true ;
}
const KeyData operator[] ( Key k ) const
{
cntr h = hash( k ) ;
const KeyData *p = _hash + h ;
const cntr skip = ((k>>HASH_BITS) & SKIP_MASK) + SKIP_MINI ;
cntr overflow = skip ;
while( p->key != k && p->key != KEY_INV )
{ // collision
h += skip ;
if( h < HASH_SIZE )
p += skip ;
else
{
h &= HASH_MASK ;
p = _hash + h ;
if( !(overflow--) )
return KD_INV ;
}
}
return *p ;
}
KeyData &operator[] ( Key k )
{
cntr h = hash( k ) ;
KeyData *p = _hash + h ;
const cntr skip = ((k>>HASH_BITS) & SKIP_MASK) + SKIP_MINI ;
cntr overflow = skip ;
while( p->key != k && p->key != KEY_INV )
{ // collision
h += skip ;
if( h < HASH_SIZE )
p += skip ;
else
{
h &= HASH_MASK ;
p = _hash + h ;
if( !(overflow--) )
return KD_INV ;
}
}
return *p ;
}
bool contains( Key k ) const { return (*this)[k].key == k ; }
//------------------------------------------------
// iterator
public :
/// iterator
class iterator
{
public :
// constructors
/// default constructors
iterator( Hash<Data> &hash_, cntr id_ = 0 ) : _ptr(hash_._hash+id_), _last(hash_._hash+HASH_SIZE) { while( _ptr != _last && _ptr->key == KEY_INV ) ++_ptr ; }
/// destructor
~iterator() {}
/// copy constructor
iterator( const iterator &it ) : _ptr(it._ptr), _last(it._last) {}
/// assignment operator
iterator &operator = ( const iterator &it )
{ _ptr = it._ptr; _last = it._last; return *this; }
//-----------------------------------------------------------------------------
// Operations
public :
/// equality operator
inline bool operator ==( const iterator &it ) const { return _ptr == it._ptr ; }
/// inequality operator
inline bool operator !=( const iterator &it ) const { return _ptr != it._ptr ; }
/// validation operator
inline bool operator ()() const { return _ptr != _last ; }
/// key accessor
inline const Key &key() const { return _ptr->key ; }
/// value accessor
inline const Data &operator * () const { return _ptr->data ; }
/// value accessor
inline Data &operator * () { return _ptr->data ; }
/// accesses the next position
inline iterator &operator ++() { while( (++_ptr != _last) && _ptr->key == KEY_INV ) ; return *this ; }
//-----------------------------------------------------------------------------
// Elements
private :
KeyData *_ptr ; ///< position pointer
const KeyData *_last ; ///< last position pointer
};
//------------------------------------------------
// const_iterator
public :
/// const_iterator
class const_iterator
{
public :
// constructors
/// default constructors
const_iterator( const Hash<Data> &hash_, cntr id_ = 0 ) : _ptr(hash_._hash+id_), _last(hash_._hash+HASH_SIZE) { while( _ptr != _last && _ptr->key == KEY_INV ) ++_ptr ; }
/// destructor
~const_iterator() {}
/// copy constructor
const_iterator( const const_iterator &it ) : _ptr(it._ptr), _last(it._last) {}
/// assignment operator
const_iterator &operator = ( const const_iterator &it )
{ _ptr = it._ptr; _last = it._last; return *this; }
//-----------------------------------------------------------------------------
// Operations
public :
/// equality operator
inline bool operator ==( const const_iterator &it ) const { return _ptr == it._ptr ; }
/// inequality operator
inline bool operator !=( const const_iterator &it ) const { return _ptr != it._ptr ; }
/// validation operator
inline bool operator ()() const { return _ptr != _last ; }
/// key accessor
inline const Key &key() const { return _ptr->key ; }
/// value accessor
inline const Data &operator * () const { return _ptr->data ; }
/// accesses the next position
inline const_iterator &operator ++() { while( (++_ptr != _last) && _ptr->key == KEY_INV ) ; return *this ; }
//-----------------------------------------------------------------------------
// Elements
private :
const KeyData * _ptr ; ///< position pointer
const KeyData * const _last ; ///< last position pointer
};
public :
/// Node iterator creation
iterator begin( cntr id = 0 ) { return iterator( *this, id ) ; }
/// Node const iterator creation
const_iterator cbegin( cntr id = 0 ) { return const_iterator( *this, id ) ; }
};
//_____________________________________________________________________________
/// hash function specification: no inversion
template <> inline Hash<real >::cntr Hash<real >::hash( Key k ) const { return k & HASH_MASK ; }
/// hash function specification: inversion
template <> inline Hash<Level>::cntr Hash<Level>::hash( Key k ) const { return (k>>NON_HASH_BITS) & HASH_MASK ; }

View File

@ -1,352 +0,0 @@
/**
* \file hash_octree.h
* \author Thomas Lewiner <tomlew@puc-rio.br>
* \author Matmidia Lab, Math Dept, PUC-Rio
* \date 10/01/2010
*
* Octree structure with hashtable and hierarchical operations
*/
//_____________________________________________________________________________
#pragma once
#ifndef WIN32
#pragma interface
#endif // WIN32
#include "mlist.h"
#include "cube.h"
#include "hash.h"
#include "MarchingCubes.h"
#include "mc_draw.h"
#include "data_access.h"
//_____________________________________________________________________________
// HashOctree
/// \class HashOctree HashOctree.h
class HashOctree
//-----------------------------------------------------------------------------
{
// forward declaration
public:
class geom_cell ;
class cell_iterator ;
class leaf_iterator ;
// Elements
protected:
/// Octree cell data structure
typedef Hash<real> HashField ;
/// Hashtable of the octree nodes
HashField _hash ;
/// Maximal level of the octree (for find_adjacent)
Level _max_level ;
/// Maximal field of the octree
real _max_field ;
/// Isosurface
MarchingCubes _mc ;
/// Isosurface Draw
MC_Draw _mc_draw ;
/// Dual run memory consumption
uint _dual_temp_memory ;
//-----------------------------------------------------------------------------
// Constructors
public:
/// Default constructor: Constructs a octree with and empty root
HashOctree() { init() ; }
/// Destructor: Free memory
~HashOctree() { clear() ; }
/// Create the root
void init() ;
/// Memory cleaning
void clear() { clear_octree() ; _mc.clean_all() ; }
/// Delete the content of the octree
void clear_octree() ;
/// Check that only the leaves have data
bool check () ;
/// Prints statistics about the octree
void stats() ;
/// Return the maximal level of the octree
Level max_level() const { return _max_level ; }
/// Return the maximal field of the octree
real max_field() const { return _max_field ; }
/// Return the isosurface
MarchingCubes &mc() { return _mc ; }
/// Return the isosurface draw
MC_Draw &mc_draw() { return _mc_draw ; }
/// set the values of each leaf from the implicit function
bool set_impl( data_access *ref = NULL ) ;
/// Refine the octree according to the data access
bool refine( data_access *ref = NULL ) ;
/// Adapt the octree according to the data access
bool adapt( data_access *ref = NULL ) ;
/// Draw the octree with wireframe
bool draw_wire() ;
/// Draw the octree with dots
bool draw_centers() ;
/// Dual function type
typedef bool hash_dual_walker( HashOctree &fo, Key *keys ) ;
/// Walk on the dual cubes
bool dual_cubes_walk( hash_dual_walker &walker ) ;
/// Build the isosurface using dual marching cubes
bool build_isosurface( data_access *ref = NULL ) ;
/// Draw the isosurface on-the-fly using dual marching cubes
bool direct_draw_isosurface( data_access *ref = NULL ) ;
/// Draw the dual octree with wireframe
bool draw_dual() ;
/// Do nothing, just for dual generation timing
bool dual_timing() ;
//-----------------------------------------------------------------------------
// iterators
public:
/// Create an iterator traversing the tree from the root
inline cell_iterator cells_begin() { return cell_iterator( *this ) ; }
/// Create an iterator traversing the leaves of the tree from the root
inline leaf_iterator leaves_begin() { return leaf_iterator( *this ) ; }
//-----------------------------------------------------------------------------
// search operations
public:
/// Find cells of the octree at a given position
bool find_leaf( real x, real y, real z, geom_cell &cell ) const ;
/// Find cells of the octree inside a given box of center x,y,z and half side r
bool find_radius( real x, real y, real z, real r, List<geom_cell> &cells ) const ;
/// Find adjacent cells of the octree to a given cell
bool adjacent( const geom_cell &cell, List<geom_cell> &cells ) const ;
/// Leaf test based on the field value
bool is_leaf( Key k ) const { return !is_inv( _hash[k].data ) ; }
//-----------------------------------------------------------------------------
// I/O
public:
/// Draws the intersecting cells of a plane with the octree with color
void draw_plane ( real nx, real ny, real nz, real d ) ;
/// Draws the intersection of a plane with the octree with color
void draw_slice ( real nx, real ny, real nz, real d, float alpha ) ;
/// Draws the isosurface of level l inside the dual graph
void draw_iso () { _mc.draw_surf() ; }
//_____________________________________________________________________________
// Iterator Cell
public :
/// Auxiliary structure to traverse the octree
class geom_cell : public Cube
//---------------------------------------------------------------------------
{
friend class HashOctree ;
protected:
Key _key ; ///< octree cell
real _field ; ///< field associated to the cell
//---------------------------------------------------------------------------
// Constructors
public:
/// Default constructor: Constructs an iterator from a cell
geom_cell( Key key_ = KEY_INV, real field_ = R_INV ) : Cube(key2cube(key_)), _key(key_), _field(field_) {}
/// Destructor
~geom_cell() {}
/// Copy constructor
geom_cell( const geom_cell &i ) : Cube(i), _key(i._key), _field(i._field) {}
/// Assignment operator
geom_cell &operator = ( const geom_cell &i )
{ Cube::operator=(i) ; _key = i._key ; _field = i._field ; return *this; }
//---------------------------------------------------------------------------
// Public constant accessors
public :
/// key const accessor
inline Key key() const { return _key ; }
/// key accessor
inline Key &key() { return _key ; }
/// id const accessor
inline real operator*() const { return _field ; }
//---------------------------------------------------------------------------
// Tests
public :
/// equality operator
inline bool operator ==( const geom_cell &i ) const { return key() == i.key() ; }
/// inequality operator
inline bool operator !=( const geom_cell &i ) const { return key() != i.key() ; }
/// leaf test
inline bool is_leaf() const { return !is_inv(*(*this)) ; }
/// validation operator
inline bool operator ()() const { return key() != KEY_INV ; }
//---------------------------------------------------------------------------
// Operations
public :
/// sons
inline bool sons( geom_cell *s /*[8]*/, const HashField &hash )
{
if( is_leaf() ) return false ;
Key k = _key << 3 ;
for( int i = 0 ; i < 8 ; ++i )
{
s[i]._key = k | i ;
s[i]._field = hash[k|i].data ;
(Cube&)s[i] = key2cube(s[i]._key) ;
}
return true ;
}
/// get son from side i
inline bool son( int i , geom_cell &s, const HashField &hash )
{
if( is_leaf() ) return false ;
s._key = (key() << 3) | i ;
s._field = hash[s._key].data ;
(Cube&)s = key2cube(s._key) ;
return true ;
}
};
const geom_cell geom_root() const { const Key root_key = 1 ; return geom_cell( root_key, _hash[root_key].data ) ; }
const geom_cell geom_key ( Key k ) const { return geom_cell( k, _hash[k].data ) ; }
//_____________________________________________________________________________
// Cell Iterator
public :
/// Octree cell iterator : Traverse the octree returning basic information on the cells
class cell_iterator
//---------------------------------------------------------------------------
{
friend class HashOctree ;
protected:
/// Octree traversal iterator
HashField::iterator _it ;
//---------------------------------------------------------------------------
// Constructors
public:
/// Default constructor : Constructs an iterator from a cell
cell_iterator( HashOctree &o ) : _it( o._hash.begin() ) {}
/// Destructor
~cell_iterator() {}
/// Copy constructor
cell_iterator( const cell_iterator &i ) : _it(i._it) {}
/// Assignment operator
cell_iterator &operator = ( const cell_iterator &i )
{ _it = i._it; return *this; }
//---------------------------------------------------------------------------
// Operations
public :
/// equality operator
inline bool operator ==( const cell_iterator &i ) const { return _it == i._it ; }
/// inequality operator
inline bool operator !=( const cell_iterator &i ) const { return _it != i._it ; }
/// validation operator
inline bool operator ()() const { return _it() ; }
/// next position
inline cell_iterator &operator ++() { ++_it ; return *this ; }
//---------------------------------------------------------------------------
// Accessors
public :
// cell accessor
inline geom_cell top() const { return geom_cell( key(), *_it ) ; }
/// id accessor
inline real &operator*() { return *_it ; }
/// level accessor
inline Level lv() { return key_level(_it.key()) ; }
/// size accessor
inline real sz() { return Cube(0,0,0,lv()).sz() ; }
/// key accessor
inline Key key() const { return _it.key() ; }
/// points accessor
inline bool is_leaf() const { return !is_inv(*_it) ; }
/// Draws the cell wire with opengl
void draw_wire () const { top().draw_wire () ; }
};
/// Octree leaf iterator : Traverse the octree returning basic information on the leaves
class leaf_iterator : public cell_iterator
//---------------------------------------------------------------------------
{
public :
leaf_iterator( HashOctree &o ) : cell_iterator( o )
{ if( (*this)() && !this->is_leaf() ) ++(*this) ; }
/// next position
inline leaf_iterator &operator ++()
{
cell_iterator &it = *this ;
do ++it ; while ( it() && !it.is_leaf() ) ;
return *this ;
}
} ;
} ;
//_____________________________________________________________________________

View File

@ -1,292 +0,0 @@
/**
* @file hash_ptr.h
* @author Thomas Lewiner
* @version
* @date
*
* @brief
*
*/
//________________________________________________
#ifndef _HASH_H_
# error This header should not be included directly! include hash.h instead
#endif // _HASH_H_
#pragma once
#define HASH_HAS_ERASE 1
#include <stdlib.h> // memset
#include <string.h>
#include <stdio.h> //printf
#include "mlist.h" // memset
#include "morton.h"
//_____________________________________________________________________________
// Class hash
template < typename Data > class Hash
//-----------------------------------------------------------------------------
{
public:
typedef uint cntr ;
// static const cntr HASH_BITS = 16 ;
// static const cntr NON_HASH_BITS = 64-HASH_BITS ;
static const cntr HASH_SIZE = ((cntr)1<<HASH_BITS) ;
static const cntr HASH_MASK = HASH_SIZE-1 ;
// Bucket associative data
typedef struct KeyData
{
Key key ;
Data data ;
/// comparison based on the key only
bool operator==( const struct KeyData& rhs) const { return key == rhs.key ; }
/// comparison based on the key only
bool operator!=( const struct KeyData& rhs) const { return key != rhs.key ; }
} KeyData ;
static KeyData KD_INV ;
class iterator ;
public:
typedef List<KeyData> KeyBucket ;
typedef typename KeyBucket::iterator keybucket_iterator ;
typedef typename KeyBucket::const_iterator keybucket_const_iterator ;
protected:
// KeyBucket _hash[HASH_SIZE] ;
KeyBucket *_hash ; // allocate dynamically since stack memory is limited
public:
// Constructor & Desctructor
Hash () { _hash = new KeyBucket[HASH_SIZE] ; }
~Hash () { delete [] _hash ; }
void reset()
{
cntr n = HASH_SIZE ;
KeyBucket *ptr = _hash ;
for( ; n > 0 ; --n, ++ptr )
{
(*ptr).clear() ;
}
KD_INV.key = KEY_INV ;
}
cntr size() const
{
cntr s = 0 ;
cntr n = HASH_SIZE ;
KeyBucket *ptr = _hash ;
for( ; n > 0 ; --n, ++ptr )
s += ptr->size() ;
return s ;
}
void stats() const
{
static const cntr MAX_COLLISION = 32 ;
cntr colls[MAX_COLLISION] ;
memset( colls, 0, MAX_COLLISION*sizeof(cntr) ) ;
KeyBucket *ptr = _hash ;
for( cntr n = HASH_SIZE ; n > 0 ; --n, ++ptr )
{
cntr s = ptr->size() ;
if( s >= MAX_COLLISION ) s = MAX_COLLISION-1 ;
++colls[s] ;
}
printf( "Hashtable collisions: [\t") ;
for( cntr n = 0 ; n < MAX_COLLISION ; ++n )
printf( "%d\t", colls[n] ) ;
printf( "\t]\n") ;
}
inline cntr hash( Key k ) const ;
bool insert( KeyData d )
{
cntr h = hash( d.key ) ;
KeyBucket &l = _hash[h] ;
return l.insert_unique( d ) ;
}
const KeyData operator[] ( Key k ) const
{
cntr h = hash( k ) ;
KeyData kd ; kd.key = k ;
keybucket_const_iterator it = _hash[h].cfind( kd ) ;
if( !it() ) return KD_INV ;
return *it ;
}
KeyData &operator[] ( Key k )
{
cntr h = hash( k ) ;
KeyData kd ; kd.key = k ;
keybucket_iterator it = _hash[h].find( kd ) ;
if( !it() ) return KD_INV ;
return *it ;
}
KeyData erase( Key k )
{
cntr h = hash( k ) ;
KeyData kd ; kd.key = k ;
if( _hash[h].remove( kd ) )
return kd ;
return KD_INV ;
}
bool contains( Key k ) const { return (*this)[k].key == k ; }
//------------------------------------------------
// iterators
public :
/// iterator
class iterator
{
public :
// constructors
/// default constructors
iterator( Hash<Data> &hash_, Key id_ = 0 ) : _ptr(hash_._hash+id_), _last(hash_._hash+HASH_SIZE)
{
while( _ptr != _last && _ptr->empty() )
++_ptr ;
if( _ptr != _last )
_l_it = _ptr->begin() ;
}
/// destructor
~iterator() {}
/// copy constructor
iterator( const iterator &it ) : _ptr(it._ptr), _last(it._last), _l_it(it._l_it) {}
/// assignment operator
iterator &operator = ( const iterator &it )
{ _ptr = it._ptr; _last = it._last; _l_it = it._l_it ; return *this; }
//-----------------------------------------------------------------------------
// Operations
public :
/// equality operator
inline bool operator ==( const iterator &it ) const { return _ptr == it._ptr && _l_it == it._l_it ; }
/// inequality operator
inline bool operator !=( const iterator &it ) const { return _ptr != it._ptr || _l_it != it._l_it ; }
/// validation operator
inline bool operator ()() const { return _ptr != _last ; }
/// key accessor
inline const Key &key() const { return (*_l_it).key ; }
/// value accessor
inline const Data &operator * () const { return (*_l_it).data ; }
/// value accessor
inline Data &operator * () { return (*_l_it).data ; }
/// accesses the next position
inline iterator &operator ++() {
if( !(++_l_it)() )
{
while( _ptr != _last && (*(++_ptr)).empty() ) ;
if( _ptr != _last )
_l_it = _ptr->begin() ;
}
return *this ;
}
//-----------------------------------------------------------------------------
// Elements
private :
KeyBucket *_ptr ; ///< position pointer
const KeyBucket *_last ; ///< last position pointer
keybucket_iterator _l_it ; ///< list iterator inside a bucket
};
//------------------------------------------------
// const_iterator
public :
/// const_iterator
class const_iterator
{
public :
// constructors
/// default constructors
const_iterator( Hash<Data> &hash_, Key id_ = 0 ) : _ptr(hash_._hash+id_), _last(hash_._hash+HASH_SIZE)
{
while( _ptr != _last && _ptr->empty() )
++_ptr ;
if( _ptr != _last )
_l_it = _ptr->cbegin() ;
}
/// destructor
~const_iterator() {}
/// copy constructor
const_iterator( const const_iterator &it ) : _ptr(it._ptr), _last(it._last), _l_it(it._l_it) {}
/// assignment operator
const_iterator &operator = ( const const_iterator &it )
{ _ptr = it._ptr; _last = it._last; _l_it = it._l_it ; return *this; }
//-----------------------------------------------------------------------------
// Operations
public :
/// equality operator
inline bool operator ==( const const_iterator &it ) const { return _ptr == it._ptr && _l_it == it._l_it ; ; }
/// inequality operator
inline bool operator !=( const const_iterator &it ) const { return _ptr != it._ptr || _l_it != it._l_it ; ; }
/// validation operator
inline bool operator ()() const { return _ptr != _last ; }
/// key accessor
inline const Key &key() const { return (*_l_it).key ; }
/// value accessor
inline const Data &operator * () const { return (*_l_it).data ; }
/// accesses the next position
inline const_iterator &operator ++() {
if( !(++_l_it)() )
{
while( _ptr != _last && (*(++_ptr)).empty() ) ;
if( _ptr != _last )
_l_it = _ptr->cbegin() ;
}
return *this ;
}
//-----------------------------------------------------------------------------
// Elements
private :
const KeyBucket * _ptr ; ///< position pointer
const KeyBucket * const _last ; ///< last position pointer
keybucket_const_iterator _l_it ; ///< list iterator inside a bucket
};
public :
/// Node iterator creation
iterator begin( cntr id = 0 ) { return iterator( *this, id ) ; }
/// Node const iterator creation
const_iterator cbegin( cntr id = 0 ) { return const_iterator( *this, id ) ; }
};
//_____________________________________________________________________________
/// hash function specification: no inversion
template <> inline Hash<real >::cntr Hash<real >::hash( Key k ) const { return k & HASH_MASK ; }
/// hash function specification: inversion
template <> inline Hash<Level>::cntr Hash<Level>::hash( Key k ) const { return (k>>NON_HASH_BITS) & HASH_MASK ; }

View File

@ -1,101 +0,0 @@
/**
* @file implfuns.h
* @author Thomas Lewiner
* @version
* @date
*
* @brief
*
*/
//________________________________________________
#pragma once
#define NFUNS 38
// implicit functions
const char *fun_list[NFUNS] =
{
"Type Formula" ,
"Sphere" ,
"Ellipsoid" ,
"Hyperboloid" ,
"Plane" ,
"Cubic" ,
"Cushin" ,
"Cassini" ,
"Tangle cube" ,
"Chair" ,
"Cyclide" ,
"2 Spheres" ,
"2 Torii" ,
"Heart" ,
"Smile" ,
"Spheres in" ,
"Spheres dif" ,
"Cross cap" ,
"Weird cube" ,
"Klein bottle" ,
"Steiner's roman" ,
"Hunt's surface" ,
"Cayley cubic" ,
"Clebsch cubic" ,
"Barth sextic" ,
"Barth decic" ,
"Steiner relative",
"Mitre" ,
"Glob tear" ,
"Piri tear" ,
"Gumdrop torus" ,
"Bretzel" ,
"Blob" ,
"Bifolia" ,
"Lemniscate" ,
"Planes" ,
"Cylinders" ,
"Torus" ,
} ;
// implicit functions
const char *fun_def [NFUNS] =
{
/* Type Formula */ "f(x,y,z)",
/* Sphere */ "4*x^2-4*x+2.51+4*y^2-4*y+4*z^2-4*z",
/* Ellipsoid */ "8*x^2-8*x+3.51+4*y^2-4*y+4*z^2-4*z",
/* Hyperboloid */ "8*x^2-8*x-.1-4*y^2+4*y-4*z^2+4*z",
/* Plane */ "x+y+z",
/* Cubic */ "16*y^2-16*y+10-64*x^3+96*x^2-44*x",
/* Cushin */ "112.5*z+81*y*z^2+51.75*x+119.25*y-135*y*z-38.8125+162*x^3-81*x^4+162*y^3+216*z^3-81*y^4-81*z^4-162*x*y-132.75*x^2-200.25*y^2-220.5*z^2+162*x*y^2+81*x*z-81*x*z^2-81*x^2*z-162*x^2*y^2-81*y^2*z^2+162*x^2*y+135*y^2*z+81*z^2*x^2",
/* Cassini */ "-167.6778*z-267.2672*y*z^2-167.6778*x-205.1322*y+267.2672*y*z+59.74405625-267.2672*x^3+133.6336*x^4-267.2672*y^3-267.2672*z^3+133.6336*y^4+133.6336*z^4+267.2672*x*y+301.3114*x^2+338.7658*y^2+301.3114*z^2-267.2672*x*y^2+267.2672*x*z-267.2672*x*z^2-267.2672*x^2*z+267.2672*x^2*y^2+267.2672*y^2*z^2-267.2672*x^2*y-267.2672*y^2*z+267.2672*z^2*x^2",
/* Tangle cube */ "-468*z-468*x-468*y+1296*y^4+1764*x^2+1764*y^2+1764*z^2+1296*z^4-2592*x^3+119.8-2592*y^3+1296*x^4-2592*z^3",
/* Chair */ "-18250*z-36000*y*z^2-2250*x-18250*y+52000*y*z+4626.5625-20000*x^3+10000*x^4-20000*y^3-4000*z^3+10000*y^4+2000*z^4-12000*x*y+12250*x^2+28250*y^2+20250*z^2+12000*x*y^2+20000*x*z-36000*x*z^2-20000*x^2*z-12000*x^2*y^2+36000*y^2*z^2+12000*x^2*y-52000*y^2*z+36000*z^2*x^2",
/* Cyclide */ "-11.23227514*x^2-6.0015984*x^4-6.0015984*y^4-6.0015984*z^4-13.56959251*z^2+12.0031968*y*z^2+12.0031968*z^3+6.027648307*x+7.256824512*y-13.25842291*y^2+12.0031968*y^3+12.0031968*x^2*z-9.79449408*x*y+9.79449408*x*y^2-9.79449408*x*z+9.79449408*x*z^2-12.0031968*x^2*y^2-12.0031968*y^2*z^2-12.0031968*z^2*x^2+7.567994112*z+12.0031968*y^2*z+12.0031968*x^2*y-12.0031968*y*z-2.289346823+9.79449408*x^3",
/* 2 Spheres */ "(40000*x^2-52400*x+48853+40000*y^2-52400*y+40000*z^2-52400*z)*(4000*x^2-2800*x+1207+4000*y^2-2800*y+4000*z^2-2800*z)",
/* 2 Torii */ "-6.929911075*x -6.559601218*z -40.61779736*z^3 +56.91300912*z^4 -17.17986918*y^7 +4.294967296*y^8 -55.95084095*z^5 +38.69346103*z^6 +38.69346103*x^6 +4.294967296*z^8 -17.17986918*x^7 +37.0828483*y^6 +4.294967296*x^8 -17.17986918*z^7 +20.40667127*z^2 -51.53960755*y^3*z^4 -89.2368375*x^4*y -41.69153918*x^3 +51.53960755*x*z^5 -51.11900275*y^5 -51.53960755*x^2*z^5 -51.53960755*y^5*z^2 +92.57432908*x^3*y +87.74249087*y^3*z -5.938337301*y +17.84876088*y^2 -35.13389168*y^3 +1.174097113 -51.53960755*y^2*z^5 +51.53960755*x^5*y -62.4313134*x*y^2 +50.14452444*y^4 +51.53960755*y^5*z -67.27041824*x^2*z -62.06100354*y*z^2 +114.4697704*y^2*z^4 +17.17986918*y^2*z^6 +88.81623269*y^3*x +112.8591576*y^4*z^2 +114.4697704*x^4*y^2 -87.08935385*y^4*z +25.76980378*y^4*z^4 +103.0792151*x^3*z^3 +103.0792151*y^3*z^3 -87.08935385*y^4*x +112.8591576*y^4*x^2 +90.42684543*y*z^3 +51.53960755*y*z^5 +116.0803831*x^2*z^4 +17.17986918*x^2*z^6 -146.2614203*x^3*z^2 +94.72181273*x^3*z +25.76980378*x^4*z^4 -51.53960755*x^4*z^3 -88.16309567*y*z^4 +25.43751542*y*z -90.31057932*x*z^4 -90.31057932*x^4*z +116.0803831*x^4*z^2 -139.2820984*y^3*z^2 -17.17986918*y^6*z -140.3558402*y^3*x^2 +17.17986918*x^6*z^2 +94.72181273*x*z^3 +17.17986918*y^6*z^2 -143.0401948*x^3*y^2 -17.17986918*x^6*z -17.17986918*x*z^6 -51.53960755*x^3*z^4 +51.53960755*x^5*z -51.53960755*x^5*z^2 +103.0792151*x^3*y^3 +17.17986918*x^6*y^2 -17.17986918*x^6*y +51.53960755*y^5*x -17.17986918*y*z^6 -51.53960755*y^5*x^2 -17.17986918*y^6*x +17.17986918*y^6*x^2 +25.76980378*x^4*y^4 -143.0401948*y^2*z^3 -146.2614203*x^2*z^3 +26.71500605*x*y +28.49944647*x*z -67.27041824*x*z^2 +125.3614762*x^2*y^2 +123.7508635*y^2*z^2 -60.82070066*y^2*z +131.8111938*z^2*x^2 +21.31385204*x^2 +51.53960755*y^4*z*x +103.0792151*y^2*z^3*x +51.53960755*y^2*z^2*x^4 -51.53960755*y^4*z^2*x +103.0792151*y^3*z^2*x -103.0792151*y^2*z^2*x^3 -51.53960755*x^4*y^2*z +103.0792151*x^2*z^3*y -51.53960755*x^2*z^4*y +103.0792151*x^3*y^2*z -51.53960755*y^2*z^4*x +51.53960755*y^4*z^2*x^2 -103.0792151*y^3*z^2*x^2 +51.53960755*y^2*z^4*x^2 -103.0792151*y^2*z^3*x^2 +51.53960755*x*z^4*y +51.53960755*x^4*y*z -51.53960755*y^4*z*x^2 -103.0792151*x^3*y*z -51.53960755*x^4*y*z^2 +103.0792151*x^3*y*z^2 -103.0792151*x*z^3*y -103.0792151*y^3*z*x +103.0792151*y^3*z*x^2 +125.8603256*y*z^2*x -177.3999332*x^2*y*z^2 -177.3999332*x^2*z*y^2 +125.8603256*y^2*z*x -177.3999332*x*y^2*z^2 +228.9395407*y^2*z^2*x^2 -74.32071807*y*z*x +125.8603256*y*z*x^2 -64.41223599*x^2*y -51.53960755*x^5*y^2 +57.44988003*x^4 -55.95084095*x^5 -51.53960755*x^4*y^3 -51.53960755*x^3*y^4 -51.53960755*y^4*z^3",
/* Heart */ "-697.347066*z-2684.277024*y*z^2-1347.168628*x-687.693448*y+926.747328*y^2*z^4+3706.989312*y^3*x+926.747328*y^4*z^2+3706.989312*x^4*y^2-926.747328*y^4*z-1853.494656*y^4*x+1853.494656*y^4*x^2+1972.308416*y*z^3+1853.494656*x^2*z^4-7413.978624*x^3*z^2+7413.978624*x^3*z-926.747328*y*z^4+1668.419376*y*z-1853.494656*x*z^4+7413.978624*x^3*y-3706.989312*x^4*z+3706.989312*x^4*z^2+1853.494656*y^3*z-1853.494656*y^3*z^2-3706.989312*y^3*x^2+3718.870688*x*z^3-7413.978624*x^3*y^2-3706.989312*x^4*y-1972.308416*y^2*z^3-3718.870688*x^2*z^3+195.187199+3706.989312*y*z^2*x-3706.989312*x^2*y*z^2-3706.989312*x^2*z*y^2+3706.989312*y^2*z*x-3706.989312*x*y^2*z^2+3706.989312*y^2*z^2*x^2-8788.562432*x^3+10572.59674*x^4-1888.224832*y^3-1920.898616*z^3+1716.401856*y^4+1716.401856*z^4-926.747328*z^5+308.915776*z^6-7413.978624*x^5+2471.326208*x^6-926.747328*y^5+308.915776*y^6+3158.618112*x*y+4505.78674*x^2+1477.347976*y^2+1511.506932*z^2-3706.989312*y*z*x-5012.112768*x*y^2+3706.989312*y*z*x^2+3167.529144*x*z-5029.934832*x*z^2-6874.518456*x^2*z+8719.10208*x^2*y^2+3611.024352*y^2*z^2-6865.607424*x^2*y-2595.166704*y^2*z+8736.924144*z^2*x^2",
/* Smile */ "-12348*z-435632*y^3-27216*y*z^2-17834.8125*x-35974.25*y-327680*y^7+733184*y^6-891648*y^4*x+11664*y*z^3+972*x^3*z+21168*y*z+2304*y^3*z+8748*x*z^3+46656*x^6*y^2-58320*x^6*y+5162.816406-1100160*y^3*x^2+11664*y*z^2*x+5184*y^2*z*x-72987.75*x^3+95610.375*x^4-20412*z^3+6561*z^4+65536*y^8-89667*x^5+60507*x^6-26244*x^7+6561*x^8+41910.1875*x^2+23814*z^2+712044*x^2*y^2-257499*x^2*y-18144*y*z*x+3888*y*z*x^2-311040*x^4*y^3+174960*x^5*y-139968*x^5*y^2+622080*x^3*y^3+552960*y^5*x-552960*y^5*x^2-147456*y^6*x+1016064*y^4*x^2+789888*y^3*x+340632*x^3*y-957440*y^5-315900*x^4*y-408060*x*y^2-248832*x^3*y^4+147456*y^6*x^2+124416*x^4*y^4-660960*x^3*y^2+155243*y^2+797792*y^4+447120*x^4*y^2+120591*x*y+15876*x*z-20412*x*z^2-6804*x^2*z+7776*y^2*z^2-12096*y^2*z+4374*z^2*x^2",
/* Spheres in */ "-(8*(4*x^2-4*x+3+4*y^2-4*y+4*z^2-4*z))*(-1+sqrt(4*x^2-4*x+3+4*y^2-4*y+4*z^2-4*z))",
/* Spheres dif */ "-496*z-4416*y*z^2-560*x-560*y+6912*y^2*z^4+1024*y^2*z^6+9728*y^3*x+7296*y^4*z^2+13056*x^4*y^2-7680*y^4*z-6144*x^4*y^3+1536*y^4*z^4+6144*x^3*z^3+6144*y^3*z^3-9984*y^4*x+13056*y^4*x^2+5760*y*z^3+3072*y*z^5-3072*x^2*z^5+6912*x^2*z^4+1024*x^2*z^6-9472*x^3*z^2+6144*x^5*y-6144*x^5*y^2+7680*x^3*z+1536*x^4*z^4-3072*x^4*z^3-5376*y*z^4-3072*y^3*z^4+4608*y^4*z*x+6144*y^2*z^3*x+3072*y^2*z^2*x^4-3072*y^4*z^2*x+6144*y^3*z^2*x-6144*y^2*z^2*x^3-4608*x^4*y^2*z+6144*x^2*z^3*y-3072*x^2*z^4*y+9216*x^3*y^2*z-3072*y^2*z^4*x+3072*y^4*z^2*x^2-6144*y^3*z^2*x^2+3072*y^2*z^4*x^2-6144*y^2*z^3*x^2+3072*x*z^4*y+4608*x^4*y*z-4608*y^4*z*x^2-9216*x^3*y*z-3072*x^4*y*z^2+6144*x^3*y*z^2-6144*x*z^3*y-9216*y^3*z*x+9216*y^3*z*x^2+2112*y*z-5376*x*z^4+9728*x^3*y-7680*x^4*z+7296*x^4*z^2+7680*y^3*z-9472*y^3*z^2-1536*y^6*z-15872*y^3*x^2+1024*x^6*z^2+5760*x*z^3+1024*y^6*z^2-3072*y^4*z^3-15872*x^3*y^2-1536*x^6*z+3072*x*z^5-1024*x*z^6-3072*x^3*z^4+4608*x^5*z-3072*x^5*z^2+12288*x^3*y^3+2048*x^6*y^2-2048*x^6*y+6144*y^5*x-1024*y*z^6-6144*y^5*x^2+4608*y^5*z-3072*y^5*z^2-9984*x^4*y-2048*y^6*x-6144*x^3*y^4+2048*y^6*x^2+3072*x^4*y^4-8832*y^2*z^3-8832*x^2*z^3-3072*y^2*z^5+96+8448*y*z^2*x-11520*x^2*y*z^2-15360*x^2*z*y^2+10752*y^2*z*x-11520*x*y^2*z^2+14592*y^2*z^2*x^2-3776*x^3+5600*x^4-3776*y^3-2560*z^3+5600*y^4+3440*z^4-2048*y^7+512*y^8-3328*z^5+2304*z^6-5888*x^5+4352*x^6-5888*y^5+256*z^8-2048*x^7+4352*y^6+512*x^8-1024*z^7+2496*x*y+1808*x^2+1808*y^2+1392*z^2-6144*y*z*x-6336*x*y^2+10752*y*z*x^2+2112*x*z-4416*x*z^2-5184*x^2*z+13248*x^2*y^2+8640*y^2*z^2-6336*x^2*y-5184*y^2*z+8640*z^2*x^2",
/* Cross cap */ ".4*sqrt(100*x-10)*x^2-0.08*sqrt(100*x-10)*x+0.008*sqrt(100*x-10)+.4*sqrt(100*x-10)*y^2-0.08*sqrt(100*x-10)*y+1.6*sqrt(100*x-10)*z^2-.8*sqrt(100*x-10)*z+.1*sqrt(100*y-10)*y^2-0.02*sqrt(100*y-10)*y+0.001*sqrt(100*y-10)+.4*sqrt(100*y-10)*z^2-.4*sqrt(100*y-10)*z",
/* Weird cube */ "59136*z-10240*y^3-10240*x^3+59136*x+59136*y+204800*z^2*x^2+204800*y^2*z^2-23232+204800*x^2*y^2-102400*x^2*y-102400*x^2*z-297216*x*z+128000*z^2-512000*y*z*x^2+128000*x^2+1566720*y*z*x-102400*x*z^2-512000*y*z^2*x-512000*y^2*z*x-102400*z^3-297216*y*z+102400*y^3*x-102400*y*z^2+102400*x^3*z+102400*x^3*y-102400*x*y^2+128000*y^2+102400*y*z^3-297216*x*y+102400*y^3*z-102400*y^2*z+102400*x*z^3",
/* Klein bottle */ "-244615.68*y^3-304335.36*x^3-96138.60864*y-786432*z^5-453427.2*y^3*z^2+1139015.68*z^4-139968*y^4*x-255052.8*y^3*x^2+248832*x^4*z^2-248832*x^4*z+33252.70426+46656*x^6+46656*y^6+1051729.92*y^2*z^2+493102.08*x^2*y^2+442368*x^2*z^4-497664*x^3*z^2-403046.4*y*z^4-442368*x*z^4-344176.128*x^2*y-705392.64*x^2*z+497664*y^2*z^2*x^2+480030.72*x*z-484761.6*y*z*x+555332.4032*z^2+453427.2*y*z*x^2+243162.3168*x^2-931184.64*x*z^2+453427.2*y*z^2*x+525312*y^2*z*x-991887.36*z^3+392220.672*y*z+255052.8*y^3*x-779599.872*y*z^2+525312*x^3*z+255052.8*x^3*y-127526.4*y^5-127526.4*x^4*y-366958.08*x*y^2-497664*x*y^2*z^2+262144*z^6-497664*x^2*z*y^2-453427.2*x^2*y*z^2+1106288.64*z^2*x^2-139968*x^5-279936*x^3*y^2-884736*x^2*z^3-120681.6768*x+196337.664*y^2-191443.7632*z+231206.4*y^4+261895.68*x^4-884736*y^2*z^3+806092.8*y*z^3+442368*y^2*z^4+248832*y^4*z^2+139968*x^4*y^2-248832*y^4*z+139968*y^4*x^2+232316.928*x*y+453427.2*y^3*z-623185.92*y^2*z+933888*x*z^3",
/* Steiner's roman */ "0.03125*y^2+.125*y*z*x-0.00390625-0.0625*y^2*z-0.0625*y*z^2+0.03125*z^2-0.0625*x^2*z+0.03125*x^2+0.0625*x^2*y^2+0.0625*z^2*x^2+0.0625*y^2*z^2-0.0625*x^2*y-0.0625*x*y^2-0.0625*x*z^2",
/* Hunt's surface */ "-321408*y-559872*z^5+1446336*z^4+933120*z^2*x^2-1990656*y^2*z^3+559872*x^4*z^2+1990656*y*z^2*x-559872*x^4*z-1990656*x^3*y^2-3538944*y^3*x^2+1119744*x*z^3-3538944*y^3*z^2-1959552*z^3-1469664*x^3+37719-1119744*x^3*z^2+1119744*x^3*z-1658880*y*z^2-1769472*y^4*z+1990656*y*z^3+1990656*x^3*y+3538944*y^3*z+3428352*y^2*z^2+1534464*x*y+186624*x^6+559872*x^2*z^4-995328*y*z^4-559872*x*z^4-373248*x^2*z-186624*x*z-3334144*y^3+4288512*y^4+1201392*x^4+1990656*y^2*z*x-1990656*x*y^2*z^2+3538944*y^3*x+1769472*y^4*z^2+1769472*y^4*x^2-1769472*y^4*x+1990656*y*z*x^2+802872*x^2-1990656*y*z*x-3303936*x*y^2-2433024*y^2*z-373248*x*z^2+663552*y*z-995328*x^4*y+4299264*x^2*y^2+1990656*y^2*z^2*x^2+186624*z^6-559872*x^5-3145728*y^5+1048576*y^6-2529792*x^2*y-161352*x-229392*z-1990656*x^2*y*z^2-1990656*x^2*z*y^2+1115856*z^2+995328*y^2*z^4+995328*x^4*y^2-1119744*x^2*z^3+1464192*y^2",
/* Cayley cubic */ "264-512*z-512*x-512*y+320*y^2-320*x^2*y-320*x^2*z-320*x*y^2+672*x*y-320*x*z^2+672*x*z-320*y^2*z-320*y*z^2+672*y*z+320*z^2+320*x^2",
/* Clebsch cubic */ "8154-15300*z-15300*x-15300*y+4176*y^2+4176*z^2+24480*x*y+24480*y*z+5184*x^3-12096*x*y^2-12096*y^2*z-12096*x*z^2-12096*y*z^2+24480*x*z-12096*x^2*y-12096*x^2*z+4176*x^2+3456*y*z*x+5184*z^3+5184*y^3",
/* Barth sextic */ "-2846.637681*z-75426.87093*y*z^2-2846.637681*x-2846.637681*y+224595.2132*y^3*z^2+42893.86887*y^2*z^4+85787.73774*y^3*x-42893.86887*y^4*x+42893.86887*y^4*x^2+85787.73774*y*z^3-85787.73774*x^3*z^2+85787.73774*x^3*z-42893.86887*y*z^4+32533.00206*y*z-42893.86887*x^4*z+42893.86887*x^4*z^2-85787.73774*y^3*x^2-85787.73774*y^2*z^3+571.8691769+36870.73567*x^3-18435.36784*x^4+36870.73567*y^3+36870.73567*z^3-18435.36784*y^4-18435.36784*z^4+32533.00206*x*y-15588.73016*x^2-15588.73016*y^2-15588.73016*z^2-112297.6066*x^2*z^4+112297.6066*x*z^4+277614.9509*y^2*z^2*x^2-75426.87093*x*y^2-277614.9509*y*z*x+277614.9509*y*z*x^2+277614.9509*y*z^2*x+277614.9509*y^2*z*x-224595.2132*x^3*y+112297.6066*x^4*y-277614.9509*x*y^2*z^2-277614.9509*x^2*z*y^2-277614.9509*x^2*y*z^2+224595.2132*x^3*y^2+224595.2132*x^2*z^3-112297.6066*y^4*z^2-112297.6066*x^4*y^2+112297.6066*y^4*z+32533.00206*x*z+79764.60454*x*z^2-75426.87093*x^2*z-36870.73567*x^2*y^2-36870.73567*y^2*z^2-224595.2132*y^3*z-224595.2132*x*z^3+79764.60454*x^2*y+79764.60454*y^2*z-36870.73567*z^2*x^2",
/* Barth decic */ "25.33143961*y^2*z^2*x^4 +25.15700632*y^4*z^2*x -34.82908387*y^2*z^4 +8.917960033*y^4*z^2 +0.04360832264*y^4*z^4 +16.49570037*y^4*z +8.917960033*x^4*y^2 -42.37063678*x^4*y^3 -34.82908387*y^4*x^2 +2.299854983*y^7*z^2 +25.37005208*x^4*y^5 +33.65896395*x^6*y^2*z -100.9768918*x^3*y^2*z^4 +1.198101193*x^3 +246.5161156*y^2*z^2*x^2 +25.36672152*x^3*y^4 +6.515326172*y^6*x^2 +44.38789864*y^2*z*x +6.273208191*y^5*z^2 +0.05111641659 +201.9537837*x^2*z^3*y^3 -8.109285345*x^3*z^2 +117.9808071*y^2*z^3*x +0.8487421525*x^8 -8.109285345*y^3*x^2 +6.515326172*x^6*z^2 +33.83339724*x^3*y^3 +50.48844592*x^4*y^2*z^4 -33.65896395*y^6*z*x +100.9768918*x^5*y*z +6.273208191*x^2*z^5 +100.9768918*x^4*y^3*z -201.9537837*x^3*y*z^3 -4.774233544*x^2*z^6 -21.54557109*x^5*y -3.716625642*x^3*z +6.273208191*x^5*y^2 +0.04360832264*x^4*z^4 -100.9768918*x^2*z^3*y^4 +33.65896395*y^2*z^6*x +16.49570037*x*z^4 +16.49570037*x^4*y -120.2077842*x^2*y*z^2 +9.865021177*x*z^6 -42.37063678*x^3*z^4 -3.39496861*x^7 -15.2723629*x^4*z^5 -2.299854983*x*z^7 +25.15700632*x^2*z^4*y +117.9808071*x^3*y^2*z +25.15700632*y^2*z^4*x +50.48844592*x^2*z^4*y^4 -25.60810291*x^3*y^2 -14.9720102*x^6*z -100.9768918*x^5*y^2*z -100.9768918*x^2*z^4*y^3 +6.515326172*y^2*z^6 -3.716625642*y^3*x -5.046246117*y*z^2 -100.9768918*x^4*y^3*z^2 -50.48844592*y^4*z^4*x +100.9768918*x^3*y^4*z +2.299854983*x^7*y^2 -3.940860141*y^8*x +5.090787632*y^6*z^4 -15.2723629*x^5*y^4 +0.8487421525*y^8 +2.299854983*x^2*z^7 -0.5749637458*x^2*z^8 -75.64545224*y^4*z*x -100.9768918*y^5*z*x^2 -50.48844592*x^4*y*z^4 +25.33143961*y^4*z^2*x^2 +1.198101193*z^3 +100.9768918*y^5*z*x +0.9611245006*y^5 -120.2077842*x^2*z*y^2 +3.940860141*y^2*z^8 -10.18157526*x^6*y^3 -8.456684027*x^4*y^6 +201.9537837*x^3*y^2*z^3 -100.9768918*x^2*z^5*y +19.60032929*y*z^4 -15.76344056*x^7*z^2 -3.940860141*x^8*z +0.2347202588*x^3*y +19.60032929*x^4*z +9.865021177*y^6*z -19.05645904*y*z*x -10.25601137*x^5*z +9.865021177*x^6*y +0.4659238756*x^2 -0.3389589536*x -0.3389589536*y +1.198101193*y^3 -3.380386036*y^4 -3.380386036*x^4 -8.109285345*y^2*z^3 -25.60810291*x^2*z^3 -4.774233544*x^6*y^2 +117.9808071*y^3*z^2*x -218.9576989*y^2*z^2*x^3 +25.15700632*x^4*y^2*z +117.9808071*x^2*z^3*y +100.9768918*x^2*z^5*y^2 +33.65896395*y^6*z*x^2 -33.65896395*x^6*y*z +100.9768918*y^4*z^3*x -50.48844592*x^4*y^4*z -50.74010416*x^3*y^5 -3.39496861*y^7 -5.892963096*x*z^2 -5.046246117*x^2*z -100.9768918*y^5*z^2*x -100.9768918*y^2*z^5*x -21.54557109*y^5*z +0.9611245006*z^5 +18.5125231*z^2*x^2 +25.15700632*x^4*y*z^2 -17.00391526*x^3*y*z -33.65896395*x*z^6*y +100.9768918*y^3*z^4*x +5.090787632*x^4*z^6 -34.82908387*x^4*z^2 +2.567983615*x*z +100.9768918*x^3*y*z^4 +3.940860141*x^8*z^2 -8.456684027*x^6*z^4 +16.91336805*y^3*z^6 +30.54472579*y^5*z^3 -15.76344056*y^7*x^2 +15.76344056*y^7*x +30.54472579*x^3*z^5 +25.37005208*x^5*z^4 +25.37005208*y^4*z^5 -10.18157526*y^6*z^3 +33.65896395*x^2*z^6*y -100.9768918*x^4*y^2*z^3 -15.2723629*y^5*z^4 -50.74010416*y^3*z^5 -100.9768918*x^3*y^4*z^2 +50.48844592*x^4*y^4*z^2 -201.9537837*x^3*y^3*z +0.5749637458*y^8*z -0.5749637458*y^8*z^2 +35.62606345*y^5*x^2 -100.9768918*x^5*y*z^2 +3.640421878*z^6 +0.9611245006*x^5 -21.54557109*x*z^5 +0.4659238756*y^2 -33.65896395*x^6*y^2*z^2 -33.65896395*y^6*z^2*x^2 +0.5749637458*x^8*y -0.5749637458*x^8*y^2 +0.2347202588*x*z^3 +3.640421878*x^6 +25.36672152*x^4*z^3 +25.36672152*y^3*z^4 +0.4659238756*z^2 -0.3389589536*z -120.2077842*x*y^2*z^2 +100.9768918*x*z^5*y +30.54472579*x^5*y^3 +16.91336805*x^6*z^3 -33.65896395*x^2*z^6*y^2 +33.65896395*x^6*y*z^2 +201.9537837*x^3*y^3*z^2 +2.567983615*x*y +18.5125231*x^2*y^2 -15.76344056*y^2*z^7 +5.090787632*x^6*y^4 -3.940860141*y*z^8 +100.9768918*y^5*z^2*x^2 +0.04360832264*x^4*y^4 +35.62606345*x^5*z^2 +117.9808071*x^3*y*z^2 -17.00391526*x*z^3*y +35.62606345*y^2*z^5 -4.774233544*y^6*z^2 -42.37063678*y^4*z^3 +0.5749637458*x*z^8 +3.940860141*y^8*x^2 -2.299854983*x^7*y -3.380386036*z^4 +0.2347202588*y^3*z -25.60810291*y^3*z^2 +16.91336805*x^3*y^6 +3.640421878*y^6 +33.83339724*x^3*z^3 +33.83339724*y^3*z^3 +19.60032929*y^4*x +8.917960033*x^2*z^4 -10.25601137*y*z^5 -3.716625642*y*z^3 -5.892963096*y^2*z -5.892963096*x^2*y +33.65896395*y^6*z^2*x +100.9768918*x^5*y^2*z^2 +44.38789864*y*z*x^2 +44.38789864*y*z^2*x -3.39496861*z^7 -10.18157526*x^3*z^6 +100.9768918*x^4*y*z^3 -5.046246117*x*y^2 -10.25601137*y^5*x -14.9720102*y*z^6 +15.76344056*y*z^7 +0.8487421525*z^8 -75.64545224*x*z^4*y -75.64545224*x^4*y*z +25.15700632*y^4*z*x^2 +18.5125231*y^2*z^2 -14.9720102*y^6*x -8.456684027*y^4*z^6 +2.567983615*y*z +15.76344056*x^7*z -218.9576989*y^3*z^2*x^2 +25.33143961*y^2*z^4*x^2 -218.9576989*y^2*z^3*x^2 -17.00391526*y^3*z*x +117.9808071*y^3*z*x^2 -201.9537837*y^3*z^3*x -50.74010416*x^5*z^3 -2.299854983*y^7*z",
/* Steiner relative */ "2-8*y*z*x-2*z-2*x-10*y+8*y^2-16*x*y^2-16*x^2*y+16*x^2*y^2+20*x*y-16*z^2*x^2+16*x^2*z+16*x*z^2+20*y*z-16*y*z^2-16*y^2*z+16*y^2*z^2-12*x*z",
/* Mitre */ "4-8*z-16*x-12*y+28*y^2-16*x*y^2-16*x^2*y+16*x^2*y^2+16*x*y+16*z^2*x^2-16*x^2*z-16*x*z^2+16*y*z-16*y*z^2-16*y^2*z+16*y^2*z^2+16*x*z+8*z^2+16*y^4+16*x^4-32*x^3+32*x^2-32*y^3",
/* Glob tear */ "16*x^5-32*x^4+24*x^3-8*x^2+x-2-4*y^2+4*y-4*z^2+4*z",
/* Piri tear */ "x^4-1*x^3+y^2-1*y+.5+z^2-1*z",
/* Gumdrop torus */ "-1792*z-2048*y*z^2-2368*x-1792*y+2048*y*z-2048*x^3+1024*x^4-2048*y^3-2048*z^3+1024*y^4+1024*z^4+4352*x*y+3392*x^2+2816*y^2+2816*z^2+641-4352*x*y^2+4352*x*z-4352*x*z^2-4352*x^2*z+4352*x^2*y^2+2048*y^2*z^2-4352*x^2*y-2048*y^2*z+4352*z^2*x^2",
/* Bretzel */ "-1*z-4.5*x-2.53125*y+7.59375*y^2-18*x*y^2+18*x*y+72*x^4*y^2-72*x^4*y-144*x^3*y^2+144*x^3*y+z^2+5.0625*y^4+674*x^4+.55640625-196*x^3+38.5*x^2-1408*x^5+256*x^8-1024*x^7+1664*x^6+90*x^2*y^2-90*x^2*y-10.125*y^3",
/* Blob */ "9*x^2-8.1*x+4.895+9*y^2-8.1*y+9*z^2-9*z+sin(12*x-5.4)+sin(12*y-5.4)+sin(12*z-6)",
/* Bifolia */ "4-16*z-16*x+4*y^2+8*x^2*y^2+32*z^2*x^2-32*x^2*z-8*x*y^2-32*x*z^2+32*x*z+8*y^2*z^2-8*y^2*z+32*z^2+y^4+16*z^4+16*x^4-32*x^3+32*x^2-32*z^3-12*x^2*y+12*x*y-6*y-12*y*z^2+12*y*z",
/* Lemniscate */ "16*x^4-32*x^3+20*x^2-4*x+2+4*y^2-4*y+4*z^2-4*z",
/* Planes */ "x*y",
/* Cylinders */ "((4*x-2)^2+(4*y-2)^2)^4+((4*x-2)^2+(4*z-2)^2)^4-((4*x-2)^2+(4*y-2)^2)^4*((4*x-2)^2+(4*z-2)^2)^4",
/* Torus */ "(1.4-sqrt((6*x-3)^2+(6*y-3)^2))^2+(6*z-3)^2-1.44"
} ;

View File

@ -1,332 +0,0 @@
/**
* \file leaf_octree.h
* \author Thomas Lewiner <tomlew@puc-rio.br>
* \author Matmidia Lab, Math Dept, PUC-Rio
* \date 10/01/2010
*
* Octree structure without intermediate nodes, hashtable and optimized operations
*/
//_____________________________________________________________________________
#pragma once
#ifndef WIN32
#pragma interface
#endif // WIN32
#include "mlist.h"
#include "cube.h"
#include "hash.h"
#include "MarchingCubes.h"
#include "mc_draw.h"
#include "data_access.h"
#ifdef HASH_HAS_ERASE
//_____________________________________________________________________________
// LeafOctree
/// \class LeafOctree LeafOctree.h
class LeafOctree
//-----------------------------------------------------------------------------
{
// forward declaration
public:
class geom_cell ;
class leaf_iterator ;
// Elements
protected:
/// Octree cell data structure
typedef Hash<real> HashField ;
/// Hashtable of the octree nodes
HashField _hash ;
/// Level distribution of the octree
uint _level_dist[MAX_LEVEL+1] ;
/// Optimal level for direct search in the octree
Level _opt_level ;
/// Maximal field of the octree
real _max_field ;
/// Isosurface
MarchingCubes _mc ;
/// Isosurface Draw
MC_Draw _mc_draw ;
private:
/// Octree vertices data structure
typedef Hash<Level> HashVerts ;
/// Hashtable of the octree vertices
HashVerts _verts ;
//-----------------------------------------------------------------------------
// Constructors
public:
/// Default constructor: Constructs a octree with and empty root
LeafOctree() { init() ; }
/// Destructor: Free memory
~LeafOctree() { clear() ; }
/// Create the root
void init() ;
/// Memory cleaning
void clear() { clear_octree() ; _mc.clean_all() ; }
/// Delete the content of the octree
void clear_octree() ;
/// Compute the optimal level
void compute_opt_level() ;
/// Check that only the leaves have data
bool check () ;
/// Prints statistics about the octree
void stats() const ;
/// Return the maximal level of the octree
Level max_level() const { Level lv = MAX_LEVEL ; while( lv > 0 && !_level_dist[lv] ) --lv ; return lv ; }
/// Return the optimal level of the octree
Level opt_level() const { return _opt_level ; }
/// Return the optimal level of the octree
Level &opt_level() { return _opt_level ; }
/// Return the maximal field of the octree
real max_field() const { return _max_field ; }
/// Return the isosurface
MarchingCubes &mc() { return _mc ; }
/// Return the isosurface draw
MC_Draw &mc_draw() { return _mc_draw ; }
/// set the values of each leaf from the implicit function
bool set_impl( data_access *ref = NULL ) ;
/// Refine the octree according to the data access
bool refine( data_access *ref = NULL ) ;
/// Adapt the octree according to the data access
bool adapt( data_access *ref = NULL ) ;
/// Draw the octree with wireframe
bool draw_wire() ;
/// Draw the octree with dots
bool draw_centers() ;
/// Dual function type
typedef bool leaf_dual_walker( LeafOctree &fo, Key *keys ) ;
/// Compute primal vertices
bool compute_primal_verts() ;
/// Walk on the dual cubes
bool dual_cubes_walk( leaf_dual_walker &walker ) ;
/// Build the isosurface using dual marching cubes
bool build_isosurface( data_access *ref = NULL ) ;
/// Draw the isosurface on-the-fly using dual marching cubes
bool direct_draw_isosurface( data_access *ref = NULL ) ;
/// Draw the dual octree with wireframe
bool draw_dual() ;
/// Do nothing, just for dual generation timing
bool dual_timing() ;
//-----------------------------------------------------------------------------
// iterators
public:
/// Create an iterator traversing the leaves of the tree from the root
inline leaf_iterator leaves_begin() { return leaf_iterator( *this ) ; }
//-----------------------------------------------------------------------------
// search operations
public:
/// Find cells of the octree at a given position
bool find_leaf( Key k, Level o_lv, geom_cell &cell ) const ;
bool find_leaf( Key k, geom_cell &cell ) const { return find_leaf( k, opt_level(), cell ) ; }
bool find_leaf( real x, real y, real z, geom_cell &cell ) const { return find_leaf( cube2key( Cube(x,y,z,MAX_LEVEL) ), opt_level(), cell ) ; }
/// Find cells of the octree inside a given box of center x,y,z and half side r
bool find_radius( real x, real y, real z, real r, List<geom_cell> &cells ) const ;
/// Find adjacent cells of the octree to a given cell
bool adjacent( Key k, List<geom_cell> &cells ) const ;
bool adjacent( const geom_cell &cell, List<geom_cell> &cells ) const { return adjacent( cell.key(), cells ) ; }
/// Node existence
bool node_exists( Key k, HashField::KeyData &kd ) const { kd = _hash[k] ; return kd.key != KEY_INV ; }
//-----------------------------------------------------------------------------
// I/O
public:
/// Draws the intersecting cells of a plane with the octree with color
void draw_plane ( real nx, real ny, real nz, real d ) ;
/// Draws the intersection of a plane with the octree with color
void draw_slice ( real nx, real ny, real nz, real d, float alpha ) ;
/// Draws the isosurface of level l inside the dual graph
void draw_iso () { _mc.draw_surf() ; }
//_____________________________________________________________________________
// Iterator Cell
public :
/// Auxiliary structure to traverse the octree
class geom_cell : public Cube
//---------------------------------------------------------------------------
{
friend class LeafOctree ;
protected:
Key _key ; ///< octree cell
real _field ; ///< field associated to the cell
//---------------------------------------------------------------------------
// Constructors
public:
/// Default constructor
geom_cell( Key key_ = KEY_INV, real field_ = R_INV ) : Cube(key2cube(key_)), _key(key_), _field(field_) {}
/// Default constructor
geom_cell( HashField::KeyData kd ) : Cube(key2cube(kd.key)), _key(kd.key), _field(kd.data) {}
/// Destructor
~geom_cell() {}
/// Copy constructor
geom_cell( const geom_cell &i ) : Cube(i), _key(i._key), _field(i._field) {}
/// Assignment operator
geom_cell &operator = ( const geom_cell &i )
{ Cube::operator=(i) ; _key = i._key ; _field = i._field ; return *this; }
//---------------------------------------------------------------------------
// Public constant accessors
public :
/// key const accessor
inline Key key() const { return _key ; }
/// key accessor
inline Key &key() { return _key ; }
/// id const accessor
inline real operator*() const { return _field ; }
//---------------------------------------------------------------------------
// Tests
public :
/// equality operator
inline bool operator ==( const geom_cell &i ) const { return key() == i.key() ; }
/// inequality operator
inline bool operator !=( const geom_cell &i ) const { return key() != i.key() ; }
/// validation operator
inline bool operator ()() const { return key() != KEY_INV ; }
};
const geom_cell geom_root() const { const Key root_key = 1 ; return geom_cell( root_key, _hash[root_key].data ) ; }
const geom_cell geom_key ( Key k ) const { return geom_cell( k, _hash[k].data ) ; }
//_____________________________________________________________________________
// Cell Iterator
public :
/// Octree cell iterator : Traverse the octree returning basic information on the cells
class leaf_iterator
//---------------------------------------------------------------------------
{
friend class LeafOctree ;
protected:
/// Octree traversal iterator
HashField::iterator _it ;
//---------------------------------------------------------------------------
// Constructors
public:
/// Default constructor : Constructs an iterator from a cell
leaf_iterator( LeafOctree &o ) : _it( o._hash.begin() ) {}
/// Destructor
~leaf_iterator() {}
/// Copy constructor
leaf_iterator( const leaf_iterator &i ) : _it(i._it) {}
/// Assignment operator
leaf_iterator &operator = ( const leaf_iterator &i )
{ _it = i._it; return *this; }
//---------------------------------------------------------------------------
// Operations
public :
/// equality operator
inline bool operator ==( const leaf_iterator &i ) const { return _it == i._it ; }
/// inequality operator
inline bool operator !=( const leaf_iterator &i ) const { return _it != i._it ; }
/// validation operator
inline bool operator ()() const { return _it() ; }
/// next position
inline leaf_iterator &operator ++() { ++_it ; return *this ; }
//---------------------------------------------------------------------------
// Accessors
public :
// cell accessor
inline geom_cell top() const { return geom_cell( key(), *_it ) ; }
/// id accessor
inline real &operator*() { return *_it ; }
/// level accessor
inline Level lv() { return key_level(_it.key()) ; }
/// size accessor
inline real sz() { return Cube(0,0,0,lv()).sz() ; }
/// key accessor
inline Key key() const { return _it.key() ; }
/// points accessor
inline bool is_leaf() const { return !is_inv(*_it) ; }
/// Draws the cell wire with opengl
void draw_wire () const { top().draw_wire () ; }
};
} ;
//_____________________________________________________________________________
#else // HASH_HAS_ERASE
#include "opt_octree.h"
typedef OptOctree LeafOctree ;
#endif // HASH_HAS_ERASE

View File

@ -1,695 +0,0 @@
/**
* @file md_draw.cpp
* @author Thomas Lewiner <thomas.lewiner@polytechnique.org>
* @author Math Dept, PUC-Rio
* @version 0.2
* @date 12/08/2002
*
* @brief MC_Draw Direct Draw Algorithm
*/
//________________________________________________
#if !defined(WIN32) || defined(__CYGWIN__)
#pragma implementation
#endif // WIN32
#include <math.h>
#include <time.h>
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>
#include <float.h>
#include "mc_draw.h"
#include "LookUpTable.h"
//_____________________________________________________________________________
// print cube for debug
void MC_Draw::print_cube() { printf( "\t%f %f %f %f %f %f %f %f\n", _cube[0], _cube[1], _cube[2], _cube[3], _cube[4], _cube[5], _cube[6], _cube[7]) ; }
//_____________________________________________________________________________
//_____________________________________________________________________________
// main algorithm
bool MC_Draw::tesselate_cube( real iso )
//-----------------------------------------------------------------------------
{
for( int p = 0 ; p < 8 ; ++p )
{
real &v = _cube[p] ;
v -= iso ;
if( fabs( v ) < R_EPSILON ) v = R_EPSILON ;
}
if( !compute_intersection_points() ) return false ;
_lut_entry = 0 ;
for( int p = 0 ; p < 8 ; ++p )
{
if( _cube[p] > 0 ) _lut_entry += 1 << p ;
}
return process_cube( ) ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
//_____________________________________________________________________________
//_____________________________________________________________________________
// Compute the intersection points
bool MC_Draw::compute_intersection_points()
//-----------------------------------------------------------------------------
{
bool res = false ;
res |= add_vertex( 0,1 ) ;
res |= add_vertex( 1,2 ) ;
res |= add_vertex( 2,3 ) ;
res |= add_vertex( 3,0 ) ;
res |= add_vertex( 4,5 ) ;
res |= add_vertex( 5,6 ) ;
res |= add_vertex( 6,7 ) ;
res |= add_vertex( 7,4 ) ;
res |= add_vertex( 0,4 ) ;
res |= add_vertex( 1,5 ) ;
res |= add_vertex( 2,6 ) ;
res |= add_vertex( 3,7 ) ;
return res ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// Test a face
// if face>0 return true if the face contains a part of the surface
bool MC_Draw::test_face( schar face )
//-----------------------------------------------------------------------------
{
real A,B,C,D ;
switch( face )
{
case -1 : case 1 : A = _cube[0] ; B = _cube[4] ; C = _cube[5] ; D = _cube[1] ; break ;
case -2 : case 2 : A = _cube[1] ; B = _cube[5] ; C = _cube[6] ; D = _cube[2] ; break ;
case -3 : case 3 : A = _cube[2] ; B = _cube[6] ; C = _cube[7] ; D = _cube[3] ; break ;
case -4 : case 4 : A = _cube[3] ; B = _cube[7] ; C = _cube[4] ; D = _cube[0] ; break ;
case -5 : case 5 : A = _cube[0] ; B = _cube[3] ; C = _cube[2] ; D = _cube[1] ; break ;
case -6 : case 6 : A = _cube[4] ; B = _cube[7] ; C = _cube[6] ; D = _cube[5] ; break ;
default : printf( "Invalid face code %d\n", face ) ; print_cube() ; A = B = C = D = 0 ;
};
if( fabs( A*C - B*D ) < R_EPSILON )
return face >= 0 ;
return face * A * ( A*C - B*D ) >= 0 ; // face and A invert signs
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// Test the interior of a cube
// if s == 7, return true if the interior is empty
// if s ==-7, return false if the interior is empty
bool MC_Draw::test_interior( schar s )
//-----------------------------------------------------------------------------
{
real 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 = ( _cube[4] - _cube[0] ) * ( _cube[6] - _cube[2] ) - ( _cube[7] - _cube[3] ) * ( _cube[5] - _cube[1] ) ;
b = _cube[2] * ( _cube[4] - _cube[0] ) + _cube[0] * ( _cube[6] - _cube[2] )
- _cube[1] * ( _cube[7] - _cube[3] ) - _cube[3] * ( _cube[5] - _cube[1] ) ;
t = - b / (2*a) ;
if( t<0 || t>1 ) return s>0 ;
At = _cube[0] + ( _cube[4] - _cube[0] ) * t ;
Bt = _cube[3] + ( _cube[7] - _cube[3] ) * t ;
Ct = _cube[2] + ( _cube[6] - _cube[2] ) * t ;
Dt = _cube[1] + ( _cube[5] - _cube[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 = _cube[0] / ( _cube[0] - _cube[1] ) ;
At = 0 ;
Bt = _cube[3] + ( _cube[2] - _cube[3] ) * t ;
Ct = _cube[7] + ( _cube[6] - _cube[7] ) * t ;
Dt = _cube[4] + ( _cube[5] - _cube[4] ) * t ;
break ;
case 1 :
t = _cube[1] / ( _cube[1] - _cube[2] ) ;
At = 0 ;
Bt = _cube[0] + ( _cube[3] - _cube[0] ) * t ;
Ct = _cube[4] + ( _cube[7] - _cube[4] ) * t ;
Dt = _cube[5] + ( _cube[6] - _cube[5] ) * t ;
break ;
case 2 :
t = _cube[2] / ( _cube[2] - _cube[3] ) ;
At = 0 ;
Bt = _cube[1] + ( _cube[0] - _cube[1] ) * t ;
Ct = _cube[5] + ( _cube[4] - _cube[5] ) * t ;
Dt = _cube[6] + ( _cube[7] - _cube[6] ) * t ;
break ;
case 3 :
t = _cube[3] / ( _cube[3] - _cube[0] ) ;
At = 0 ;
Bt = _cube[2] + ( _cube[1] - _cube[2] ) * t ;
Ct = _cube[6] + ( _cube[5] - _cube[6] ) * t ;
Dt = _cube[7] + ( _cube[4] - _cube[7] ) * t ;
break ;
case 4 :
t = _cube[4] / ( _cube[4] - _cube[5] ) ;
At = 0 ;
Bt = _cube[7] + ( _cube[6] - _cube[7] ) * t ;
Ct = _cube[3] + ( _cube[2] - _cube[3] ) * t ;
Dt = _cube[0] + ( _cube[1] - _cube[0] ) * t ;
break ;
case 5 :
t = _cube[5] / ( _cube[5] - _cube[6] ) ;
At = 0 ;
Bt = _cube[4] + ( _cube[7] - _cube[4] ) * t ;
Ct = _cube[0] + ( _cube[3] - _cube[0] ) * t ;
Dt = _cube[1] + ( _cube[2] - _cube[1] ) * t ;
break ;
case 6 :
t = _cube[6] / ( _cube[6] - _cube[7] ) ;
At = 0 ;
Bt = _cube[5] + ( _cube[4] - _cube[5] ) * t ;
Ct = _cube[1] + ( _cube[0] - _cube[1] ) * t ;
Dt = _cube[2] + ( _cube[3] - _cube[2] ) * t ;
break ;
case 7 :
t = _cube[7] / ( _cube[7] - _cube[4] ) ;
At = 0 ;
Bt = _cube[6] + ( _cube[5] - _cube[6] ) * t ;
Ct = _cube[2] + ( _cube[1] - _cube[2] ) * t ;
Dt = _cube[3] + ( _cube[0] - _cube[3] ) * t ;
break ;
case 8 :
t = _cube[0] / ( _cube[0] - _cube[4] ) ;
At = 0 ;
Bt = _cube[3] + ( _cube[7] - _cube[3] ) * t ;
Ct = _cube[2] + ( _cube[6] - _cube[2] ) * t ;
Dt = _cube[1] + ( _cube[5] - _cube[1] ) * t ;
break ;
case 9 :
t = _cube[1] / ( _cube[1] - _cube[5] ) ;
At = 0 ;
Bt = _cube[0] + ( _cube[4] - _cube[0] ) * t ;
Ct = _cube[3] + ( _cube[7] - _cube[3] ) * t ;
Dt = _cube[2] + ( _cube[6] - _cube[2] ) * t ;
break ;
case 10 :
t = _cube[2] / ( _cube[2] - _cube[6] ) ;
At = 0 ;
Bt = _cube[1] + ( _cube[5] - _cube[1] ) * t ;
Ct = _cube[0] + ( _cube[4] - _cube[0] ) * t ;
Dt = _cube[3] + ( _cube[7] - _cube[3] ) * t ;
break ;
case 11 :
t = _cube[3] / ( _cube[3] - _cube[7] ) ;
At = 0 ;
Bt = _cube[2] + ( _cube[6] - _cube[2] ) * t ;
Ct = _cube[1] + ( _cube[5] - _cube[1] ) * t ;
Dt = _cube[0] + ( _cube[4] - _cube[0] ) * t ;
break ;
default : printf( "Invalid edge %d\n", edge ) ; print_cube() ; break ;
}
break ;
default : printf( "Invalid ambiguous case %d\n", _case ) ; print_cube() ; 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 < R_EPSILON ) 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 >= R_EPSILON ) 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 ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// Process a unit cube
bool MC_Draw::process_cube( )
//-----------------------------------------------------------------------------
{
if( _originalMC )
{
char nt = 0 ;
while( casesClassic[_lut_entry][3*nt] != -1 ) nt++ ;
draw_triangle( casesClassic[_lut_entry], nt ) ;
return true ;
}
int v12 = -1 ;
_case = cases[_lut_entry][0] ;
_config = cases[_lut_entry][1] ;
_subconfig = 0 ;
switch( _case )
{
case 0 :
break ;
case 1 :
draw_triangle( tiling1[_config], 1 ) ;
break ;
case 2 :
draw_triangle( tiling2[_config], 2 ) ;
break ;
case 3 :
if( test_face( test3[_config]) )
draw_triangle( tiling3_2[_config], 4 ) ; // 3.2
else
draw_triangle( tiling3_1[_config], 2 ) ; // 3.1
break ;
case 4 :
if( test_interior( test4[_config]) )
draw_triangle( tiling4_1[_config], 2 ) ; // 4.1.1
else
draw_triangle( tiling4_2[_config], 6 ) ; // 4.1.2
break ;
case 5 :
draw_triangle( tiling5[_config], 3 ) ;
break ;
case 6 :
if( test_face( test6[_config][0]) )
draw_triangle( tiling6_2[_config], 5 ) ; // 6.2
else
{
if( test_interior( test6[_config][1]) )
draw_triangle( tiling6_1_1[_config], 3 ) ; // 6.1.1
else
{
comp_c_vertex() ;
draw_triangle( tiling6_1_2[_config], 9 , v12) ; // 6.1.2
}
}
break ;
case 7 :
if( test_face( test7[_config][0] ) ) _subconfig += 1 ;
if( test_face( test7[_config][1] ) ) _subconfig += 2 ;
if( test_face( test7[_config][2] ) ) _subconfig += 4 ;
switch( _subconfig )
{
case 0 :
draw_triangle( tiling7_1[_config], 3 ) ; break ;
case 1 :
draw_triangle( tiling7_2[_config][0], 5 ) ; break ;
case 2 :
draw_triangle( tiling7_2[_config][1], 5 ) ; break ;
case 3 :
comp_c_vertex() ;
draw_triangle( tiling7_3[_config][0], 9, v12 ) ; break ;
case 4 :
draw_triangle( tiling7_2[_config][2], 5 ) ; break ;
case 5 :
comp_c_vertex() ;
draw_triangle( tiling7_3[_config][1], 9, v12 ) ; break ;
case 6 :
comp_c_vertex() ;
draw_triangle( tiling7_3[_config][2], 9, v12 ) ; break ;
case 7 :
if( test_interior( test7[_config][3]) )
draw_triangle( tiling7_4_2[_config], 9 ) ;
else
draw_triangle( tiling7_4_1[_config], 5 ) ;
break ;
};
break ;
case 8 :
draw_triangle( tiling8[_config], 2 ) ;
break ;
case 9 :
draw_triangle( tiling9[_config], 4 ) ;
break ;
case 10 :
if( test_face( test10[_config][0]) )
{
if( test_face( test10[_config][1]) )
draw_triangle( tiling10_1_1_[_config], 4 ) ; // 10.1.1
else
{
comp_c_vertex() ;
draw_triangle( tiling10_2[_config], 8, v12 ) ; // 10.2
}
}
else
{
if( test_face( test10[_config][1]) )
{
comp_c_vertex() ;
draw_triangle( tiling10_2_[_config], 8, v12 ) ; // 10.2
}
else
{
if( test_interior( test10[_config][2]) )
draw_triangle( tiling10_1_1[_config], 4 ) ; // 10.1.1
else
draw_triangle( tiling10_1_2[_config], 8 ) ; // 10.1.2
}
}
break ;
case 11 :
draw_triangle( tiling11[_config], 4 ) ;
break ;
case 12 :
if( test_face( test12[_config][0]) )
{
if( test_face( test12[_config][1]) )
draw_triangle( tiling12_1_1_[_config], 4 ) ; // 12.1.1
else
{
comp_c_vertex() ;
draw_triangle( tiling12_2[_config], 8, v12 ) ; // 12.2
}
}
else
{
if( test_face( test12[_config][1]) )
{
comp_c_vertex() ;
draw_triangle( tiling12_2_[_config], 8, v12 ) ; // 12.2
}
else
{
if( test_interior( test12[_config][2]) )
draw_triangle( tiling12_1_1[_config], 4 ) ; // 12.1.1
else
draw_triangle( tiling12_1_2[_config], 8 ) ; // 12.1.2
}
}
break ;
case 13 :
if( test_face( test13[_config][0] ) ) _subconfig += 1 ;
if( test_face( test13[_config][1] ) ) _subconfig += 2 ;
if( test_face( test13[_config][2] ) ) _subconfig += 4 ;
if( test_face( test13[_config][3] ) ) _subconfig += 8 ;
if( test_face( test13[_config][4] ) ) _subconfig += 16 ;
if( test_face( test13[_config][5] ) ) _subconfig += 32 ;
switch( subconfig13[_subconfig] )
{
case 0 :/* 13.1 */
draw_triangle( tiling13_1[_config], 4 ) ; break ;
case 1 :/* 13.2 */
draw_triangle( tiling13_2[_config][0], 6 ) ; break ;
case 2 :/* 13.2 */
draw_triangle( tiling13_2[_config][1], 6 ) ; break ;
case 3 :/* 13.2 */
draw_triangle( tiling13_2[_config][2], 6 ) ; break ;
case 4 :/* 13.2 */
draw_triangle( tiling13_2[_config][3], 6 ) ; break ;
case 5 :/* 13.2 */
draw_triangle( tiling13_2[_config][4], 6 ) ; break ;
case 6 :/* 13.2 */
draw_triangle( tiling13_2[_config][5], 6 ) ; break ;
case 7 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3[_config][0], 10, v12 ) ; break ;
case 8 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3[_config][1], 10, v12 ) ; break ;
case 9 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3[_config][2], 10, v12 ) ; break ;
case 10 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3[_config][3], 10, v12 ) ; break ;
case 11 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3[_config][4], 10, v12 ) ; break ;
case 12 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3[_config][5], 10, v12 ) ; break ;
case 13 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3[_config][6], 10, v12 ) ; break ;
case 14 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3[_config][7], 10, v12 ) ; break ;
case 15 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3[_config][8], 10, v12 ) ; break ;
case 16 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3[_config][9], 10, v12 ) ; break ;
case 17 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3[_config][10], 10, v12 ) ; break ;
case 18 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3[_config][11], 10, v12 ) ; break ;
case 19 :/* 13.4 */
comp_c_vertex() ;
draw_triangle( tiling13_4[_config][0], 12, v12 ) ; break ;
case 20 :/* 13.4 */
comp_c_vertex() ;
draw_triangle( tiling13_4[_config][1], 12, v12 ) ; break ;
case 21 :/* 13.4 */
comp_c_vertex() ;
draw_triangle( tiling13_4[_config][2], 12, v12 ) ; break ;
case 22 :/* 13.4 */
comp_c_vertex() ;
draw_triangle( tiling13_4[_config][3], 12, v12 ) ; break ;
case 23 :/* 13.5 */
_subconfig = 0 ;
if( test_interior( test13[_config][6] ) )
draw_triangle( tiling13_5_1[_config][0], 6 ) ;
else
draw_triangle( tiling13_5_2[_config][0], 10 ) ;
break ;
case 24 :/* 13.5 */
_subconfig = 1 ;
if( test_interior( test13[_config][6] ) )
draw_triangle( tiling13_5_1[_config][1], 6 ) ;
else
draw_triangle( tiling13_5_2[_config][1], 10 ) ;
break ;
case 25 :/* 13.5 */
_subconfig = 2 ;
if( test_interior( test13[_config][6] ) )
draw_triangle( tiling13_5_1[_config][2], 6 ) ;
else
draw_triangle( tiling13_5_2[_config][2], 10 ) ;
break ;
case 26 :/* 13.5 */
_subconfig = 3 ;
if( test_interior( test13[_config][6] ) )
draw_triangle( tiling13_5_1[_config][3], 6 ) ;
else
draw_triangle( tiling13_5_2[_config][3], 10 ) ;
break ;
case 27 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3_[_config][0], 10, v12 ) ; break ;
case 28 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3_[_config][1], 10, v12 ) ; break ;
case 29 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3_[_config][2], 10, v12 ) ; break ;
case 30 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3_[_config][3], 10, v12 ) ; break ;
case 31 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3_[_config][4], 10, v12 ) ; break ;
case 32 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3_[_config][5], 10, v12 ) ; break ;
case 33 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3_[_config][6], 10, v12 ) ; break ;
case 34 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3_[_config][7], 10, v12 ) ; break ;
case 35 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3_[_config][8], 10, v12 ) ; break ;
case 36 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3_[_config][9], 10, v12 ) ; break ;
case 37 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3_[_config][10], 10, v12 ) ; break ;
case 38 :/* 13.3 */
comp_c_vertex() ;
draw_triangle( tiling13_3_[_config][11], 10, v12 ) ; break ;
case 39 :/* 13.2 */
draw_triangle( tiling13_2_[_config][0], 6 ) ; break ;
case 40 :/* 13.2 */
draw_triangle( tiling13_2_[_config][1], 6 ) ; break ;
case 41 :/* 13.2 */
draw_triangle( tiling13_2_[_config][2], 6 ) ; break ;
case 42 :/* 13.2 */
draw_triangle( tiling13_2_[_config][3], 6 ) ; break ;
case 43 :/* 13.2 */
draw_triangle( tiling13_2_[_config][4], 6 ) ; break ;
case 44 :/* 13.2 */
draw_triangle( tiling13_2_[_config][5], 6 ) ; break ;
case 45 :/* 13.1 */
draw_triangle( tiling13_1_[_config], 4 ) ; break ;
default :
printf("Marching Cubes: Impossible case 13?\n" ) ; print_cube() ;
}
break ;
case 14 :
draw_triangle( tiling14[_config], 4 ) ;
break ;
};
return true ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// Adding triangles
void MC_Draw::draw_triangle( const char* trig_, char n, int v12 )
//-----------------------------------------------------------------------------
{
for( int t = 0 ; t < 3*n ; t++ )
{
switch( trig_[t] )
{
case 0 : _verts[0][1].draw() ; break ;
case 1 : _verts[1][2].draw() ; break ;
case 2 : _verts[2][3].draw() ; break ;
case 3 : _verts[3][0].draw() ; break ;
case 4 : _verts[4][5].draw() ; break ;
case 5 : _verts[5][6].draw() ; break ;
case 6 : _verts[6][7].draw() ; break ;
case 7 : _verts[7][4].draw() ; break ;
case 8 : _verts[0][4].draw() ; break ;
case 9 : _verts[1][5].draw() ; break ;
case 10 : _verts[2][6].draw() ; break ;
case 11 : _verts[3][7].draw() ; break ;
case 12 : _c_vert .draw() ; break ;
default : break ;
}
}
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// Adding vertices
bool MC_Draw::add_vertex( char i, char j )
//-----------------------------------------------------------------------------
{
real ci = _cube[i] ;
real cj = _cube[j] ;
if( ci * cj >= 0 ) { _verts[i][j] = P_INV ; return false ; }
_dat_access->interpolate( ci,cj, _space[i],_space[j], _verts[i][j] ) ;
return true ;
}
//-----------------------------------------------------------------------------
bool MC_Draw::comp_c_vertex( )
//-----------------------------------------------------------------------------
{
real u = 0 ;
_c_vert.x() = _c_vert.y() = _c_vert.z() = 0 ;
// Computes the average of the intersection points of the cube
Point &v01 = _verts[0][1] ; if( v01 != P_INV ) { ++u ; _c_vert += v01 ; }
Point &v12 = _verts[1][2] ; if( v12 != P_INV ) { ++u ; _c_vert += v12 ; }
Point &v23 = _verts[2][3] ; if( v23 != P_INV ) { ++u ; _c_vert += v23 ; }
Point &v30 = _verts[3][0] ; if( v30 != P_INV ) { ++u ; _c_vert += v30 ; }
Point &v45 = _verts[4][5] ; if( v45 != P_INV ) { ++u ; _c_vert += v45 ; }
Point &v56 = _verts[5][6] ; if( v56 != P_INV ) { ++u ; _c_vert += v56 ; }
Point &v67 = _verts[6][7] ; if( v67 != P_INV ) { ++u ; _c_vert += v67 ; }
Point &v74 = _verts[7][4] ; if( v74 != P_INV ) { ++u ; _c_vert += v74 ; }
Point &v04 = _verts[0][4] ; if( v04 != P_INV ) { ++u ; _c_vert += v04 ; }
Point &v15 = _verts[1][5] ; if( v15 != P_INV ) { ++u ; _c_vert += v15 ; }
Point &v26 = _verts[2][6] ; if( v26 != P_INV ) { ++u ; _c_vert += v26 ; }
Point &v37 = _verts[3][7] ; if( v37 != P_INV ) { ++u ; _c_vert += v37 ; }
_c_vert /= u ;
return u > 0 ;
}
//_____________________________________________________________________________

View File

@ -1,116 +0,0 @@
/**
* @file mc_draw.h
* @author Thomas Lewiner <thomas.lewiner@polytechnique.org>
* @author Math Dept, PUC-Rio
* @version 0.2
* @date 12/08/2002
*
* @brief MarchingCubes Direct Draw
*/
//________________________________________________
#pragma once
#if !defined(WIN32) || defined(__CYGWIN__)
#pragma interface
#endif // WIN32
#include <map>
#include "point.h"
#include "data_access.h"
//_____________________________________________________________________________
/** Marching Cubes algorithm wrapper */
/** \class MarchingCubes Direct Draw
* \brief Marching Cubes Direct Draw.
*/
class MC_Draw
//-----------------------------------------------------------------------------
{
// Constructors
public :
/**
* Main and default constructor
* \brief constructor
*/
MC_Draw () : _originalMC(true) {}
/** Destructor */
~MC_Draw () {}
//-----------------------------------------------------------------------------
// Accessors
public :
/**
* selects wether the algorithm will use the enhanced topologically controlled lookup table or the original MarchingCubes
* \param originalMC true for the original Marching Cubes
*/
inline void set_method ( const bool originalMC = false ) { _originalMC = originalMC ; }
//-----------------------------------------------------------------------------
// Algorithm
public :
/** retrieves the isovalues at the cube vertices */
real *cube () { return _cube ; }
/** retrieves the geometry of the cube */
Point *space () { return _space; }
/** retrieves the data accessor */
data_access *&dat_access() { return _dat_access ; }
/**
* Main algorithm
* \param iso isovalue
*/
bool tesselate_cube( real iso ) ;
protected :
/** tesselates one cube */
bool process_cube () ;
/** tests if the components of the tesselation of the cube should be connected by the interior of an ambiguous face */
bool test_face ( schar face ) ;
/** tests if the components of the tesselation of the cube should be connected through the interior of the cube */
bool test_interior( schar s ) ;
//-----------------------------------------------------------------------------
// Operations
protected :
/** computes almost all the vertices of the mesh by interpolation along the cubes edges */
bool compute_intersection_points() ;
/** adds a vertex on edge cube[i] cube[j] */
bool add_vertex( char i, char j ) ;
/** compute a vertex inside the current cube */
bool comp_c_vertex() ;
/**
* routine to add a triangle to the mesh
* \param trig the code for the triangle as a sequence of edges index
* \param n the number of triangles to produce
* \param v12 the index of the interior vertex to use, if necessary
*/
void draw_triangle ( const char* trig, char n, int v12 = -1 ) ;
/** prints cube for debug */
void print_cube() ;
//-----------------------------------------------------------------------------
// Elements
protected :
bool _originalMC ; /**< selects wether the algorithm will use the enhanced topologically controlled lookup table or the original MarchingCubes */
real _cube[8] ; /**< values of the implicit function on the active cube */
Point _space[8] ; /**< coordinates of the active cube */
Point _verts[8][8] ; /**< coordinates of the vertices, per edge */
Point _c_vert ; /**< coordinates of the central vertex */
uchar _lut_entry ; /**< cube sign representation in [0..255] */
uchar _case ; /**< case of the active cube in [0..15] */
uchar _config ; /**< configuration of the active cube */
uchar _subconfig ; /**< subconfiguration of the active cube */
data_access *_dat_access ; /**< data accessor */
};
//_____________________________________________________________________________

View File

@ -1,367 +0,0 @@
/**
* \file mem_octree.h
* \author Thomas Lewiner <tomlew@puc-rio.br>
* \author Matmidia Lab, Math Dept, PUC-Rio
* \date 10/01/2010
*
* Octree structure with hashtable and optimized operations without auxiliary memory
*/
//_____________________________________________________________________________
#pragma once
#ifndef WIN32
#pragma interface
#endif // WIN32
#include "mlist.h"
#include "cube.h"
#include "hash.h"
#include "MarchingCubes.h"
#include "mc_draw.h"
#include "data_access.h"
//_____________________________________________________________________________
// MemOctree
/// \class MemOctree MemOctree.h
class MemOctree
//-----------------------------------------------------------------------------
{
// forward declaration
public:
class geom_cell ;
class cell_iterator ;
class leaf_iterator ;
// Elements
protected:
/// Octree cell data structure
typedef Hash<real> HashField ;
/// Hashtable of the octree nodes
HashField _hash ;
/// Level distribution of the octree
uint _level_dist[MAX_LEVEL+1] ;
/// Memimal level for direct search in the octree
Level _opt_level ;
/// Maximal field of the octree
real _max_field ;
/// Isosurface
MarchingCubes _mc ;
/// Isosurface Draw
MC_Draw _mc_draw ;
//-----------------------------------------------------------------------------
// Constructors
public:
/// Default constructor: Constructs a octree with and empty root
MemOctree() { init() ; }
/// Destructor: Free memory
~MemOctree() { clear() ; }
/// Create the root
void init() ;
/// Memory cleaning
void clear() { clear_octree() ; _mc.clean_all() ; }
/// Delete the content of the octree
void clear_octree() ;
/// Compute the optimal level
void compute_opt_level() ;
/// Check that only the leaves have data
bool check () ;
/// Prints statistics about the octree
void stats() const ;
/// Return the maximal level of the octree
Level max_level() const { Level lv = MAX_LEVEL ; while( lv > 0 && !_level_dist[lv] ) --lv ; return lv ; }
/// Return the optimal level of the octree
Level opt_level() const { return _opt_level ; }
/// Return the optimal level of the octree
Level &opt_level() { return _opt_level ; }
/// Return the maximal field of the octree
real max_field() const { return _max_field ; }
/// Return the isosurface
MarchingCubes &mc() { return _mc ; }
/// Return the isosurface draw
MC_Draw &mc_draw() { return _mc_draw ; }
/// set the values of each leaf from the implicit function
bool set_impl( data_access *ref = NULL ) ;
/// Refine the octree according to the data access
bool refine( data_access *ref = NULL ) ;
/// Adapt the octree according to the data access
bool adapt( data_access *ref = NULL ) ;
/// Draw the octree with wireframe
bool draw_wire() ;
/// Draw the octree with dots
bool draw_centers() ;
/// Dual function type
typedef bool mem_dual_walker( MemOctree &fo, Key *keys ) ;
/// Walk on the dual cubes
bool dual_cubes_walk( mem_dual_walker &walker ) ;
/// Build the isosurface using dual marching cubes
bool build_isosurface( data_access *ref = NULL ) ;
/// Draw the isosurface on-the-fly using dual marching cubes
bool direct_draw_isosurface( data_access *ref = NULL ) ;
/// Draw the dual octree with wireframe
bool draw_dual() ;
/// Do nothing, just for dual generation timing
bool dual_timing() ;
//-----------------------------------------------------------------------------
// iterators
public:
/// Create an iterator traversing the tree from the root
inline cell_iterator cells_begin() { return cell_iterator( *this ) ; }
/// Create an iterator traversing the leaves of the tree from the root
inline leaf_iterator leaves_begin() { return leaf_iterator( *this ) ; }
//-----------------------------------------------------------------------------
// search operations
public:
/// Find cells of the octree at a given position
bool find_leaf( Key k, Level o_lv, geom_cell &cell ) const ;
bool find_leaf( Key k, geom_cell &cell ) const { return find_leaf( k, opt_level(), cell ) ; }
bool find_leaf( real x, real y, real z, geom_cell &cell ) const { return find_leaf( cube2key( Cube(x,y,z,MAX_LEVEL) ), opt_level(), cell ) ; }
/// Find cells of the octree inside a given box of center x,y,z and half side r
bool find_radius( real x, real y, real z, real r, List<geom_cell> &cells ) const ;
/// Find adjacent cells of the octree to a given cell
bool adjacent( Key k, List<geom_cell> &cells ) const ;
bool adjacent( const geom_cell &cell, List<geom_cell> &cells ) const { return adjacent( cell.key(), cells ) ; }
/// Leaf test based on the field value
bool is_leaf( const HashField::KeyData &kd ) const { return !is_inv( kd.data ) ; }
/// Leaf test based on the field value
bool is_leaf( Key k, real &d ) const { const HashField::KeyData &kd = _hash[k] ; d = kd.data ; return is_leaf( kd ) ; }
/// Leaf test based on the field value
bool is_leaf( Key k ) const { return is_leaf( _hash[k] ) ; }
/// Node existence
bool node_exists( Key k, HashField::KeyData &kd ) const { kd = _hash[k] ; return kd.key != KEY_INV ; }
//-----------------------------------------------------------------------------
// I/O
public:
/// Draws the intersecting cells of a plane with the octree with color
void draw_plane ( real nx, real ny, real nz, real d ) ;
/// Draws the intersection of a plane with the octree with color
void draw_slice ( real nx, real ny, real nz, real d, float alpha ) ;
/// Draws the isosurface of level l inside the dual graph
void draw_iso () { _mc.draw_surf() ; }
//_____________________________________________________________________________
// Iterator Cell
public :
/// Auxiliary structure to traverse the octree
class geom_cell : public Cube
//---------------------------------------------------------------------------
{
friend class MemOctree ;
protected:
Key _key ; ///< octree cell
real _field ; ///< field associated to the cell
//---------------------------------------------------------------------------
// Constructors
public:
/// Default constructor
geom_cell( Key key_ = KEY_INV, real field_ = R_INV ) : Cube(key2cube(key_)), _key(key_), _field(field_) {}
/// Default constructor
geom_cell( HashField::KeyData kd ) : Cube(key2cube(kd.key)), _key(kd.key), _field(kd.data) {}
/// Destructor
~geom_cell() {}
/// Copy constructor
geom_cell( const geom_cell &i ) : Cube(i), _key(i._key), _field(i._field) {}
/// Assignment operator
geom_cell &operator = ( const geom_cell &i )
{ Cube::operator=(i) ; _key = i._key ; _field = i._field ; return *this; }
//---------------------------------------------------------------------------
// Public constant accessors
public :
/// key const accessor
inline Key key() const { return _key ; }
/// key accessor
inline Key &key() { return _key ; }
/// id const accessor
inline real operator*() const { return _field ; }
//---------------------------------------------------------------------------
// Tests
public :
/// equality operator
inline bool operator ==( const geom_cell &i ) const { return key() == i.key() ; }
/// inequality operator
inline bool operator !=( const geom_cell &i ) const { return key() != i.key() ; }
/// leaf test
inline bool is_leaf() const { return !is_inv(*(*this)) ; }
/// validation operator
inline bool operator ()() const { return key() != KEY_INV ; }
//---------------------------------------------------------------------------
// Operations
public :
/// sons
inline bool sons( geom_cell *s /*[8]*/, const HashField &hash )
{
if( is_leaf() ) return false ;
Key k = _key << 3 ;
for( int i = 0 ; i < 8 ; ++i )
{
s[i]._key = k | i ;
s[i]._field = hash[k|i].data ;
(Cube&)s[i] = key2cube(s[i]._key) ;
}
return true ;
}
};
const geom_cell geom_root() const { const Key root_key = 1 ; return geom_cell( root_key, _hash[root_key].data ) ; }
const geom_cell geom_key ( Key k ) const { return geom_cell( k, _hash[k].data ) ; }
//_____________________________________________________________________________
// Cell Iterator
public :
/// Octree cell iterator : Traverse the octree returning basic information on the cells
class cell_iterator
//---------------------------------------------------------------------------
{
friend class MemOctree ;
protected:
/// Octree traversal iterator
HashField::iterator _it ;
//---------------------------------------------------------------------------
// Constructors
public:
/// Default constructor : Constructs an iterator from a cell
cell_iterator( MemOctree &o ) : _it( o._hash.begin() ) {}
/// Destructor
~cell_iterator() {}
/// Copy constructor
cell_iterator( const cell_iterator &i ) : _it(i._it) {}
/// Assignment operator
cell_iterator &operator = ( const cell_iterator &i )
{ _it = i._it; return *this; }
//---------------------------------------------------------------------------
// Operations
public :
/// equality operator
inline bool operator ==( const cell_iterator &i ) const { return _it == i._it ; }
/// inequality operator
inline bool operator !=( const cell_iterator &i ) const { return _it != i._it ; }
/// validation operator
inline bool operator ()() const { return _it() ; }
/// next position
inline cell_iterator &operator ++() { ++_it ; return *this ; }
//---------------------------------------------------------------------------
// Accessors
public :
// cell accessor
inline geom_cell top() const { return geom_cell( key(), *_it ) ; }
/// id accessor
inline real &operator*() { return *_it ; }
/// level accessor
inline Level lv() { return key_level(_it.key()) ; }
/// size accessor
inline real sz() { return Cube(0,0,0,lv()).sz() ; }
/// key accessor
inline Key key() const { return _it.key() ; }
/// points accessor
inline bool is_leaf() const { return !is_inv(*_it) ; }
/// Draws the cell wire with opengl
void draw_wire () const { top().draw_wire () ; }
};
/// Octree leaf iterator : Traverse the octree returning basic information on the leaves
class leaf_iterator : public cell_iterator
//---------------------------------------------------------------------------
{
public :
leaf_iterator( MemOctree &o ) : cell_iterator( o )
{ if( (*this)() && !this->is_leaf() ) ++(*this) ; }
/// next position
inline leaf_iterator &operator ++()
{
cell_iterator &it = *this ;
do ++it ; while ( it() && !it.is_leaf() ) ;
return *this ;
}
} ;
} ;
//_____________________________________________________________________________

View File

@ -1,502 +0,0 @@
/**
* @file mlist.h
* @author Thomas Lewiner <thomas.lewiner@polytechnique.org>
* @version 0.3
* @date 28/06/2004
*
* @brief template list class
*/
//_____________________________________________________________________________
#pragma once
#include <stdlib.h> // qsort
typedef unsigned int lsize ;
typedef const lsize clsize ;
//_____________________________________________________________________________
/// template list class
template <typename T> class List
//-----------------------------------------------------------------------------
{
// types
public :
class node ;
class iterator ;
class const_iterator ;
//-----------------------------------------------------------------------------
// default constructors
public :
/// default constructors
List() : _first((node*)NULL) {}
/// one-element constructor
List( const T &val ) : _first((node*)NULL) { insert(val) ; }
/// copy constructor (reverse order)
List( const List<T> &l ) : _first((node*)NULL)
{
for( const_iterator it = l.cbegin() ; it() ; ++it )
insert( *it ) ;
}
/// assignment operator
List<T> &operator = ( const List<T> &l ) { if( this != &l) { clear() ; for( const_iterator it = l.cbegin() ; it() ; ++it ) insert( *it ) ; } return *this; }
/// destructor
~List() { clear() ; }
/// number of elements of the list
clsize size() const { lsize n = 0 ; for( const_iterator it = cbegin() ; it() ; ++it ) ++n ; return n ; }
/// number of elements of the list
bool size_greater( clsize m ) const { lsize n = 0 ; for( const_iterator it = cbegin() ; it() ; ++it ) { if(++n > m) return true ; } return false ; }
/// number of elements of the list
bool size_greater_or_equal( clsize m ) const { if( m == 0 ) return true ; lsize n = 0 ; for( const_iterator it = cbegin() ; it() ; ++it ) { if(++n >= m) return true ; } return false ; }
/// tests if the list has one element
bool empty () const { return _first == (node*)NULL ; }
/// tests if the list has two elements
bool single() const { return !empty() && _first->next() == (node*)NULL ; }
/// tests if the list has three elements
bool pair () const { return !empty() && _first->next() != (node*)NULL && _first->next()->next() == (node*)NULL ; }
/// tests if the list has more than three elements
bool triple() const { return !empty() && _first->next() != (node*)NULL && _first->next()->next() != (node*)NULL ; }
const T first () const { return _first->val() ; } ///< first element accessor
T &first () { return _first->val() ; } ///< first element accessor
const T second() const { return _first->next()->val() ; } ///< second element accessor
T &second() { return _first->next()->val() ; } ///< second element accessor
const T third () const { return _first->next()->next()->val() ; } ///< third element accessor
T &third () { return _first->next()->next()->val() ; } ///< third element accessor
/// get the first two elements
bool firsts( T &t1, T &t2 ) const { if( !empty() ) { t1 = first() ; if( !single() ) { t2 = second() ; return true ; } } return false ; }
/// get the first three elements
bool firsts( T &t1, T &t2, T &t3 ) const { if( firsts( t1,t2 ) ) { if( !pair() ) t3 = third() ; return true ; } return false ; }
const T top () const { return _first->val() ; } ///< first element accessor
T &top () { return _first->val() ; } ///< first element accessor
//-----------------------------------------------------------------------------
// clear
public :
/// destructor
void clear()
{
node *p = _first ;
while( p != (node*)NULL )
{
node *n = p->next() ;
delete p ;
p = n ;
}
_first = (node*)NULL ;
}
/// emptyness test
inline bool empty() { return _first == (node*)NULL ; }
//-----------------------------------------------------------------------------
// find and replace
public :
/// membership test
const_iterator cfind( const T &val ) const { for( const_iterator it = cbegin() ; it() ; ++it ) if( (*it) == val ) return it ; return cend() ; }
/// membership test
iterator find( const T &val ) { for( iterator it = begin() ; it() ; ++it ) if( (*it) == val ) return it ; return end() ; }
/// membership test (return also the last pointer for eventual remotion)
iterator find( const T &val, iterator &lst ) { lst = end() ; for( iterator it = begin() ; it() ; ++it ) { if( *it == val ) return it ; lst = it ; } return end() ; }
/// membership test
clsize pos( const T &val ) const { lsize i = 0 ; for( const_iterator it = cbegin() ; it() ; ++it, ++i ) if( *it == val ) return i ; return (clsize)-1 ; }
/// get the minimal element
const_iterator min_val() const { if( empty() ) return cend() ; const_iterator it = cbegin(), m = it ; for( ++it ; it() ; ++it ) { if( *it < *m ) m = it ; } return m ; }
/// get the minimal element
iterator min_val() { if( empty() ) return end() ; iterator it = begin(), m = it ; for( ++it ; it() ; ++it ) { if( *it < *m ) m = it ; } return m ; }
/// get the maximal element
const_iterator max_val() const { if( empty() ) return cend() ; const_iterator it = cbegin(), m = it ; for( ++it ; it() ; ++it ) { if( *it > *m ) m = it ; } return m ; }
/// get the maximal element
iterator max_val() { if( empty() ) return end() ; iterator it = begin(), m = it ; for( ++it ; it() ; ++it ) { if( *it > *m ) m = it ; } return m ; }
/// replacing the elements of a list
clsize replace( const T &old_val, const T &new_val )
{
lsize n = 0 ;
for( iterator it = begin() ; it() ; ++it )
if( *it == old_val ) { *it = new_val ; ++n ; }
return n ;
}
//-----------------------------------------------------------------------------
// element insertion
public :
/// insertion at the beginning
inline void push_front( const T &val ) { _first = new node( val, _first ) ; }
/// insertion in the middle
iterator push_after( const T &val, iterator i = begin() )
{
if( i == end() ) { push_front( val ) ; return begin() ; }
i._node->next() = new node( val, i._node->next() ) ;
return ++i ;
}
/// insertion at the end
iterator push_back( const T &val )
{
return push_after( val, last() ) ;
}
/// insertion
inline void insert( const T &val ) { push_front( val ) ; }
/// insertion
inline void push( const T &val ) { push_front( val ) ; }
/// insertion without duplicates
inline bool insert_unique( const T &val ) { if( !find(val)() ) {push_front( val ); return true;} return false; }
/// list insertion (reverse, at the begining)
void insert( const List<T> &l )
{ for( const_iterator lit = l.cbegin() ; lit() ; ++lit ) insert( *lit ) ; }
/// list insertion without duplicates (reverse, at the begining)
void insert_unique( const List<T> &l )
{ for( const_iterator lit = l.cbegin() ; lit() ; ++lit ) insert_unique( *lit ) ; }
/// list insertion (ordered)
void insert_ordered( const List<T> &l )
{
const_iterator lit = l.cbegin() ;
iterator it = push_back( *lit ) ;
for( ; lit() ; ++lit )
it = push_after( *lit, it ) ;
}
/// copy a list and clear its content
void insert_and_clear( List<T> &l )
{
if( this == &l ) return ;
iterator lst = last() ;
if( lst() )
lst._node->next() = l._first ;
else
_first = l._first ;
l._first = NULL ;
}
//-----------------------------------------------------------------------------
// element remotion
public :
/// removing the first element of the list
void remove_first()
{
node *p = _first->next() ;
delete _first ;
_first = p ;
}
/// removing the first element of the list
void pop() { remove_first() ; }
/// removing elements from the list
void remove_next( iterator &prev )
{
node *p ;
if( prev == end() )
{ p = _first->next() ; delete _first ; _first = p ; }
else if( prev._node )
{ p = prev._node->next() ; prev._node->next() = p->next() ; delete p ; }
}
/// removing elements from the list
bool remove( T &val )
{
iterator prev = end() ;
for( iterator it = begin() ; it() ; )
{
if( *it != val ) { prev = it ; ++it ; continue ; }
val = *it ;
node *p ;
if( prev == end() )
{ p = _first->next() ; delete _first ; _first = p ; it = begin() ; }
else
{ p = it._node ; prev._node->next() = it._node->next() ; delete p ; it = prev ; ++it ; }
return true ;
}
return false ;
}
/// removing elements from the list
clsize remove_all( const T &val )
{
lsize n = 0 ;
iterator prev = end() ;
for( iterator it = begin() ; it() ; )
{
if( *it != val ) { prev = it ; ++it ; continue ; }
node *p ;
if( prev == end() )
{ p = _first->next() ; delete _first ; _first = p ; it = begin() ; }
else
{ p = it._node ; prev._node->next() = it._node->next() ; delete p ; it = prev ; ++it ; }
++n ;
if( !it() ) return n ;
}
return n ;
}
//-----------------------------------------------------------------------------
// sort
public :
/// array transform
void get_array( T *a, clsize sz /*= size()*/ )
{
lsize i = 0 ;
for( const_iterator it = cbegin() ; it() && i < sz ; ++it, ++i )
a[i] = *it ;
}
/// array transform
T *get_array( clsize sz /*= size()*/ )
{
T *a = new T[sz] ;
get_array( a,sz ) ;
return a ;
}
/// array read
void set_array( clsize sz = 0, const T *a = (const T*)NULL )
{
clear() ;
if( sz == 0 ) return ;
push_front( a[0] ) ;
iterator it = begin() ;
for( lsize i = 1 ; i < sz ; ++i )
it = push_after( a[i], it ) ;
}
/// sort
void sort( int compare(const void*,const void*) )
{
clsize sz = size() ;
T *a = get_array( sz ) ;
qsort( (void*)a, sz, sizeof(T), compare ) ;
set_array( sz, a ) ;
delete [] a ;
}
//-----------------------------------------------------------------------------
// Elements
private :
node *_first; ///< link to the first element
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// node representation
public :
/// node of a list
class node
{
public :
// constructors
/// default constructors
node( T val_, node *next_ = (node*)NULL ) : _val (val_) , _next (next_) {}
/// destructor
~node() {}
/// copy constructor
node( const node &n ) : _val(n.val()), _next(n.next()) {}
/// assignment operator
node &operator = ( const node &n )
{ _val = n.val(); _next = n.next(); return this; }
//-----------------------------------------------------------------------------
// Accessors
public :
inline const T &val () const { return _val ; } ///< accesses the value of the node
inline const node *next() const { return _next ; } ///< accesses the next element
inline T &val () { return _val ; } ///< accesses the value of the node
inline node *&next() { return _next ; } ///< accesses the next element
//-----------------------------------------------------------------------------
// Elements
private :
T _val ; ///< value
node *_next; ///< link to the next element
};
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// const_iterator
public :
/// list const iterator
class const_iterator
{
public :
// constructors
/// default constructors
const_iterator( node *n = (node*)NULL ) : _node(n) {}
/// destructor
~const_iterator() {}
/// copy constructor
const_iterator( const const_iterator &i ) : _node(i._node) {}
/// assignment operator
const_iterator &operator = ( const const_iterator &i )
{ _node = i._node; return *this; }
friend class List<T> ;
//-----------------------------------------------------------------------------
// Operations
public :
inline bool operator ==( const const_iterator &i ) const { return _node == i._node ; } ///< equality operator
inline bool operator !=( const const_iterator &i ) const { return _node != i._node ; } ///< inequality operator
inline bool operator ()() const { return _node != (node*)NULL ; } ///< validation operator
inline const T &operator * () const { return _node->val() ; } ///< value accessor
inline const_iterator &operator ++() { _node = _node->next() ; return *this ; } ///< accesses the next position
//-----------------------------------------------------------------------------
// Elements
private :
node *_node; ///< node position
};
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// iterator
public :
/// list iterator
class iterator
{
public :
// constructors
/// default constructors
iterator( node *n = (node*)NULL ) : _node(n) {}
/// destructor
~iterator() {}
/// copy constructor
iterator( const iterator &i ) : _node(i._node) {}
/// assignment operator
iterator &operator = ( const iterator &i )
{ _node = i._node; return *this; }
friend class List <T> ;
//-----------------------------------------------------------------------------
// Operations
public :
inline bool operator ==( const iterator &i ) const { return _node == i._node ; } ///< equality operator
inline bool operator !=( const iterator &i ) const { return _node != i._node ; } ///< inequality operator
inline bool operator ()() const { return _node != (node*)NULL ; } ///< validation operator
inline T &operator * () const { return _node->val() ; } ///< value accessor
inline iterator &operator ++() { _node = _node->next() ; return *this ; } ///< accesses the next position
//-----------------------------------------------------------------------------
// Elements
private :
node *_node; ///< node position
};
//-----------------------------------------------------------------------------
// iterator creation
public :
inline const_iterator cbegin() const { return const_iterator( _first ) ; } ///< iterator creation
inline const_iterator cend () const { return const_iterator( (node*)NULL ) ; } ///< iterator end
inline iterator begin() { return iterator( _first ) ; } ///< iterator creation
inline iterator end () { return iterator( (node*)NULL ) ; } ///< iterator end
/// last position
iterator last () { iterator lst = end(), it = begin() ; while( it() ) { lst = it ; ++it ; } return lst ; }
};
//_____________________________________________________________________________
//_____________________________________________________________________________
/// template list class
template <typename T> class Queue : public List<T>
//-----------------------------------------------------------------------------
{
//-----------------------------------------------------------------------------
// default constructors
public :
/// default constructors
Queue() : List<T>() { _last = this->end() ; }
/// one-element constructor
Queue( const T &val ) : List<T>( val ) { _last = this->begin() ; }
/// copy constructor (reverse order)
Queue( const Queue<T> &q ) : List<T>()
{ for( typename List<T>::const_iterator it = q.cbegin() ; it() ; ++it ) Queue<T>::insert( *it ) ; }
/// assignment operator
Queue<T> &operator = ( const Queue<T> &q )
{ if( this != &q) { this->clear() ; for( typename List<T>::const_iterator it = q.cbegin() ; it() ; ++it ) insert( *it ) ; } return *this; }
/// destructor
~Queue() { this->clear() ; }
//-----------------------------------------------------------------------------
// element insertion
public :
/// insertion at the end
inline void insert( const T &val )
{ _last = push_after( val, _last ) ; }
/// queue insertion
void insert( const Queue<T> &l )
{ for( typename List<T>::const_iterator lit = l.cbegin() ; lit() ; ++lit ) insert( *lit ) ; }
//-----------------------------------------------------------------------------
// stqndqrd function
public :
/// first element
inline const T front() const { return this->first() ; }
/// insertion at the end
inline void push( const T &val ) { this->insert( val ) ; }
/// deletion at the beginning
inline void pop () { this->remove_first() ; if( this->empty() ) _last = this->end() ; }
//-----------------------------------------------------------------------------
// Elements
private :
typename List<T>::iterator _last; ///< link to the last element
};
//_____________________________________________________________________________

View File

@ -1,458 +0,0 @@
/**
* \file morton.cpp
* \author Thomas Lewiner <tomlew@puc-rio.br>
* \author Rener Pereira de Castro <rener@mat.puc-rio.br>
* \author Matmidia Lab, Math Dept, PUC-Rio
* \date 10/01/2010
*
* \brief Morton codes manipulation
*
* Morton codes manipulation
*/
//_____________________________________________________________________________
#ifndef WIN32
#pragma implementation
#endif // WIN32
#include "morton.h"
//_____________________________________________________________________________
// static
#ifdef UNIX
real R_INV = strtof("NAN(char-sequence)", NULL); //nanf(0) ;
#else
real R_INV = nan(0) ;
#endif
Level L_INV = (Level)-1 ;
Point P_INV( R_INV, R_INV, R_INV ) ;
Cube C_INV( P_INV, L_INV ) ;
Key KEY_INV = 0 ;
//_____________________________________________________________________________
//_____________________________________________________________________________
// Static Members Aux
// 1 << ((dz==0)+(dy==0)+(dx==0))
static const char nsubneighbors[27] = { 1, // Direction (-1,-1,-1)
2, // Direction (-1,-1, 0)
1, // Direction (-1,-1, 1)
2, // Direction (-1, 0,-1)
4, // Direction (-1, 0, 0)
2, // Direction (-1, 0, 1)
1, // Direction (-1, 1,-1)
2, // Direction (-1, 1, 0)
1, // Direction (-1, 1, 1)
2, // Direction ( 0,-1,-1)
4, // Direction ( 0,-1, 0)
2, // Direction ( 0,-1, 1)
4, // Direction ( 0, 0,-1)
0, // Direction ( 0, 0, 0)
4, // Direction ( 0, 0, 1)
2, // Direction ( 0, 1,-1)
4, // Direction ( 0, 1, 0)
2, // Direction ( 0, 1, 1)
1, // Direction ( 1,-1,-1)
2, // Direction ( 1,-1, 0)
1, // Direction ( 1,-1, 1)
2, // Direction ( 1, 0,-1)
4, // Direction ( 1, 0, 0)
2, // Direction ( 1, 0, 1)
1, // Direction ( 1, 1,-1)
2, // Direction ( 1, 1, 0)
1, // Direction ( 1, 1, 1)
};
static const char l3b[27][4] = { {7,-1,-1,-1},{6, 7,-1,-1},{6,-1,-1,-1},{5, 7,-1,-1},{4, 5, 6, 7},{4, 6,-1,-1},{ 5,-1,-1,-1},
{4, 5,-1,-1},{4,-1,-1,-1},{3, 7,-1,-1},{2, 3, 6, 7},{2, 6,-1,-1},{1, 3, 5, 7},{-1,-1,-1,-1},
{0, 2, 4, 6},{1, 5,-1,-1},{0, 1, 4, 5},{0, 4,-1,-1},{3,-1,-1,-1},{2, 3,-1,-1},{ 2,-1,-1,-1},
{1, 3,-1,-1},{0, 1, 2, 3},{0, 2,-1,-1},{1,-1,-1,-1},{0, 1,-1,-1},{0,-1,-1,-1},};
//_____________________________________________________________________________
// Contraction and Dilatation Masks
static const uint three_2 = 9 ;
static const uint three_1 = 3 ;
static const uint three_0 = 1 ;
static const uint shift_2a = 18, shift_2b = 36 ;
static const uint shift_1a = 6, shift_1b = 12 ;
static const uint shift_0a = 2, shift_0b = 4 ;
static const Key dilate_mask_2 = (Key)0x7FC0000FF80001FFLL ; // bits 1 from 0-9, 27-36 and 54-63
static const Key dilate_mask_1 = (Key)0x01C0E070381C0E07LL ; // bits 1 from 0-3, 9-12, 18-21,...
static const Key dilate_mask_0 = (Key)0x9249249249249249LL ; // bits 1 at 0,3,6,9,12,...
static const Key dilate_tz = (Key)0x4924924924924924LL ; // bits 1 at 2,5,8,11,14,... rigth to left
static const Key dilate_ty = (Key)0x2492492492492492LL ; // bits 1 at 1,4,7,10,13,...
static const Key dilate_tx = (Key)0x9249249249249249LL ; // bits 1 at 0,3,6,9,12,...
static const Key dilate_t1 = (Key)0xB6DB6DB6DB6DB6DBLL ; // bits 0 at 2,5,8,11,14,... = ~tz
static const Key dilate_t2 = (Key)0xDB6DB6DB6DB6DB6DLL ; // bits 0 at 1,4,7,10,13,... = ~ty
static const Key dilate_t3 = (Key)0x6DB6DB6DB6DB6DB6LL ; // bits 0 at 0,3,6,9,12,... = ~tx
//_____________________________________________________________________________
// Step Directions Find Neighbours - 26 (dz,dy,dx)
static const Key dir_neigh[27] = { (Key)0xFFFFFFFFFFFFFFFFLL , // Direction (-1,-1,-1)
(Key)0x6DB6DB6DB6DB6DB6LL , // Direction (-1,-1, 0)
(Key)0x6DB6DB6DB6DB6DB7LL , // Direction (-1,-1, 1)
(Key)0xDB6DB6DB6DB6DB6DLL , // Direction (-1, 0,-1)
(Key)0x4924924924924924LL , // Direction (-1, 0, 0)
(Key)0x4924924924924925LL , // Direction (-1, 0, 1)
(Key)0xDB6DB6DB6DB6DB6FLL , // Direction (-1, 1,-1)
(Key)0x4924924924924926LL , // Direction (-1, 1, 0)
(Key)0x4924924924924927LL , // Direction (-1, 1, 1)
(Key)0xB6DB6DB6DB6DB6DBLL , // Direction ( 0,-1,-1)
(Key)0x2492492492492492LL , // Direction ( 0,-1, 0)
(Key)0x2492492492492493LL , // Direction ( 0,-1, 1)
(Key)0x9249249249249249LL , // Direction ( 0, 0,-1)
(Key)0x0000000000000000LL , // Direction ( 0, 0, 0)
(Key)0x0000000000000001LL , // Direction ( 0, 0, 1)
(Key)0x924924924924924BLL , // Direction ( 0, 1,-1)
(Key)0x0000000000000002LL , // Direction ( 0, 1, 0)
(Key)0x0000000000000003LL , // Direction ( 0, 1, 1)
(Key)0xB6DB6DB6DB6DB6DFLL , // Direction ( 1,-1,-1)
(Key)0x2492492492492496LL , // Direction ( 1,-1, 0)
(Key)0x2492492492492497LL , // Direction ( 1,-1, 1)
(Key)0x924924924924924DLL , // Direction ( 1, 0,-1)
(Key)0x0000000000000004LL , // Direction ( 1, 0, 0)
(Key)0x0000000000000005LL , // Direction ( 1, 0, 1)
(Key)0x924924924924924FLL , // Direction ( 1, 1,-1)
(Key)0x0000000000000006LL , // Direction ( 1, 1, 0)
(Key)0x0000000000000007LL , // Direction ( 1, 1, 1)
};
//_____________________________________________________________________________
//_____________________________________________________________________________
// octree depth level associated to a morton key ( = (bit length - 1) / 3 )
Level key_level ( Key k )
//_____________________________________________________________________________
{
static const real lg2_3 = 1.0 / (log(2)*3) ;
if( k == KEY_INV ) return L_INV ;
return (Level) floor( log(k) * lg2_3 ) ;
/*
Level count = 0 ;
do
{
k >>= 3 ;
++count;
}
while( k > 0 ) ;
return count-1 ;
*/
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// containment text implemented directly onf the key
bool key_contains( Key k_big, Key k_small )
//_____________________________________________________________________________
{
while( (k_small!=KEY_INV) && ((k_small>>3) != k_big) )
k_small >>= 3;
return k_small != KEY_INV ;
// k_small & 7
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// convert an octree cube to a morton key using integer contraction
Key cube2key ( const Cube &c )
//_____________________________________________________________________________
{
uint level = c.lv();
Key m = 1 << level ;
real sz = (real) m ;
Key bz = (Key) floor( c.z() * sz ) ;
Key by = (Key) floor( c.y() * sz ) ;
Key bx = (Key) floor( c.x() * sz ) ;
/*
if( bz >= m ) bz = m-1 ;
if( by >= m ) by = m-1 ;
if( bx >= m ) bx = m-1 ;
*/
if( level > three_2 )
{
bz = ( bz | (bz << shift_2a) | (bz << shift_2b) ) & dilate_mask_2 ;
by = ( by | (by << shift_2a) | (by << shift_2b) ) & dilate_mask_2 ;
bx = ( bx | (bx << shift_2a) | (bx << shift_2b) ) & dilate_mask_2 ;
}
if( level > three_1 )
{
bz = ( bz | (bz << shift_1a) | (bz << shift_1b) ) & dilate_mask_1 ;
by = ( by | (by << shift_1a) | (by << shift_1b) ) & dilate_mask_1 ;
bx = ( bx | (bx << shift_1a) | (bx << shift_1b) ) & dilate_mask_1 ;
}
if( level > three_0 )
{
bz = ( bz | (bz << shift_0a) | (bz << shift_0b) ) & dilate_mask_0 ;
by = ( by | (by << shift_0a) | (by << shift_0b) ) & dilate_mask_0 ;
bx = ( bx | (bx << shift_0a) | (bx << shift_0b) ) & dilate_mask_0 ;
}
return (Key(1) << (3*level)) | (bz << 2) | (by << 1) | bx ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// convert a morton key to a key using integer dilation
const Cube key2cube ( Key key )
//_____________________________________________________________________________
{
if( key == KEY_INV )
return C_INV ;
Level level = key_level( key ) ;
Key bz( (key >> 2) & dilate_mask_0 ) ;
Key by( (key >> 1) & dilate_mask_0 ) ;
Key bx( ( key ) & dilate_mask_0 ) ;
if( level > three_0 )
{
bz = ( bz | (bz >> shift_0a) | (bz >> shift_0b) ) & dilate_mask_1 ;
by = ( by | (by >> shift_0a) | (by >> shift_0b) ) & dilate_mask_1 ;
bx = ( bx | (bx >> shift_0a) | (bx >> shift_0b) ) & dilate_mask_1 ;
if( level > three_1 )
{
bz = ( bz | (bz >> shift_1a) | (bz >> shift_1b) ) & dilate_mask_2 ;
by = ( by | (by >> shift_1a) | (by >> shift_1b) ) & dilate_mask_2 ;
bx = ( bx | (bx >> shift_1a) | (bx >> shift_1b) ) & dilate_mask_2 ;
if( level > three_2 )
{
bz = bz | (bz >> shift_2a) | (bz >> shift_2b) ;
by = by | (by >> shift_2a) | (by >> shift_2b) ;
bx = bx | (bx >> shift_2a) | (bx >> shift_2b) ;
}
}
}
Key length_mask = (1 << level) -1 ;
bz &= length_mask ;
by &= length_mask ;
bx &= length_mask ;
Cube c ;
c.lv() = level ;
real sz = c.sz() ;
real sz2 = sz*2 ;
c.z() = (real)(bz) * sz2 + sz ;
c.y() = (real)(by) * sz2 + sz ;
c.x() = (real)(bx) * sz2 + sz ;
return c ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// addition in dilated integer
Key addition_locate_code( const Key& N , const Key& DN )
//-----------------------------------------------------------------------------
{
return (
( ((N | dilate_t1) + (DN & dilate_tz)) & dilate_tz ) |
( ((N | dilate_t2) + (DN & dilate_ty)) & dilate_ty ) |
( ((N | dilate_t3) + (DN & dilate_tx)) & dilate_tx )
);
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// addition in dilated integer
Key substraction_locate_code( const Key& N , const Key& DN )
//-----------------------------------------------------------------------------
{
return (
( ((N & dilate_tz) - (DN & dilate_tz)) & dilate_tz ) |
( ((N & dilate_ty) - (DN & dilate_ty)) & dilate_ty ) |
( ((N & dilate_tx) - (DN & dilate_tx)) & dilate_tx )
);
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// generate a list of 27 neighbor keys of same level, with their direction, indexed by 9*(dz+1) + 3*(dy+1) + (dx+1)
bool neighbor_keys( Key k, Key *neighbors )
//_____________________________________________________________________________
{
Level nbits_neigh = 3*key_level(k) ;
for( uint dir = 0 ; dir < 27 ; ++dir )
{
Key &nk = neighbors[dir] ;
if( dir == 13 ) { nk = KEY_INV ; continue ; }
nk = addition_locate_code( k , dir_neigh[dir] ) ;
if( (nk >> nbits_neigh) != 1 )
nk = KEY_INV ;
}
return true ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// generate a list of the subneighbor keys from a neighbor direction
// returns the number of subneighbors
char subneighbor_keys( Key k, char dir, std::stack<Key> &subneighbors )
//_____________________________________________________________________________
{
k <<= 3 ;
char nsub = nsubneighbors[dir] ;
for( char i = 0 ; i < nsub ; ++i )
{
subneighbors.push( k | l3b[dir][i] ) ;
}
return nsub ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
void print_binary( const Key k )
//_____________________________________________________________________________
{
printf( "0x" ) ;
for( char i = 63 ; i >= 0 ; --i )
printf( "%c", (k>>i)&1 ? '1' : '0' ) ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// generate a list of 8 vertices keys
Level vertices_keys( Key k, Key *verts )
//_____________________________________________________________________________
{
Level lv = key_level(k) ;
Key lv_k = 1 << (3*lv) ;
Key lv_K = lv_k << 1 ;
for( int i = 0 ; i < 8 ; ++i )
{
Key vk = addition_locate_code( k,i ) ;
if( vk >= lv_K || !((vk-lv_k)&dilate_tx) || !((vk-lv_k)&dilate_ty) || !((vk-lv_k)&dilate_tz) )
{
verts[i] = KEY_INV ;
continue ;
}
verts[i] = vk << 3*(MAX_LEVEL - lv) ;
}
return lv ;
/*
Level lv = key_level(k) ;
Key lv_k = 1 << (3*lv) ;
Key lv_K = lv_k << 1 ;
Cube c = key2cube(k) ;
const real ix = c.x () ;
const real iy = c.y () ;
const real iz = c.z () ;
const real is = c.sz() ;
for( int i = 0 ; i < 8 ; ++i )
{
Key vk = addition_locate_code( k,i ) ;
Cube v( (i&1) ? ix+is : ix-is,
(i&2) ? iy+is : iy-is,
(i&4) ? iz+is : iz-is,
MAX_LEVEL ) ;
bool invalid = (
v.x() <= 0.0 || v.x() >= 1 ||
v.y() <= 0.0 || v.y() >= 1 ||
v.z() <= 0.0 || v.z() >= 1
) ;
bool k_invalid = vk >= lv_K || !((vk-lv_k)&dilate_tx) || !((vk-lv_k)&dilate_ty) || !((vk-lv_k)&dilate_tz) ;
if( invalid != k_invalid )
printf( "problem\n" ) ;
if( invalid )
{
verts[i] = KEY_INV ;
continue ;
}
vk <<= 3*(MAX_LEVEL - lv) ;
verts[i] = cube2key(v) ;
if( vk != verts[i] )
printf( "problem\n" ) ;
}
return c.lv() ;
*/
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// generate a list of 8 dual vertices keys from a vertex key and the deepest neighbor level
bool dual_vertices_keys( Key k, Level lv, Key *dual_verts )
//_____________________________________________________________________________
{
Key dk = k >> (3*(MAX_LEVEL - lv)) ;
for( int i = 0 ; i < 8 ; ++i )
{
dual_verts[i] = substraction_locate_code( dk,i ) ;
}
return true ;
/*
Key dk = k >> (3*(MAX_LEVEL - lv)) ;
Cube c = key2cube( k ) ;
c.lv() = lv ;
const real ix = c.x () ;
const real iy = c.y () ;
const real iz = c.z () ;
const real is = c.sz() ;
// print_binary( k ) ;
// printf( " <- \n" ) ;
for( int i = 0 ; i < 8 ; ++i )
{
Cube dv( (i&1) ? ix+is : ix-is,
(i&2) ? iy+is : iy-is,
(i&4) ? iz+is : iz-is,
lv ) ;
dual_verts[i] = cube2key(dv) ;
if( substraction_locate_code( dk,7-i) != dual_verts[i] )
printf( "problem\n" ) ;
// print_binary( dual_verts[i] ) ;
// printf( "\n" ) ;
// print_binary( substraction_locate_code( dk,7-i) ) ;
// printf( "\n" ) ;
}
// printf( "\n" ) ;
return true ;
*/
}
//_____________________________________________________________________________
// testar que dois cubos se intersectam???

View File

@ -1,62 +0,0 @@
/**
* \file morton.h
* \author Thomas Lewiner <tomlew@puc-rio.br>
* \author Rener Pereira de Castro <rener@mat.puc-rio.br>
* \author Matmidia Lab, Math Dept, PUC-Rio
* \date 10/01/2010
*
* \brief Morton codes manipulation
*
* Morton codes manipulation
*/
//_____________________________________________________________________________
#pragma once
#ifndef WIN32
#pragma interface
#endif // WIN32
#include <stdint.h>
#include <stdio.h>
#include <math.h>
#include <stack>
#include "cube.h"
typedef uint64_t Key;
extern Key KEY_INV ;
const uint MAX_LEVEL = (sizeof(Key)*8-1)/3 ;
//_____________________________________________________________________________
/// octree depth level associated to a morton key ( = (bit length - 1) / 3 )
Level key_level ( Key k ) ;
/// containment text implemented directly onf the key
bool key_contains( Key k_big, Key k_small ) ;
/// convert an octree cube to a morton key using integer contraction
Key cube2key ( const Cube &c ) ;
/// convert a morton key to a key using integer dilation
const Cube key2cube ( Key k ) ;
/// generate a list of 27 neighbor keys of same level, with their direction, indexed by 9*(dx+1) + 3*(dy+1) + (dz+1)
bool neighbor_keys( Key k, Key *neighbors ) ;
/// generate a list of the subneighbor keys from a neighbor direction, and return the number of subneighbors
char subneighbor_keys( Key k, char dir, std::stack<Key> &subneighbors ) ;
/// generate a list of 8 vertices keys from a cell key
Level vertices_keys( Key k, Key *verts ) ;
/// generate a list of 8 dual vertices keys from a vertex key and the deepest neighbor level
bool dual_vertices_keys( Key k, Level lv, Key *dual_verts ) ;
//_____________________________________________________________________________

View File

@ -1,261 +0,0 @@
/**
* \file mvector.h
* \author Thomas Lewiner <tomlew@puc-rio.br>
* \author Matmidia Lab, Math Dept, PUC-Rio
* \date 10/01/2010
*
* \brief light array container
*
* Light array container
*/
//_____________________________________________________________________________
#pragma once
#include <stdlib.h>
#include <string.h> // memcpy, memset
#include <mlist.h>
/// unsigned int alias
typedef unsigned int uint ;
/// const unsigned int alias
typedef const uint cuint ;
/// default data size
#define INITIAL_MVECTOR_SIZE ((uint)1024)
//_____________________________________________________________________________
// mvector
/// \class mvector mvector.h
template< typename Data > class mvector
//-----------------------------------------------------------------------------
{
// Constructors
public :
/// Constructor
mvector() : _data((Data*)NULL), _allocated_size(0), _used_size(0) {} ;
/// Destructor
~mvector() { clear() ; }
// no copy on purpose
//------------------------------------------------
// Operations
public :
/// delete the data
void clear() { free(_data) ; _data = (Data*)NULL ; _allocated_size = 0 ; _used_size = 0 ; _deleted.clear() ; }
/// estimation of the memory that will be used
bool reserve( uint n )
{
if( n < INITIAL_MVECTOR_SIZE ) n = INITIAL_MVECTOR_SIZE ;
if( n <= _allocated_size ) return true ;
Data *temp = _data ;
_data = (Data*)malloc( n*sizeof(Data) ) ;
if( temp ) memcpy( _data, temp, _used_size*sizeof(Data) ) ;
memset( _data + _used_size, 0, (n-_used_size)*sizeof(Data) ) ;
free( temp ) ;
_allocated_size = n ;
return _data != (Data*)NULL ;
}
/// reserve space for n new elements
bool reserve_more( uint n )
{
if( _used_size + n > _allocated_size + _deleted.size() )
{
uint new_size = 2*_allocated_size ;
if( new_size < _used_size + n ) new_size = _used_size + n ;
//return reserve( 2*_allocated_size ) ;
return reserve( new_size ) ;
}
return true ;
}
/// insert n new elements
bool allocate_more( uint n )
{
if( !reserve_more( n ) ) return false ;
_used_size += n ;
return true ;
}
/// add one more element and
Data &add( uint &id )
{
if( _deleted.empty() )
{
id = _used_size ;
allocate_more( 1 ) ;
}
else
{
id = _deleted.first() ;
_deleted.remove_first() ;
}
return at(id) ;
}
/// lazy remotion
bool remove( uint id )
{
if( id+1 == _used_size )
--_used_size ;
else
_deleted.insert(id) ;
return true ;
}
//------------------------------------------------
// Accessor
public :
/// size accessor
uint size() { return _used_size - _deleted.size() ; }
/// size accessor
uint used_size() { return _used_size ; }
/// non checked const accessor
const Data &at( uint id ) const { return _data[id] ; }
/// non checked accessor
Data &at( uint id ) { return _data[id] ; }
/// non checked const accessor
const Data &operator[]( uint id ) const { return at(id) ; }
/// non checked accessor
Data &operator[]( uint id ) { return at(id) ; }
/// non checked pointer accessor
Data *operator +( uint id ) { return _data + id ; }
/// id range validity check
bool is_valid( uint id ) { return (id < size() && id>=0) ; }
/// id validity check
bool is_deleted( uint id ) { return is_valid(id) && _deleted.find(id) () ; }
//------------------------------------------------
// Elements
private :
/// main data array
Data *_data ;
/// real data size
uint _allocated_size ;
/// filled data size
uint _used_size ;
/// deleted data
List<uint> _deleted ;
//------------------------------------------------
// iterator
public :
/// iterator
class iterator
{
public :
// constructors
/// default constructors
iterator( mvector<Data> &vec_, uint id_ = 0 ) : _vec(vec_), _id(id_) {}
/// destructor
~iterator() {}
/// copy constructor
iterator( const iterator &it ) : _vec(it._vec), _id(it._id) {}
/// assignment operator
iterator &operator = ( const iterator &it )
{ _vec = it._vec; _id = it._id; return *this; }
//-----------------------------------------------------------------------------
// Operations
public :
/// equality operator
inline bool operator ==( const iterator &it ) const { return &_vec == &it._vec && _id == it._id ; }
/// inequality operator
inline bool operator !=( const iterator &it ) const { return &_vec != &it._vec || _id != it._id ; }
/// validation operator
inline bool operator ()() const { return _vec.is_valid( _id ) ; }
/// id accessor
inline uint id () const { return _id ; }
/// value accessor
inline const Data &operator * () const { return _vec[_id] ; }
/// value accessor
inline Data &operator * () { return _vec[_id] ; }
/// accesses the next position
inline iterator &operator ++() { do ++_id ; while( _vec.is_valid(_id) && _vec.is_deleted(_id) ) ; return *this ; }
//-----------------------------------------------------------------------------
// Elements
private :
mvector<Data> &_vec ; ///< data vector
uint _id ; ///< node position
};
//------------------------------------------------
// const_iterator
public :
/// const_iterator
class const_iterator
{
public :
// constructors
/// default constructors
const_iterator( const mvector<Data> &vec_, uint id_ = 0 ) : _vec(vec_), _id(id_) {}
/// destructor
~const_iterator() {}
//-----------------------------------------------------------------------------
// Operations
public :
/// equality operator
inline bool operator ==( const const_iterator &it ) const { return &_vec == &it._vec && _id == it._id ; }
/// inequality operator
inline bool operator !=( const const_iterator &it ) const { return &_vec != &it._vec || _id != it._id ; }
/// validation operator
inline bool operator ()() const { return _vec.is_valid( _id ) ; }
/// id accessor
inline uint id () const { return _id ; }
/// value accessor
inline const Data &operator * () const { return _vec[_id] ; }
/// accesses the next position
inline const_iterator &operator ++() { do ++_id ; while( _vec.is_valid(_id) && _vec.is_deleted(_id) ) ; return *this ; }
//-----------------------------------------------------------------------------
// Elements
private :
const mvector<Data> &_vec ; ///< data vector
uint _id ; ///< node position
};
public :
/// Node iterator creation
iterator begin( uint id = 0 ) { return iterator( *this, id ) ; }
/// Node const iterator creation
const_iterator cbegin( uint id = 0 ) { return const_iterator( *this, id ) ; }
};
//_____________________________________________________________________________

View File

@ -1,376 +0,0 @@
/**
* \file opt_octree.h
* \author Thomas Lewiner <tomlew@puc-rio.br>
* \author Matmidia Lab, Math Dept, PUC-Rio
* \date 10/01/2010
*
* Octree structure with hashtable and optimized operations
*/
//_____________________________________________________________________________
#pragma once
#ifndef WIN32
#pragma interface
#endif // WIN32
#include "mlist.h"
#include "cube.h"
#include "hash.h"
#include "MarchingCubes.h"
#include "mc_draw.h"
#include "data_access.h"
//_____________________________________________________________________________
// OptOctree
/// \class OptOctree OptOctree.h
class OptOctree
//-----------------------------------------------------------------------------
{
// forward declaration
public:
class geom_cell ;
class cell_iterator ;
class leaf_iterator ;
// Elements
protected:
/// Octree cell data structure
typedef Hash<real> HashField ;
/// Hashtable of the octree nodes
HashField _hash ;
/// Level distribution of the octree
uint _level_dist[MAX_LEVEL+1] ;
/// Optimal level for direct search in the octree
Level _opt_level ;
/// Maximal field of the octree
real _max_field ;
/// Isosurface
MarchingCubes _mc ;
/// Isosurface Draw
MC_Draw _mc_draw ;
private :
/// Octree vertices data structure
typedef Hash<Level> HashVerts ;
/// Hashtable of the octree vertices
HashVerts _verts ;
//-----------------------------------------------------------------------------
// Constructors
public:
/// Default constructor: Constructs a octree with and empty root
OptOctree() { init() ; }
/// Destructor: Free memory
~OptOctree() { clear() ; }
/// Create the root
void init() ;
/// Memory cleaning
void clear() { clear_octree() ; _mc.clean_all() ; }
/// Delete the content of the octree
void clear_octree() ;
/// Compute the optimal level
void compute_opt_level() ;
/// Check that only the leaves have data
bool check () ;
/// Prints statistics about the octree
void stats() const ;
/// Return the maximal level of the octree
Level max_level() const { Level lv = MAX_LEVEL ; while( lv > 0 && !_level_dist[lv] ) --lv ; return lv ; }
/// Return the optimal level of the octree
Level opt_level() const { return _opt_level ; }
/// Return the optimal level of the octree
Level &opt_level() { return _opt_level ; }
/// Return the maximal field of the octree
real max_field() const { return _max_field ; }
/// Return the isosurface
MarchingCubes &mc() { return _mc ; }
/// Return the isosurface draw
MC_Draw &mc_draw() { return _mc_draw ; }
/// set the values of each leaf from the implicit function
bool set_impl( data_access *ref = NULL ) ;
/// Refine the octree according to the data access
bool refine( data_access *ref = NULL ) ;
/// Adapt the octree according to the data access
bool adapt( data_access *ref = NULL ) ;
/// Draw the octree with wireframe
bool draw_wire() ;
/// Draw the octree with dots
bool draw_centers() ;
/// Dual function type
typedef bool opt_dual_walker( OptOctree &fo, Key *keys ) ;
/// Compute primal vertices
bool compute_primal_verts() ;
/// Walk on the dual cubes
bool dual_cubes_walk( opt_dual_walker &walker ) ;
/// Build the isosurface using dual marching cubes
bool build_isosurface( data_access *ref = NULL ) ;
/// Draw the isosurface on-the-fly using dual marching cubes
bool direct_draw_isosurface( data_access *ref = NULL ) ;
/// Draw the dual octree with wireframe
bool draw_dual() ;
/// Do nothing, just for dual generation timing
bool dual_timing() ;
//-----------------------------------------------------------------------------
// iterators
public:
/// Create an iterator traversing the tree from the root
inline cell_iterator cells_begin() { return cell_iterator( *this ) ; }
/// Create an iterator traversing the leaves of the tree from the root
inline leaf_iterator leaves_begin() { return leaf_iterator( *this ) ; }
//-----------------------------------------------------------------------------
// search operations
public:
/// Find cells of the octree at a given position
bool find_leaf( Key k, Level o_lv, geom_cell &cell ) const ;
bool find_leaf( Key k, geom_cell &cell ) const { return find_leaf( k, opt_level(), cell ) ; }
bool find_leaf( real x, real y, real z, geom_cell &cell ) const { return find_leaf( cube2key( Cube(x,y,z,MAX_LEVEL) ), opt_level(), cell ) ; }
/// Find cells of the octree inside a given box of center x,y,z and half side r
bool find_radius( real x, real y, real z, real r, List<geom_cell> &cells ) const ;
/// Find adjacent cells of the octree to a given cell
bool adjacent( Key k, List<geom_cell> &cells ) const ;
bool adjacent( const geom_cell &cell, List<geom_cell> &cells ) const { return adjacent( cell.key(), cells ) ; }
/// Leaf test based on the field value
bool is_leaf( const HashField::KeyData &kd ) const { return !is_inv( kd.data ) ; }
/// Leaf test based on the field value
bool is_leaf( Key k, real &d ) const { const HashField::KeyData &kd = _hash[k] ; d = kd.data ; return is_leaf( kd ) ; }
/// Leaf test based on the field value
bool is_leaf( Key k ) const { return is_leaf( _hash[k] ) ; }
/// Node existence
bool node_exists( Key k, HashField::KeyData &kd ) const { kd = _hash[k] ; return kd.key != KEY_INV ; }
//-----------------------------------------------------------------------------
// I/O
public:
/// Draws the intersecting cells of a plane with the octree with color
void draw_plane ( real nx, real ny, real nz, real d ) ;
/// Draws the intersection of a plane with the octree with color
void draw_slice ( real nx, real ny, real nz, real d, float alpha ) ;
/// Draws the isosurface of level l inside the dual graph
void draw_iso () { _mc.draw_surf() ; }
//_____________________________________________________________________________
// Iterator Cell
public :
/// Auxiliary structure to traverse the octree
class geom_cell : public Cube
//---------------------------------------------------------------------------
{
friend class OptOctree ;
protected:
Key _key ; ///< octree cell
real _field ; ///< field associated to the cell
//---------------------------------------------------------------------------
// Constructors
public:
/// Default constructor
geom_cell( Key key_ = KEY_INV, real field_ = R_INV ) : Cube(key2cube(key_)), _key(key_), _field(field_) {}
/// Default constructor
geom_cell( HashField::KeyData kd ) : Cube(key2cube(kd.key)), _key(kd.key), _field(kd.data) {}
/// Destructor
~geom_cell() {}
/// Copy constructor
geom_cell( const geom_cell &i ) : Cube(i), _key(i._key), _field(i._field) {}
/// Assignment operator
geom_cell &operator = ( const geom_cell &i )
{ Cube::operator=(i) ; _key = i._key ; _field = i._field ; return *this; }
//---------------------------------------------------------------------------
// Public constant accessors
public :
/// key const accessor
inline Key key() const { return _key ; }
/// key accessor
inline Key &key() { return _key ; }
/// id const accessor
inline real operator*() const { return _field ; }
//---------------------------------------------------------------------------
// Tests
public :
/// equality operator
inline bool operator ==( const geom_cell &i ) const { return key() == i.key() ; }
/// inequality operator
inline bool operator !=( const geom_cell &i ) const { return key() != i.key() ; }
/// leaf test
inline bool is_leaf() const { return !is_inv(*(*this)) ; }
/// validation operator
inline bool operator ()() const { return key() != KEY_INV ; }
//---------------------------------------------------------------------------
// Operations
public :
/// sons
inline bool sons( geom_cell *s /*[8]*/, const HashField &hash )
{
if( is_leaf() ) return false ;
Key k = _key << 3 ;
for( int i = 0 ; i < 8 ; ++i )
{
s[i]._key = k | i ;
s[i]._field = hash[k|i].data ;
(Cube&)s[i] = key2cube(s[i]._key) ;
}
return true ;
}
};
const geom_cell geom_root() const { const Key root_key = 1 ; return geom_cell( root_key, _hash[root_key].data ) ; }
const geom_cell geom_key ( Key k ) const { return geom_cell( k, _hash[k].data ) ; }
//_____________________________________________________________________________
// Cell Iterator
public :
/// Octree cell iterator : Traverse the octree returning basic information on the cells
class cell_iterator
//---------------------------------------------------------------------------
{
friend class OptOctree ;
protected:
/// Octree traversal iterator
HashField::iterator _it ;
//---------------------------------------------------------------------------
// Constructors
public:
/// Default constructor : Constructs an iterator from a cell
cell_iterator( OptOctree &o ) : _it( o._hash.begin() ) {}
/// Destructor
~cell_iterator() {}
/// Copy constructor
cell_iterator( const cell_iterator &i ) : _it(i._it) {}
/// Assignment operator
cell_iterator &operator = ( const cell_iterator &i )
{ _it = i._it; return *this; }
//---------------------------------------------------------------------------
// Operations
public :
/// equality operator
inline bool operator ==( const cell_iterator &i ) const { return _it == i._it ; }
/// inequality operator
inline bool operator !=( const cell_iterator &i ) const { return _it != i._it ; }
/// validation operator
inline bool operator ()() const { return _it() ; }
/// next position
inline cell_iterator &operator ++() { ++_it ; return *this ; }
//---------------------------------------------------------------------------
// Accessors
public :
// cell accessor
inline geom_cell top() const { return geom_cell( key(), *_it ) ; }
/// id accessor
inline real &operator*() { return *_it ; }
/// level accessor
inline Level lv() { return key_level(_it.key()) ; }
/// size accessor
inline real sz() { return Cube(0,0,0,lv()).sz() ; }
/// key accessor
inline Key key() const { return _it.key() ; }
/// points accessor
inline bool is_leaf() const { return !is_inv(*_it) ; }
/// Draws the cell wire with opengl
void draw_wire () const { top().draw_wire () ; }
};
/// Octree leaf iterator : Traverse the octree returning basic information on the leaves
class leaf_iterator : public cell_iterator
//---------------------------------------------------------------------------
{
public :
leaf_iterator( OptOctree &o ) : cell_iterator( o )
{ if( (*this)() && !this->is_leaf() ) ++(*this) ; }
/// next position
inline leaf_iterator &operator ++()
{
cell_iterator &it = *this ;
do ++it ; while ( it() && !it.is_leaf() ) ;
return *this ;
}
} ;
} ;
//_____________________________________________________________________________

View File

@ -1,265 +0,0 @@
/**
* \file perf_main.cpp
* \author Thomas Lewiner <tomlew@puc-rio.br>
* \author Matmidia Lab, Math Dept, PUC-Rio
* \date 10/01/2010
*
* Octree performances test
*/
//_____________________________________________________________________________
/*
with pointers
level 10,12: hash 27, non hash 31
level 8: hash 27, non hash 37
without pointers
level 10: hash 21, non hash 31
level 8: hash 21, non hash 37/40
*/
#define OCTREE_SWITCH 2
#ifdef OCTREE_SWITCH
# if OCTREE_SWITCH==0
# define OCTREE_PTR 1
# elif OCTREE_SWITCH==1
# define OCTREE_HASH 1
# elif OCTREE_SWITCH==2
# define OCTREE_OPT 1
# elif OCTREE_SWITCH==3
# define OCTREE_LEAF 1
# elif OCTREE_SWITCH==4
# define OCTREE_MEM 1
# endif // OCTREE_SWITCH
#endif // OCTREE_SWITCH
// switch values between pointer and hash octree
#if !OCTREE_PTR && !OCTREE_HASH && !OCTREE_OPT && !OCTREE_LEAF && !OCTREE_MEM
// # define OCTREE_PTR 1
// # define OCTREE_HASH 1
# define OCTREE_OPT 1
// # define OCTREE_LEAF 1
// # define OCTREE_MEM 1
#endif // !OCTREE_PTR && !OCTREE_HASH && !OCTREE_OPT && !OCTREE_LEAF && !OCTREE_MEM
#ifdef OCTREE_PTR
# undef OCTREE_HASH
# undef OCTREE_OPT
# undef OCTREE_LEAF
# undef OCTREE_MEM
# define OCTREE_STRING "0 pointer"
# include "ptr_octree.h"
/// octree type
typedef PtrOctree Octree ;
#endif //OCTREE_PTR
#ifdef OCTREE_HASH
# undef OCTREE_PTR
# undef OCTREE_OPT
# undef OCTREE_LEAF
# undef OCTREE_MEM
# define OCTREE_STRING "1 hash"
# include "hash_octree.h"
/// octree type
typedef HashOctree Octree ;
#endif //OCTREE_HASH
#ifdef OCTREE_OPT
# undef OCTREE_PTR
# undef OCTREE_HASH
# undef OCTREE_LEAF
# undef OCTREE_MEM
# define OCTREE_STRING "2 opt"
# include "opt_octree.h"
/// octree type
typedef OptOctree Octree ;
#endif //OCTREE_OPT
#ifdef OCTREE_LEAF
# undef OCTREE_PTR
# undef OCTREE_HASH
# undef OCTREE_OPT
# undef OCTREE_MEM
# define OCTREE_STRING "3 leaf"
# include "leaf_octree.h"
/// octree type
typedef LeafOctree Octree ;
#endif //OCTREE_LEAF
#ifdef OCTREE_MEM
# undef OCTREE_PTR
# undef OCTREE_HASH
# undef OCTREE_OPT
# undef OCTREE_LEAF
# define OCTREE_STRING "4 mem"
# include "mem_octree.h"
/// octree type
typedef MemOctree Octree ;
#endif //OCTREE_MEM
#ifndef NPOINTS
# define NPOINTS 100
#endif // NPOINTS
#ifndef RADIUS
# define RADIUS (0.003f)
#endif // RADIUS
#ifndef NDUALS
# define NDUALS 10
#endif // NDUALS
#ifndef MLEVEL
# define MLEVEL 5
#endif // MLEVEL
#ifndef IMPLFUN // set to 0 for random
# define IMPLFUN 1
#endif // IMPLFUN
#ifndef ISOVAL
# define ISOVAL 0.5
#endif // ISOVAL
#include "hash.h"
#include "implfuns.h"
#include <stdio.h>
//_____________________________________________________________________________
//
int main( int argc , char* argv[] )
//-----------------------------------------------------------------------------
{
#if OCTREE_LEAF && !USE_HASH_PTR
return 0 ;
#endif // OCTREE_LEAF && !USE_HASH_PTR
srand(77) ;
// Chrono::ResetClocks() ;
printf( "\n\n\n-----------------------------------------------------------------------------\n"
OCTREE_STRING
"\n\thash\t%s\tpointers\n"
"\thash bits =\t%d\n"
"\tnon hash bits=\t%d\n"
"\tmax_level =\t%d\n"
"\tdensity =\t%f\n"
"\tnpoints =\t%d\n"
"\tradius =\t%f\n"
"\timplicit function =\t%s\n"
"\tisovalue =\t%f\n"
"\tnumber of duals=\t%d\n\n",
(USE_HASH_PTR ? "with" : "without"), HASH_BITS, NON_HASH_BITS, MLEVEL, RAND_THRES, NPOINTS, RADIUS, fun_list[IMPLFUN], ISOVAL, NDUALS ) ;
fflush(stdout);
/// main data structure
Octree octree ;
#if IMPLFUN==0
data_rand ref( MLEVEL ) ;
octree.refine( &ref ) ;
#else // IMPLFUN
data_func ref( MLEVEL, ISOVAL, fun_def[IMPLFUN] ) ;
octree.refine( &ref ) ;
octree.set_impl( &ref ) ;
#endif // IMPLFUN
fflush(stdout);
/*
//-------------------------------------------------
// search for random points
Chrono::ResetClocks() ;
printf( "\n\nRandom Points\n" ) ;
for( int i = 0 ; i < NPOINTS ; ++i )
{
real x = (real)rand()/(real)RAND_MAX;
real y = (real)rand()/(real)RAND_MAX;
real z = (real)rand()/(real)RAND_MAX;
Octree::geom_cell gc ;
List<Octree::geom_cell> gc_list ;
octree.find_leaf( x,y,z, gc ) ;
octree.find_radius( x,y,z, RADIUS, gc_list ) ; gc_list.clear() ;
octree.adjacent( gc, gc_list ) ; gc_list.clear() ;
}
Chrono::PrintClocks() ;
fflush(stdout);
//-------------------------------------------------
//-------------------------------------------------
// search for all leaves once
printf( "\nLeaves\n" ) ;
Chrono::ResetClocks() ;
for( Octree::leaf_iterator it = octree.leaves_begin() ; it() ; ++it )
{
Octree::geom_cell g_it = it.top() ;
Octree::geom_cell gc ;
List<Octree::geom_cell> gc_list ;
octree.find_leaf( g_it.cx(), g_it.cy(), g_it.cz(), gc ) ;
octree.find_radius( g_it.cx(), g_it.cy(), g_it.cz(), RADIUS, gc_list ) ; gc_list.clear() ;
octree.adjacent( gc, gc_list ) ; gc_list.clear() ;
}
Chrono::PrintClocks() ;
fflush(stdout);
//-------------------------------------------------
//-------------------------------------------------
// search for all points at the maximal level
printf( "\n\nGrid\n" ) ;
Level lv = octree.max_level() - 4 ;
real step = 1.0 / (1 << lv) ;
Chrono::ResetClocks() ;
for( real x = 0.0 ; x <= 1.0 ; x += step )
{
for( real y = 0.0 ; y <= 1.0 ; y += step )
{
for( real z = 0.0 ; z <= 1.0 ; z += step )
{
Octree::geom_cell gc ;
List<Octree::geom_cell> gc_list ;
octree.find_leaf( x,y,z, gc ) ;
octree.find_radius( x,y,z, RADIUS, gc_list ) ; gc_list.clear() ;
octree.adjacent( gc, gc_list ) ; gc_list.clear() ;
}
}
}
Chrono::PrintClocks() ;
fflush(stdout);
//-------------------------------------------------
*/
//-------------------------------------------------
// build many duals
printf( "\n\nDuals\n" ) ;
// Chrono::ResetClocks() ;
for( int i = 0 ; i < NDUALS ; ++i )
{
#if IMPLFUN==0
octree.dual_timing() ;
#else // IMPLFUN
octree.mc().clean_all() ;
octree.build_isosurface(&ref) ;
#endif // IMPLFUN
}
// Chrono::PrintClocks() ;
octree.stats() ;
fflush(stdout);
//-------------------------------------------------
return 0;
}
//_____________________________________________________________________________

View File

@ -1,289 +0,0 @@
/**
* \file point.h
* \author Thomas Lewiner <tomlew@puc-rio.br>
* \author Matmidia Lab, Math Dept, PUC-Rio
* \date 10/01/2010
*
* \brief (Point/Vector Class).
*/
/**------------------------------------------------------------------------------------*/
#pragma once
#include <stdlib.h>
#include <float.h> // FLT_EPSILON
#include <math.h> // nan
#ifdef UNIX
#include <GL/gl.h>
#else
#include <OpenGL/GL.h>
#endif
//------------------------------------------------
/** real number type */
typedef float real ;
typedef const real creal ;
#define R_PI ((creal)3.1415926535897932384626433832795)
#define R_EPSILON ((real)FLT_EPSILON)
inline bool is_inv( real x ) { return isnan(x) ; }
extern real R_INV ;
/** integer number aliases */
typedef signed char schar ;
typedef unsigned char uchar ;
typedef unsigned int uint ;
typedef const int cint ;
typedef const uint cuint ;
/** \brief Axis Definition */
enum Axis { X = 0, Y = 1, Z = 2 } ;
//------------------------------------------------
/** \brief point with normal */
class Point
{
protected :
real _x, _y, _z ;
public :
Point() : _x(R_INV), _y(R_INV), _z(R_INV) {}
Point( creal x_, creal y_, creal z_ ) : _x(x_), _y(y_), _z(z_) {}
Point( const Point &p_ ) : _x(p_._x), _y(p_._y), _z(p_._z) {}
Point &operator = ( const Point &p_ )
{ _x=p_._x ; _y=p_._y ; _z=p_._z ; return *this; }
public :
inline real &x() { return _x ; }
inline real &y() { return _y ; }
inline real &z() { return _z ; }
inline creal x() const { return _x ; }
inline creal y() const { return _y ; }
inline creal z() const { return _z ; }
inline creal &operator[] ( Axis a ) const
{ switch( a ) {
case X : return _x ;
case Y : return _y ;
case Z : return _z ;
default: return R_INV ;
} }
inline real &operator[] ( Axis a )
{ switch( a ) {
case X : return _x ;
case Y : return _y ;
case Z : return _z ;
default: return R_INV ;
} }
/**------------------------------------------------------------------------------------*/
inline bool valid()
{
return
( !is_inv( x() ) ) &&
( !is_inv( y() ) ) &&
( !is_inv( z() ) ) ;
}
inline bool invalid()
{
return
( is_inv( x() ) ) ||
( is_inv( y() ) ) ||
( is_inv( z() ) ) ;
}
/**------------------------------------------------------------------------------------*/
// Basic operations
/// +=
inline Point &operator+= ( const Point &p_ )
{
x() += p_.x() ; y() += p_.y() ; z() += p_.z() ;
return *this ;
}
/// unary -
inline const Point operator- ()
{
x() = -x() ; y() = -y() ; z() = -z() ;
return *this ;
}
/// -=
inline Point &operator-= ( const Point &p_ )
{
x() -= p_.x() ; y() -= p_.y() ; z() -= p_.z() ;
return *this ;
}
/// *= scalar
inline Point &operator*= ( const real l )
{
x() *= l ; y() *= l ; z() *= l ;
return *this ;
}
/// /= scalar
inline Point &operator/= ( const real l )
{
if( fabs(l) < R_EPSILON ) return *this ;
real s = 1.0/l ;
return *this *= s ;
}
/**------------------------------------------------------------------------------------*/
// Norms
inline real length () const
{
return hypot( hypot( x(), y() ), z() ) ;
}
inline real norm () const { return length() ; }
inline real dist ( const Point &p_ ) const { Point r = *this ; r -= p_ ; return r.length() ; }
inline bool operator== ( const Point &p_ ) const { return dist( p_ ) < R_EPSILON ; }
inline bool operator!= ( const Point &p_ ) const { return !( *this == p_ ) ; }
inline bool normalize()
{
real l = length() ;
if( l < R_EPSILON ) return false ;
*this /= l ;
return true ;
}
/** replaces p by the by-coordinate minimum of p and p_ */
inline void pmin( const Point &p_ )
{
if( x() > p_.x() ) x() = p_.x() ;
if( y() > p_.y() ) y() = p_.y() ;
if( z() > p_.z() ) z() = p_.z() ;
}
/** replaces p by the by-coordinate maximum of p and p_ */
inline void pmax( const Point &p_ )
{
if( x() < p_.x() ) x() = p_.x() ;
if( y() < p_.y() ) y() = p_.y() ;
if( z() < p_.z() ) z() = p_.z() ;
}
//-----------------------------------------------------------------------------
// Drawing
public:
/// Draws the point with opengl
void draw () const { ::glVertex3f( (float)x(), (float)y(), (float)z() ) ; }
} ;
// Valid point
extern Point P_INV ;
/**------------------------------------------------------------------------------------*/
// Geometric Operations
/// +
inline const Point operator+ ( const Point &p, const Point &p_ )
{
Point r = p ;
return (r += p_) ;
}
/// -
inline const Point operator- ( const Point &p, const Point &p_ )
{
Point r = p ;
return r -= p_ ;
}
/// * scalar
inline const Point operator* ( const Point &p, const real l )
{
Point r = p ;
return r *= l ;
}
/// * scalar
inline const Point operator* ( const real l, const Point &p )
{
return p * l ;
}
/// / scalar
inline const Point operator/ ( const Point &p, const real l )
{
Point r = p ;
return r /= l ;
}
/// scalar (dot) product
inline real operator* ( const Point &p, const Point &p_ )
{
return p.x()*p_.x() + p.y()*p_.y() + p.z()*p_.z() ;
}
/// vector (cross) product
static inline const Point operator^ ( const Point &p, const Point &p_ )
{
Point r ;
r.x() = p.y() * p_.z() - p.z() * p_.y() ;
r.y() = p.z() * p_.x() - p.x() * p_.z() ;
r.z() = p.x() * p_.y() - p.y() * p_.x() ;
return r ;
}
static inline real det( const Point &p, const Point &q, const Point &r )
{
return
p.x()*q.y()*r.z() + p.y()*q.z()*r.x() + p.z()*q.x()*r.y() -
p.z()*q.y()*r.x() - p.x()*q.z()*r.y() - p.y()*q.x()*r.z() ;
}
/**------------------------------------------------------------------------------------*/
// Geometric Operations
inline real length ( const Point &p ) { return p.length() ; }
inline real norm ( const Point &p ) { return p.norm() ; }
inline real dist ( const Point &p, const Point &p_ ) { return p.dist(p_) ; }
inline real sqdist ( const Point &p, const Point &p_ ) { Point r = p-p_ ; return r*r ; }
/** \brief Computes the normal of a triangle
* \param const Point &v0
* \param const Point &v1
* \param const Point &v2 */
inline const Point normal (const Point & v0, const Point & v1, const Point & v2)
{
Point n = ( v1-v0 ) ^ ( v2 - v0 ) ;
n.normalize() ;
return n ;
}
/** \brief Computes the area of a triangle
* \param const Point &v0
* \param const Point &v1
* \param const Point &v2 */
inline real area (const Point & v0, const Point & v1, const Point & v2)
{
return 0.5 * norm( ( v1-v0 ) ^ ( v2 - v0 ) );
}
/** \brief Computes the cotangent of ange v v1,v v2
* \param const Point &v
* \param const Point &v1
* \param const Point &v2 */
inline const real cotan (const Point & v, const Point & v1, const Point & v2)
{
Point u = v1-v ;
Point w = v2-v ;
return (u*w) / norm( u ^ w ) ;
}
/** \brief Computes the middle of an edge
* \param const Point &v0
* \param const Point &v1 */
inline const Point middle (const Point & v0, const Point & v1)
{
return 0.5 * (v0+v1) ;
}
inline void pmin( Point &p, const Point &p_ ) { p.pmin( p_ ) ; }
inline void pmax( Point &p, const Point &p_ ) { p.pmax( p_ ) ; }

View File

@ -1,400 +0,0 @@
/**
* \file ptr_octree.h
* \author Thomas Lewiner <tomlew@puc-rio.br>
* \author Matmidia Lab, Math Dept, PUC-Rio
* \date 10/01/2010
*
* Octree structure with son-brother pointers
*/
//_____________________________________________________________________________
#pragma once
#ifndef WIN32
#pragma interface
#endif // WIN32
#include <stack>
#include "mlist.h"
#include "cube.h"
#include "MarchingCubes.h"
#include "mc_draw.h"
#include "data_access.h"
//_____________________________________________________________________________
// PtrOctree
/// \class PtrOctree PtrOctree.h
class PtrOctree
//-----------------------------------------------------------------------------
{
// forward declaration
public:
class geom_cell ;
class cell_iterator ;
class leaf_iterator ;
// Elements
protected:
/// Octree cell data structure
typedef struct cell
{
struct cell *brother ; ///< next brother of the cell
struct cell *first_son ; ///< first son of the cell
real field ; ///< field supported by the cell
} cell ;
/// Root of the octree
cell _root ;
/// Maximal level of the octree (for find_adjacent)
Level _max_level ;
/// Maximal field of the octree
real _max_field ;
/// Isosurface
MarchingCubes _mc ;
/// Isosurface Draw
MC_Draw _mc_draw ;
/// Dual run memory consumption
uint _dual_temp_memory ;
//-----------------------------------------------------------------------------
// Constructors
public:
/// Default constructor: Constructs a octree with and empty root
PtrOctree() { init() ; }
/// Destructor: Free memory
~PtrOctree() { clear() ; }
/// Create the root
void init() ;
/// Memory cleaning
void clear() { clear_octree() ; _mc.clean_all() ; }
/// Delete the branch below a given node
void clear_branch( cell *b ) ;
/// Delete the content of the octree
void clear_octree() { clear_branch( &_root ) ; }
/// Check that only the leaves have data
bool check () ;
/// Prints statistics about the octree
void stats() ;
/// Return the maximal level of the octree
Level max_level() const { return _max_level ; }
/// Return the maximal field of the octree
real max_field() const { return _max_field ; }
/// Return the isosurface
MarchingCubes &mc() { return _mc ; }
/// Return the isosurface draw
MC_Draw &mc_draw() { return _mc_draw ; }
/// set the values of each leaf from the implicit function
bool set_impl( data_access *ref = NULL ) ;
/// Refine the octree according to the data access
bool refine( data_access *ref = NULL ) ;
/// Adapt the octree according to the data access
bool adapt( data_access *ref = NULL ) ;
/// Draw the octree with wireframe
bool draw_wire() ;
/// Draw the octree with dots
bool draw_centers() ;
/// Dual function type
typedef bool ptr_dual_walker( PtrOctree &fo, geom_cell *cells ) ;
/// Walk on the dual cubes
bool dual_cubes_walk( ptr_dual_walker &walker ) ;
/// Build the isosurface using dual marching cubes
bool build_isosurface( data_access *ref = NULL ) ;
/// Draw the isosurface on-the-fly using dual marching cubes
bool direct_draw_isosurface( data_access *ref = NULL ) ;
/// Draw the dual octree with wireframe
bool draw_dual() ;
/// Do nothing, just for dual generation timing
bool dual_timing() ;
//-----------------------------------------------------------------------------
// iterators
public:
/// Create an iterator traversing the tree from the root
inline cell_iterator cells_begin() { return cell_iterator( &_root ) ; }
/// Create an iterator traversing the leaves of the tree from the root
inline leaf_iterator leaves_begin() { return leaf_iterator( &_root ) ; }
//-----------------------------------------------------------------------------
// search operations
public:
/// Find cells of the octree at a given position
bool find_leaf( real x, real y, real z, geom_cell &cell ) ;
/// Find cells of the octree inside a given box of center x,y,z and half side r
bool find_radius( real x, real y, real z, real r, List<geom_cell> &cells ) ;
/// Find adjacent cells of the octree to a given cell
bool adjacent( const geom_cell &cell, List<geom_cell> &cells ) ;
//-----------------------------------------------------------------------------
// I/O
public:
/// Draws the intersecting cells of a plane with the octree with color
void draw_plane ( real nx, real ny, real nz, real d ) ;
/// Draws the intersection of a plane with the octree with color
void draw_slice ( real nx, real ny, real nz, real d, float alpha ) ;
/// Draws the isosurface of level l inside the dual graph
void draw_iso () { _mc.draw_surf() ; }
//_____________________________________________________________________________
// Iterator Cell
public :
/// Auxiliary structure to traverse the octree
class geom_cell : public Cube
//---------------------------------------------------------------------------
{
friend class PtrOctree ;
protected:
PtrOctree::cell *_cell ; ///< octree cell
//---------------------------------------------------------------------------
// Constructors
public:
/// Default constructor: Constructs an iterator from a cell
geom_cell( PtrOctree::cell *cell_ = NULL, real cx_ = 0.5, real cy_ = 0.5, real cz_ = 0.5, Level lv_ = 0 )
: Cube(cx_,cy_,cz_,lv_), _cell(cell_) {}
/// Destructor
~geom_cell() {}
/// Copy constructor
geom_cell( const geom_cell &i )
: Cube(i), _cell(i._cell) {}
/// Assignment operator
geom_cell &operator = ( const geom_cell &i )
{ Cube::operator=(i); _cell=i._cell; return *this; }
//---------------------------------------------------------------------------
// Public constant accessors
public :
/// cell const accessor
inline const PtrOctree::cell * cell() const { return _cell ; }
/// cell accessor
inline PtrOctree::cell *&cell() { return _cell ; }
/// first son const accessor
inline const PtrOctree::cell * first_son() const { return _cell->first_son ; }
/// first son accessor
inline PtrOctree::cell *&first_son() { return _cell->first_son ; }
/// brother const accessor
inline const PtrOctree::cell * brother() const { return _cell->brother ; }
/// brother accessor
inline PtrOctree::cell *&brother() { return _cell->brother ; }
/// id const accessor
inline real operator*() const { return cell()->field ; }
/// id accessor
inline real &operator*() { return cell()->field ; }
//---------------------------------------------------------------------------
// Tests
public :
/// equality operator
inline bool operator ==( const geom_cell &i ) const { return cell() == i.cell() ; }
/// inequality operator
inline bool operator !=( const geom_cell &i ) const { return cell() != i.cell() ; }
/// leaf test
inline bool is_leaf() const { return first_son() == NULL ; }
/// validation operator
inline bool operator ()() const { return cell() != NULL ; }
//---------------------------------------------------------------------------
// Operations
public :
/// sons
inline bool sons( geom_cell *s /*[8]*/ )
{
if( !first_son() ) return false ;
int level_ = lv() + 1 ;
real sz_ = sz() / 2.0 ;
for( int i = 0 ; i < 8 ; ++i )
{
s[i].cell () = (i==0) ? first_son() : s[i-1].brother() ;
s[i].lv () = level_ ;
s[i].cx () = (i&1) ? cx() + sz_ : cx() - sz_ ;
s[i].cy () = (i&2) ? cy() + sz_ : cy() - sz_ ;
s[i].cz () = (i&4) ? cz() + sz_ : cz() - sz_ ;
}
return true ;
}
/// get son from side i
inline bool son( int i , geom_cell &s )
{
if( is_leaf() ) return false ;
real sz_ = s.sz() / 2.0 ;
++s.lv() ;
s.cx() = (i&1) ? cx() + sz_ : cx() - sz_ ;
s.cy() = (i&2) ? cy() + sz_ : cy() - sz_ ;
s.cz() = (i&4) ? cz() + sz_ : cz() - sz_ ;
s.cell() = first_son() ;
while( --i > -1 ) s.cell() = s.brother() ;
return true ;
}
};
//_____________________________________________________________________________
// Cell Iterator
public :
/// Octree cell iterator : Traverse the octree returning basic information on the cells
class cell_iterator
//---------------------------------------------------------------------------
{
friend class PtrOctree ;
protected:
/// Octree traversal stack
std::stack<geom_cell> _s ;
//---------------------------------------------------------------------------
// Constructors
public:
/// Default constructor : Constructs an iterator from a cell
cell_iterator( PtrOctree::cell *root = NULL, real cx_ = 0.5, real cy_ = 0.5, real cz_ = 0.5, Level lv_ = 0 )
{ if( root ) _s.push( geom_cell( root, cx_, cy_, cz_, lv_ ) ) ; }
/// Destructor
~cell_iterator() {}
/// Copy constructor
cell_iterator( const cell_iterator &i ) : _s(i._s) {}
/// Assignment operator
cell_iterator &operator = ( const cell_iterator &i )
{ _s = i._s; return *this; }
//---------------------------------------------------------------------------
// Operations
public :
/// validation operator
inline bool operator ()() const { return !_s.empty() ; }
/// next position
inline cell_iterator &operator ++()
{
if( _s.empty() ) return *this ;
geom_cell n = _s.top() ; _s.pop() ;
if( n.is_leaf() ) return *this ;
// depth first search
geom_cell sons[8] ;
n.sons( sons ) ;
for( int i = 0 ; i < 8 ; ++i )
_s.push( sons[i] ) ;
return *this ;
}
//---------------------------------------------------------------------------
// Accessors
public :
/// geom_cell accessor
inline geom_cell &top() { return _s.top() ; }
/// id accessor
inline real &operator*() { return * _s.top() ; }
/// level accessor
inline Level &lv() { return _s.top().lv() ; }
/// center x position accessor
inline real &cx() { return _s.top().cx() ; }
/// center y position accessor
inline real &cy() { return _s.top().cy() ; }
/// center y position accessor
inline real &cz() { return _s.top().cz() ; }
/// size accessor
inline real sz() { return _s.top().sz() ; }
/// points accessor
inline bool is_leaf() const { return _s.top().is_leaf() ; }
/// inside test
inline bool contains( real x, real y, real z ) const { return _s.top().contains( x,y,z ) ; }
/// get son from its side:
inline bool son( int i , geom_cell &s_ ) { return _s.top().son(i,s_) ; }
/// Draws the cell wire with opengl
void draw_wire () const { _s.top().draw_wire () ; }
protected :
/// stack accessor for ad hoc iterations
inline std::stack< geom_cell > &s() { return _s ; }
};
/// Octree leaf iterator : Traverse the octree returning basic information on the leaves
class leaf_iterator : public cell_iterator
//---------------------------------------------------------------------------
{
public :
leaf_iterator( PtrOctree::cell *root = NULL, real cx_ = 0.5, real cy_ = 0.5, real cz_ = 0.5, Level lv_ = 0 ) : cell_iterator( root, cx_,cy_,cz_,lv_ )
{ if( root && !this->is_leaf() ) ++(*this) ; }
/// next position
inline leaf_iterator &operator ++()
{
cell_iterator &it = *this ;
do ++it ; while ( it() && !it.is_leaf() ) ;
return *this ;
}
} ;
} ;
//_____________________________________________________________________________

View File

@ -1,71 +0,0 @@
/**
* @file glui_cmdline.cpp
* @author Thomas Lewiner <thomas.lewiner@polytechnique.org>
* @author Math Dept, PUC-Rio
* @version 0.1
* @date 20/08/2007
*
* @brief Example Graphical interface: command line parser
*/
//________________________________________________
#ifndef WIN32
#pragma implementation "viz_glui_defs.h"
#endif // WIN32
#include "viz_glui_defs.h"
//_____________________________________________________________________________
// parse command line
bool parse_command_line(int argc, char* argv[])
//-----------------------------------------------------------------------------
{
bool quit = false ;
for( int i = 1 ; i < argc ; ++i )
{
if ( !strcmp( argv[i], "-lv" ) )
{
if( ++i != argc ) { max_level = atoi( argv[i] ) ; }
}
else if( !strcmp( argv[i], "+ortho" ) )
{
ortho = true ;
}
else if( !strcmp( argv[i], "-ortho" ) )
{
ortho = false ;
}
else if( !strcmp( argv[i], "-pos" ) )
{
if( ++i != argc ) { obj_pos[0] = atof( argv[i] ) ; }
if( ++i != argc ) { obj_pos[1] = atof( argv[i] ) ; }
if( ++i != argc ) { obj_pos[2] = atof( argv[i] ) ; }
}
else if( !strcmp( argv[i], "-rot" ) )
{
for( int j = 0 ; j < 16 ; ++j )
if( ++i != argc ) { view_rotate[j] = atof( argv[i] ) ; }
}
else if( !strcmp( argv[i], "-view" ) )
{
control_cb( LOAD_VIEWPORT_ID ) ;
}
else if( !strcmp( argv[i], "-q" ) )
{
quit = true ;
}
else if( !strcmp( argv[i], "-h" ) )
{
printf( "usage %s [-in file.xyz] [-q]\n", argv[0] ) ;
}
}
// glui_side ->sync_live() ;
glui_bottom->sync_live() ;
return quit ;
}
//_____________________________________________________________________________

View File

@ -1,346 +0,0 @@
/**
* @file glui_controls.cpp
* @author Thomas Lewiner <thomas.lewiner@polytechnique.org>
* @author Math Dept, PUC-Rio
* @version 0.1
* @date 30/05/2006
*
* @brief Octree graphical interface: interface controls
*/
//________________________________________________
#if !defined(WIN32) || defined(__CYGWIN__)
#pragma implementation "viz_glui_defs.h"
#endif // WIN32
#include "viz_glui_defs.h"
#include "implfuns.h"
//_____________________________________________________________________________
// declarations of this file
// main object: octree
Octree octree ;
// switch between implicit funciont or volumetric data
int impl_data = SWITCH_DATA ;
// octree implicit data wrapper
data_func *dat_func = NULL ;
// octree data file wrapper
data_file *dat_data = NULL ;
// maximal level of the tree
int max_level = 4;
// isovalue
float iso_val = 0.0 ;
// curvature threshold
float curv_thres = 0.5 ;
// selected implicit function
int curr_fun = 0 ;
//-----------------------------------------------------------------------------
// main glui class: (right) side panel
GLUI *glui_side = NULL ;
// bottom panel
GLUI *glui_bottom = NULL ;
// name of the import file
GLUI_FileBrowser *file_browser ;
// iso file
GLUI_String filename ;
// formula of the implicit function
GLUI_String impl_fun ;
//-----------------------------------------------------------------------------
// control events callback
void control_cb( int control ) ;
// create side panel
void create_side_panel() ;
// create bottom panel
void create_bottom_panel() ;
/// set file extension
int set_ext( const char ext[4] ) ;
//_____________________________________________________________________________
//_____________________________________________________________________________
// control events callback
void control_cb( int control )
//-----------------------------------------------------------------------------
{
data_access *ref = NULL ;
switch( impl_data )
{
case SWITCH_IMPL : ref = dat_func ; break ;
case SWITCH_DATA : ref = dat_data ; break ;
}
switch( control )
{
case SET_IMPL_DATA_ID :
switch( impl_data )
{
case SWITCH_IMPL : delete dat_func ; dat_func = new data_func ( max_level, iso_val, impl_fun ) ; break ;
case SWITCH_DATA : delete dat_data ; dat_data = new data_file ( max_level, iso_val, filename.c_str() ) ; break ;
}
break ;
case SET_VAL_ID :
if( !ref ) break ;
ref->_max_level = max_level ;
ref->_iso_val = iso_val ;
octree.set_impl( ref ) ;
octree.check() ;
break ;
case REFINE_ID :
if( !ref ) break ;
ref->_max_level = max_level ;
ref->_iso_val = iso_val ;
octree.clear() ;
octree.refine( ref ) ;
octree.set_impl( ref ) ;
octree.check() ;
break ;
case ADAPT_ID :
if( !ref ) break ;
ref->_max_level = max_level ;
ref->_iso_val = iso_val ;
octree.adapt( ref ) ;
octree.set_impl( ref ) ;
octree.check() ;
break ;
case ISO_BUILD_ID :
if( !ref ) break ;
ref->_iso_val = iso_val ;
octree.build_isosurface(ref) ;
octree.mc().writeOFF("iso.off") ;
octree.check() ;
break ;
// set implicit function
case FUN_ID :
if( curr_fun == 0 ) break ;
impl_fun.clear() ;
impl_fun = fun_def[curr_fun] ;
control_cb( SET_IMPL_DATA_ID ) ;
control_cb( ADAPT_ID ) ;
glui_bottom->sync_live() ;
break ;
// load/save viewpoint
case SAVE_VIEWPORT_ID : save_viewport() ; break ;
case LOAD_VIEWPORT_ID : load_viewport() ; glui_bottom->sync_live() ; break ;
// reset rotation
case RESET_ROTATION_ID :
view_rotate[ 0] = view_rotate[ 5] = view_rotate[10] = view_rotate[15] = 1.0f ;
view_rotate[ 1] = view_rotate[ 2] = view_rotate[ 3] = view_rotate[ 4] = 0.0f ;
view_rotate[ 6] = view_rotate[ 7] = view_rotate[ 8] = view_rotate[ 9] = 0.0f ;
view_rotate[11] = view_rotate[12] = view_rotate[13] = view_rotate[14] = 0.0f ;
break ;
// reset translation
case RESET_TRANSLATION_ID : obj_pos[0] = obj_pos[1] = 0.0f ; break ;
// reset zoom
case RESET_ZOOM_ID : obj_pos[2] = 0.0f ; break ;
// changed a parameter
case REDRAW_ID : break ;
// changed a parameter
case FILENAME_ID : filename = file_browser->current_dir + file_browser->get_file() ;
// orthographic/perspective projection
case PROJ_ID : reshape (0,0) ; break ;
case EXIT_ID :
delete dat_func ;
delete dat_data ;
octree.clear() ;
exit(0) ;
break ;
default : break ;
}
::glutPostRedisplay();
}
//_____________________________________________________________________________
//_____________________________________________________________________________
//_____________________________________________________________________________
//_____________________________________________________________________________
// create side panel
void create_side_panel()
//-----------------------------------------------------------------------------
{
glui_side = NULL ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// create bottom panel
void create_bottom_panel()
//-----------------------------------------------------------------------------
{
GLUI_Rollout *roll ;
GLUI_EditText *text ;
GLUI_Rotation *rot ;
GLUI_Translation *trans;
GLUI_RadioGroup *radio;
GLUI_Listbox *list ;
GLUI_Scrollbar *sb ;
glui_bottom = GLUI_Master.create_glui("controls") ; //create_glui_subwindow( main_window, GLUI_SUBWINDOW_BOTTOM );
//--------------------------------------------------//
file_browser = new GLUI_FileBrowser( glui_bottom, "iso file", false, FILENAME_ID, control_cb ) ;
file_browser->current_dir = "data" ;
file_browser->fbreaddir( "data" ) ;
filename = "data/engine.iso.gz";
text = glui_bottom ->add_edittext( "iso file" , filename ) ;
text->set_w( 200 ) ;
list = glui_bottom->add_listbox( "Implicit Functions:", &curr_fun, FUN_ID, control_cb );
for( int i=0; i<NFUNS; i++ ) list->add_item( i, fun_list[i] );
impl_fun = "";
text = glui_bottom ->add_edittext( "impl fun" , impl_fun ) ;
text->set_w( 200 ) ;
//--------------------------------------------------//
//
roll = glui_bottom ->add_rollout( "iso value", true );
sb = new GLUI_Scrollbar( roll, "iso value in [-1,1]",GLUI_SCROLL_HORIZONTAL, &iso_val, ADAPT_ID,control_cb);
sb->set_float_limits(-1,1);
sb->set_speed( .005f );
roll = glui_bottom ->add_rollout( "level in [2,7]", true );
sb = new GLUI_Scrollbar( roll, "level", GLUI_SCROLL_HORIZONTAL, &max_level, ADAPT_ID, control_cb);
sb->set_int_limits(2,7);
sb->set_speed( .005f );
//--------------------------------------------------//
glui_bottom->add_column( true );
radio = glui_bottom->add_radiogroup( &impl_data, SET_IMPL_DATA_ID, control_cb ) ;
glui_bottom->add_radiobutton_to_group( radio, "Implicit function" ) ;
glui_bottom->add_radiobutton_to_group( radio, "Direct data file" ) ;
//--------------------------------------------------//
glui_bottom ->add_button ( "load" , SET_IMPL_DATA_ID, control_cb ) ;
glui_bottom ->add_button ( "set values", SET_VAL_ID , control_cb ) ;
glui_bottom ->add_button ( "refine" , REFINE_ID, control_cb ) ;
glui_bottom ->add_button ( "adapt" , ADAPT_ID , control_cb ) ;
//--------------------------------------------------//
// display element
glui_bottom->add_checkbox( "ortho" , &ortho , PROJ_ID , control_cb );
glui_bottom->add_checkbox( "octree" , &show_octree , REDRAW_ID, control_cb );
glui_bottom->add_checkbox( "nodes" , &show_nodes , REDRAW_ID, control_cb );
glui_bottom->add_checkbox( "dual" , &show_dual , REDRAW_ID, control_cb );
glui_bottom->add_checkbox( "surface" , &show_iso , REDRAW_ID, control_cb );
glui_bottom->add_checkbox( "dir surf" , &show_direct_iso , SET_VAL_ID, control_cb );
glui_bottom->add_checkbox( "dir sur w", &show_direct_iso_wire, SET_VAL_ID, control_cb );
glui_bottom ->add_button ( "Isosurface", ISO_BUILD_ID, control_cb ) ;
// glui_bottom->add_button( "Redraw", REDRAW_ID, control_cb ) ;
glui_bottom ->add_button( "Open View", LOAD_VIEWPORT_ID, control_cb ) ;
glui_bottom ->add_button( "Save View", SAVE_VIEWPORT_ID, control_cb ) ;
glui_bottom ->add_button( "Quit", EXIT_ID, control_cb );
glui_bottom->add_column( true );
glui_bottom->add_column( true );
//--------------------------------------------------//
// position
roll = glui_bottom ->add_rollout( "3D position", true );
objects_rot = glui_bottom->add_rotation_to_panel( roll, "Objects", view_rotate );
objects_rot->set_spin( 1.0f );
glui_bottom->add_button_to_panel( roll, "Reset", RESET_ROTATION_ID, control_cb ) ;
glui_bottom->add_column_to_panel( roll, false );
objects_mv = glui_bottom->add_translation_to_panel( roll, "Objects XY", GLUI_TRANSLATION_XY, obj_pos );
objects_mv->set_speed( .005f );
glui_bottom->add_button_to_panel( roll, "Reset", RESET_TRANSLATION_ID, control_cb ) ;
glui_bottom->add_column_to_panel( roll, false );
objects_zm = glui_bottom->add_translation_to_panel( roll, "Objects Z", GLUI_TRANSLATION_Z, &obj_pos[2] );
objects_zm->set_speed( .005f );
glui_bottom->add_button_to_panel( roll, "Reset", RESET_ZOOM_ID, control_cb ) ;
//--------------------------------------------------//
// Lights
roll = glui_bottom->add_rollout( "Lights", true );
rot = glui_bottom->add_rotation_to_panel( roll, "Blue Light", light0_rotation );
rot->set_spin( .82f );
rot = glui_bottom->add_rotation_to_panel( roll, "Orange Light", light1_rotation );
rot->set_spin( .82f );
glui_bottom->add_column_to_panel( roll, false );
glui_bottom->add_checkbox_to_panel( roll, "On", &light0_enabled );
text = glui_bottom->add_edittext_to_panel( roll, "Id (%)", GLUI_EDITTEXT_INT, &light0_intensity );
text->set_int_limits( 0, 100 );
text->set_w(4) ;
text = glui_bottom->add_edittext_to_panel( roll, "Is (%)", GLUI_EDITTEXT_INT, &light0_intensity2 );
text->set_int_limits( 0, 100 );
text->set_w(4) ;
glui_bottom->add_checkbox_to_panel( roll, "On", &light1_enabled );
text = glui_bottom->add_edittext_to_panel( roll, "Id (%)", GLUI_EDITTEXT_INT, &light1_intensity );
text->set_int_limits( 0, 100 );
text->set_w(4) ;
text = glui_bottom->add_edittext_to_panel( roll, "Is (%)", GLUI_EDITTEXT_INT, &light1_intensity2 );
text->set_int_limits( 0, 100 );
text->set_w(4) ;
}
//_____________________________________________________________________________

View File

@ -1,361 +0,0 @@
/**
* @file glui_defs.h
* @author Thomas Lewiner <thomas.lewiner@polytechnique.org>
* @author Math Dept, PUC-Rio
* @version 0.1
* @date 30/05/2006
*
* @brief Octree graphical interface
*/
//________________________________________________
#pragma once
#if !defined(WIN32) || defined(__CYGWIN__)
#pragma interface
#endif // WIN32
#include <GL/glui.h> // openGL user interface
#define OCTREE_SWITCH 4
//_____________________________________________________________________________
// octree switch
#ifdef OCTREE_SWITCH
# if OCTREE_SWITCH==0
# define OCTREE_PTR 1
# elif OCTREE_SWITCH==1
# define OCTREE_HASH 1
# elif OCTREE_SWITCH==2
# define OCTREE_OPT 1
# elif OCTREE_SWITCH==3
# define OCTREE_LEAF 1
# elif OCTREE_SWITCH==4
# define OCTREE_MEM 1
# endif // OCTREE_SWITCH
#endif // OCTREE_SWITCH
// switch values between pointer and hash octree
#if !OCTREE_PTR && !OCTREE_HASH && !OCTREE_OPT && !OCTREE_LEAF && !OCTREE_MEM
// # define OCTREE_PTR 1
// # define OCTREE_HASH 1
# define OCTREE_OPT 1
// # define OCTREE_LEAF 1
// # define OCTREE_MEM 1
#endif // !OCTREE_PTR && !OCTREE_HASH && !OCTREE_OPT && !OCTREE_LEAF && !OCTREE_MEM
#ifdef OCTREE_PTR
# undef OCTREE_HASH
# undef OCTREE_OPT
# undef OCTREE_LEAF
# undef OCTREE_MEM
# define OCTREE_STRING "pointer octree"
# include "ptr_octree.h"
/// octree type
typedef PtrOctree Octree ;
#endif //OCTREE_PTR
#ifdef OCTREE_HASH
# undef OCTREE_PTR
# undef OCTREE_OPT
# undef OCTREE_LEAF
# undef OCTREE_MEM
# define OCTREE_STRING "hash octree"
# include "hash_octree.h"
/// octree type
typedef HashOctree Octree ;
#endif //OCTREE_HASH
#ifdef OCTREE_OPT
# undef OCTREE_PTR
# undef OCTREE_HASH
# undef OCTREE_LEAF
# undef OCTREE_MEM
# define OCTREE_STRING "optimized octree"
# include "opt_octree.h"
/// octree type
typedef OptOctree Octree ;
#endif //OCTREE_OPT
#ifdef OCTREE_LEAF
# undef OCTREE_PTR
# undef OCTREE_HASH
# undef OCTREE_OPT
# undef OCTREE_MEM
# define OCTREE_STRING "leaf octree"
# include "leaf_octree.h"
/// octree type
typedef LeafOctree Octree ;
#endif //OCTREE_LEAF
#ifdef OCTREE_MEM
# undef OCTREE_PTR
# undef OCTREE_HASH
# undef OCTREE_OPT
# undef OCTREE_LEAF
# define OCTREE_STRING "mem octree"
# include "mem_octree.h"
/// octree type
typedef MemOctree Octree ;
#endif //OCTREE_MEM
#ifdef _DEBUG
#define PRINT_GL_DEBUG { if( ::glGetError() != GL_NO_ERROR ) printf( "openGL watch at line %d: %s\n", __LINE__, ::gluErrorString( ::glGetError() ) ) ; }
#else // _DEBUG
#define PRINT_GL_DEBUG {}
#endif // _DEBUG
//_____________________________________________________________________________
// Main objects
/// main object: octree
extern Octree octree ;
/// switch between implicit funciont or volumetric data
extern int impl_data ;
/// switch values between implicit funciont or volumetric data
enum { SWITCH_IMPL = 0, SWITCH_DATA = 1 } ;
/// octree implicit data wrapper
extern data_func *dat_func ;
/// octree data file wrapper
extern data_file *dat_data ;
/// maximal level of the tree
extern int max_level ;
/// isovalue
extern float iso_val ;
//-----------------------------------------------------------------------------
// Display elements
/// display element switch: octree wireframe
extern int show_octree ;
/// display element switch: octree cells' centers
extern int show_nodes ;
/// display element switch: octree dual
extern int show_dual ;
/// display element switch: isosurface of the field
extern int show_iso ;
/// display element switch: direct drawing isosurface of the field
extern int show_direct_iso ;
/// display element switch: direct drawing wire isosurface of the field
extern int show_direct_iso_wire ;
//-----------------------------------------------------------------------------
// GLUI windows
/// main window id
extern int main_window ;
/// main glui class: (right) side panel
extern GLUI *glui_side ;
/// bottom panel
extern GLUI *glui_bottom ;
/// create side panel
void create_side_panel() ;
/// create bottom panel
void create_bottom_panel() ;
/// control events callback
void control_cb( int control ) ;
/// parse command line
bool parse_command_line(int argc, char* argv[]) ;
//-----------------------------------------------------------------------------
// Lights
/// enable blue light
extern int light0_enabled ;
/// enable orange light
extern int light1_enabled ;
/// blue light intensity
extern int light0_intensity ;
/// orange light intensity
extern int light1_intensity ;
/// blue light intensity (specular)
extern int light0_intensity2 ;
/// orange light intensity (specular)
extern int light1_intensity2 ;
/// blue light diffuse color
extern float light0_diffuse[4] ;
/// orange light diffuse color
extern float light1_diffuse[4] ;
/// blue light position
extern float light0_rotation[16] ;
/// orange light position
extern float light1_rotation[16] ;
//-----------------------------------------------------------------------------
// mouse and object movements
/// motion type (-1 -> no motion, 0 -> rotate, 1 -> zoom, 2 -> translate)
extern int motion_type ;
/// window trackball
extern GLUI_Rotation mouse_rot ;
/// panel trackball
extern GLUI_Rotation *objects_rot ;
/// window translation
extern GLUI_Translation mouse_mv ;
/// panel translation
extern GLUI_Translation *objects_mv ;
/// window zoom
extern GLUI_Translation mouse_zm ;
/// panel zoom
extern GLUI_Translation *objects_zm ;
/// number of calls for updating the GLUI control
extern int ncalls ;
/// export movie switch
extern int export_movie ;
/// automatic rotation
extern int auto_rotate ;
/// automatic x translation
extern int auto_translate_x ;
/// automatic y translation
extern int auto_translate_y ;
/// automatic zoom
extern int auto_zoom ;
/// automatic plane
extern int auto_translate_d ;
/// mouse x position
extern int mouse_x ;
/// mouse y position
extern int mouse_y ;
/// init mouse and window controls
void init_trackballs() ;
/// mouse events tracking
void mouse(int button, int button_state, int x, int y ) ;
/// mouse motion tracking
void motion(int x, int y ) ;
/// keyboard events
void keyboard(unsigned char key, int x, int y);
//-----------------------------------------------------------------------------
// implicit function
/// implicit function formula
extern GLUI_String impl_fun ;
//-----------------------------------------------------------------------------
// i/o filenames
/// iso file
extern GLUI_String filename ;
/// file browser
extern GLUI_FileBrowser *file_browser ;
//-----------------------------------------------------------------------------
// drawing parameters
/// orthographic / perspective projection switch
extern int ortho ;
/// object rotation
extern float view_rotate[16] ;
/// object translation
extern float obj_pos [3 ] ;
/// point size
extern int point_size;
/// 3D projection matrix
void project( int o, float sx, float sy, int &tx, int &ty, int &tw, int &th ) ;
/// window resizing
void reshape( int x, int y ) ;
/// main drawing function
void display() ;
/// print screen
void export_png() ;
/// load viewport
void load_viewport() ;
/// save viewport
void save_viewport() ;
//_____________________________________________________________________________
//_____________________________________________________________________________
/// Callback ids
enum
{
SET_IMPL_DATA_ID ,
SET_VAL_ID ,
REFINE_ID ,
ADAPT_ID ,
ISO_BUILD_ID ,
SEARCH_ID ,
FUN_ID ,
SAVE_VIEWPORT_ID ,
LOAD_VIEWPORT_ID ,
RESET_ROTATION_ID ,
RESET_TRANSLATION_ID ,
RESET_ZOOM_ID ,
REDRAW_ID ,
FILENAME_ID ,
PROJ_ID ,
EXIT_ID
};
//_____________________________________________________________________________

View File

@ -1,321 +0,0 @@
/**
* @file glui_draws.cpp
* @author Thomas Lewiner <thomas.lewiner@polytechnique.org>
* @author Math Dept, PUC-Rio
* @version 0.1
* @date 30/05/2006
*
* @brief Octree graphical interface: drawing commands
*/
//________________________________________________
#if !defined(WIN32) || defined(__CYGWIN__)
#pragma implementation "viz_glui_defs.h"
#endif // WIN32
#include "viz_glui_defs.h"
//_____________________________________________________________________________
// declarations of this file
// display element switches
int show_octree = 1 ;
int show_nodes = 0 ;
int show_dual = 0 ;
int show_iso = 0 ;
int show_direct_iso = 0 ;
int show_direct_iso_wire = 0 ;
// orthographic / perspective projection
int ortho = 0 ;
// object transformation
float view_rotate[16] = { 1.0f,0.0f,0.0f,0.0f, 0.0f,1.0f,0.0f,0.0f, 0.0f,0.0f,1.0f,0.0f, 0.0f,0.0f,0.0f,1.0f };
float obj_pos [3 ] = { 0.0f, 0.0f, 0.0f };
//-----------------------------------------------------------------------------
// lights
int light0_enabled = 1 ;
int light1_enabled = 0 ;
int light0_intensity = 100 ;
int light1_intensity = 60 ;
int light0_intensity2 = 50 ;
int light1_intensity2 = 30 ;
GLfloat light0_diffuse [ 4] = {.7f, .7f, 1.0f, 1.0f};
GLfloat light1_diffuse [ 4] = {.9f, .7f, 0.2f, 1.0f};
GLfloat light0_position[ 4] = {.5f, .5f, 10.0f, 0.0f};
GLfloat light1_position[ 4] = {-1.0f, -1.0f, 10.0f, 0.0f};
GLfloat light0_rotation[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };
GLfloat light1_rotation[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };
//-----------------------------------------------------------------------------
// 3D projection matrix
void project( int o, float sx, float sy, int &tx, int &ty, int &tw, int &th ) ;
// window resizing
void reshape( int x, int y ) ;
// main drawing function
void display() ;
//_____________________________________________________________________________
//_____________________________________________________________________________
// 3D projection matrix
void project( int o, float sx, float sy, int &tx, int &ty, int &tw, int &th )
//-----------------------------------------------------------------------------
{
// get viewport
GLUI_Master.get_viewport_area( &tx, &ty, &tw, &th );
tw = (int)( tw * sx );
th = (int)( th * sy );
::glViewport( tx, ty, tw, th );
// sets the projection matrix
::glMatrixMode(GL_PROJECTION);
::glLoadIdentity();
// sets the viewport
if( o )
{
if( th > tw )
::glOrtho( -1.2, 1.2, -1.2*(double)th/tw, 1.2*(double)th/tw, 0.0, 10.0 ) ;
else
::glOrtho( -1.2*(double)tw/th, 1.2*(double)tw/th, -1.2, 1.2, 0.0, 10.0 ) ;
}
else
::gluPerspective( 45.0, th>0?(double)tw/th:1.0, 0.5, 10.0 );
::gluLookAt( 0.0f,0.0f,3.0f, 0.0f,0.0f,0.5f, 0.0f,1.0f,0.0f ) ;
// switch to the modelview matrix
::glMatrixMode( GL_MODELVIEW );
::glLoadIdentity();
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// window resizing
void reshape( int x, int y )
//-----------------------------------------------------------------------------
{
::glutSetWindow(main_window);
int tx, ty, tw, th;
project( ortho, 1.0f, 1.0f, tx, ty, tw, th ) ;
// sets the window trackball
mouse_rot.set_w( tw ) ;
mouse_rot.set_h( th ) ;
mouse_mv .set_w( tw ) ;
mouse_mv .set_h( th ) ;
mouse_zm .set_w( tw ) ;
mouse_zm .set_h( th ) ;
// redisplay
::glutPostRedisplay();
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// main drawing function
void display()
//-----------------------------------------------------------------------------
{
::glutSetWindow(main_window);
// clear screen
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
if( !true ) { ::glutSwapBuffers(); return ; }
int tx, ty, tw, th ;
project( ortho, 1.0f, 1.0f, tx, ty, tw, th ) ;
::glEnable( GL_DEPTH_TEST );
::glShadeModel(GL_SMOOTH);
::glEnable(GL_LIGHTING);
//::glDisable (GL_LIGHTING);
float val[3] ;
if ( light0_enabled )
{
::glEnable( GL_LIGHT0 ) ;
val[0] = light0_diffuse[0] * light0_intensity / 100 ;
val[1] = light0_diffuse[1] * light0_intensity / 100 ;
val[2] = light0_diffuse[2] * light0_intensity / 100 ;
::glLightfv(GL_LIGHT0, GL_DIFFUSE, val );
val[0] = light0_diffuse[0] * light0_intensity2 / 100 ;
val[1] = light0_diffuse[1] * light0_intensity2 / 100 ;
val[2] = light0_diffuse[2] * light0_intensity2 / 100 ;
::glLightfv(GL_LIGHT0, GL_SPECULAR, val );
const GLfloat light0_ambient[4] = {0.1f, 0.1f, 0.3f, 1.0f};
::glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
::glLoadIdentity();
::glMultMatrixf( light0_rotation );
::glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
}
else
::glDisable( GL_LIGHT0 );
if ( light1_enabled )
{
::glEnable( GL_LIGHT1 );
val[0] = light1_diffuse[0] * light1_intensity / 100 ;
val[1] = light1_diffuse[1] * light1_intensity / 100 ;
val[2] = light1_diffuse[2] * light1_intensity / 100 ;
::glLightfv(GL_LIGHT1, GL_DIFFUSE, val );
val[0] = light1_diffuse[0] * light1_intensity2 / 100 ;
val[1] = light1_diffuse[1] * light1_intensity2 / 100 ;
val[2] = light1_diffuse[2] * light1_intensity2 / 100 ;
::glLightfv(GL_LIGHT1, GL_SPECULAR, val );
const GLfloat light1_ambient[4] = {0.1f, 0.1f, 0.3f, 1.0f};
::glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);
::glLoadIdentity();
::glMultMatrixf( light1_rotation );
::glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
}
else
::glDisable( GL_LIGHT1 );
// transformation matrix
::glLoadIdentity();
::glTranslatef( obj_pos[0], obj_pos[1], obj_pos[2] );
if( ortho )
{
::glScalef( 1.0+obj_pos[2], 1.0+obj_pos[2], 1.0+obj_pos[2] ) ;
::glEnable( GL_NORMALIZE );
}
else
{
::glDisable( GL_NORMALIZE );
}
::glMultMatrixf( view_rotate );
::glTranslatef( -0.5f, -0.5f, -0.5f );
PRINT_GL_DEBUG ;
//-----------------------------------------------------------------------------
// 3D display
data_access *ref = NULL ;
switch( impl_data )
{
case SWITCH_IMPL : ref = dat_func ; break ;
case SWITCH_DATA : ref = dat_data ; break ;
}
if( ref )
::glScalef( ref->_sx, ref->_sy, ref->_sz ) ;
// octree wireframe
if( show_octree )
{
::glDisable( GL_TEXTURE_1D ) ;
::glLineWidth( 0.5 ) ;
::glColor3f( 0.3f, 0.3f, 0.5f ) ;
::glBegin( GL_LINES ) ;
{
octree.draw_wire() ;
}
::glEnd() ; // GL_LINES
}
// cells' centers
if( show_nodes )
{
::glEnable( GL_TEXTURE_1D ) ;
::glPointSize( 4.0 ) ;
::glColor3f( 0.0f, 0.8f, 0.2f ) ;
::glBegin( GL_POINTS ) ;
{
octree.draw_centers() ;
}
::glEnd() ; // GL_POINTS
}
// octree dual
if( show_dual )
{
::glDisable( GL_TEXTURE_1D ) ;
::glDisable(GL_LIGHTING);
octree.draw_dual() ;
::glEnable(GL_LIGHTING);
}
// isosurface of the field
if( show_iso )
{
::glDisable( GL_TEXTURE_1D ) ;
::glDisable(GL_LIGHTING);
::glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) ;
::glColor3f( 0.3f, 0.3f, 0.5f ) ;
::glBegin( GL_TRIANGLES ) ;
octree.draw_iso() ;
::glEnd() ; // GL_TRIANGLES
::glEnable(GL_LIGHTING);
::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) ;
::glColor3f( 0.6f, 0.6f, 0.7f ) ;
::glBegin( GL_TRIANGLES ) ;
octree.draw_iso() ;
::glEnd() ; // GL_TRIANGLES
}
if( ref && show_direct_iso_wire )
{
::glDisable( GL_TEXTURE_1D ) ;
::glDisable(GL_LIGHTING);
::glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) ;
::glColor3f( 0.3f, 0.3f, 0.5f ) ;
::glBegin( GL_TRIANGLES ) ;
octree.direct_draw_isosurface(ref) ;
::glEnd() ; // GL_TRIANGLES
}
if( ref && show_direct_iso )
{
::glDisable( GL_TEXTURE_1D ) ;
::glEnable(GL_LIGHTING);
::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) ;
::glColor3f( 0.6f, 0.6f, 0.7f ) ;
::glBegin( GL_TRIANGLES ) ;
octree.direct_draw_isosurface(ref) ;
::glEnd() ; // GL_TRIANGLES
}
PRINT_GL_DEBUG ;
// next frame
::glutSwapBuffers();
}
//_____________________________________________________________________________

View File

@ -1,323 +0,0 @@
/**
* @file glui_export.cpp
* @author Thomas Lewiner <thomas.lewiner@polytechnique.org>
* @author Math Dept, PUC-Rio
* @version 0.1
* @date 20/08/2007
*
* @brief Example Graphical interface: screen image exporatation
*/
//________________________________________________
#ifndef WIN32
#pragma implementation "viz_glui_defs.h"
#endif // WIN32
#include <png.h>
#include <stdio.h>
#include "viz_glui_defs.h"
//_____________________________________________________________________________
// declarations of this file
// set file extension of filename
int set_ext( const char ext[3], char *fn ) ;
// PPM export
void export_ppm() ;
// PNG image export
void export_png() ;
// Viewport save
void save_viewport() ;
// Viewport load
void load_viewport() ;
//_____________________________________________________________________________
//_____________________________________________________________________________
// set file extension of filename
int set_ext( const char ext[3], char *fn )
//-----------------------------------------------------------------------------
{
strcpy( fn, filename.c_str() ) ;
int l = (int)strlen(fn) ;
if( l == 0 ) return 0 ;
if( fn[l-4] != '.' )
{
strcat( fn, "." ) ;
strcat( fn, ext ) ;
}
else if( strcmp( fn + l-3, ext ) )
{
fn[l-3] = ext[0] ;
fn[l-2] = ext[1] ;
fn[l-1] = ext[2] ;
}
return l ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// PPM export
void export_ppm()
//-----------------------------------------------------------------------------
{
char fn[1024] ;
set_ext( "ppm", fn ) ;
FILE *fp = fopen( fn, "w" ) ;
if( !fp ) return ;
int tx, ty, tw, th;
glutSetWindow(main_window);
GLUI_Master.get_viewport_area( &tx, &ty, &tw, &th );
// read openGL buffer
int buf_size = (tw * th * 3);
unsigned char *buffer = new unsigned char[buf_size] ;
memset(buffer, 0, buf_size * sizeof(unsigned char)) ;
display() ;
glFinish() ;
glPixelStorei( GL_PACK_ALIGNMENT, 1 ); // Force 1-byte alignment
glPixelStorei( GL_PACK_ROW_LENGTH, 0 );
glPixelStorei( GL_PACK_SKIP_ROWS, 0 );
glPixelStorei( GL_PACK_SKIP_PIXELS,0 );
glReadPixels(tx, ty, tw, th, GL_RGB, GL_UNSIGNED_BYTE, buffer);
// write the header
fprintf(fp, "P6\n%d %d\n", tw, th);
fprintf(fp, "# %s (Affine Surface by Thomas Lewiner)\n", fn ) ;
fprintf(fp, "255\n");
// write file
for (int i = 0; i < buf_size; ++i)
fputc( buffer[i], fp ) ;
delete [] buffer ;
fclose(fp);
printf( "exported image to PPM file %s\n", fn ) ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
//
void export_tga()
//-----------------------------------------------------------------------------
{
char fn[1024] ;
set_ext("tga", fn) ;
FILE *fp = fopen( fn, "w" ) ;
if (!fp)
return ;
int tx, ty, tw, th;
glutSetWindow(main_window);
GLUI_Master.get_viewport_area(&tx, &ty, &tw, &th);
int buf_size = 18 + (tw* th * 3); // HEADER_SIZE ==> 18
unsigned char* buffer = new unsigned char[buf_size] ;
memset(buffer, 0, buf_size * sizeof(unsigned char)) ;
// Header
buffer[2] = 2; // Non-compressed
buffer[12] = tw & 255;
buffer[13] = (tw >> 8) & 255 ;
buffer[14] = th & 255;
buffer[15] = (th >> 8) & 255 ;
buffer[16] = 24; // 24 bits per pixel
// Read openGL buffer
display() ;
glFinish() ;
glPixelStorei(GL_PACK_ALIGNMENT, 1); // Force 1-byte alignment
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
glReadPixels(tx, ty, tw, th, GL_RGB, GL_UNSIGNED_BYTE, buffer + 18);
// Conversion from RGB to BGR
for (int i = 18; i < buf_size; i += 3)
{
unsigned char temp = buffer[i];
buffer[i] = buffer[i + 2];
buffer[i + 2] = temp;
}
// Write file
fwrite(buffer, sizeof(unsigned char), buf_size, fp);
fclose(fp);
delete[] buffer ;
printf("exported image to TGA file %s\n", fn ) ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
//_____________________________________________________________________________
//_____________________________________________________________________________
//
void save_viewport()
//-----------------------------------------------------------------------------
{
char fn[1024] ;
set_ext( "view", fn ) ;
FILE *fp = fopen( fn, "w" ) ;
if( !fp ) return ;
fprintf( fp, "rotate:\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\n",
view_rotate[ 0], view_rotate[ 1], view_rotate[ 2], view_rotate[ 3],
view_rotate[ 4], view_rotate[ 5], view_rotate[ 6], view_rotate[ 7],
view_rotate[ 8], view_rotate[ 9], view_rotate[10], view_rotate[11],
view_rotate[12], view_rotate[13], view_rotate[14], view_rotate[15] ) ;
fprintf( fp, "translate:\t%f %f %f\n", obj_pos[0], obj_pos[1], obj_pos[2] ) ;
fprintf( fp, "plane rotate:\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f\n\n",
1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0, 0.0 ) ;
fprintf( fp, "corner size:\t%f %f\n", 0.0,0.0 ) ;
fprintf( fp, "corner trans:\t%f %f %f\n", 0.0,0.0,1.0 ) ;
fprintf( fp, "light 0:\n\t%d %d %d\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\n\n",
light0_enabled, light0_intensity, light0_intensity2,
light0_diffuse [ 0], light0_diffuse [ 1], light0_diffuse [ 2], light0_diffuse [ 3],
light0_rotation[ 0], light0_rotation[ 1], light0_rotation[ 2], light0_rotation[ 3],
light0_rotation[ 4], light0_rotation[ 5], light0_rotation[ 6], light0_rotation[ 7],
light0_rotation[ 8], light0_rotation[ 9], light0_rotation[10], light0_rotation[11],
light0_rotation[12], light0_rotation[13], light0_rotation[14], light0_rotation[15] ) ;
fprintf( fp, "light 1:\n\t%d %d %d\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\n\n",
light1_enabled, light1_intensity, light1_intensity2,
light1_diffuse [ 0], light1_diffuse [ 1], light1_diffuse [ 2], light1_diffuse [ 3],
light1_rotation[ 0], light1_rotation[ 1], light1_rotation[ 2], light1_rotation[ 3],
light1_rotation[ 4], light1_rotation[ 5], light1_rotation[ 6], light1_rotation[ 7],
light1_rotation[ 8], light1_rotation[ 9], light1_rotation[10], light1_rotation[11],
light1_rotation[12], light1_rotation[13], light1_rotation[14], light1_rotation[15] ) ;
fclose( fp ) ;
printf("saved viewport to file %s\n", fn ) ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
//
void load_viewport()
//-----------------------------------------------------------------------------
{
char fn[1024] ;
set_ext("view",fn) ;
FILE* fp = fopen( fn, "r" ) ;
if( !fp ) return ;
fscanf( fp, "rotate: %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f ",
view_rotate + 0, view_rotate + 1, view_rotate + 2, view_rotate + 3,
view_rotate + 4, view_rotate + 5, view_rotate + 6, view_rotate + 7,
view_rotate + 8, view_rotate + 9, view_rotate + 10, view_rotate + 11,
view_rotate + 12, view_rotate + 13, view_rotate + 14, view_rotate + 15 ) ;
fscanf( fp, "translate: %f %f %f ", obj_pos + 0, obj_pos + 1, obj_pos + 2 ) ;
fscanf ( fp, "plane rotate:\n\t%*f %*f %*f %*f\n\t%*f %*f %*f %*f\n\t%*f %*f %*f %*f\n\t%*f %*f %*f %*f\n\t%*f\n\n" ) ;
fscanf ( fp, "corner size:\t%*f %*f\n" ) ;
fscanf ( fp, "corner trans:\t%*f %*f %*f\n" ) ;
fscanf ( fp, "light 0:\n\t%d %d %d\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\n\n",
&light0_enabled, &light0_intensity, &light0_intensity2,
light0_diffuse + 0, light0_diffuse + 1, light0_diffuse + 2, light0_diffuse + 3,
light0_rotation + 0, light0_rotation + 1, light0_rotation + 2, light0_rotation + 3,
light0_rotation + 4, light0_rotation + 5, light0_rotation + 6, light0_rotation + 7,
light0_rotation + 8, light0_rotation + 9, light0_rotation + 10, light0_rotation + 11,
light0_rotation + 12, light0_rotation + 13, light0_rotation + 14, light0_rotation + 15 ) ;
fscanf ( fp, "light 1:\n\t%d %d %d\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\n\n",
&light1_enabled, &light1_intensity, &light1_intensity2,
light1_diffuse + 0, light1_diffuse + 1, light1_diffuse + 2, light1_diffuse + 3,
light1_rotation + 0, light1_rotation + 1, light1_rotation + 2, light1_rotation + 3,
light1_rotation + 4, light1_rotation + 5, light1_rotation + 6, light1_rotation + 7,
light1_rotation + 8, light1_rotation + 9, light1_rotation + 10, light1_rotation + 11,
light1_rotation + 12, light1_rotation + 13, light1_rotation + 14, light1_rotation + 15 ) ;
fclose( fp ) ;
printf("loaded viewport from file %s\n", fn ) ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// PNG export
void export_png()
//-----------------------------------------------------------------------------
{
char fn[1024] ;
set_ext( "png", fn ) ;
FILE *fp = fopen( fn, "wb" ) ;
if( !fp ) return ;
int tx, ty, tw, th;
glutSetWindow(main_window);
GLUI_Master.get_viewport_area( &tx, &ty, &tw, &th );
// read openGL buffer
int buf_size = (tw * th * 3);
unsigned char *buffer = new unsigned char[buf_size] ;
memset(buffer, 0, buf_size * sizeof(unsigned char)) ;
display() ;
glFinish() ;
glPixelStorei( GL_PACK_ALIGNMENT, 1 ); // Force 1-byte alignment
glPixelStorei( GL_PACK_ROW_LENGTH, 0 );
glPixelStorei( GL_PACK_SKIP_ROWS, 0 );
glPixelStorei( GL_PACK_SKIP_PIXELS,0 );
glReadPixels(tx, ty, tw, th, GL_RGB, GL_UNSIGNED_BYTE, buffer);
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL, NULL, NULL);
png_infop info_ptr = png_create_info_struct(png_ptr);
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp);
return;
}
png_init_io(png_ptr, fp);
png_set_IHDR(png_ptr, info_ptr, tw, th, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(png_ptr, info_ptr);
for (int i=0; i<th; i++)
png_write_row(png_ptr, &(buffer[3*tw*((th-1) - i)]));
png_write_end(png_ptr, NULL);
png_destroy_write_struct(&png_ptr, &info_ptr);
delete [] buffer ;
fclose(fp);
printf( "exported image to PNG file %s\n", fn ) ;
}
//_____________________________________________________________________________

View File

@ -1,312 +0,0 @@
/**
* @file glui_mouse.cpp
* @author Thomas Lewiner <thomas.lewiner@polytechnique.org>
* @author Math Dept, PUC-Rio
* @version 0.1
* @date 30/05/2006
*
* @brief Octree Graphical interface: mouse controls
*/
//________________________________________________
#if !defined(WIN32) || defined(__CYGWIN__)
#pragma implementation "viz_glui_defs.h"
#endif // WIN32
#include "viz_glui_defs.h"
//_____________________________________________________________________________
// declarations of this file
// motion type (-1 -> no motion, 0 -> rotate, 1 -> zoom, 2 -> translate)
int motion_type = -1 ;
// panel and window trackballs and sliders
GLUI_Rotation mouse_rot, *objects_rot, *plane_rot ;
GLUI_Translation mouse_mv , *objects_mv , *plane_trans ;
GLUI_Translation mouse_zm , *objects_zm ;
// number of calls for updating the GLUI control
int ncalls = 0 ;
//-----------------------------------------------------------------------------
// init mouse and window controls
void init_trackballs() ;
// mouse events tracking
void mouse(int button, int button_state, int x, int y ) ;
// mouse motion tracking
void motion(int x, int y ) ;
// automatic rotation
int auto_rotate = 0 ;
// automatic x translation
int auto_translate_x = 0 ;
// automatic y translation
int auto_translate_y = 0 ;
// automatic zoom
int auto_zoom = 0 ;
// automatic plane
int auto_translate_d = 0 ;
// mouse x position
int mouse_x = 0 ;
// mouse y position
int mouse_y = 0 ;
//_____________________________________________________________________________
//_____________________________________________________________________________
// init mouse and window controls
void init_trackballs()
//-----------------------------------------------------------------------------
{
// init trackball
int tx,ty,tw,th ;
GLUI_Master.get_viewport_area( &tx, &ty, &tw, &th );
mouse_rot.set_spin(0.05f) ;
mouse_rot.set_w( tw ) ;
mouse_rot.set_h( th ) ;
mouse_rot.set_ptr_val( view_rotate );
mouse_rot.init_live() ;
mouse_mv.set_speed(0.005f) ;
mouse_mv.set_w( tw ) ;
mouse_mv.set_h( th ) ;
mouse_mv.set_ptr_val( obj_pos );
mouse_mv.init_live() ;
mouse_mv.trans_type = GLUI_TRANSLATION_XY;
mouse_mv.float_array_size = 2 ;
mouse_mv.hidden = true ;
mouse_zm.set_speed(0.01f) ;
mouse_zm.set_w( tw ) ;
mouse_zm.set_h( th ) ;
mouse_zm.set_ptr_val( &obj_pos[2] );
mouse_zm.init_live() ;
mouse_zm.trans_type = GLUI_TRANSLATION_Z ;
mouse_zm.float_array_size = 1 ;
mouse_zm.hidden = true ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// mouse events
void mouse(int button, int button_state, int x, int y )
//-----------------------------------------------------------------------------
{
mouse_x = x ;
mouse_y = y ;
// determine motion type
if ( glutGetModifiers() & GLUT_ACTIVE_CTRL ) motion_type = 1 ;
else if( glutGetModifiers() & GLUT_ACTIVE_SHIFT ) motion_type = 2 ;
else if( glutGetModifiers() & GLUT_ACTIVE_ALT ) motion_type = 3 ;
else motion_type = 0 ;
switch( motion_type )
{
// rotation
case 0 :
// line selection
if ( button == GLUT_LEFT_BUTTON){
if (button_state == GLUT_DOWN )
{
mouse_rot.init_live() ;
mouse_rot.mouse_down_handler(x,y) ;
}
if ( button_state != GLUT_DOWN )
{
mouse_rot.mouse_up_handler(x,y,1) ;
motion_type = -1 ;
}
objects_rot->sync_live(0,1) ;
}
if ( button == GLUT_RIGHT_BUTTON && button_state == GLUT_DOWN)
{
}
break ;
// zoom
case 1 :
if ( button == GLUT_LEFT_BUTTON && button_state == GLUT_DOWN )
{
mouse_zm.init_live() ;
mouse_zm.glui = glui_bottom ;
mouse_zm.mouse_down_handler(x,y) ;
mouse_zm.glui = NULL ;
}
if ( button_state != GLUT_DOWN )
{
mouse_zm.glui = glui_bottom ;
mouse_zm.mouse_up_handler(x,y,1) ;
mouse_zm.glui = NULL ;
motion_type = -1 ;
}
objects_zm->sync_live(0,1) ;
break ;
// translation
case 2 :
if ( button == GLUT_LEFT_BUTTON && button_state == GLUT_DOWN )
{
mouse_mv.init_live() ;
mouse_mv.glui = glui_bottom ;
mouse_mv.mouse_down_handler(x,y) ;
mouse_mv.glui = NULL ;
}
if ( button_state != GLUT_DOWN )
{
mouse_mv.glui = glui_bottom ;
mouse_mv.mouse_up_handler(x,y,1) ;
mouse_mv.glui = NULL ;
motion_type = -1 ;
}
objects_mv->sync_live(0,1) ;
break ;
// no movement
default :
break ;
}
ncalls = 0 ;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// keyboard
void keyboard(unsigned char key, int x, int y)
{
switch(key)
{
case 's':
export_png();
break;
case 'S':
export_movie = !export_movie;
break;
case 'r' :
if( auto_rotate == -1 ) auto_rotate = 0 ;
else auto_rotate = -1 ;
break ;
case 'R' :
if( auto_rotate == +1 ) auto_rotate = 0 ;
else auto_rotate = +1 ;
break ;
case 'D' :
if( auto_translate_d == -1 ) auto_translate_d = 0 ;
else auto_translate_d = -1 ;
break ;
case 'd' :
if( auto_translate_d == +1 ) auto_translate_d = 0 ;
else auto_translate_d = +1 ;
break ;
case 'X' :
if( auto_translate_x == -1 ) auto_translate_x = 0 ;
else auto_translate_x = -1 ;
break ;
case 'x' :
if( auto_translate_x == +1 ) auto_translate_x = 0 ;
else auto_translate_x = +1 ;
break ;
case 'Y' :
if( auto_translate_y == -1 ) auto_translate_y = 0 ;
else auto_translate_y = -1 ;
break ;
case 'y' :
if( auto_translate_y == +1 ) auto_translate_y = 0 ;
else auto_translate_y = +1 ;
break ;
case 'Z' :
if( auto_zoom == -1 ) auto_zoom = 0 ;
else auto_zoom = -1 ;
break ;
case 'z' :
if( auto_zoom == +1 ) auto_zoom = 0 ;
else auto_zoom = +1 ;
break ;
default:
break;
}
}
//_____________________________________________________________________________
//_____________________________________________________________________________
// motion
void motion(int x, int y )
//-----------------------------------------------------------------------------
{
mouse_x = x ;
mouse_y = y ;
switch( motion_type )
{
// rotation
case 0 :
mouse_rot.glui = glui_bottom ;
mouse_rot.iaction_mouse_held_down_handler(x,y,1);
mouse_rot.glui = NULL ;
if( ++ncalls > 10 ) { objects_rot->sync_live(0,1) ; ncalls = 0 ; }
break ;
// zoom
case 1 :
mouse_zm.glui = glui_bottom ;
mouse_zm.iaction_mouse_held_down_handler(x,y,1);
mouse_zm.glui = NULL ;
if( ++ncalls > 10 ) { objects_zm->sync_live(0,1) ; ncalls = 0 ; }
break ;
// translation
case 2 :
mouse_mv.glui = glui_bottom ;
mouse_mv.iaction_mouse_held_down_handler(x,y,1);
mouse_mv.glui = NULL ;
if( ++ncalls > 10 ) { objects_mv->sync_live(0,1) ; ncalls = 0 ; }
break ;
// no movement
default :
break ;
}
::glutPostRedisplay() ;
}
//_____________________________________________________________________________