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

bintree.c

Go to the documentation of this file.
00001 00002 /* ---------------------------------------------------------------------------- 00003 @COPYRIGHT : 00004 Copyright 1993,1994,1995 David MacDonald, 00005 McConnell Brain Imaging Centre, 00006 Montreal Neurological Institute, McGill University. 00007 Permission to use, copy, modify, and distribute this 00008 software and its documentation for any purpose and without 00009 fee is hereby granted, provided that the above copyright 00010 notice appear in all copies. The author and McGill University 00011 make no representations about the suitability of this 00012 software for any purpose. It is provided "as is" without 00013 express or implied warranty. 00014 ---------------------------------------------------------------------------- */ 00015 00016 #include <volume_io/internal_volume_io.h> 00017 #include <bicpl/data_structures.h> 00018 00019 #ifndef lint 00020 static char rcsid[] = "$Header: /software/source//libraries/bicpl/Data_structures/bintree.c,v 1.9 2000/02/06 15:30:09 stever Exp $"; 00021 #endif 00022 00023 private Status io_range( 00024 FILE *file, 00025 IO_types direction, 00026 File_formats format, 00027 range_struct *range ); 00028 private Status output_bintree_node( 00029 FILE *file, 00030 File_formats format, 00031 bintree_node_struct *node ); 00032 private Status input_bintree_node( 00033 FILE *file, 00034 File_formats format, 00035 bintree_node_struct **node ); 00036 00037 /* ----------------------------- MNI Header ----------------------------------- 00038 @NAME : initialize_bintree 00039 @INPUT : x_min 00040 x_max 00041 y_min 00042 y_max 00043 z_min 00044 z_max 00045 @OUTPUT : bintree 00046 @RETURNS : 00047 @DESCRIPTION: Initializes the bintree (a multidimensional binary tree) 00048 to empty. Bintrees are usually used to organize geometric 00049 objects for fast intersection and proximity tests. 00050 @METHOD : 00051 @GLOBALS : 00052 @CALLS : 00053 @CREATED : 1993 David MacDonald 00054 @MODIFIED : 00055 ---------------------------------------------------------------------------- */ 00056 00057 public void initialize_bintree( 00058 Real x_min, 00059 Real x_max, 00060 Real y_min, 00061 Real y_max, 00062 Real z_min, 00063 Real z_max, 00064 bintree_struct_ptr bintree ) 00065 { 00066 bintree->range.limits[X][0] = (float) x_min; 00067 bintree->range.limits[X][1] = (float) x_max; 00068 bintree->range.limits[Y][0] = (float) y_min; 00069 bintree->range.limits[Y][1] = (float) y_max; 00070 bintree->range.limits[Z][0] = (float) z_min; 00071 bintree->range.limits[Z][1] = (float) z_max; 00072 00073 bintree->n_nodes = 0; 00074 bintree->root = (bintree_node_struct *) 0; 00075 } 00076 00077 /* ----------------------------- MNI Header ----------------------------------- 00078 @NAME : delete_bintree_node 00079 @INPUT : node 00080 @OUTPUT : 00081 @RETURNS : 00082 @DESCRIPTION: Deletes a node of the bintree. 00083 @METHOD : 00084 @GLOBALS : 00085 @CALLS : 00086 @CREATED : 1993 David MacDonald 00087 @MODIFIED : 00088 ---------------------------------------------------------------------------- */ 00089 00090 public void delete_bintree_node( 00091 bintree_node_struct *node ) 00092 { 00093 FREE( node ); 00094 } 00095 00096 /* ----------------------------- MNI Header ----------------------------------- 00097 @NAME : recursive_delete_bintree 00098 @INPUT : node 00099 @OUTPUT : 00100 @RETURNS : 00101 @DESCRIPTION: Deletes a bintree node and its children. 00102 @METHOD : 00103 @GLOBALS : 00104 @CALLS : 00105 @CREATED : 1993 David MacDonald 00106 @MODIFIED : 00107 ---------------------------------------------------------------------------- */ 00108 00109 private void recursive_delete_bintree( 00110 bintree_node_struct *node ) 00111 { 00112 bintree_node_struct *left, *right; 00113 00114 if( get_bintree_left_child( node, &left ) ) 00115 recursive_delete_bintree( left ); 00116 if( get_bintree_right_child( node, &right ) ) 00117 recursive_delete_bintree( right ); 00118 00119 delete_bintree_node( node ); 00120 } 00121 00122 /* ----------------------------- MNI Header ----------------------------------- 00123 @NAME : delete_bintree 00124 @INPUT : bintree 00125 @OUTPUT : 00126 @RETURNS : 00127 @DESCRIPTION: Deletes the bintree. 00128 @METHOD : 00129 @GLOBALS : 00130 @CALLS : 00131 @CREATED : 1993 David MacDonald 00132 @MODIFIED : 00133 ---------------------------------------------------------------------------- */ 00134 00135 public void delete_bintree( 00136 bintree_struct_ptr bintree ) 00137 { 00138 if( bintree->root != NULL ) 00139 recursive_delete_bintree( bintree->root ); 00140 } 00141 00142 /* ----------------------------- MNI Header ----------------------------------- 00143 @NAME : get_bintree_limits 00144 @INPUT : bintree 00145 @OUTPUT : limits 00146 @RETURNS : 00147 @DESCRIPTION: Passes back the x, y, z range of the bintree. 00148 @METHOD : 00149 @GLOBALS : 00150 @CALLS : 00151 @CREATED : 1993 David MacDonald 00152 @MODIFIED : 00153 ---------------------------------------------------------------------------- */ 00154 00155 public void get_bintree_limits( 00156 bintree_struct_ptr bintree, 00157 range_struct *limits ) 00158 { 00159 *limits = bintree->range; 00160 } 00161 00162 /* ----------------------------- MNI Header ----------------------------------- 00163 @NAME : set_bintree_child 00164 @INPUT : node 00165 which : LEFT_CHILD or RIGHT_CHILD 00166 child 00167 @OUTPUT : 00168 @RETURNS : 00169 @DESCRIPTION: Sets the given child of the node to the 'child'. 00170 @METHOD : 00171 @GLOBALS : 00172 @CALLS : 00173 @CREATED : 1993 David MacDonald 00174 @MODIFIED : 00175 ---------------------------------------------------------------------------- */ 00176 00177 private void set_bintree_child( 00178 bintree_node_struct *node, 00179 int which, 00180 bintree_node_struct *child ) 00181 { 00182 int ind; 00183 00184 if( which == LEFT_CHILD ) 00185 ind = 0; 00186 else 00187 { 00188 if( (node->node_info & LEFT_CHILD_EXISTS) != 0 ) 00189 ind = 1; 00190 else 00191 ind = 0; 00192 } 00193 00194 node->data.children[ind] = child; 00195 } 00196 00197 /* ----------------------------- MNI Header ----------------------------------- 00198 @NAME : create_bintree_node 00199 @INPUT : bintree 00200 @OUTPUT : node_index 00201 @RETURNS : 00202 @DESCRIPTION: Creates an empty bintree leaf node. 00203 @METHOD : 00204 @GLOBALS : 00205 @CALLS : 00206 @CREATED : 1993 David MacDonald 00207 @MODIFIED : 00208 ---------------------------------------------------------------------------- */ 00209 00210 public bintree_node_struct *create_bintree_internal_node( 00211 int split_coord, 00212 Real split_position, 00213 bintree_node_struct *left, 00214 bintree_node_struct *right ) 00215 { 00216 bintree_node_struct *node; 00217 int n_children, children_bits; 00218 00219 n_children = 0; 00220 00221 children_bits = 0; 00222 00223 if( left != NULL ) 00224 { 00225 children_bits |= LEFT_CHILD_EXISTS; 00226 ++n_children; 00227 } 00228 if( right != NULL ) 00229 { 00230 children_bits |= RIGHT_CHILD_EXISTS; 00231 ++n_children; 00232 } 00233 00234 if( n_children == 0 ) 00235 { 00236 handle_internal_error( "create_bintree_internal_node" ); 00237 return( NULL ); 00238 } 00239 00240 ALLOC_VAR_SIZED_STRUCT( node, bintree_node_struct *, n_children ); 00241 00242 node->node_info = (unsigned char) (split_coord | children_bits); 00243 node->split_position = (float) split_position; 00244 00245 /* --- set the children */ 00246 00247 if( left != NULL ) 00248 set_bintree_child( node, LEFT_CHILD, left ); 00249 00250 if( right != NULL ) 00251 set_bintree_child( node, RIGHT_CHILD, right ); 00252 00253 return( node ); 00254 } 00255 00256 /* ----------------------------- MNI Header ----------------------------------- 00257 @NAME : create_bintree_leaf 00258 @INPUT : split_position 00259 n_objects 00260 object_list 00261 @OUTPUT : 00262 @RETURNS : leaf 00263 @DESCRIPTION: Creates a leaf node containing pointers to the objects. 00264 @METHOD : 00265 @GLOBALS : 00266 @CALLS : 00267 @CREATED : 1993 David MacDonald 00268 @MODIFIED : 00269 ---------------------------------------------------------------------------- */ 00270 00271 public bintree_node_struct *create_bintree_leaf( 00272 Real split_position, 00273 int n_objects, 00274 int object_list[] ) 00275 { 00276 bintree_node_struct *node; 00277 int i, n_alloc, *node_list, n_objects_bits; 00278 00279 if( n_objects <= MAX_NODE_INFO_OBJECTS ) 00280 { 00281 n_alloc = n_objects; 00282 n_objects_bits = n_objects; 00283 } 00284 else 00285 { 00286 n_alloc = n_objects + 1; 00287 n_objects_bits = 0; 00288 } 00289 00290 ALLOC_VAR_SIZED_STRUCT( node, int, n_alloc ); 00291 00292 node->node_info = (unsigned char) 00293 (LEAF_SIGNAL | (n_objects_bits << NODE_INFO_OBJECTS_SHIFT)); 00294 node->split_position = (float) split_position; 00295 00296 node_list = node->data.object_list; 00297 00298 if( n_objects > MAX_NODE_INFO_OBJECTS ) 00299 { 00300 node_list[0] = n_objects; 00301 ++node_list; 00302 } 00303 00304 for_less( i, 0, n_objects ) 00305 node_list[i] = object_list[i]; 00306 00307 return( node ); 00308 } 00309 00310 /* ----------------------------- MNI Header ----------------------------------- 00311 @NAME : bintree_node_is_leaf 00312 @INPUT : bintree 00313 node 00314 @OUTPUT : 00315 @RETURNS : TRUE if node is leaf 00316 @DESCRIPTION: 00317 @METHOD : 00318 @GLOBALS : 00319 @CALLS : 00320 @CREATED : 1993 David MacDonald 00321 @MODIFIED : 00322 ---------------------------------------------------------------------------- */ 00323 00324 public BOOLEAN bintree_node_is_leaf( 00325 bintree_node_struct *node ) 00326 { 00327 return( (node->node_info & SUBDIVISION_AXIS_BITS) == LEAF_SIGNAL ); 00328 } 00329 00330 /* ----------------------------- MNI Header ----------------------------------- 00331 @NAME : get_bintree_leaf_info 00332 @INPUT : bintree 00333 node 00334 @OUTPUT : object_list 00335 @RETURNS : # objects 00336 @DESCRIPTION: Passes back the object list and returns the number in the list. 00337 @METHOD : 00338 @GLOBALS : 00339 @CALLS : 00340 @CREATED : 1993 David MacDonald 00341 @MODIFIED : 00342 ---------------------------------------------------------------------------- */ 00343 00344 public int get_bintree_leaf_objects( 00345 bintree_node_struct *node, 00346 int *object_list[] ) 00347 { 00348 int *node_list, n_objects; 00349 00350 node_list = node->data.object_list; 00351 n_objects = node->node_info >> NODE_INFO_OBJECTS_SHIFT; 00352 00353 if( n_objects == 0 ) 00354 { 00355 n_objects = node_list[0]; 00356 ++node_list; 00357 } 00358 00359 if( n_objects > 0 ) 00360 *object_list = node_list; 00361 00362 return( n_objects ); 00363 } 00364 00365 /* ----------------------------- MNI Header ----------------------------------- 00366 @NAME : get_bintree_left_child 00367 @INPUT : bintree 00368 node 00369 @OUTPUT : left_child 00370 left_limit 00371 @RETURNS : TRUE if child exists 00372 @DESCRIPTION: Passes back the left child of the given node, if it exists. 00373 @METHOD : 00374 @GLOBALS : 00375 @CALLS : 00376 @CREATED : 1993 David MacDonald 00377 @MODIFIED : 00378 ---------------------------------------------------------------------------- */ 00379 00380 public BOOLEAN get_bintree_left_child_ptr( 00381 bintree_node_struct *node, 00382 bintree_node_struct ***ptr_to_left_child ) 00383 { 00384 BOOLEAN child_exists; 00385 00386 child_exists = !bintree_node_is_leaf(node) && 00387 (node->node_info & LEFT_CHILD_EXISTS) != 0; 00388 00389 if( child_exists ) 00390 *ptr_to_left_child = &node->data.children[0]; 00391 00392 return( child_exists ); 00393 } 00394 00395 /* ----------------------------- MNI Header ----------------------------------- 00396 @NAME : get_bintree_left_child 00397 @INPUT : bintree 00398 node 00399 @OUTPUT : left_child 00400 @RETURNS : TRUE if child exists 00401 @DESCRIPTION: Passes back the left child of the given node, if it exists. 00402 @METHOD : 00403 @GLOBALS : 00404 @CALLS : 00405 @CREATED : 1993 David MacDonald 00406 @MODIFIED : 00407 ---------------------------------------------------------------------------- */ 00408 00409 public BOOLEAN get_bintree_left_child( 00410 bintree_node_struct *node, 00411 bintree_node_struct **left_child ) 00412 { 00413 BOOLEAN child_exists; 00414 bintree_node_struct **ptr; 00415 00416 child_exists = get_bintree_left_child_ptr( node, &ptr ); 00417 00418 if( child_exists ) 00419 *left_child = *ptr; 00420 00421 return( child_exists ); 00422 } 00423 00424 /* ----------------------------- MNI Header ----------------------------------- 00425 @NAME : get_bintree_right_child 00426 @INPUT : bintree 00427 node 00428 @OUTPUT : right_child 00429 @RETURNS : TRUE if child exists 00430 @DESCRIPTION: Passes back the right child of the given node, if it exists. 00431 @METHOD : 00432 @GLOBALS : 00433 @CALLS : 00434 @CREATED : 1993 David MacDonald 00435 @MODIFIED : 00436 ---------------------------------------------------------------------------- */ 00437 00438 public BOOLEAN get_bintree_right_child_ptr( 00439 bintree_node_struct *node, 00440 bintree_node_struct ***ptr_to_right_child ) 00441 { 00442 BOOLEAN child_exists; 00443 int ind; 00444 00445 child_exists = !bintree_node_is_leaf(node) && 00446 (node->node_info & RIGHT_CHILD_EXISTS) != 0; 00447 00448 if( child_exists ) 00449 { 00450 if( (node->node_info & LEFT_CHILD_EXISTS) != 0 ) 00451 ind = 1; 00452 else 00453 ind = 0; 00454 00455 *ptr_to_right_child = &node->data.children[ind]; 00456 } 00457 00458 return( child_exists ); 00459 } 00460 00461 /* ----------------------------- MNI Header ----------------------------------- 00462 @NAME : get_bintree_right_child 00463 @INPUT : bintree 00464 node 00465 @OUTPUT : right_child 00466 @RETURNS : TRUE if child exists 00467 @DESCRIPTION: Passes back the right child of the given node, if it exists. 00468 @METHOD : 00469 @GLOBALS : 00470 @CALLS : 00471 @CREATED : 1993 David MacDonald 00472 @MODIFIED : 00473 ---------------------------------------------------------------------------- */ 00474 00475 public BOOLEAN get_bintree_right_child( 00476 bintree_node_struct *node, 00477 bintree_node_struct **right_child ) 00478 { 00479 BOOLEAN child_exists; 00480 bintree_node_struct **ptr; 00481 00482 child_exists = get_bintree_right_child_ptr( node, &ptr ); 00483 00484 if( child_exists ) 00485 *right_child = *ptr; 00486 00487 return( child_exists ); 00488 } 00489 00490 00491 /* ----------------------------- MNI Header ----------------------------------- 00492 @NAME : get_node_split_axis 00493 @INPUT : node 00494 @OUTPUT : 00495 @RETURNS : axis X, Y, or Z 00496 @DESCRIPTION: Returns the split axis of the node. 00497 @METHOD : 00498 @GLOBALS : 00499 @CALLS : 00500 @CREATED : 1993 David MacDonald 00501 @MODIFIED : 00502 ---------------------------------------------------------------------------- */ 00503 00504 public int get_node_split_axis( 00505 bintree_node_struct *node ) 00506 { 00507 return( node->node_info & SUBDIVISION_AXIS_BITS ); 00508 } 00509 00510 /* ----------------------------- MNI Header ----------------------------------- 00511 @NAME : get_node_split_position 00512 @INPUT : node 00513 @OUTPUT : 00514 @RETURNS : position 00515 @DESCRIPTION: Returns the split position of the node. 00516 @METHOD : 00517 @GLOBALS : 00518 @CALLS : 00519 @CREATED : 1993 David MacDonald 00520 @MODIFIED : 00521 ---------------------------------------------------------------------------- */ 00522 00523 public Real get_node_split_position( 00524 bintree_node_struct *node ) 00525 { 00526 return( (Real) node->split_position ); 00527 } 00528 00529 /* ----------------------------- MNI Header ----------------------------------- 00530 @NAME : point_within_range 00531 @INPUT : point 00532 range 00533 @OUTPUT : 00534 @RETURNS : TRUE if point is within the box 00535 @DESCRIPTION: Checks if the point is within the given 3D box. 00536 @METHOD : 00537 @GLOBALS : 00538 @CALLS : 00539 @CREATED : 1993 David MacDonald 00540 @MODIFIED : 00541 ---------------------------------------------------------------------------- */ 00542 00543 public BOOLEAN point_within_range( 00544 Point *point, 00545 range_struct *range ) 00546 { 00547 BOOLEAN within; 00548 00549 within = (Point_x(*point) >= range->limits[X][0] && 00550 Point_x(*point) <= range->limits[X][1] && 00551 Point_y(*point) >= range->limits[Y][0] && 00552 Point_y(*point) <= range->limits[Y][1] && 00553 Point_z(*point) >= range->limits[Z][0] && 00554 Point_z(*point) <= range->limits[Z][1]); 00555 00556 return( within ); 00557 } 00558 00559 /* ----------------------------- MNI Header ----------------------------------- 00560 @NAME : range_volume 00561 @INPUT : range 00562 @OUTPUT : 00563 @RETURNS : returns volume 00564 @DESCRIPTION: Returns the volume of the given range. 00565 @METHOD : 00566 @GLOBALS : 00567 @CALLS : 00568 @CREATED : 1993 David MacDonald 00569 @MODIFIED : 00570 ---------------------------------------------------------------------------- */ 00571 00572 public Real range_volume( 00573 range_struct *range ) 00574 { 00575 return( ((Real) range->limits[X][1] - (Real) range->limits[X][0]) * 00576 ((Real) range->limits[Y][1] - (Real) range->limits[Y][0]) * 00577 ((Real) range->limits[Z][1] - (Real) range->limits[Z][0]) ); 00578 } 00579 00580 /* ----------------------------- MNI Header ----------------------------------- 00581 @NAME : range_surface_area 00582 @INPUT : range 00583 @OUTPUT : 00584 @RETURNS : returns surface area 00585 @DESCRIPTION: Returns the surface area of the given range. 00586 @METHOD : 00587 @GLOBALS : 00588 @CALLS : 00589 @CREATED : 1993 David MacDonald 00590 @MODIFIED : 00591 ---------------------------------------------------------------------------- */ 00592 00593 public Real range_surface_area( 00594 range_struct *range ) 00595 { 00596 Real dx, dy, dz; 00597 00598 dx = (Real) range->limits[X][1] - (Real) range->limits[X][0]; 00599 dy = (Real) range->limits[Y][1] - (Real) range->limits[Y][0]; 00600 dz = (Real) range->limits[Z][1] - (Real) range->limits[Z][0]; 00601 00602 return( 2.0 * (dx * dy + dy * dz + dz * dx) ); 00603 } 00604 00605 /* ----------------------------- MNI Header ----------------------------------- 00606 @NAME : io_bintree 00607 @INPUT : file 00608 direction 00609 format 00610 n_objects 00611 bintree 00612 @OUTPUT : 00613 @RETURNS : OK or ERROR 00614 @DESCRIPTION: Writes or reads the bintree. 00615 @METHOD : 00616 @GLOBALS : 00617 @CALLS : 00618 @CREATED : 1993 David MacDonald 00619 @MODIFIED : 00620 ---------------------------------------------------------------------------- */ 00621 00622 public Status io_bintree( 00623 FILE *file, 00624 IO_types direction, 00625 File_formats format, 00626 bintree_struct_ptr bintree ) 00627 { 00628 Status status; 00629 00630 status = io_range( file, direction, format, &bintree->range ); 00631 00632 if( status == OK && direction == WRITE_FILE ) 00633 status = output_bintree_node( file, format, bintree->root ); 00634 else if( status == OK && direction == READ_FILE ) 00635 status = input_bintree_node( file, format, &bintree->root ); 00636 00637 return( status ); 00638 } 00639 00640 /* ----------------------------- MNI Header ----------------------------------- 00641 @NAME : io_range 00642 @INPUT : file 00643 direction 00644 format 00645 range 00646 @OUTPUT : 00647 @RETURNS : OK or ERROR 00648 @DESCRIPTION: Writes or reads a 3D box range. 00649 @METHOD : 00650 @GLOBALS : 00651 @CALLS : 00652 @CREATED : 1993 David MacDonald 00653 @MODIFIED : 00654 ---------------------------------------------------------------------------- */ 00655 00656 private Status io_range( 00657 FILE *file, 00658 IO_types direction, 00659 File_formats format, 00660 range_struct *range ) 00661 { 00662 Status status; 00663 int c, l; 00664 00665 status = OK; 00666 00667 for_less( c, 0, N_DIMENSIONS ) 00668 { 00669 for_less( l, 0, 2 ) 00670 { 00671 if( status == OK ) 00672 { 00673 status = io_float( file, direction, format, 00674 &range->limits[c][l] ); 00675 } 00676 } 00677 } 00678 00679 return( status ); 00680 } 00681 00682 /* ----------------------------- MNI Header ----------------------------------- 00683 @NAME : output_leaf_node 00684 @INPUT : file 00685 format 00686 node 00687 @OUTPUT : 00688 @RETURNS : OK or ERROR 00689 @DESCRIPTION: Outputs a leaf node. 00690 @METHOD : 00691 @GLOBALS : 00692 @CALLS : 00693 @CREATED : 1993 David MacDonald 00694 @MODIFIED : 00695 ---------------------------------------------------------------------------- */ 00696 00697 private Status output_leaf_node( 00698 FILE *file, 00699 File_formats format, 00700 bintree_node_struct *node ) 00701 { 00702 Status status; 00703 int *object_list, n_objects; 00704 00705 status = OK ; 00706 00707 n_objects = get_bintree_leaf_objects( node, &object_list ); 00708 00709 if( n_objects > MAX_NODE_INFO_OBJECTS ) 00710 status = io_int( file, WRITE_FILE, format, &n_objects ); 00711 00712 if( status == OK ) 00713 status = io_ints( file, WRITE_FILE, format, n_objects, &object_list ); 00714 00715 return( status ); 00716 } 00717 00718 /* ----------------------------- MNI Header ----------------------------------- 00719 @NAME : output_bintree_node 00720 @INPUT : file 00721 format 00722 node 00723 @OUTPUT : 00724 @RETURNS : OK or ERROR 00725 @DESCRIPTION: Outputs a bintree node. 00726 @METHOD : 00727 @GLOBALS : 00728 @CALLS : 00729 @CREATED : 1993 David MacDonald 00730 @MODIFIED : 00731 ---------------------------------------------------------------------------- */ 00732 00733 private Status output_bintree_node( 00734 FILE *file, 00735 File_formats format, 00736 bintree_node_struct *node ) 00737 { 00738 Status status; 00739 bintree_node_struct *left, *right; 00740 00741 status = io_binary_data( file, WRITE_FILE, &node->node_info, 00742 sizeof(node->node_info), 1 ); 00743 00744 if( status == OK ) 00745 status = io_float( file, WRITE_FILE, format, &node->split_position ); 00746 00747 if( status == OK ) 00748 { 00749 if( bintree_node_is_leaf( node ) ) 00750 { 00751 status = output_leaf_node( file, format, node ); 00752 } 00753 else 00754 { 00755 if( get_bintree_left_child( node, &left ) ) 00756 status = output_bintree_node( file, format, left ); 00757 if( status == OK && get_bintree_right_child( node, &right ) ) 00758 status = output_bintree_node( file, format, right ); 00759 } 00760 } 00761 00762 return( status ); 00763 } 00764 00765 /* ----------------------------- MNI Header ----------------------------------- 00766 @NAME : input_bintree_node 00767 @INPUT : file 00768 format 00769 @OUTPUT : node 00770 @RETURNS : OK or ERROR 00771 @DESCRIPTION: Inputs a bintree node 00772 @METHOD : 00773 @GLOBALS : 00774 @CALLS : 00775 @CREATED : 1993 David MacDonald 00776 @MODIFIED : 00777 ---------------------------------------------------------------------------- */ 00778 00779 private Status input_bintree_node( 00780 FILE *file, 00781 File_formats format, 00782 bintree_node_struct **node ) 00783 { 00784 Status status; 00785 node_info_type node_info; 00786 float split_position; 00787 int n_objects, *object_list; 00788 bintree_node_struct *left, *right; 00789 00790 *node = NULL; 00791 00792 status = io_binary_data( file, READ_FILE, &node_info, sizeof(node_info), 1); 00793 00794 if( status == OK ) 00795 status = io_float( file, READ_FILE, format, &split_position ); 00796 00797 if( (node_info & SUBDIVISION_AXIS_BITS) == LEAF_SIGNAL ) 00798 { 00799 n_objects = node_info >> NODE_INFO_OBJECTS_SHIFT; 00800 00801 if( n_objects == 0 ) 00802 status = io_int( file, READ_FILE, format, &n_objects ); 00803 00804 if( status == OK && n_objects > 0 ) 00805 status = io_ints( file, READ_FILE, format, n_objects, &object_list); 00806 00807 if( status == OK ) 00808 { 00809 *node = create_bintree_leaf( (Real) split_position, 00810 n_objects, object_list ); 00811 if( n_objects > 0 ) 00812 FREE( object_list ); 00813 } 00814 } 00815 else 00816 { 00817 status = input_bintree_node( file, format, &left ); 00818 if( status == OK ) 00819 status = input_bintree_node( file, format, &right ); 00820 00821 if( status == OK ) 00822 *node = create_bintree_internal_node( 00823 node_info & SUBDIVISION_AXIS_BITS, 00824 (Real) split_position, left, right ); 00825 } 00826 00827 return( status ); 00828 }

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