00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef lint
00042 static const char bn_RCSvert_tree[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/libbn/vert_tree.c,v 14.13 2006/09/07 01:19:17 lbutler Exp $ (ARL)";
00043 #endif
00044
00045 #include "common.h"
00046
00047 #include <stdlib.h>
00048 #include <stdio.h>
00049 #include <math.h>
00050 #ifdef HAVE_STRING_H
00051 # include <string.h>
00052 #else
00053 # include <strings.h>
00054 #endif
00055 #include <ctype.h>
00056 #include <errno.h>
00057
00058 #include "machine.h"
00059 #include "vmath.h"
00060 #include "raytrace.h"
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 union vert_tree {
00076 char type;
00077 struct vert_leaf {
00078 char type;
00079 int index;
00080 } vleaf;
00081 struct vert_node {
00082 char type;
00083 double cut_val;
00084 int coord;
00085 union vert_tree *higher, *lower;
00086 } vnode;
00087 };
00088
00089
00090 #define VERT_LEAF 'l'
00091 #define VERT_NODE 'n'
00092
00093
00094
00095
00096
00097
00098
00099
00100 struct vert_root *
00101 create_vert_tree()
00102 {
00103 struct vert_root *tree;
00104
00105 tree = (struct vert_root *)bu_calloc( 1, sizeof( struct vert_root ), "vert_tree_root" );
00106 tree->magic = VERT_TREE_MAGIC;
00107 tree->tree_type = TREE_TYPE_VERTS;
00108 tree->the_tree = (union vert_tree *)NULL;
00109 tree->curr_vert = 0;
00110 tree->max_vert = VERT_BLOCK;
00111 tree->the_array = (fastf_t *)bu_malloc( tree->max_vert * 3 * sizeof( fastf_t ), "vert tree array" );
00112
00113 return( tree );
00114 }
00115
00116
00117
00118
00119
00120
00121
00122 struct vert_root *
00123 create_vert_tree_w_norms()
00124 {
00125 struct vert_root *tree;
00126
00127 tree = (struct vert_root *)bu_calloc( 1, sizeof( struct vert_root ), "vert_tree_root" );
00128 tree->magic = VERT_TREE_MAGIC;
00129 tree->tree_type = TREE_TYPE_VERTS_AND_NORMS;
00130 tree->the_tree = (union vert_tree *)NULL;
00131 tree->curr_vert = 0;
00132 tree->max_vert = VERT_BLOCK;
00133 tree->the_array = (fastf_t *)bu_malloc( tree->max_vert * 6 * sizeof( fastf_t ), "vert tree array" );
00134
00135 return( tree );
00136 }
00137
00138
00139
00140
00141
00142 static void
00143 clean_vert_tree_recurse( union vert_tree *ptr )
00144 {
00145 if( ptr->type == VERT_NODE ) {
00146 clean_vert_tree_recurse( ptr->vnode.higher );
00147 clean_vert_tree_recurse( ptr->vnode.lower );
00148 }
00149
00150 bu_free( (char *)ptr, "vert_tree" );
00151
00152 }
00153
00154
00155
00156
00157
00158
00159 void
00160 clean_vert_tree( struct vert_root *tree_root )
00161 {
00162 BN_CK_VERT_TREE( tree_root );
00163
00164 if( !tree_root->the_tree ) return;
00165
00166 clean_vert_tree_recurse( tree_root->the_tree );
00167 tree_root->the_tree = (union vert_tree *)NULL;
00168 tree_root->curr_vert = 0;
00169 }
00170
00171
00172
00173
00174
00175
00176 static void
00177 free_vert_tree_recurse( union vert_tree *ptr )
00178 {
00179 if( ptr->type == VERT_NODE ) {
00180 free_vert_tree_recurse( ptr->vnode.higher );
00181 free_vert_tree_recurse( ptr->vnode.lower );
00182 }
00183
00184 bu_free( (char *)ptr, "vert_tree" );
00185
00186 }
00187
00188
00189
00190
00191
00192 void
00193 free_vert_tree( struct vert_root *vert_root )
00194 {
00195 union vert_tree *ptr;
00196
00197 if( !vert_root )
00198 return;
00199
00200 BN_CK_VERT_TREE( vert_root );
00201
00202 ptr = vert_root->the_tree;
00203 if( !ptr )
00204 return;
00205
00206 free_vert_tree_recurse( ptr );
00207
00208 if( vert_root->the_array ) {
00209 bu_free( (char *)vert_root->the_array, "vertex array" );
00210 }
00211
00212 vert_root->the_tree = (union vert_tree *)NULL;
00213 vert_root->the_array = (fastf_t *)NULL;
00214 vert_root->curr_vert = 0;
00215 vert_root->max_vert = 0;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224 int
00225 Add_vert( double x, double y, double z, struct vert_root *vert_root, fastf_t local_tol_sq )
00226 {
00227 union vert_tree *ptr, *prev=NULL, *new_leaf, *new_node;
00228 vect_t diff;
00229 vect_t vertex;
00230
00231 BN_CK_VERT_TREE( vert_root );
00232
00233 if( vert_root->tree_type != TREE_TYPE_VERTS ) {
00234 bu_bomb( "Error: Add_vert() called for a tree containing vertices and normals\n" );
00235 }
00236
00237 VSET( vertex, x, y, z );
00238
00239
00240 ptr = vert_root->the_tree;
00241 while( ptr ) {
00242 if( ptr->type == VERT_NODE ) {
00243 prev = ptr;
00244 if( vertex[ptr->vnode.coord] >= ptr->vnode.cut_val ) {
00245 ptr = ptr->vnode.higher;
00246 } else {
00247 ptr = ptr->vnode.lower;
00248 }
00249 } else {
00250 int ij;
00251
00252 ij = ptr->vleaf.index*3;
00253 diff[0] = fabs( vertex[0] - vert_root->the_array[ij] );
00254 diff[1] = fabs( vertex[1] - vert_root->the_array[ij+1] );
00255 diff[2] = fabs( vertex[2] - vert_root->the_array[ij+2] );
00256 if( (diff[0]*diff[0] + diff[1]*diff[1] + diff[2]*diff[2]) <= local_tol_sq ) {
00257
00258 return( ptr->vleaf.index );
00259 }
00260 break;
00261 }
00262 }
00263
00264
00265 if( vert_root->curr_vert >= vert_root->max_vert ) {
00266
00267 vert_root->max_vert += VERT_BLOCK;
00268
00269 vert_root->the_array = (fastf_t *)bu_realloc( vert_root->the_array, sizeof( fastf_t ) * vert_root->max_vert * 3,
00270 "vert_root->the_array" );
00271 }
00272
00273 VMOVE( &vert_root->the_array[vert_root->curr_vert*3], vertex );
00274
00275
00276 new_leaf = (union vert_tree *)bu_malloc( sizeof( union vert_tree ), "new_leaf" );
00277 new_leaf->vleaf.type = VERT_LEAF;
00278 new_leaf->vleaf.index = vert_root->curr_vert++;
00279 if( !vert_root->the_tree ) {
00280
00281 vert_root->the_tree = new_leaf;
00282 } else if( ptr && ptr->type == VERT_LEAF ) {
00283
00284 new_node = (union vert_tree *)bu_malloc( sizeof( union vert_tree ), "new_node" );
00285 new_node->vnode.type = VERT_NODE;
00286
00287
00288 if( diff[0] >= diff[1] && diff[0] >= diff[2] ) {
00289 new_node->vnode.coord = 0;
00290 } else if( diff[1] >= diff[2] && diff[1] >= diff[0] ) {
00291 new_node->vnode.coord = 1;
00292 } else if( diff[2] >= diff[1] && diff[2] >= diff[0] ) {
00293 new_node->vnode.coord = 2;
00294 }
00295
00296
00297 new_node->vnode.cut_val = (vertex[new_node->vnode.coord] +
00298 vert_root->the_array[ptr->vleaf.index * 3 + new_node->vnode.coord]) * 0.5;
00299
00300
00301 if( vertex[new_node->vnode.coord] >=
00302 vert_root->the_array[ptr->vleaf.index * 3 + new_node->vnode.coord] ) {
00303 new_node->vnode.higher = new_leaf;
00304 new_node->vnode.lower = ptr;
00305 } else {
00306 new_node->vnode.higher = ptr;
00307 new_node->vnode.lower = new_leaf;
00308 }
00309
00310 if( ptr == vert_root->the_tree ) {
00311
00312 vert_root->the_tree = new_node;
00313 } else {
00314
00315 if( prev->vnode.higher == ptr ) {
00316 prev->vnode.higher = new_node;
00317 } else {
00318 prev->vnode.lower = new_node;
00319 }
00320 }
00321 } else if( ptr && ptr->type == VERT_NODE ) {
00322
00323 prev = ptr;
00324 if( vertex[prev->vnode.coord] >= prev->vnode.cut_val ) {
00325 if( prev->vnode.higher ) {
00326 bu_bomb("higher vertex node already exists in Add_vert()?\n");
00327 }
00328 prev->vnode.higher = new_leaf;
00329 } else {
00330 if( prev->vnode.lower ) {
00331 bu_bomb("lower vertex node already exists in Add_vert()?\n");
00332 }
00333 prev->vnode.lower = new_leaf;
00334 }
00335 } else {
00336 fprintf( stderr, "*********ERROR********\n" );
00337 }
00338
00339
00340 return( new_leaf->vleaf.index );
00341 }
00342
00343
00344
00345
00346
00347
00348
00349 int
00350 Add_vert_and_norm( double x, double y, double z, double nx, double ny, double nz, struct vert_root *vert_root, fastf_t local_tol_sq )
00351 {
00352 union vert_tree *ptr, *prev=NULL, *new_leaf, *new_node;
00353 fastf_t diff[6];
00354 fastf_t vertex[6];
00355 double d1_sq=0.0, d2_sq=0.0;
00356
00357 BN_CK_VERT_TREE( vert_root );
00358
00359 if( vert_root->tree_type != TREE_TYPE_VERTS_AND_NORMS ) {
00360 bu_bomb( "Error: Add_vert_and_norm() called for a tree containing just vertices\n" );
00361 }
00362
00363 VSET( vertex, x, y, z );
00364 VSET( &vertex[3], nx, ny, nz );
00365
00366
00367 ptr = vert_root->the_tree;
00368 while( ptr ) {
00369 int i;
00370
00371 if( ptr->type == VERT_NODE ) {
00372 prev = ptr;
00373 if( vertex[ptr->vnode.coord] >= ptr->vnode.cut_val ) {
00374 ptr = ptr->vnode.higher;
00375 } else {
00376 ptr = ptr->vnode.lower;
00377 }
00378 } else {
00379 int ij;
00380
00381 ij = ptr->vleaf.index*6;
00382 for( i=0 ; i<6 ; i++ ) {
00383 diff[i] = fabs( vertex[i] - vert_root->the_array[ij+i] );
00384 }
00385 d1_sq = VDOT( diff, diff );
00386 d2_sq = VDOT( &diff[3], &diff[3] );
00387 if( d1_sq <= local_tol_sq && d2_sq <= 0.0001 ) {
00388
00389 return( ptr->vleaf.index );
00390 }
00391 break;
00392 }
00393 }
00394
00395
00396 if( vert_root->curr_vert >= vert_root->max_vert ) {
00397
00398 vert_root->max_vert += VERT_BLOCK;
00399
00400 vert_root->the_array = (fastf_t *)bu_realloc( vert_root->the_array,
00401 sizeof( fastf_t ) * vert_root->max_vert * 6,
00402 "vert_root->the_array" );
00403 }
00404
00405 VMOVE( &vert_root->the_array[vert_root->curr_vert*6], vertex );
00406 VMOVE( &vert_root->the_array[vert_root->curr_vert*6+3], &vertex[3] );
00407
00408
00409 new_leaf = (union vert_tree *)bu_malloc( sizeof( union vert_tree ), "new_leaf" );
00410 new_leaf->vleaf.type = VERT_LEAF;
00411 new_leaf->vleaf.index = vert_root->curr_vert++;
00412 if( !vert_root->the_tree ) {
00413
00414 vert_root->the_tree = new_leaf;
00415 } else if( ptr && ptr->type == VERT_LEAF ) {
00416 fastf_t max;
00417 int i;
00418
00419
00420 new_node = (union vert_tree *)bu_malloc( sizeof( union vert_tree ), "new_node" );
00421 new_node->vnode.type = VERT_NODE;
00422
00423
00424 if( d1_sq <= local_tol_sq ) {
00425
00426 new_node->vnode.coord = 3;
00427 } else {
00428 new_node->vnode.coord = 0;
00429 }
00430 max = diff[new_node->vnode.coord];
00431 for( i=new_node->vnode.coord+1 ; i<6 ; i++ ) {
00432 if( diff[i] > max ) {
00433 new_node->vnode.coord = i;
00434 max = diff[i];
00435 }
00436 }
00437
00438
00439 new_node->vnode.cut_val = (vertex[new_node->vnode.coord] +
00440 vert_root->the_array[ptr->vleaf.index * 3 + new_node->vnode.coord]) * 0.5;
00441
00442
00443 if( vertex[new_node->vnode.coord] >=
00444 vert_root->the_array[ptr->vleaf.index * 3 + new_node->vnode.coord] ) {
00445 new_node->vnode.higher = new_leaf;
00446 new_node->vnode.lower = ptr;
00447 } else {
00448 new_node->vnode.higher = ptr;
00449 new_node->vnode.lower = new_leaf;
00450 }
00451
00452 if( ptr == vert_root->the_tree ) {
00453
00454 vert_root->the_tree = new_node;
00455 } else {
00456
00457 if( prev->vnode.higher == ptr ) {
00458 prev->vnode.higher = new_node;
00459 } else {
00460 prev->vnode.lower = new_node;
00461 }
00462 }
00463 } else if( ptr && ptr->type == VERT_NODE ) {
00464
00465 prev = ptr;
00466 if( vertex[prev->vnode.coord] >= prev->vnode.cut_val ) {
00467 if( prev->vnode.higher ) {
00468 bu_bomb("higher vertex node already exists in Add_vert_and_norm()?\n");
00469 }
00470 prev->vnode.higher = new_leaf;
00471 } else {
00472 if( prev->vnode.lower ) {
00473 bu_bomb("lower vertex node already exists in Add_vert_and_norm()?\n");
00474 }
00475 prev->vnode.lower = new_leaf;
00476 }
00477 } else {
00478 fprintf( stderr, "*********ERROR********\n" );
00479 }
00480
00481
00482 return( new_leaf->vleaf.index );
00483 }
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493