00001
#include <bicpl/marching.h>
00002
#include <volume_io/internal_volume_io.h>
00003
00004 private int get_polygons(
00005 Marching_cubes_methods method,
00006
int x,
00007
int y,
00008
int z,
00009 Real corners[2][2][2],
00010 Real isovalue,
00011
int *sizes[],
00012
voxel_point_type *points[] )
00013 {
00014
int n_polygons;
00015
static int static_sizes[4] = { 3, 3, 3, 3 };
00016
00017
switch( method )
00018 {
00019
case MARCHING_CUBES:
00020 n_polygons =
compute_isotriangles_in_voxel( corners, isovalue, points );
00021 *sizes = static_sizes;
00022
break;
00023
00024
case MARCHING_NO_HOLES:
00025 n_polygons =
get_holeless_isosurface_polygons( corners, isovalue, sizes,
00026 points );
00027
break;
00028
00029
case MARCHING_TETRA:
00030 n_polygons =
get_tetra_isosurface_polygons( x,
y, z, corners,
00031 isovalue, sizes, points );
00032
break;
00033 }
00034
00035
return( n_polygons );
00036 }
00037
00038 private BOOLEAN
is_binary_inside(
00039 Real value,
00040 Real min_value,
00041 Real max_value )
00042 {
00043
return( min_value <= value && value <= max_value );
00044 }
00045
00046 public int compute_isosurface_in_voxel(
00047 Marching_cubes_methods method,
00048
int x,
00049
int y,
00050
int z,
00051 Real corners[2][2][2],
00052 BOOLEAN binary_flag,
00053 Real min_value,
00054 Real max_value,
00055
int *sizes[],
00056
voxel_point_type *points[] )
00057 {
00058
int i, j, k;
00059 Real binary_corners[2][2][2];
00060
00061
if( binary_flag )
00062 {
00063 for_less( i, 0, 2 )
00064 for_less( j, 0, 2 )
00065 for_less( k, 0, 2 )
00066 {
00067
if(
is_binary_inside( corners[i][j][k],
00068 min_value, max_value ) )
00069 {
00070 binary_corners[i][j][k] = 1.0;
00071 }
00072
else
00073 binary_corners[i][j][k] = 0.0;
00074 }
00075
00076
return(
get_polygons( method, x,
y, z, binary_corners,
00077 0.5, sizes, points ) );
00078 }
00079
else
00080
return(
get_polygons( method, x,
y, z, corners, min_value,
00081 sizes, points ) );
00082 }
00083
00084 public Point_classes get_isosurface_point(
00085 Real corners[2][2][2],
00086
int voxel[],
00087
int edge_intersected,
00088 BOOLEAN binary_flag,
00089 Real min_value,
00090 Real max_value,
00091 Real point[] )
00092 {
00093
int dim;
00094
int v1[N_DIMENSIONS], v2[N_DIMENSIONS];
00095
int offset[N_DIMENSIONS];
00096 Real alpha, val1, val2;
00097
Point_classes point_class;
00098
00099 v1[0] = voxel[0];
00100 v1[1] = voxel[1];
00101 v1[2] = voxel[2];
00102
00103
translate_from_edge_index( edge_intersected, offset );
00104
00105 for_less( dim, 0, N_DIMENSIONS )
00106 v2[dim] = v1[dim] + offset[dim];
00107
00108 val1 = corners[v1[0]][v1[1]][v1[2]];
00109 val2 = corners[v2[0]][v2[1]][v2[2]];
00110
00111
if( binary_flag )
00112 {
00113
if(
is_binary_inside( val1, min_value, max_value ) !=
00114
is_binary_inside( val2, min_value, max_value ) )
00115 {
00116 point_class =
ON_EDGE;
00117 for_less( dim, 0, N_DIMENSIONS )
00118 point[dim] = (Real) (v1[dim] + v2[dim]) / 2.0;
00119 }
00120
else
00121 point_class = (
Point_classes) -1;
00122 }
00123
else
00124 {
00125
if( val1 == min_value )
00126 {
00127 point_class =
ON_FIRST_CORNER;
00128 alpha = 0.0;
00129 }
00130
else if( val2 == min_value )
00131 {
00132 point_class =
ON_SECOND_CORNER;
00133 alpha = 1.0;
00134 }
00135
else if( (val1 < min_value && val2 > min_value) ||
00136 (val1 > min_value && val2 < min_value) )
00137 {
00138 point_class =
ON_EDGE;
00139 alpha = (min_value - val1) / (val2 - val1);
00140 }
00141
else
00142 point_class = (
Point_classes) -1;
00143
00144
if( point_class >= (
Point_classes) 0 )
00145 {
00146 for_less( dim, 0, N_DIMENSIONS )
00147 {
00148 point[dim] = INTERPOLATE( alpha,
00149 (Real) v1[dim], (Real) v2[dim] );
00150 }
00151 }
00152 }
00153
00154
return( point_class );
00155 }
00156
00157 public int get_max_marching_edges(
00158 Marching_cubes_methods method )
00159 {
00160
switch( method )
00161 {
00162
case MARCHING_CUBES:
00163
case MARCHING_NO_HOLES:
00164
return( 3 );
00165
00166
case MARCHING_TETRA:
00167
return(
N_MARCHING_TETRA_EDGES );
00168
00169
default:
00170 print_error(
"Invalid parameter in get_max_marching_edges.\n" );
00171
return( 0 );
00172 }
00173 }
00174
00175 public int get_max_marching_polygons_per_voxel(
00176 Marching_cubes_methods method )
00177 {
00178
switch( method )
00179 {
00180
case MARCHING_CUBES:
00181
return( 4 );
00182
00183
case MARCHING_NO_HOLES:
00184
return( 4 );
00185
00186
case MARCHING_TETRA:
00187
return( 5 );
00188
00189
default:
00190 print_error(
00191
"Invalid parameter in get_max_marching_polygons_per_voxel.\n" );
00192
return( 0 );
00193 }
00194 }
00195