Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

poly_neighs.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- 00002 @COPYRIGHT : 00003 Copyright 1993,1994,1995 David MacDonald, 00004 McConnell Brain Imaging Centre, 00005 Montreal Neurological Institute, McGill University. 00006 Permission to use, copy, modify, and distribute this 00007 software and its documentation for any purpose and without 00008 fee is hereby granted, provided that the above copyright 00009 notice appear in all copies. The author and McGill University 00010 make no representations about the suitability of this 00011 software for any purpose. It is provided "as is" without 00012 express or implied warranty. 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 /* ----------------------------- MNI Header ----------------------------------- 00029 @NAME : check_polygons_neighbours_computed 00030 @INPUT : polygons 00031 @OUTPUT : 00032 @RETURNS : 00033 @DESCRIPTION: Creates the polygons neighbours (neighbouring polygon index for 00034 each polygon edge), if necessary. 00035 @METHOD : 00036 @GLOBALS : 00037 @CALLS : 00038 @CREATED : 1993 David MacDonald 00039 @MODIFIED : 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 /* ----------------------------- MNI Header ----------------------------------- 00326 @NAME : create_polygon_neighbours 00327 @INPUT : n_polygons 00328 indices 00329 end_indices 00330 @OUTPUT : neighbours 00331 @RETURNS : 00332 @DESCRIPTION: Computes the neighbours for each edge of the polygons 00333 @METHOD : 00334 @GLOBALS : 00335 @CALLS : 00336 @CREATED : 1993 David MacDonald 00337 @MODIFIED : 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 }

Generated on Wed Jul 28 09:10:57 2004 for BICPL by doxygen 1.3.7