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/objects.h>
00017
00018
#ifndef lint
00019
static char rcsid[] =
"$Header: /software/source//libraries/bicpl/Objects/poly_neighs.c,v 1.22 2000/02/06 15:30:45 stever Exp $";
00020
#endif
00021
00022 #define SMALL_CHUNK_SIZE 4
00023
00024
private void create_polygon_neighbours(
00025
polygons_struct *polygons,
00026
int neighbours[] );
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 public void check_polygons_neighbours_computed(
00043
polygons_struct *polygons )
00044 {
00045
if( polygons->
neighbours == NULL && polygons->
n_items > 0 )
00046 {
00047 ALLOC( polygons->
neighbours,polygons->
end_indices[polygons->
n_items-1]);
00048
create_polygon_neighbours( polygons, polygons->
neighbours );
00049 }
00050 }
00051
00052 public void delete_polygon_point_neighbours(
00053
polygons_struct *polygons,
00054
int n_point_neighbours[],
00055
int *point_neighbours[],
00056 Smallest_int interior_flags[],
00057
int *point_polygons[] )
00058 {
00059
int i;
00060
00061 FREE( n_point_neighbours );
00062
00063 for_less( i, 0, polygons->
n_points )
00064 FREE( point_neighbours[i] );
00065 FREE( point_neighbours );
00066
00067
if( interior_flags != NULL )
00068 FREE( interior_flags );
00069
00070
if( point_polygons != NULL )
00071 {
00072 FREE( point_polygons[0] );
00073 FREE( point_polygons );
00074 }
00075 }
00076
00077 private void insert_neighbours(
00078
int n_to_add,
00079
int indices[],
00080
int n_nodes,
00081
int *n_neighbours,
00082
int *neighbours[] )
00083 {
00084
int p1, p2, first_index, start, i, n_to_insert, n_to_do, last_index;
00085 BOOLEAN wrapped;
00086
00087 p1 = indices[0];
00088 for_less( first_index, 0, *n_neighbours )
00089 {
00090
if( (*neighbours)[first_index] == p1 + n_nodes )
00091
break;
00092 }
00093
00094 wrapped =
FALSE;
00095
00096
if( first_index < *n_neighbours )
00097 {
00098 start = first_index-1;
00099
while( start >= 0 && (*neighbours)[start] < n_nodes )
00100 --start;
00101 ++start;
00102
00103 n_to_insert = first_index - start;
00104 for_down( i, n_to_add - 1, 0 )
00105 indices[n_to_insert+i] = indices[i];
00106
00107 for_less( i, 0, n_to_insert )
00108 {
00109 indices[i] = (*neighbours)[start+i];
00110 (*neighbours)[start+i] = -1;
00111 }
00112 (*neighbours)[first_index] = -1;
00113 n_to_add += n_to_insert;
00114
if( indices[n_to_add-1] == indices[0] )
00115 {
00116 --n_to_add;
00117 wrapped =
TRUE;
00118 }
00119 }
00120
00121 p2 = indices[n_to_add-1];
00122 for_less( last_index, 0, *n_neighbours )
00123 {
00124
if( (*neighbours)[last_index] == p2 )
00125
break;
00126 }
00127
00128
if( last_index == *n_neighbours )
00129 {
00130
if( !wrapped )
00131 indices[n_to_add-1] += n_nodes;
00132 last_index = 0;
00133 n_to_do = *n_neighbours;
00134 }
00135
else
00136 {
00137 ++last_index;
00138 n_to_do = *n_neighbours-1;
00139 }
00140
00141 for_less( i, 0, n_to_do )
00142 {
00143
if( (*neighbours)[(last_index+i)%*n_neighbours] >= 0 )
00144 {
00145 indices[n_to_add] = (*neighbours)[(last_index+i)%*n_neighbours];
00146 ++n_to_add;
00147 }
00148 }
00149
00150 SET_ARRAY_SIZE( *neighbours, *n_neighbours, n_to_add,
SMALL_CHUNK_SIZE);
00151
00152 *n_neighbours = n_to_add;
00153 for_less( i, 0, n_to_add )
00154 (*neighbours)[i] = indices[i];
00155 }
00156
00157 public void create_polygon_point_neighbours(
00158
polygons_struct *polygons,
00159 BOOLEAN across_polygons_flag,
00160
int *n_point_neighbours_ptr[],
00161
int **point_neighbours_ptr[],
00162 Smallest_int *interior_flags_ptr[],
00163
int **point_polygons_ptr[] )
00164 {
00165
int edge, i0, i1, size, poly, total_neighbours, p0, p1;
00166
int points_to_add_alloced;
00167
int n_points, n;
00168
int *n_point_neighbours, **point_neighbours;
00169
int **point_polygons, point, index0, index1;
00170
int i, v, indices[
MAX_POINTS_PER_POLYGON], ii;
00171
int n_to_add, *points_to_add;
00172 progress_struct progress;
00173
00174
if( across_polygons_flag && point_polygons_ptr != NULL )
00175 {
00176 print_error(
00177
"create_polygon_point_neighbours: conflicting argument.\n" );
00178
return;
00179 }
00180
00181 points_to_add_alloced = 0;
00182 points_to_add = NULL;
00183
00184 n_points = polygons->
n_points;
00185
00186 ALLOC( n_point_neighbours, n_points );
00187 for_less( point, 0, n_points )
00188 n_point_neighbours[point] = 0;
00189
00190 ALLOC( point_neighbours, n_points );
00191
00192 initialize_progress_report( &progress,
FALSE, polygons->
n_items,
00193
"Neighbour-finding" );
00194
00195 for_less( poly, 0, polygons->
n_items )
00196 {
00197
00198 size =
GET_OBJECT_SIZE( *polygons, poly );
00199 for_less( v, 0, size )
00200 {
00201 indices[v] = polygons->
indices[
00202
POINT_INDEX(polygons->
end_indices,poly,v)];
00203 }
00204
00205 for_less( i0, 0, size )
00206 {
00207 p0 = indices[i0];
00208
00209
if( size + n_point_neighbours[p0] > points_to_add_alloced )
00210 {
00211 SET_ARRAY_SIZE( points_to_add, points_to_add_alloced,
00212 size + n_point_neighbours[p0],
00213 DEFAULT_CHUNK_SIZE);
00214 points_to_add_alloced = size + n_point_neighbours[p0];
00215 }
00216
00217 n_to_add = 0;
00218 for_less( ii, 0, size-1 )
00219 {
00220 i1 = (i0 + 1 + ii) % size;
00221
if( !across_polygons_flag && ii != 0 && ii != size-2 )
00222
continue;
00223
00224 p1 = indices[i1];
00225 points_to_add[n_to_add] = p1;
00226 ++n_to_add;
00227 }
00228
00229
insert_neighbours( n_to_add, points_to_add, n_points,
00230 &n_point_neighbours[p0], &point_neighbours[p0] );
00231 }
00232
00233 update_progress_report( &progress, poly+1 );
00234 }
00235
00236 terminate_progress_report( &progress );
00237
00238
if( points_to_add_alloced > 0 )
00239 FREE( points_to_add );
00240
00241 total_neighbours = 0;
00242 for_less( i, 0, n_points )
00243 {
00244 REALLOC( point_neighbours[i], n_point_neighbours[i] );
00245 total_neighbours += n_point_neighbours[i];
00246 }
00247
00248
if( interior_flags_ptr != NULL )
00249 {
00250 ALLOC( *interior_flags_ptr, n_points );
00251 for_less( point, 0, n_points )
00252 {
00253 (*interior_flags_ptr)[point] = (Smallest_int)
00254 (point_neighbours[point][n_point_neighbours[point]-1] < n_points);
00255 }
00256 }
00257
00258 for_less( point, 0, n_points )
00259 {
00260 for_less( n, 0, n_point_neighbours[point] )
00261 {
00262
if( point_neighbours[point][n] >= n_points )
00263 point_neighbours[point][n] -= n_points;
00264 }
00265 }
00266
00267 *n_point_neighbours_ptr = n_point_neighbours;
00268 *point_neighbours_ptr = point_neighbours;
00269
00270
if( point_polygons_ptr == NULL )
00271
return;
00272
00273 ALLOC( point_polygons, n_points );
00274 ALLOC( point_polygons[0], total_neighbours );
00275
00276 for_less( point, 0, total_neighbours )
00277 point_polygons[0][point] = -1;
00278
00279 for_less( point, 1, n_points )
00280 {
00281 point_polygons[point] = &point_polygons[point-1]
00282 [n_point_neighbours[point-1]];
00283 }
00284
00285 initialize_progress_report( &progress,
FALSE, polygons->
n_items,
00286
"Neighbour-finding step 2" );
00287
00288 for_less( poly, 0, polygons->
n_items )
00289 {
00290 size =
GET_OBJECT_SIZE( *polygons, poly );
00291
00292 i1 = polygons->
indices[
POINT_INDEX(polygons->
end_indices,poly,0)];
00293 for_less( edge, 0, size )
00294 {
00295 i0 = i1;
00296 i1 = polygons->
indices[
00297
POINT_INDEX(polygons->
end_indices,poly,(edge+1)%size)];
00298
00299 for_less( index0, 0, n_point_neighbours[i0] )
00300 {
00301
if( point_neighbours[i0][index0] == i1 )
00302
break;
00303 }
00304
00305 for_less( index1, 0, n_point_neighbours[i1] )
00306 {
00307
if( point_neighbours[i1][index1] == i0 )
00308
break;
00309 }
00310
00311
if( point_polygons[i0][index0] < 0 )
00312 point_polygons[i0][index0] = poly;
00313
else
00314 point_polygons[i1][index1] = poly;
00315 }
00316
00317 update_progress_report( &progress, poly+1 );
00318 }
00319
00320 terminate_progress_report( &progress );
00321
00322 *point_polygons_ptr = point_polygons;
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 private void create_polygon_neighbours(
00341
polygons_struct *polygons,
00342
int neighbours[] )
00343 {
00344
int i0, i1, size1, size2, n1, n2;
00345
int poly1, poly2, point1, point2, edge1, edge2;
00346
int *n_point_neighbours, **point_neighbours;
00347
int **point_polygons;
00348 progress_struct progress;
00349
00350 for_less( i0, 0, polygons->
end_indices[polygons->
n_items-1] )
00351 neighbours[i0] = -1;
00352
00353
create_polygon_point_neighbours( polygons,
FALSE, &n_point_neighbours,
00354 &point_neighbours, NULL, &point_polygons );
00355
00356 initialize_progress_report( &progress,
FALSE, polygons->
n_items,
00357
"Neighbour-finding step 2" );
00358
00359 for_less( point1, 0, polygons->
n_points )
00360 {
00361 for_less( n1, 0, n_point_neighbours[point1] )
00362 {
00363 point2 = point_neighbours[point1][n1];
00364
00365
if( point2 <= point1 )
00366
continue;
00367
00368 poly1 = point_polygons[point1][n1];
00369
if( poly1 < 0 )
00370
continue;
00371
00372 for_less( n2, 0, n_point_neighbours[point2] )
00373 {
00374
if( point_neighbours[point2][n2] == point1 )
00375
break;
00376 }
00377
00378
if( n2 >= n_point_neighbours[point2] )
00379 handle_internal_error(
"create_polygon_neighbours" );
00380
00381 poly2 = point_polygons[point2][n2];
00382
if( poly2 < 0 )
00383
continue;
00384
00385 size1 =
GET_OBJECT_SIZE( *polygons, poly1 );
00386 for_less( edge1, 0, size1 )
00387 {
00388 i0 = polygons->
indices[
POINT_INDEX(polygons->
end_indices,
00389 poly1,edge1)];
00390 i1 = polygons->
indices[
POINT_INDEX(polygons->
end_indices,
00391 poly1,(edge1+1)%size1)];
00392
00393
if( (i0 == point1 && i1 == point2) ||
00394 (i1 == point1 && i0 == point2) )
00395
break;
00396 }
00397
00398
if( edge1 >= size1 )
00399 handle_internal_error(
"create_polygon_neighbours" );
00400
00401 size2 =
GET_OBJECT_SIZE( *polygons, poly2 );
00402 for_less( edge2, 0, size2 )
00403 {
00404 i0 = polygons->
indices[
POINT_INDEX(polygons->
end_indices,
00405 poly2,edge2)];
00406 i1 = polygons->
indices[
POINT_INDEX(polygons->
end_indices,
00407 poly2,(edge2+1)%size2)];
00408
00409
if( (i0 == point1 && i1 == point2) ||
00410 (i1 == point1 && i0 == point2) )
00411
break;
00412 }
00413
00414
if( edge2 >= size2 )
00415 handle_internal_error(
"create_polygon_neighbours" );
00416
00417 neighbours[
POINT_INDEX( polygons->
end_indices, poly1, edge1 )] =
00418 poly2;
00419 neighbours[
POINT_INDEX( polygons->
end_indices, poly2, edge2 )] =
00420 poly1;
00421 }
00422
00423 update_progress_report( &progress, point1+1 );
00424 }
00425
00426 terminate_progress_report( &progress );
00427
00428
delete_polygon_point_neighbours( polygons,
00429 n_point_neighbours, point_neighbours,
00430 NULL, point_polygons );
00431
00432
#ifdef DEBUG
00433
for_less( i0, 0, polygons->
end_indices[polygons->
n_items-1] )
00434 {
00435
if( neighbours[i0] < 0 )
00436
break;
00437 }
00438
00439
if( i0 < polygons->
end_indices[polygons->
n_items-1] )
00440 handle_internal_error(
"create_polygon_neighbours: topology\n" );
00441
#endif
00442
}