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 #ifndef lint
00027 static const char RCSid[] = "$Header: /cvsroot/brlcad/brlcad/src/librt/importFg4Section.c,v 1.10 2006/09/16 02:04:25 lbutler Exp $";
00028 #endif
00029
00030 #include "common.h"
00031
00032
00033 #include <stdlib.h>
00034 #include <stdio.h>
00035 #include <math.h>
00036 #ifdef HAVE_STRING_H
00037 # include <string.h>
00038 #else
00039 # include <strings.h>
00040 #endif
00041 #include <ctype.h>
00042 #include <errno.h>
00043 #if defined(HAVE_UNISTD_H)
00044 # include <unistd.h>
00045 #else
00046 # if defined(HAVE_SYS_UNISTD_H)
00047 # include <sys/unistd.h>
00048 # endif
00049 #endif
00050
00051
00052 #include "machine.h"
00053 #include "db.h"
00054 #include "vmath.h"
00055 #include "nmg.h"
00056 #include "rtgeom.h"
00057 #include "raytrace.h"
00058 #include "wdb.h"
00059 #include "plot3.h"
00060
00061
00062 #include "../librt/debug.h"
00063
00064
00065 static int grid_size;
00066 static int max_grid_no=0;
00067 static int mode=0;
00068 static int group_id=(-1);
00069 static int comp_id=(-1);
00070 static int region_id=0;
00071 static char field[9];
00072 static int name_count;
00073 static int bot=0;
00074 static int warnings=0;
00075 static int debug=0;
00076 static int rt_debug=0;
00077 static int quiet=0;
00078 static int comp_count=0;
00079
00080 static int *faces=NULL;
00081 static fastf_t *thickness;
00082 static char *facemode;
00083 static int face_size=0;
00084 static int face_count=0;
00085
00086 static int *int_list;
00087 static int int_list_count=0;
00088 static int int_list_length=0;
00089
00090 #define PLATE_MODE 1
00091 #define VOLUME_MODE 2
00092
00093 #define POS_CENTER 1
00094 #define POS_FRONT 2
00095
00096 #define END_OPEN 1
00097 #define END_CLOSED 2
00098
00099 #define GRID_BLOCK 256
00100
00101 #define CLINE 'l'
00102 #define CHEX1 'p'
00103 #define CHEX2 'b'
00104 #define CTRI 't'
00105 #define CQUAD 'q'
00106 #define CCONE1 'c'
00107 #define CCONE2 'd'
00108 #define CCONE3 'e'
00109 #define CSPHERE 's'
00110 #define NMG 'n'
00111 #define BOT 't'
00112 #define COMPSPLT 'h'
00113
00114 point_t *grid_pts;
00115
00116 void do_grid(char *line);
00117 void do_tri(char *line);
00118 void do_quad(char *line);
00119 void make_bot_object(char *name,
00120 struct rt_wdb *wdbp);
00121
00122
00123
00124 static int
00125 rt_mk_bot_w_normals(
00126 struct rt_wdb *fp,
00127 const char *name,
00128 unsigned char mode,
00129 unsigned char orientation,
00130 unsigned char flags,
00131 int num_vertices,
00132 int num_faces,
00133 fastf_t *vertices,
00134 int *faces,
00135 fastf_t *thickness,
00136
00137
00138 struct bu_bitv *face_mode,
00139
00140
00141 int num_normals,
00142 fastf_t *normals,
00143 int *face_normals )
00144 {
00145 struct rt_bot_internal *bot;
00146 int i;
00147
00148 if( (num_normals > 0) && (fp->dbip->dbi_version < 5 ) ) {
00149 bu_log( "You are using an old database format which does not support surface normals for BOT primitives\n" );
00150 bu_log( "You are attempting to create a BOT primitive named \"%s\" with surface normals\n" );
00151 bu_log( "The surface normals will not be saved\n" );
00152 bu_log( "Please upgrade to the current database format by using \"dbupgrade\"\n" );
00153 }
00154
00155 BU_GETSTRUCT( bot, rt_bot_internal );
00156 bot->magic = RT_BOT_INTERNAL_MAGIC;
00157 bot->mode = mode;
00158 bot->orientation = orientation;
00159 bot->bot_flags = flags;
00160 bot->num_vertices = num_vertices;
00161 bot->num_faces = num_faces;
00162 bot->vertices = (fastf_t *)bu_calloc( num_vertices * 3, sizeof( fastf_t ), "bot->vertices" );
00163 for( i=0 ; i<num_vertices*3 ; i++ )
00164 bot->vertices[i] = vertices[i];
00165 bot->faces = (int *)bu_calloc( num_faces * 3, sizeof( int ), "bot->faces" );
00166 for( i=0 ; i<num_faces*3 ; i++ )
00167 bot->faces[i] = faces[i];
00168 if( mode == RT_BOT_PLATE )
00169 {
00170 bot->thickness = (fastf_t *)bu_calloc( num_faces, sizeof( fastf_t ), "bot->thickness" );
00171 for( i=0 ; i<num_faces ; i++ )
00172 bot->thickness[i] = thickness[i];
00173 bot->face_mode = bu_bitv_dup( face_mode );
00174 }
00175 else
00176 {
00177 bot->thickness = (fastf_t *)NULL;
00178 bot->face_mode = (struct bu_bitv *)NULL;
00179 }
00180
00181 if( (num_normals > 0) && (fp->dbip->dbi_version >= 5 ) ) {
00182 bot->num_normals = num_normals;
00183 bot->num_face_normals = bot->num_faces;
00184 bot->normals = (fastf_t *)bu_calloc( bot->num_normals * 3, sizeof( fastf_t ), "BOT normals" );
00185 bot->face_normals = (int *)bu_calloc( bot->num_faces * 3, sizeof( int ), "BOT face normals" );
00186 memcpy( bot->normals, normals, bot->num_normals * 3 * sizeof( fastf_t ) );
00187 memcpy( bot->face_normals, face_normals, bot->num_faces * 3 * sizeof( int ) );
00188 } else {
00189 bot->bot_flags = 0;
00190 bot->num_normals = 0;
00191 bot->num_face_normals = 0;
00192 bot->normals = (fastf_t *)NULL;
00193 bot->face_normals = (int *)NULL;
00194 }
00195
00196 return wdb_export(fp, name, (genptr_t)bot, ID_BOT, 1.0);
00197 }
00198
00199 static int
00200 rt_mk_bot(
00201 struct rt_wdb *fp,
00202 const char *name,
00203 unsigned char mode,
00204 unsigned char orientation,
00205 unsigned char flags,
00206 int num_vertices,
00207 int num_faces,
00208 fastf_t *vertices,
00209 int *faces,
00210 fastf_t *thickness,
00211
00212
00213 struct bu_bitv *face_mode )
00214
00215
00216 {
00217 return( rt_mk_bot_w_normals( fp, name, mode, orientation, flags, num_vertices, num_faces, vertices,
00218 faces, thickness, face_mode, 0, NULL, NULL ) );
00219 }
00220
00221
00222
00223 void
00224 do_grid(char *line)
00225 {
00226 int grid_no;
00227 fastf_t x,y,z;
00228
00229 if( RT_G_DEBUG&DEBUG_MEM_FULL && bu_mem_barriercheck() )
00230 bu_log( "ERROR: bu_mem_barriercheck failed at start of do_grid\n" );
00231
00232 strncpy( field , &line[8] , 8 );
00233 grid_no = atoi( field );
00234
00235 if( grid_no < 1 )
00236 {
00237 bu_log( "ERROR: grid id number = %d\n" , grid_no );
00238 rt_bomb( "BAD GRID ID NUMBER\n" );
00239 }
00240
00241 strncpy( field , &line[24] , 8 );
00242 x = atof( field );
00243
00244 strncpy( field , &line[32] , 8 );
00245 y = atof( field );
00246
00247 strncpy( field , &line[40] , 8 );
00248 z = atof( field );
00249
00250 while( grid_no > grid_size - 1 )
00251 {
00252 grid_size += GRID_BLOCK;
00253 grid_pts = (point_t *)bu_realloc( (char *)grid_pts , grid_size * sizeof( point_t ) , "fast4-g: grid_pts" );
00254 }
00255
00256 VSET( grid_pts[grid_no] , x*25.4 , y*25.4 , z*25.4 );
00257
00258 if( grid_no > max_grid_no )
00259 max_grid_no = grid_no;
00260 if( RT_G_DEBUG&DEBUG_MEM_FULL && bu_mem_barriercheck() )
00261 bu_log( "ERROR: bu_mem_barriercheck failed at end of do_grid\n" );
00262 }
00263
00264 void
00265 Add_bot_face(int pt1, int pt2, int pt3, fastf_t thick, int pos)
00266 {
00267
00268 if( pt1 == pt2 || pt2 == pt3 || pt1 == pt3 )
00269 {
00270 bu_log( "Add_bot_face: ignoring degenerate triangle in group %d component %d\n", group_id, comp_id );
00271 return;
00272 }
00273
00274 if( pos == 0 )
00275 pos = POS_FRONT;
00276
00277 if( mode == PLATE_MODE )
00278 {
00279 if( pos != POS_CENTER && pos != POS_FRONT )
00280 {
00281 bu_log( "Add_bot_face: illegal postion parameter (%d), must be one or two (ignoring face for group %d component %d)\n" , pos, group_id, comp_id );
00282 return;
00283 }
00284 }
00285
00286 if( face_count >= face_size )
00287 {
00288 face_size += GRID_BLOCK;
00289 if(bu_debug&BU_DEBUG_MEM_CHECK && bu_mem_barriercheck() )
00290 bu_log( "memory corrupted before realloc of faces, thickness, and facemode\n" );
00291 faces = (int *)bu_realloc( (void *)faces, face_size*3*sizeof( int ), "faces" );
00292 thickness = (fastf_t *)bu_realloc( (void *)thickness, face_size*sizeof( fastf_t ), "thickness" );
00293 facemode = (char *)bu_realloc( (void *)facemode, face_size*sizeof( char ), "facemode" );
00294 if(bu_debug&BU_DEBUG_MEM_CHECK && bu_mem_barriercheck() )
00295 bu_log( "memory corrupted after realloc of faces, thickness, and facemode\n" );
00296 }
00297
00298 faces[face_count*3] = pt1;
00299 faces[face_count*3+1] = pt2;
00300 faces[face_count*3+2] = pt3;
00301
00302 if( mode == PLATE_MODE )
00303 {
00304 thickness[face_count] = thick;
00305 facemode[face_count] = pos;
00306 }
00307 else
00308 {
00309 thickness[face_count] = 0,0;
00310 facemode[face_count] = 0;
00311 }
00312
00313 face_count++;
00314
00315 if(bu_debug&BU_DEBUG_MEM_CHECK && bu_mem_barriercheck() )
00316 bu_log( "memory corrupted at end of Add_bot_face()\n" );
00317 }
00318
00319 void
00320 do_tri(char *line)
00321 {
00322 int element_id;
00323 int pt1,pt2,pt3;
00324 fastf_t thick;
00325 int pos;
00326
00327 if( debug )
00328 bu_log( "do_tri: %s\n" , line );
00329
00330 strncpy( field , &line[8] , 8 );
00331 element_id = atoi( field );
00332
00333 if( !bot )
00334 bot = element_id;
00335
00336 if( faces == NULL )
00337 {
00338 if(bu_debug&BU_DEBUG_MEM_CHECK && bu_mem_barriercheck() )
00339 bu_log( "memory corrupted before malloc of faces\n" );
00340 faces = (int *)bu_malloc( GRID_BLOCK*3*sizeof( int ), "faces" );
00341 thickness = (fastf_t *)bu_malloc( GRID_BLOCK*sizeof( fastf_t ), "thickness" );
00342 facemode = (char *)bu_malloc( GRID_BLOCK*sizeof( char ), "facemode" );
00343 face_size = GRID_BLOCK;
00344 face_count = 0;
00345 if(bu_debug&BU_DEBUG_MEM_CHECK && bu_mem_barriercheck() )
00346 bu_log( "memory corrupted after malloc of faces , thickness, and facemode\n" );
00347 }
00348
00349 strncpy( field , &line[24] , 8 );
00350 pt1 = atoi( field );
00351
00352 strncpy( field , &line[32] , 8 );
00353 pt2 = atoi( field );
00354
00355 strncpy( field , &line[40] , 8 );
00356 pt3 = atoi( field );
00357
00358 thick = 0.0;
00359 pos = 0;
00360
00361 if( mode == PLATE_MODE )
00362 {
00363 strncpy( field , &line[56] , 8 );
00364 thick = atof( field ) * 25.4;
00365
00366 strncpy( field , &line[64] , 8 );
00367 pos = atoi( field );
00368 if( pos == 0 )
00369 pos = POS_FRONT;
00370
00371 if( debug )
00372 bu_log( "\tplate mode: thickness = %f\n" , thick );
00373
00374 }
00375
00376 if(bu_debug&BU_DEBUG_MEM_CHECK && bu_mem_barriercheck() )
00377 bu_log( "memory corrupted before call to Add_bot_face()\n" );
00378
00379 Add_bot_face( pt1, pt2, pt3, thick, pos );
00380
00381 if(bu_debug&BU_DEBUG_MEM_CHECK && bu_mem_barriercheck() )
00382 bu_log( "memory corrupted after call to Add_bot_face()\n" );
00383 }
00384
00385 void
00386 do_quad(char *line)
00387 {
00388 int element_id;
00389 int pt1,pt2,pt3,pt4;
00390 fastf_t thick = 0.0;
00391 int pos = 0;
00392
00393 strncpy( field , &line[8] , 8 );
00394 element_id = atoi( field );
00395
00396 if( debug )
00397 bu_log( "do_quad: %s\n" , line );
00398
00399 if( !bot )
00400 bot = element_id;
00401
00402 if( faces == NULL )
00403 {
00404 faces = (int *)bu_malloc( GRID_BLOCK*3*sizeof( int ), "faces" );
00405 thickness = (fastf_t *)bu_malloc( GRID_BLOCK*sizeof( fastf_t ), "thickness" );
00406 facemode = (char *)bu_malloc( GRID_BLOCK*sizeof( char ), "facemode" );
00407 face_size = GRID_BLOCK;
00408 face_count = 0;
00409 }
00410
00411 strncpy( field , &line[24] , 8 );
00412 pt1 = atoi( field );
00413
00414 strncpy( field , &line[32] , 8 );
00415 pt2 = atoi( field );
00416
00417 strncpy( field , &line[40] , 8 );
00418 pt3 = atoi( field );
00419
00420 strncpy( field , &line[48] , 8 );
00421 pt4 = atoi( field );
00422
00423 if( mode == PLATE_MODE )
00424 {
00425 strncpy( field , &line[56] , 8 );
00426 thick = atof( field ) * 25.4;
00427
00428 strncpy( field , &line[64] , 8 );
00429 pos = atoi( field );
00430
00431 if( pos == 0 )
00432 pos = POS_FRONT;
00433
00434 if( pos != POS_CENTER && pos != POS_FRONT )
00435 {
00436 bu_log( "do_quad: illegal postion parameter (%d), must be one or two\n" , pos );
00437 bu_log( "\telement %d, component %d, group %d\n" , element_id , comp_id , group_id );
00438 return;
00439 }
00440 }
00441
00442 Add_bot_face( pt1, pt2, pt3, thick, pos );
00443 Add_bot_face( pt1, pt3, pt4, thick, pos );
00444 }
00445
00446 void
00447 make_bot_object(char *name,
00448 struct rt_wdb *wdbp)
00449 {
00450 int i;
00451 int max_pt=0, min_pt=999999;
00452 int num_vertices;
00453 struct bu_bitv *bv=NULL;
00454 int bot_mode;
00455 int element_id=bot;
00456 int count;
00457 struct rt_bot_internal bot_ip;
00458
00459 bot_ip.magic = RT_BOT_INTERNAL_MAGIC;
00460 for( i=0 ; i<face_count ; i++ )
00461 {
00462 V_MIN( min_pt, faces[i*3] );
00463 V_MAX( max_pt, faces[i*3] );
00464 V_MIN( min_pt, faces[i*3+1] );
00465 V_MAX( max_pt, faces[i*3+1] );
00466 V_MIN( min_pt, faces[i*3+2] );
00467 V_MAX( max_pt, faces[i*3+2] );
00468 }
00469
00470 num_vertices = max_pt - min_pt + 1;
00471 bot_ip.num_vertices = num_vertices;
00472 bot_ip.vertices = (fastf_t *)bu_calloc( num_vertices*3, sizeof( fastf_t ), "BOT vertices" );
00473 for( i=0 ; i<num_vertices ; i++ )
00474 VMOVE( &bot_ip.vertices[i*3], grid_pts[min_pt+i] )
00475
00476 for( i=0 ; i<face_count*3 ; i++ )
00477 faces[i] -= min_pt;
00478 bot_ip.num_faces = face_count;
00479 bot_ip.faces = bu_calloc( face_count*3, sizeof( int ), "BOT faces" );
00480 for( i=0 ; i<face_count*3 ; i++ )
00481 bot_ip.faces[i] = faces[i];
00482
00483 bot_ip.face_mode = (struct bu_bitv *)NULL;
00484 bot_ip.thickness = (fastf_t *)NULL;
00485 if( mode == PLATE_MODE )
00486 {
00487 bot_mode = RT_BOT_PLATE;
00488 bv = bu_bitv_new( face_count );
00489 bu_bitv_clear( bv );
00490 for( i=0 ; i<face_count ; i++ )
00491 {
00492 if( facemode[i] == POS_FRONT )
00493 BU_BITSET( bv, i );
00494 }
00495 bot_ip.face_mode = bv;
00496 bot_ip.thickness = (fastf_t *)bu_calloc( face_count, sizeof( fastf_t ), "BOT thickness" );
00497 for( i=0 ; i<face_count ; i++ )
00498 bot_ip.thickness[i] = thickness[i];
00499 }
00500 else
00501 bot_mode = RT_BOT_SOLID;
00502
00503 bot_ip.mode = bot_mode;
00504 bot_ip.orientation = RT_BOT_UNORIENTED;
00505 bot_ip.bot_flags = 0;
00506
00507 count = rt_bot_vertex_fuse( &bot_ip );
00508 if( count )
00509 (void)rt_bot_condense( &bot_ip );
00510
00511 count = rt_bot_face_fuse( &bot_ip );
00512 if( count )
00513 bu_log( "WARNING: %d duplicate faces eliminated from group %d component %d\n", count, group_id, comp_id );
00514
00515 rt_mk_bot(wdbp, name, bot_mode, RT_BOT_UNORIENTED, 0,
00516 bot_ip.num_vertices, bot_ip.num_faces, bot_ip.vertices,
00517 bot_ip.faces, bot_ip.thickness, bot_ip.face_mode);
00518
00519 if( mode == PLATE_MODE )
00520 {
00521 bu_free( (char *)bot_ip.thickness, "BOT thickness" );
00522 bu_free( (char *)bot_ip.face_mode, "BOT face_mode" );
00523 }
00524 bu_free( (char *)bot_ip.vertices, "BOT vertices" );
00525 bu_free( (char *)bot_ip.faces, "BOT faces" );
00526 }
00527
00528
00529
00530
00531 #define FIND_NEWLINE(_cp,_eosFlag) \
00532 while (*(_cp) != '\0' && \
00533 *(_cp) != '\n') \
00534 ++(_cp); \
00535 \
00536 if (*(_cp) == '\0') \
00537 _eosFlag = 1; \
00538 else \
00539 *(_cp) = '\0';
00540
00541 int
00542 wdb_importFg4Section_cmd(struct rt_wdb *wdbp,
00543 Tcl_Interp *interp,
00544 int argc,
00545 char **argv)
00546 {
00547 char *cp;
00548 char *line;
00549 char *lines;
00550 int eosFlag = 0;
00551
00552 if (argc != 3) {
00553 struct bu_vls vls;
00554
00555 bu_vls_init(&vls);
00556 bu_vls_printf(&vls, "helplib_alias wdb_importFg4Section %s", argv[0]);
00557 Tcl_Eval(interp, bu_vls_addr(&vls));
00558 bu_vls_free(&vls);
00559 return TCL_ERROR;
00560 }
00561
00562 grid_size = GRID_BLOCK;
00563 grid_pts = (point_t *)bu_malloc(grid_size * sizeof(point_t) ,
00564 "importFg4Section: grid_pts");
00565
00566 lines = strdup(argv[2]);
00567 cp = line = lines;
00568
00569 FIND_NEWLINE(cp,eosFlag);
00570
00571 strncpy(field, line+8, 8);
00572 group_id = atoi(field);
00573
00574 strncpy(field, line+16, 8);
00575 comp_id = atoi(field);
00576
00577 region_id = group_id * 1000 + comp_id;
00578
00579 if (comp_id > 999) {
00580 bu_log( "Illegal component id number %d, changed to 999\n" , comp_id );
00581 comp_id = 999;
00582 }
00583
00584 strncpy(field, line+24, 8);
00585 mode = atoi(field);
00586 if (mode != 1 && mode != 2) {
00587 bu_log("Illegal mode (%d) for group %d component %d, using volume mode\n",
00588 mode, group_id, comp_id);
00589 mode = 2;
00590 }
00591
00592 while (!eosFlag) {
00593 ++cp;
00594 line = cp;
00595 FIND_NEWLINE(cp,eosFlag);
00596
00597 if (!strncmp(line , "GRID" , 4))
00598 do_grid(line);
00599 else if (!strncmp(line , "CTRI" , 4))
00600 do_tri(line);
00601 else if (!strncmp(line , "CQUAD" , 4))
00602 do_quad(line);
00603 }
00604
00605 make_bot_object(argv[1], wdbp);
00606 free((void *)lines);
00607 bu_free((void *)grid_pts, "importFg4Section: grid_pts");
00608
00609
00610 bu_free((void *)faces, "importFg4Section: faces");
00611 bu_free((void *)thickness, "importFg4Section: thickness");
00612 bu_free((void *)facemode, "importFg4Section: facemode");
00613
00614 faces = NULL;
00615 thickness = NULL;
00616 facemode = NULL;
00617
00618 return TCL_OK;
00619 }
00620