00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
#include <volume_io/internal_volume_io.h>
00016
#include <bicpl/geom.h>
00017
#include <bicpl/data_structures.h>
00018
00019
#ifndef lint
00020
static char rcsid[] =
"$Header: /software/source/libraries/bicpl/Geometry/smooth_curvature.c,v 1.15 2002/11/27 22:48:11 stever Exp $";
00021
#endif
00022
00023
private int get_smoothing_points(
00024
polygons_struct *polygons,
00025
int n_neighbours[],
00026
int *neighbours[],
00027
int n_found,
00028
int list[],
00029 Real smoothing_distance,
00030
float distances[],
00031 Point *smoothing_points[] );
00032
00033
private Real
get_average_curvature(
00034 Point *point,
00035 Vector *normal,
00036
int n_smoothing_points,
00037 Point smoothing_points[] );
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 public Real
get_smooth_surface_curvature(
00058
polygons_struct *polygons,
00059
int n_neighbours[],
00060
int *neighbours[],
00061
int poly,
00062
int vertex,
00063 BOOLEAN distances_initialized,
00064
float distances[],
00065 Real smoothing_distance )
00066 {
00067
int n_smoothing_points, point_index, n_found, *list, p;
00068 Point *smoothing_points;
00069 Real curvature;
00070 BOOLEAN alloced_distances;
00071
00072
if( distances == NULL )
00073 {
00074 alloced_distances =
TRUE;
00075 distances_initialized =
FALSE;
00076 ALLOC( distances, polygons->
n_points );
00077 }
00078
else
00079 alloced_distances =
FALSE;
00080
00081 point_index = polygons->
indices[
00082
POINT_INDEX(polygons->
end_indices,poly,vertex)];
00083
00084
00085
00086
00087
00088
00089
00090
00091 n_found =
compute_distances_from_point( polygons, n_neighbours, neighbours,
00092 &polygons->
points[point_index], poly,
00093 smoothing_distance,
00094 distances_initialized, distances,
00095 &list );
00096
00097 n_smoothing_points =
get_smoothing_points( polygons,
00098 n_neighbours, neighbours,
00099 n_found, list,
00100 smoothing_distance,
00101 distances, &smoothing_points );
00102
00103
if( alloced_distances )
00104 FREE( distances );
00105
else
00106 {
00107 for_less( p, 0, n_found )
00108 distances[list[p]] = -1.0f;
00109 }
00110
00111
if( n_found > 0 )
00112 FREE( list );
00113
00114
if( n_smoothing_points > 0 )
00115 {
00116 curvature =
get_average_curvature( &polygons->
points[point_index],
00117 &polygons->
normals[point_index],
00118 n_smoothing_points,
00119 smoothing_points );
00120 }
00121
else
00122 curvature = 0.0;
00123
00124
if( n_smoothing_points > 0 )
00125 FREE( smoothing_points );
00126
00127
return( curvature );
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 private int get_smoothing_points(
00146
polygons_struct *polygons,
00147
int n_neighbours[],
00148
int *neighbours[],
00149
int n_found,
00150
int list[],
00151 Real smoothing_distance,
00152
float distances[],
00153 Point *smoothing_points[] )
00154 {
00155
int p, neigh, point_index, prev_index, inside, outside;
00156
int n_smoothing_points;
00157 Real dist, ratio;
00158 Point point;
00159
00160 n_smoothing_points = 0;
00161
00162 for_less( p, 0, n_found )
00163 {
00164 point_index = list[p];
00165
00166
if( distances[point_index] < 0.0f )
00167 handle_internal_error(
"get_smoothing_points" );
00168
00169 for_less( neigh, 0, n_neighbours[point_index] )
00170 {
00171 prev_index = neighbours[point_index][neigh];
00172
00173
00174
00175
00176
if( distances[prev_index] < 0.0f )
00177 {
00178 inside = point_index;
00179 outside = prev_index;
00180
00181 dist = (Real) distances[inside] +
00182
distance_between_points(
00183 &polygons->
points[inside],
00184 &polygons->
points[outside] );
00185
00186
if( dist != (Real) distances[inside] )
00187 {
00188 ratio = (smoothing_distance - (Real) distances[inside]) /
00189 (dist - (Real) distances[inside]);
00190 INTERPOLATE_POINTS( point,
00191 polygons->
points[inside],
00192 polygons->
points[outside],
00193 ratio );
00194 ADD_ELEMENT_TO_ARRAY( *smoothing_points, n_smoothing_points,
00195 point, DEFAULT_CHUNK_SIZE );
00196 }
00197 }
00198 }
00199 }
00200
00201
return( n_smoothing_points );
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 private Real
get_average_curvature(
00221 Point *point,
00222 Vector *normal,
00223
int n_smoothing_points,
00224 Point smoothing_points[] )
00225 {
00226
int i;
00227 Real sum_curvature, curvature, angle, sign_curvature;
00228 Point centroid;
00229 Vector offset;
00230
00231
get_points_centroid( n_smoothing_points, smoothing_points, ¢roid );
00232
00233 SUB_POINTS( offset, *point, centroid );
00234
if( DOT_VECTORS( offset, *normal ) < 0.0 )
00235 sign_curvature = -1.0;
00236
else
00237 sign_curvature = 1.0;
00238
00239 sum_curvature = 0.0;
00240 for_less( i, 0, n_smoothing_points )
00241 {
00242 angle = RAD_TO_DEG *
get_angle_between_points( &smoothing_points[i],
00243 point, ¢roid );
00244
00245 curvature = 180.0 - 2.0 * angle;
00246 sum_curvature += curvature;
00247 }
00248
00249 curvature = sum_curvature * sign_curvature / (Real) n_smoothing_points;
00250
00251
#ifdef DEBUG
00252
{
00253
static BOOLEAN first =
TRUE;
00254 Real **tags;
00255
if( first )
00256 {
00257 first =
FALSE;
00258 ALLOC2D( tags, n_smoothing_points+1, 3 );
00259 tags[0][X] = RPoint_x(*point);
00260 tags[0][Y] = RPoint_y(*point);
00261 tags[0][Z] = RPoint_z(*point);
00262 for_less( i, 0, n_smoothing_points )
00263 {
00264 tags[i+1][X] = RPoint_x(smoothing_points[i]);
00265 tags[i+1][Y] = RPoint_y(smoothing_points[i]);
00266 tags[i+1][Z] = RPoint_z(smoothing_points[i]);
00267 }
00268 (
void) output_tag_file(
"smooth_curvature.tag",
"", 1, n_smoothing_points+1,
00269 tags, NULL, NULL, NULL, NULL, NULL );
00270 FREE2D( tags );
00271 }
00272 }
00273
#endif
00274
00275
return( curvature );
00276 }