static int subdivide_Octree(register Octree *parentp, int level) { PtList *points = parentp->o_points->c_next; Trie *triep = parentp->o_triep; int temp = parentp->o_temp; /* Ward against integer overflow in 2^level. */ if ( level > L_MAX_POWER_TWO ) { bu_log( "Can not subdivide, level = %d\n", level ); prnt_Octree( &ir_octree, 0 ); return 0; } /* Remove datum from parent, it only belongs in leaves. */ parentp->o_triep = TRIE_NULL; parentp->o_temp = ABSOLUTE_ZERO; parentp->o_points->c_next = PTLIST_NULL; /* Delete reference in trie tree to parent node. */ delete_Node_OcList( &triep->l.t_octp, parentp ); { register PtList *cp; /* Shove data down to sub-levels. */ for ( cp = points; cp != PTLIST_NULL; cp = cp->c_next ) { fastf_t c_point[3]; Octree *octreep; VMOVE( c_point, cp->c_point ); if ( (octreep = add_Region_Octree( parentp, c_point, triep, temp, level ) ) != OCTREE_NULL ) append_Octp( triep, octreep ); else return 0; } } delete_PtList( &points ); return 1; }
Octree * add_Region_Octree(Octree *parentp, fastf_t *pt, Trie *triep, int temp, int level) { Octree *newp; /* Traverse to octant leaf node containing "pt". */ if ( (newp = find_Octant( parentp, pt, &level )) == OCTREE_NULL ) { bu_log( "find_Octant() returned NULL!\n" ); return OCTREE_NULL; } /* Decide where to put datum. */ if ( newp->o_points->c_next == PTLIST_NULL ) { /* Octant empty, so place region here. */ newp->o_triep = triep; if ( ! NewPoint( newp->o_points->c_next ) ) { Malloc_Bomb(sizeof(PtList)); fatal_error = TRUE; return OCTREE_NULL; } VMOVE( newp->o_points->c_next->c_point, pt ); newp->o_points->c_next->c_next = PTLIST_NULL; if ( temp != AMBIENT-1 ) newp->o_temp = temp; return newp; } else /* Octant occupied. */ if ( triep != newp->o_triep ) { /* Region collision, must subdivide octant. */ if ( ! subdivide_Octree( newp, level )) return OCTREE_NULL; return add_Region_Octree( newp, pt, triep, temp, level ); } else if ( temp != AMBIENT-1 ) { /* We are assigning a temperature. */ if ( newp->o_temp < AMBIENT ) { /* Temperature not assigned yet. */ newp->o_temp = temp; if ( ! append_PtList( pt, newp->o_points ) ) return OCTREE_NULL; } else if ( Abs(newp->o_temp - temp) < ir_noise ) { /* Temperatures close enough. */ if ( ! append_PtList( pt, newp->o_points ) ) return OCTREE_NULL; } else if ( newp->o_points->c_next->c_next == PTLIST_NULL && SamePoint( newp->o_points->c_next->c_point, pt, F2D_EPSILON ) ) /* Only point in leaf node is this point. */ newp->o_temp = temp; else { /* Temperature collision, must subdivide. */ if ( ! subdivide_Octree( newp, level ) ) return OCTREE_NULL; return add_Region_Octree( newp, pt, triep, temp, level ); } } else /* Region pointers match, so append coordinate to list. */ if ( ! append_PtList( pt, newp->o_points ) ) return OCTREE_NULL; return newp; }
int read_Trie(FILE *fp) { static char name_buf[MAX_TRIE_LEVEL+1]; Trie *triep; F_Hdr_Ptlist hdr_ptlist; int min, max; /* Read temperature range information. */ if ( fread( (char *) &min, (int) sizeof(int), 1, fp ) != 1 || fread( (char *) &max, (int) sizeof(int), 1, fp ) != 1 ) { bu_log( "Could not read min/max info.\n" ); rewind( fp ); } else { bu_log( "IR data base temperature range is %d to %d\n", min, max ); if ( ir_min == ABSOLUTE_ZERO ) { /* Temperature range not set. */ ir_min = min; ir_max = max; } else { /* Merge with existing range. */ V_MIN( ir_min, min ); V_MAX( ir_max, max ); bu_log( "Global temperature range is %d to %d\n", ir_min, ir_max ); (void) fflush( stdout ); } } if ( ! init_Temp_To_RGB() ) { return 0; } while ( bu_fgets( name_buf, MAX_TRIE_LEVEL, fp ) != NULL ) { name_buf[strlen(name_buf)-1] = '\0'; /* Clobber new-line.*/ triep = add_Trie( name_buf, ®_triep ); if ( fread( (char *) &hdr_ptlist, (int) sizeof(F_Hdr_Ptlist), 1, fp ) != 1 ) { bu_log( "\"%s\"(%d) Read failed!\n", __FILE__, __LINE__ ); return 0; } for (; hdr_ptlist.f_length > 0; hdr_ptlist.f_length-- ) { fastf_t point[3]; float c_point[3]; Octree *octreep; if ( fread( (char *) c_point, (int) sizeof(c_point), 1, fp ) != 1 ) { bu_log( "\"%s\"(%d) Read failed.\n", __FILE__, __LINE__ ); return 0; } VMOVE( point, c_point ); if ( (octreep = add_Region_Octree( &ir_octree, point, triep, hdr_ptlist.f_temp, 0 ) ) != OCTREE_NULL ) append_Octp( triep, octreep ); } } return 1; }