예제 #1
0
파일: nmg-bot.c 프로젝트: kanzure/brlcad
int
main(int argc, char **argv)
{
    struct directory *dp;

    if (argc != 3 && argc != 4) {
	bu_exit(1, "Usage:\n\t%s [-v] input.g output.g\n", argv[0]);
    }

    if (argc == 4) {
	if (BU_STR_EQUAL(argv[1], "-v"))
	    verbose = 1;
	else {
	    bu_log("Illegal option: %s\n", argv[1]);
	    bu_exit(1, "Usage:\n\t%s [-v] input.g output.g\n", argv[0]);
	}
    }

    rt_init_resource(&rt_uniresource, 0, NULL);

    dbip = db_open(argv[argc-2], DB_OPEN_READONLY);
    if (dbip == DBI_NULL) {
	perror(argv[0]);
	bu_exit(1, "Cannot open geometry database file (%s)\n", argv[argc-2]);
    }

    if ((fdout=wdb_fopen(argv[argc-1])) == NULL) {
	perror(argv[0]);
	bu_exit(1, "Cannot open file (%s)\n", argv[argc-1]);
    }
    if (db_dirbuild(dbip)) {
	bu_exit(1, "db_dirbuild failed\n");
    }

    /* Visit all records in input database, and spew them out,
     * modifying NMG objects into BoTs.
     */
    FOR_ALL_DIRECTORY_START(dp, dbip) {
	struct rt_db_internal intern;
	int id;
	int ret;
	id = rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource);
	if (id < 0) {
	    fprintf(stderr,
		    "%s: rt_db_get_internal(%s) failure, skipping\n",
		    argv[0], dp->d_namep);
	    continue;
	}
	if (id == ID_NMG) {
	    nmg_conv(&intern, dp->d_namep);
	} else {
	    ret = wdb_put_internal(fdout, dp->d_namep, &intern, 1.0);
	    if (ret < 0) {
		fprintf(stderr,
			"%s: wdb_put_internal(%s) failure, skipping\n",
			argv[0], dp->d_namep);
		rt_db_free_internal(&intern);
		continue;
	    }
	}
	rt_db_free_internal(&intern);
    } FOR_ALL_DIRECTORY_END
	  wdb_close(fdout);
    return 0;
}
예제 #2
0
파일: g-x3d.c 프로젝트: cogitokat/brlcad
/*
 *			M A I N
 */
int
main(int argc, char **argv)
{
    int	i;
    int	c;
    struct plate_mode pm;

    bu_setprogname(argv[0]);
    bu_setlinebuf( stderr );

    the_model = nmg_mm();
    tree_state = rt_initial_tree_state;	/* struct copy */
    tree_state.ts_tol = &tol;
    tree_state.ts_ttol = &ttol;
    tree_state.ts_m = &the_model;

    ttol.magic = RT_TESS_TOL_MAGIC;
    /* Defaults, updated by command line options. */
    ttol.abs = 0.0;
    ttol.rel = 0.01;
    ttol.norm = 0.0;

    /* FIXME: These need to be improved */
    tol.magic = BN_TOL_MAGIC;
    tol.dist = 0.0005;
    tol.dist_sq = tol.dist * tol.dist;
    tol.perp = 1e-6;
    tol.para = 1 - tol.perp;

    /* NOTE: For visualization purposes, in the debug plot files */
    {
	/* WTF: This value is specific to the Bradley */
	nmg_eue_dist = 2.0;
    }

    rt_init_resource( &rt_uniresource, 0, NULL );

    BU_LIST_INIT( &rt_g.rtg_vlfree );	/* for vlist macros */

    BARRIER_CHECK;
    /* Get command line arguments. */
    while ((c = bu_getopt(argc, argv, "d:a:n:o:r:vx:P:X:u:")) != -1) {
	switch (c) {
	    case 'a':		/* Absolute tolerance. */
		ttol.abs = atof(bu_optarg);
		ttol.rel = 0.0;
		break;
	    case 'd':		/* calculational tolerance */
		tol.dist = atof( bu_optarg );
		tol.dist_sq = tol.dist * tol.dist;
		break;
	    case 'n':		/* Surface normal tolerance. */
		ttol.norm = atof(bu_optarg)*bn_pi/180.0;
		ttol.rel = 0.0;
		break;
	    case 'o':		/* Output file name */
		out_file = bu_optarg;
		break;
	    case 'r':		/* Relative tolerance. */
		ttol.rel = atof(bu_optarg);
		break;
	    case 'v':
		verbose++;
		break;
	    case 'P':
		rt_g.debug = 1;
		break;
	    case 'x':
		sscanf( bu_optarg, "%x", (unsigned int *)&rt_g.debug );
		break;
	    case 'X':
		sscanf( bu_optarg, "%x", (unsigned int *)&rt_g.NMG_debug );
		NMG_debug = rt_g.NMG_debug;
		break;
	    case 'u':
		units = bu_strdup( bu_optarg );
		scale_factor = bu_units_conversion( units );
		if ( ZERO(scale_factor) )
		{
		    bu_exit(1, "Unrecognized units (%s)\n", units );
		}
		scale_factor = 1.0 / scale_factor;
		break;
	    default:
		bu_exit(1, usage, argv[0]);
		break;
	}
    }

    if (bu_optind+1 >= argc) {
	bu_exit(1, usage, argv[0]);
    }

    if ( !units )
	units = "mm";

    /* Open BRL-CAD database */
    if ((dbip = db_open( argv[bu_optind], "r")) == DBI_NULL)
    {
	perror(argv[0]);
	bu_exit(1, "Cannot open %s\n", argv[bu_optind] );
    }
    if ( db_dirbuild( dbip ) ) {
	bu_exit(1, "db_dirbuild() failed!\n" );
    }

    if (out_file == NULL) {
	outfp = stdout;
#if defined(_WIN32) && !defined(__CYGWIN__)
	setmode(fileno(outfp), O_BINARY);
#endif
    } else {
	if ((outfp = fopen( out_file, "wb")) == NULL)
	{
	    perror( argv[0] );
	    bu_exit(2, "Cannot open %s\n", out_file );
	}
    }

    writeX3dHeader(outfp, out_file);
    bu_optind++;

    BARRIER_CHECK;

    pm.num_bots = 0;
    pm.num_nonbots = 0;
    pm.array_size = 5;
    pm.bots = (struct rt_bot_internal **)bu_calloc( pm.array_size,
						    sizeof( struct rt_bot_internal *), "pm.bots" );
    for ( i=bu_optind; i<argc; i++ )
    {
	struct directory *dp;

	dp = db_lookup( dbip, argv[i], LOOKUP_QUIET );
	if ( dp == RT_DIR_NULL )
	{
	    bu_log( "Cannot find %s\n", argv[i] );
	    continue;
	}

	/* light source must be a combination */
	if ( !(dp->d_flags & RT_DIR_COMB) )
	    continue;

	/* walk trees selecting only light source regions */
	(void)db_walk_tree(dbip, 1, (const char **)(&argv[i]),
			   1,				/* ncpu */
			   &tree_state,
			   select_lights,
			   do_region_end,
			   leaf_tess,
			   (genptr_t)&pm);	/* in librt/nmg_bool.c */


    }
    BARRIER_CHECK;

    /* Walk indicated tree(s).  Each non-light-source region will be output separately */
    (void)db_walk_tree(dbip, argc-bu_optind, (const char **)(&argv[bu_optind]),
		       1,				/* ncpu */
		       &tree_state,
		       select_non_lights,
		       do_region_end,
		       leaf_tess,
		       (genptr_t)&pm);	/* in librt/nmg_bool.c */

    BARRIER_CHECK;
    /* Release dynamic storage */
    nmg_km(the_model);

    db_close(dbip);

    /* Now we need to close each group set */
    writeX3dEnd(outfp);

    if ( verbose )
	bu_log( "Total of %d regions converted of %d regions attempted\n",
		regions_converted, regions_tried );

    return 0;
}
예제 #3
0
파일: shp-g.c 프로젝트: kanzure/brlcad
int
main(int argc, char *argv[])
{
    int opt;
    size_t i;
    const char *argv0 = argv[0];
    struct rt_wdb *fd_out;
    struct bu_vls vls_in = BU_VLS_INIT_ZERO;
    struct bu_vls vls_out = BU_VLS_INIT_ZERO;

    int opt_debug = 0;
    int opt_verbose = 0;

    /* shapelib vars */
    SHPHandle shapefile;
    size_t shp_num_invalid = 0;
    int shp_num_entities = 0;
    int shp_type = 0;

    /* intentionally double for scan */
    double shp_min[4] = HINIT_ZERO;
    double shp_max[4] = HINIT_ZERO;

    /* geometry */
    point2d_t *verts = NULL;
    size_t num_verts = 0;

    if (argc < 2) {
	usage(argv0);
	bu_exit(1, NULL);
    }

    while ((opt = bu_getopt(argc, argv, "dxv")) != -1) {
	switch (opt) {
	    case 'd':
		opt_debug = 1;
		break;
	    case 'x':
		sscanf(bu_optarg, "%x", (unsigned int *) &RTG.debug);
		bu_printb("librt RT_G_DEBUG", RT_G_DEBUG, DEBUG_FORMAT);
		bu_log("\n");
		break;
	    case 'v':
		opt_verbose++;
		break;
	    default:
		usage(argv0);
		bu_exit(1, NULL);
		break;
	}
    }
    argv += bu_optind;
    argc -= bu_optind;

    if (opt_verbose)
	bu_log("Verbose output enabled.\n");

    if (opt_debug)
	bu_log("Debugging output enabled.\n");

    /* validate input/output file specifiers */
    if (argc < 1) {
	usage(argv0);
	bu_exit(1, "ERROR: Missing input and output file names\n");
    }

    bu_vls_strcat(&vls_in, argv[0]);

    if (argc < 2) {
	bu_vls_printf(&vls_out, "%s.g", argv[0]);
    } else {
	bu_vls_strcat(&vls_out, argv[1]);
    }

    if (opt_verbose) {
	bu_log("Reading from [%s]\n", bu_vls_addr(&vls_in));
	bu_log("Writing to [%s]\n\n", bu_vls_addr(&vls_out));
    }

    /* initialize single threaded resource */
    rt_init_resource(&rt_uniresource, 0, NULL);

    /* open the input */
    shapefile = SHPOpen(bu_vls_addr(&vls_in), "rb");
    if (!shapefile) {
	bu_log("ERROR: Unable to open shapefile [%s]\n", bu_vls_addr(&vls_in));
	bu_vls_free(&vls_in);
	bu_vls_free(&vls_out);
	bu_exit(4, NULL);    }

    /* print shapefile details */
    if (opt_verbose) {
	SHPGetInfo(shapefile, &shp_num_entities, &shp_type, shp_min, shp_max);

	bu_log("Shapefile Type: %s\n", SHPTypeName(shp_type));
	bu_log("# of Shapes: %d\n\n", shp_num_entities);
	bu_log("File Bounds: (%12.3f,%12.3f, %.3g, %.3g)\n"
	       "         to  (%12.3f,%12.3f, %.3g, %.3g)\n",
	       shp_min[0], shp_min[1], shp_min[2], shp_min[3],
	       shp_max[0], shp_max[1], shp_max[2], shp_max[3]);
    }

    /* open the .g for writing */
    if ((fd_out = wdb_fopen(bu_vls_addr(&vls_out))) == NULL) {
	bu_log("ERROR: Unable to open shapefile [%s]\n", bu_vls_addr(&vls_out));
	bu_vls_free(&vls_in);
	bu_vls_free(&vls_out);
	perror(argv0);
	bu_exit(5, NULL);
    }

    /* iterate over all entities */
    for (i=0; i < (size_t)shp_num_entities; i++) {
	SHPObject *object;
	int shp_part;
	size_t j;

	object = SHPReadObject(shapefile, i);
	if (!object) {
	    if (opt_debug)
		bu_log("Shape %zu of %zu is missing, skipping.\n", i+1, (size_t)shp_num_entities);
	    continue;
	}

	/* validate the object */
	if (opt_debug) {
	    int shp_altered = SHPRewindObject(shapefile, object);
	    if (shp_altered > 0) {
		bu_log("WARNING: Shape %zu of %zu has [%d] bad loop orientations.\n", i+1, (size_t)shp_num_entities, shp_altered);
		shp_num_invalid++;
	    }
	}

	/* print detail header */
	if (opt_verbose) {
	    if (object->bMeasureIsUsed) {
		bu_log("\nShape:%zu (%s)  nVertices=%d, nParts=%d\n"
		       "  Bounds:(%12.3f,%12.3f, %g, %g)\n"
		       "      to (%12.3f,%12.3f, %g, %g)\n",
		       i+1, SHPTypeName(object->nSHPType), object->nVertices, object->nParts,
		       object->dfXMin, object->dfYMin, object->dfZMin, object->dfMMin,
		       object->dfXMax, object->dfYMax, object->dfZMax, object->dfMMax);
	    } else {
		bu_log("\nShape:%zu (%s)  nVertices=%d, nParts=%d\n"
		       "  Bounds:(%12.3f,%12.3f, %g)\n"
		       "      to (%12.3f,%12.3f, %g)\n",
		       i+1, SHPTypeName(object->nSHPType), object->nVertices, object->nParts,
		       object->dfXMin, object->dfYMin, object->dfZMin,
		       object->dfXMax, object->dfYMax, object->dfZMax);
	    }

	    if (object->nParts > 0 && object->panPartStart[0] != 0) {
		if (opt_debug)
		    bu_log("Shape %zu of %zu: panPartStart[0] = %d, not zero as expected.\n", i+1, (size_t)shp_num_entities, object->panPartStart[0]);
		continue;
	    }
	}

	num_verts = 0;
	verts = (point2d_t *)bu_calloc((size_t)object->nVertices, sizeof(point2d_t), "alloc point array");

	for (j = 0, shp_part = 1; j < (size_t)object->nVertices; j++) {
	    if (shp_part < object->nParts
		&& j == (size_t)object->panPartStart[shp_part]) {
		shp_part++;
		bu_log("Shape %zu of %zu: End of Loop\n", i+1, (size_t)shp_num_entities);
		make_shape(fd_out, opt_verbose, opt_debug, i, num_verts, verts);

		/* reset for next loop */
		memset(verts, 0, sizeof(point2d_t) * object->nVertices);
		num_verts = 0;
	    }
	    bu_log("%zu/%zu:%zu/%zu\t\t", i+1, (size_t)shp_num_entities, j+1, (size_t)object->nVertices);
	    bu_log("(%12.4f, %12.4f, %12.4f, %g)\n", object->padfX[j], object->padfY[j], object->padfZ[j], object->padfM[j]);

	    V2SET(verts[num_verts], object->padfX[j], object->padfY[j]);
	    num_verts++;
	}
	bu_log("Shape %zu of %zu: End of Loop\n", i+1, (size_t)shp_num_entities);
	make_shape(fd_out, opt_verbose, opt_debug, i, num_verts, verts);

	bu_free(verts, "free point array");
	verts = NULL;
	num_verts = 0;

	SHPDestroyObject(object);
	object = NULL;
    }

    if (opt_verbose) {
	if (shp_num_invalid > 0) {
	    bu_log("WARNING: %zu of %zu shape(s) had bad loop orientations.\n", shp_num_invalid, (size_t)shp_num_entities);
	}
	bu_log("\nDone.\n");
    }

    /* close up our files */
    SHPClose(shapefile);
    wdb_close(fd_out);

    /* free up allocated resources */
    bu_vls_free(&vls_in);
    bu_vls_free(&vls_out);

    return 0;
}
예제 #4
0
파일: g-iges.c 프로젝트: kanzure/brlcad
int
main(int argc, char *argv[])
{
    size_t i;
    int ret;
    int c;
    double percent;
    char copy_buffer[CP_BUF_SIZE] = {0};
    struct directory *dp;

    bu_setprogname(argv[0]);
    bu_setlinebuf(stderr);

    bu_log("%s", brlcad_ident("BRL-CAD to IGES Translator"));
    bu_log("Please direct bug reports to <*****@*****.**>\n\n");

    tree_state = rt_initial_tree_state;	/* struct copy */
    tree_state.ts_tol = &tol;
    tree_state.ts_ttol = &ttol;
    tree_state.ts_m = &the_model;

    ttol.magic = RT_TESS_TOL_MAGIC;
    /* Defaults, updated by command line options. */
    ttol.abs = 0.0;
    ttol.rel = 0.01;
    ttol.norm = 0.0;

    /* FIXME: These need to be improved */
    tol.magic = BN_TOL_MAGIC;
    tol.dist = 0.0005;
    tol.dist_sq = tol.dist * tol.dist;
    tol.perp = 1e-6;
    tol.para = 1 - tol.perp;

    the_model = nmg_mm();
    BU_LIST_INIT(&RTG.rtg_vlfree);	/* for vlist macros */

    rt_init_resource(&rt_uniresource, 0, NULL);

    prog_name = argv[0];

    /* Get command line arguments. */
    while ((c = bu_getopt(argc, argv, "ftsmd:a:n:o:p:r:vx:P:X:")) != -1) {
	switch (c) {
	    case 'f':		/* Select facetized output */
		mode = FACET_MODE;
		multi_file = 0;
		break;
	    case 't':
		mode = TRIMMED_SURF_MODE;
		multi_file = 0;
		break;
	    case 'm':		/* multi-file mode */
		multi_file = 1;
		mode = TRIMMED_SURF_MODE;
		break;
	    case 's':		/* Select NURB output */
		do_nurbs = 1;
		break;
	    case 'v':
		verbose++;
		break;
	    case 'a':		/* Absolute tolerance. */
		ttol.abs = atof(bu_optarg);
		break;
	    case 'r':		/* Relative tolerance. */
		ttol.rel = atof(bu_optarg);
		break;
	    case 'n':		/* Surface normal tolerance. */
		ttol.norm = atof(bu_optarg);
		break;
	    case 'd':		/* distance tolerance */
		tol.dist = atof(bu_optarg);
		tol.dist_sq = tol.dist * tol.dist;
		break;
	    case 'x':
		sscanf(bu_optarg, "%x", (unsigned int *)&RTG.debug);
		break;
	    case 'X':
		sscanf(bu_optarg, "%x", (unsigned int *)&RTG.NMG_debug);
		NMG_debug = RTG.NMG_debug;
		break;
	    case 'o':		/* Output file name. */
		output_file = bu_optarg;
		break;
	    case 'P':
		ncpu = atoi(bu_optarg);
		break;
	    default:
		usage(argv[0]);
		break;
	}
    }

    if (bu_optind+1 >= argc) {
	usage(argv[0]);
    }

    /* Open BRL-CAD database */
    argc -= bu_optind;
    argv += bu_optind;
    db_name = argv[0];
    if ((DBIP = db_open(db_name, DB_OPEN_READONLY)) == DBI_NULL) {
	perror("g-iges");
	bu_exit(1, "ERROR: unable to open geometry database file (%s)\n", db_name);
    }

    /* Scan the database */
    if (db_dirbuild(DBIP)) {
	bu_exit(1, "db_dirbuild failed\n");
    }

    if (!multi_file) {
	/* let the IGES routines know the selected tolerances and the database pointer */
	iges_init(&tol, &ttol, verbose, DBIP);

	/* Open the output file */
	if (output_file == NULL)
	    fp_dir = stdout;
	else {
	    if ((fp_dir = fopen(output_file, "wb")) == NULL) {
		perror(output_file);
		bu_exit(1, "Cannot open output file: %s\n", output_file);
	    }
	}

	/* Open the temporary file for the parameter section */
	if ((fp_param = bu_temp_file(NULL, 0)) == NULL) {
	    perror("g-iges");
	    bu_exit(1, "Cannot open temporary file\n");
	}

	/* Write start and global sections of the IGES file */
	w_start_global(fp_dir, fp_param, argv[0], prog_name, output_file, __DATE__, brlcad_version());
    } else {
	if (!bu_file_directory(output_file)) {
	    bu_exit(1, "-o option must provide a directory, %s is not a directory\n", output_file);
	}
    }

    /* Count object references */
/* for (i = 1; i < argc; i++) {
   dp = db_lookup(DBIP, argv[i], 1);
   db_functree(DBIP, dp, count_refs, 0, NULL);
   }	*/

    /* tree tops must have independent status, so we need to remember them */
    independent = (argv+1);
    no_of_indeps = (size_t)argc-1;

    if (mode == FACET_MODE) {
	/* Walk indicated tree(s).  Each region will be output
	 * as a single manifold solid BREP object */

	ret = db_walk_tree(DBIP, argc-1, (const char **)(argv+1),
			   ncpu,
			   &tree_state,
			   0,			/* take all regions */
			   do_nmg_region_end,
			   nmg_booltree_leaf_tess,
			   (void *)NULL);	/* in librt/nmg_bool.c */

	if (ret)
	    bu_exit(1, "g-iges: Could not facetize anything!");

	if (!multi_file) {
	    /* Now walk the same trees again, but only output groups */
	    for (i = 1; i < (size_t)argc; i++) {
		char *ptr;

		ptr = strrchr(argv[i], '/');
		if (ptr != NULL) {
		    ptr++;
		} else {
		    ptr = argv[i];
		}
		dp = db_lookup(DBIP, ptr, 1);
		if (!dp) {
		    bu_log("WARNING: Unable to locate %s in %s\n, skipping\n", ptr, db_name);
		    continue;
		}
		db_functree(DBIP, dp, csg_comb_func, 0, &rt_uniresource, NULL);
	    }
	}
    } else if (mode == CSG_MODE) {
	/* Walk indicated tree(s). Each combination and solid will be output
	 * as a CSG object, unless there is no IGES equivalent (then the
	 * solid will be tessellated and output as a BREP object) */

	for (i = 1; i < (size_t)argc; i++) {
	    dp = db_lookup(DBIP, argv[i], 1);
	    if (!dp) {
		bu_log("WARNING: Unable to locate %s in %s\n, skipping\n", argv[i], db_name);
		continue;
	    }
	    db_functree(DBIP, dp, csg_comb_func, csg_leaf_func, &rt_uniresource, NULL);
	}
    } else if (mode == TRIMMED_SURF_MODE) {
	/* Walk the indicated tree(s). Each region is output as a collection
	 * of trimmed NURBS */

	ret = db_walk_tree(DBIP, argc-1, (const char **)(argv+1),
			   ncpu,
			   &tree_state,
			   0,			/* take all regions */
			   do_nmg_region_end,
			   nmg_booltree_leaf_tess,
			   (void *)NULL);	/* in librt/nmg_bool.c */

	if (ret)
	    bu_exit(1, "g-iges: Could not facetize anything!");

    }

    if (!multi_file) {
	/* Copy the parameter section from the temporary file to the output file */
	if ((bu_fseek(fp_param, 0, 0))) {
	    perror("g-iges");
	    bu_exit(1, "Cannot seek to start of temporary file\n");
	}

	while ((i = fread(copy_buffer, 1, CP_BUF_SIZE, fp_param)))
	    if (fwrite(copy_buffer, 1, i, fp_dir) != i) {
		perror("g-iges");
		bu_exit(1, "Error in copying parameter data to %s\n", output_file);
	    }

	/* Write the terminate section */
	w_terminate(fp_dir);
    }

    /* Print some statistics */
    Print_stats(stdout);

    /* report on the success rate for facetizing regions */
    if (mode == FACET_MODE || mode == TRIMMED_SURF_MODE) {
	percent = 0;
	if (regions_tried>0) percent = ((double)regions_done * 100) / regions_tried;
	bu_log("Tried %d regions, %d converted to nmg's successfully.  %g%%\n",
	       regions_tried, regions_done, percent);
    }

    /* re-iterate warnings */
    if (scale_error || solid_error || comb_error)
	bu_log("WARNING: the IGES file produced has errors:\n");
    if (scale_error)
	bu_log("\t%d scaled objects found, written to IGES file without being scaled\n", scale_error);
    if (solid_error)
	bu_log("\t%d solids were not converted to IGES format\n", solid_error);
    if (comb_error)
	bu_log("\t%d combinations were not converted to IGES format\n", comb_error);

    return 0;
}
/* 0 = no difference within tolerance, 1 = difference >= tolerance */
int
analyze_raydiff(/* TODO - decide what to return.  Probably some sort of left, common, right segment sets.  See what rtcheck does... */
	struct db_i *dbip, const char *obj1, const char *obj2, struct bn_tol *tol)
{
    int ret;
    int count = 0;
    struct rt_i *rtip;
    int ncpus = bu_avail_cpus();
    point_t min, mid, max;
    struct rt_pattern_data *xdata, *ydata, *zdata;
    fastf_t *rays;
    struct raydiff_container *state;

    if (!dbip || !obj1 || !obj2 || !tol) return 0;

    rtip = rt_new_rti(dbip);
    if (rt_gettree(rtip, obj1) < 0) return -1;
    if (rt_gettree(rtip, obj2) < 0) return -1;
    rt_prep_parallel(rtip, 1);


    /* Now we've got the bounding box - set up the grids */
    VMOVE(min, rtip->mdl_min);
    VMOVE(max, rtip->mdl_max);
    VSET(mid, (max[0] - min[0])/2, (max[1] - min[1])/2, (max[2] - min[2])/2);

    BU_GET(xdata, struct rt_pattern_data);
    VSET(xdata->center_pt, min[0] - 0.1 * min[0], mid[1], mid[2]);
    VSET(xdata->center_dir, 1, 0, 0);
    xdata->vn = 2;
    xdata->pn = 2;
    xdata->n_vec = (vect_t *)bu_calloc(xdata->vn + 1, sizeof(vect_t), "vects array");
    xdata->n_p = (fastf_t *)bu_calloc(xdata->pn + 1, sizeof(fastf_t), "params array");
    xdata->n_p[0] = 50; /* TODO - get tolerances from caller */
    xdata->n_p[1] = 50;
    VSET(xdata->n_vec[0], 0, max[1], 0);
    VSET(xdata->n_vec[1], 0, 0, max[2]);
    ret = rt_pattern(xdata, RT_PATTERN_RECT_ORTHOGRID);
    bu_free(xdata->n_vec, "x vec inputs");
    bu_free(xdata->n_p, "x p inputs");
    if (ret < 0) return -1;


    BU_GET(ydata, struct rt_pattern_data);
    VSET(ydata->center_pt, mid[0], min[1] - 0.1 * min[1], mid[2]);
    VSET(ydata->center_dir, 0, 1, 0);
    ydata->vn = 2;
    ydata->pn = 2;
    ydata->n_vec = (vect_t *)bu_calloc(ydata->vn + 1, sizeof(vect_t), "vects array");
    ydata->n_p = (fastf_t *)bu_calloc(ydata->pn + 1, sizeof(fastf_t), "params array");
    ydata->n_p[0] = 50; /* TODO - get tolerances from caller */
    ydata->n_p[1] = 50;
    VSET(ydata->n_vec[0], max[0], 0, 0);
    VSET(ydata->n_vec[1], 0, 0, max[2]);
    ret = rt_pattern(ydata, RT_PATTERN_RECT_ORTHOGRID);
    bu_free(ydata->n_vec, "y vec inputs");
    bu_free(ydata->n_p, "y p inputs");
    if (ret < 0) return -1;

    BU_GET(zdata, struct rt_pattern_data);
    VSET(zdata->center_pt, mid[0], mid[1], min[2] - 0.1 * min[2]);
    VSET(zdata->center_dir, 0, 0, 1);
    zdata->vn = 2;
    zdata->pn = 2;
    zdata->n_vec = (vect_t *)bu_calloc(zdata->vn + 1, sizeof(vect_t), "vects array");
    zdata->n_p = (fastf_t *)bu_calloc(zdata->pn + 1, sizeof(fastf_t), "params array");
    zdata->n_p[0] = 50; /* TODO - get tolerances from caller */
    zdata->n_p[1] = 50;
    VSET(zdata->n_vec[0], max[0], 0, 0);
    VSET(zdata->n_vec[1], 0, max[1], 0);
    ret = rt_pattern(zdata, RT_PATTERN_RECT_ORTHOGRID);
    bu_free(zdata->n_vec, "x vec inputs");
    bu_free(zdata->n_p, "x p inputs");
    if (ret < 0) return -1;

    /* Consolidate the grids into a single ray array */
    {
	size_t i, j;
	rays = (fastf_t *)bu_calloc((xdata->ray_cnt + ydata->ray_cnt + zdata->ray_cnt + 1) * 6, sizeof(fastf_t), "rays");
	count = 0;
	for (i = 0; i < xdata->ray_cnt; i++) {
	    for (j = 0; j < 6; j++) {
		rays[6*count+j] = xdata->rays[6*i + j];
	    }
	    count++;
	}
	for (i = 0; i < ydata->ray_cnt; i++) {
	    for (j = 0; j < 6; j++) {
		rays[6*count+j] = ydata->rays[6*i + j];
	    }
	    count++;
	}
	for (i = 0; i < zdata->ray_cnt; i++) {
	    for (j = 0; j < 6; j++) {
		rays[6*count+j] = zdata->rays[6*i+j];
	    }
	    count++;
	}

    }
    bu_free(xdata->rays, "x rays");
    bu_free(ydata->rays, "y rays");
    bu_free(zdata->rays, "z rays");
    BU_PUT(xdata, struct rt_pattern_data);
    BU_PUT(ydata, struct rt_pattern_data);
    BU_PUT(zdata, struct rt_pattern_data);

    bu_log("ray cnt: %d\n", count);

    {
	int i, j;
	ncpus = 2;
	state = (struct raydiff_container *)bu_calloc(ncpus+1, sizeof(struct raydiff_container), "resources");
	for (i = 0; i < ncpus+1; i++) {
	    state[i].rtip = rtip;
	    state[i].tol = 0.5;
	    state[i].ncpus = ncpus;
	    state[i].left_name = bu_strdup(obj1);
	    state[i].right_name = bu_strdup(obj2);
	    BU_GET(state[i].resp, struct resource);
	    rt_init_resource(state[i].resp, i, state->rtip);
	    BU_GET(state[i].left, struct bu_ptbl);
	    bu_ptbl_init(state[i].left, 64, "left solid hits");
	    BU_GET(state[i].both, struct bu_ptbl);
	    bu_ptbl_init(state[i].both, 64, "hits on both solids");
	    BU_GET(state[i].right, struct bu_ptbl);
	    bu_ptbl_init(state[i].right, 64, "right solid hits");
	    state[i].rays_cnt = count;
	    state[i].rays = rays;
	}
	bu_parallel(raydiff_gen_worker, ncpus, (void *)state);

	/* Collect and print all of the results */
	for (i = 0; i < ncpus+1; i++) {
	    for (j = 0; j < (int)BU_PTBL_LEN(state[i].left); j++) {
		struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].left, j);
		bu_log("Result: LEFT diff vol (%s): %g %g %g -> %g %g %g\n", obj1, V3ARGS(dseg->in_pt), V3ARGS(dseg->out_pt));
	    }
	    for (j = 0; j < (int)BU_PTBL_LEN(state[i].both); j++) {
		struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].both, j);
		bu_log("Result: BOTH): %g %g %g -> %g %g %g\n", V3ARGS(dseg->in_pt), V3ARGS(dseg->out_pt));
	    }
	    for (j = 0; j < (int)BU_PTBL_LEN(state[i].right); j++) {
		struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].right, j);
		bu_log("Result: RIGHT diff vol (%s): %g %g %g -> %g %g %g\n", obj2, V3ARGS(dseg->in_pt), V3ARGS(dseg->out_pt));
	    }
	}

	/* Free results */
	for (i = 0; i < ncpus+1; i++) {
	    for (j = 0; j < (int)BU_PTBL_LEN(state[i].left); j++) {
		struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].left, j);
		BU_PUT(dseg, struct diff_seg);
	    }
	    bu_ptbl_free(state[i].left);
	    BU_PUT(state[i].left, struct diff_seg);
	    for (j = 0; j < (int)BU_PTBL_LEN(state[i].both); j++) {
		struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].both, j);
		BU_PUT(dseg, struct diff_seg);
	    }
	    bu_ptbl_free(state[i].both);
	    BU_PUT(state[i].both, struct diff_seg);
	    for (j = 0; j < (int)BU_PTBL_LEN(state[i].right); j++) {
		struct diff_seg *dseg = (struct diff_seg *)BU_PTBL_GET(state[i].right, j);
		BU_PUT(dseg, struct diff_seg);
	    }
	    bu_ptbl_free(state[i].right);
	    BU_PUT(state[i].right, struct diff_seg);

	    bu_free((void *)state[i].left_name, "left name");
	    bu_free((void *)state[i].right_name, "right name");
	    BU_PUT(state[i].resp, struct resource);
	}
	bu_free(state, "free state containers");
    }
    return 0;
}
예제 #6
0
/*
 *			M A I N
 */
int main(int argc, char **argv)
{
    struct rt_i *rtip = NULL;
    char *title_file = NULL, *title_obj = NULL;	/* name of file and first object */
    char idbuf[RT_BUFSIZE] = {0};		/* First ID record info */
    void	application_init();
    struct bu_vls	times;
    int i;

#if defined(_WIN32) && !defined(__CYGWIN__)
    setmode(fileno(stdin), O_BINARY);
    setmode(fileno(stdout), O_BINARY);
    setmode(fileno(stderr), O_BINARY);
#else
    bu_setlinebuf( stdout );
    bu_setlinebuf( stderr );
#endif

#ifdef HAVE_SBRK
    beginptr = (char *) sbrk(0);
#endif
    azimuth = 35.0;			/* GIFT defaults */
    elevation = 25.0;

    AmbientIntensity=0.4;
    background[0] = background[1] = 0.0;
    background[2] = 1.0/255.0; /* slightly non-black */

    /* Before option processing, get default number of processors */
    npsw = bu_avail_cpus();		/* Use all that are present */
    if ( npsw > MAX_PSW )  npsw = MAX_PSW;

    /* Before option processing, do application-specific initialization */
    RT_APPLICATION_INIT( &ap );
    application_init();

    /* Process command line options */
    if ( !get_args( argc, argv ) )  {
	(void)fputs(usage, stderr);
	return 1;
    }
    /* Identify the versions of the libraries we are using. */
    if (rt_verbosity & VERBOSE_LIBVERSIONS) {
	(void)fprintf(stderr, "%s%s%s%s\n",
		      brlcad_ident(title),
		      rt_version(),
		      bn_version(),
		      bu_version()
	    );
    }
#if defined(DEBUG)
    (void)fprintf(stderr, "Compile-time debug symbols are available\n");
#endif
#if defined(NO_BOMBING_MACROS) || defined(NO_MAGIC_CHECKING) || defined(NO_BADRAY_CECHKING) || defined(NO_DEBUG_CHECKING)
    (void)fprintf(stderr, "WARNING: Run-time debugging is disabled and may enhance performance\n");
#endif

    /* Identify what host we're running on */
    if (rt_verbosity & VERBOSE_LIBVERSIONS) {
	char	hostname[512] = {0};
#ifndef _WIN32
	if ( gethostname( hostname, sizeof(hostname) ) >= 0 &&
	     hostname[0] != '\0' )
	    (void)fprintf(stderr, "Running on %s\n", hostname);
#else
	sprintf(hostname, "Microsoft Windows");
	(void)fprintf(stderr, "Running on %s\n", hostname);
#endif
    }

    if ( bu_optind >= argc )  {
	fprintf(stderr, "%s:  MGED database not specified\n", argv[0]);
	(void)fputs(usage, stderr);
	return 1;
    }

    if (rpt_overlap)
	ap.a_logoverlap = ((void (*)())0);
    else
	ap.a_logoverlap = rt_silent_logoverlap;

    /* If user gave no sizing info at all, use 512 as default */
    if ( width <= 0 && cell_width <= 0 )
	width = 512;
    if ( height <= 0 && cell_height <= 0 )
	height = 512;

    /* If user didn't provide an aspect ratio, use the image
     * dimensions ratio as a default.
     */
    if (aspect <= 0.0) {
	aspect = (fastf_t)width / (fastf_t)height;
    }

    if ( sub_grid_mode ) {
	/* check that we have a legal subgrid */
	if ( sub_xmax >= width || sub_ymax >= height ) {
	    fprintf( stderr, "rt: illegal values for subgrid %d,%d,%d,%d\n",
		     sub_xmin, sub_ymin, sub_xmax, sub_ymax );
	    fprintf( stderr, "\tFor a %d X %d image, the subgrid must be within 0, 0,%d,%d\n",
		     width, height, width-1, height-1 );
	    return 1;
	}
    }

    if ( incr_mode )  {
	int x = height;
	if ( x < width )  x = width;
	incr_nlevel = 1;
	while ( (1<<incr_nlevel) < x )
	    incr_nlevel++;
	height = width = 1<<incr_nlevel;
	if (rt_verbosity & VERBOSE_INCREMENTAL)
	    fprintf(stderr,
		    "incremental resolution, nlevels = %d, width=%d\n",
		    incr_nlevel, width);
    }

    /*
     *  Handle parallel initialization, if applicable.
     */
#ifndef PARALLEL
    npsw = 1;			/* force serial */
#endif

    if ( npsw < 0 )  {
	/* Negative number means "all but" npsw */
	npsw = bu_avail_cpus() + npsw;
    }


    /* allow debug builds to go higher than the max */
    if (!(bu_debug & BU_DEBUG_PARALLEL)) {
	if ( npsw > MAX_PSW ) {
	    npsw = MAX_PSW;
	}
    }

    if (npsw > 1) {
	rt_g.rtg_parallel = 1;
	if (rt_verbosity & VERBOSE_MULTICPU)
	    fprintf(stderr, "Planning to run with %d processors\n", npsw );
    } else {
	rt_g.rtg_parallel = 0;
    }

    /* Initialize parallel processor support */
    bu_semaphore_init( RT_SEM_LAST );

    /*
     *  Do not use bu_log() or bu_malloc() before this point!
     */

    if ( bu_debug )  {
	bu_printb( "libbu bu_debug", bu_debug, BU_DEBUG_FORMAT );
	bu_log("\n");
    }

    if ( RT_G_DEBUG )  {
	bu_printb( "librt rt_g.debug", rt_g.debug, DEBUG_FORMAT );
	bu_log("\n");
    }
    if ( rdebug )  {
	bu_printb( "rt rdebug", rdebug, RDEBUG_FORMAT );
	bu_log("\n");
    }

    /* We need this to run rt_dirbuild */
    rt_init_resource( &rt_uniresource, MAX_PSW, NULL );
    bn_rand_init( rt_uniresource.re_randptr, 0 );

    title_file = argv[bu_optind];
    title_obj = argv[bu_optind+1];
    nobjs = argc - bu_optind - 1;
    objtab = &(argv[bu_optind+1]);

    if ( nobjs <= 0 )  {
	bu_log("%s: no objects specified -- raytrace aborted\n", argv[0]);
	return 1;
    }

    /* Echo back the command line arugments as given, in 3 Tcl commands */
    if (rt_verbosity & VERBOSE_MODELTITLE) {
	struct bu_vls str;
	bu_vls_init(&str);
	bu_vls_from_argv( &str, bu_optind, (const char **)argv );
	bu_vls_strcat( &str, "\nopendb "  );
	bu_vls_strcat( &str, title_file );
	bu_vls_strcat( &str, ";\ntree " );
	bu_vls_from_argv( &str,
			  nobjs <= 16 ? nobjs : 16,
			  (const char **)argv+bu_optind+1 );
	if ( nobjs > 16 )
	    bu_vls_strcat( &str, " ...");
	else
	    bu_vls_putc( &str, ';' );
	bu_log("%s\n", bu_vls_addr(&str) );
	bu_vls_free(&str);
    }

    /* Build directory of GED database */
    bu_vls_init( &times );
    rt_prep_timer();
    if ( (rtip=rt_dirbuild(title_file, idbuf, sizeof(idbuf))) == RTI_NULL ) {
	bu_log("rt:  rt_dirbuild(%s) failure\n", title_file);
	return 2;
    }
    ap.a_rt_i = rtip;
    (void)rt_get_timer( &times, NULL );
    if (rt_verbosity & VERBOSE_MODELTITLE)
	bu_log("db title:  %s\n", idbuf);
    if (rt_verbosity & VERBOSE_STATS)
	bu_log("DIRBUILD: %s\n", bu_vls_addr(&times) );
    bu_vls_free( &times );
    memory_summary();

    /* Copy values from command line options into rtip */
    rtip->rti_space_partition = space_partition;
    rtip->rti_nugrid_dimlimit = nugrid_dimlimit;
    rtip->rti_nu_gfactor = nu_gfactor;
    rtip->useair = use_air;
    rtip->rti_save_overlaps = save_overlaps;
    if ( rt_dist_tol > 0 )  {
	rtip->rti_tol.dist = rt_dist_tol;
	rtip->rti_tol.dist_sq = rt_dist_tol * rt_dist_tol;
    }
    if ( rt_perp_tol > 0 )  {
	rtip->rti_tol.perp = rt_perp_tol;
	rtip->rti_tol.para = 1 - rt_perp_tol;
    }
    if (rt_verbosity & VERBOSE_TOLERANCE)
	rt_pr_tol( &rtip->rti_tol );

    /* before view_init */
    if ( outputfile && strcmp( outputfile, "-") == 0 )
	outputfile = (char *)0;

    /*
     *  Initialize application.
     *  Note that width & height may not have been set yet,
     *  since they may change from frame to frame.
     */
    if ( view_init( &ap, title_file, title_obj, outputfile!=(char *)0, framebuffer!=(char *)0 ) != 0 )  {
	/* Framebuffer is desired */
	register int xx, yy;
	int	zoom;

	/* Ask for a fb big enough to hold the image, at least 512. */
	/* This is so MGED-invoked "postage stamps" get zoomed up big enough to see */
	xx = yy = 512;
	if ( width > xx || height > yy )  {
	    xx = width;
	    yy = height;
	}
	bu_semaphore_acquire( BU_SEM_SYSCALL );
	fbp = fb_open( framebuffer, xx, yy );
	bu_semaphore_release( BU_SEM_SYSCALL );
	if ( fbp == FBIO_NULL )  {
	    fprintf(stderr, "rt:  can't open frame buffer\n");
	    return 12;
	}

	bu_semaphore_acquire( BU_SEM_SYSCALL );
	/* If fb came out smaller than requested, do less work */
	if ( fb_getwidth(fbp) < width )  width = fb_getwidth(fbp);
	if ( fb_getheight(fbp) < height )  height = fb_getheight(fbp);

	/* If the fb is lots bigger (>= 2X), zoom up & center */
	if ( width > 0 && height > 0 )  {
	    zoom = fb_getwidth(fbp)/width;
	    if ( fb_getheight(fbp)/height < zoom )
		zoom = fb_getheight(fbp)/height;
	} else {
	    zoom = 1;
	}
	(void)fb_view( fbp, width/2, height/2,
		       zoom, zoom );
	bu_semaphore_release( BU_SEM_SYSCALL );
    }
    if ( (outputfile == (char *)0) && (fbp == FBIO_NULL) )  {
	/* If not going to framebuffer, or to a file, then use stdout */
	if ( outfp == NULL )  outfp = stdout;
	/* output_is_binary is changed by view_init, as appropriate */
	if ( output_is_binary && isatty(fileno(outfp)) )  {
	    fprintf(stderr, "rt:  attempting to send binary output to terminal, aborting\n");
	    return 14;
	}
    }

    /*
     *  Initialize all the per-CPU memory resources.
     *  The number of processors can change at runtime, init them all.
     */
    for ( i=0; i < MAX_PSW; i++ )  {
	rt_init_resource( &resource[i], i, rtip );
	bn_rand_init( resource[i].re_randptr, i );
    }
    memory_summary();

#ifdef SIGUSR1
    (void)signal( SIGUSR1, siginfo_handler );
#endif
#ifdef SIGINFO
    (void)signal( SIGINFO, siginfo_handler );
#endif

    if ( !matflag )  {
	int frame_retval;
	def_tree( rtip );		/* Load the default trees */
	do_ae( azimuth, elevation );
	frame_retval = do_frame( curframe );
	if (frame_retval != 0) {
	    /* Release the framebuffer, if any */
	    if ( fbp != FBIO_NULL ) {
		fb_close(fbp);
	    }

	    return 1;
	}
    } else if ( !isatty(fileno(stdin)) && old_way( stdin ) )  {
	; /* All is done */
    } else {
	register char	*buf;
	register int	ret;
	/*
	 * New way - command driven.
	 * Process sequence of input commands.
	 * All the work happens in the functions
	 * called by rt_do_cmd().
	 */
	while ( (buf = rt_read_cmd( stdin )) != (char *)0 )  {
	    if ( R_DEBUG&RDEBUG_PARSE )
		fprintf(stderr, "cmd: %s\n", buf );
	    ret = rt_do_cmd( rtip, buf, rt_cmdtab );
	    bu_free( buf, "rt_read_cmd command buffer" );
	    if ( ret < 0 )
		break;
	}
	if ( curframe < desiredframe )  {
	    fprintf(stderr,
		    "rt:  Desired frame %d not reached, last was %d\n",
		    desiredframe, curframe);
	}
    }

    /* Release the framebuffer, if any */
    if (fbp != FBIO_NULL) {
	fb_close(fbp);
    }

    return(0);
}
예제 #7
0
int
main(int argc, char *argv[])
{
    struct rt_i *rtip = NULL;

    char db_title[TITLE_LEN+1];/* title from MGED file */
    const char *tmp_str;
    extern char local_u_name[65];
    extern double base2local;
    extern double local2base;
    FILE *fPtr;
    int Ch;		/* Option name */
    int mat_flag = 0;	/* Read matrix from stdin? */
    int use_of_air = 0;
    int print_ident_flag = 1;
    char ocastring[1024] = {0};
    struct bu_list script_list;	/* For -e and -f options */
    struct script_rec *srp;
    extern outval ValTab[];

    /* from if.c, callback functions for overlap, hit, and miss shots */
    int if_overlap(struct application *, struct partition *, struct region *, struct region *, struct partition *);
    int if_hit(struct application *, struct partition *, struct seg *);
    int if_miss(struct application *);

    BU_LIST_INIT(&script_list);

    bu_setprogname(argv[0]);

    ocname[OVLP_RESOLVE] = "resolve";
    ocname[OVLP_REBUILD_FASTGEN] = "rebuild_fastgen";
    ocname[OVLP_REBUILD_ALL] = "rebuild_all";
    ocname[OVLP_RETAIN] = "retain";
    *ocastring = '\0';

    bu_optind = 1;		/* restart */

    /* Handle command-line options */
    while ((Ch = bu_getopt(argc, argv, OPT_STRING)) != -1) {
    	if (bu_optopt == '?') Ch='h';
	switch (Ch) {
	    case 'A':
		attrib_add(bu_optarg, &need_prep);
		break;
	    case 'B':
		rt_bot_minpieces = atoi(bu_optarg);
		break;
	    case 'T':
		setenv("LIBRT_BOT_MINTIE", bu_optarg, 1);
		break;
	    case 'b':
		do_backout = 1;
		break;
	    case 'E':
		if (nirt_debug & DEBUG_SCRIPTS)
		    show_scripts(&script_list, "before erasure");
		while (BU_LIST_WHILE(srp, script_rec, &script_list)) {
		    BU_LIST_DEQUEUE(&(srp->l));
		    free_script(srp);
		}
		if (nirt_debug & DEBUG_SCRIPTS)
		    show_scripts(&script_list, "after erasure");
		break;
	    case 'e':
		enqueue_script(&script_list, READING_STRING, bu_optarg);
		if (nirt_debug & DEBUG_SCRIPTS)
		    show_scripts(&script_list, "after enqueueing a literal");
		break;
	    case 'f':
		enqueue_script(&script_list, READING_FILE, bu_optarg);
		if (nirt_debug & DEBUG_SCRIPTS)
		    show_scripts(&script_list, "after enqueueing a file name");
		break;
	    case 'L':
		listformats();
		bu_exit(EXIT_SUCCESS, NULL);
	    case 'M':
		mat_flag = 1;
		break;
	    case 'O':
		sscanf(bu_optarg, "%1024s", ocastring);
		break;
	    case 's':
		silent_flag = SILENT_YES;	/* Positively yes */
		break;
	    case 'v':
		silent_flag = SILENT_NO;	/* Positively no */
		break;
	    case 'x':
		sscanf(bu_optarg, "%x", (unsigned int *)&RTG.debug);
		break;
	    case 'X':
		sscanf(bu_optarg, "%x", (unsigned int *)&nirt_debug);
		break;
	    case 'u':
		if (sscanf(bu_optarg, "%d", &use_of_air) != 1) {
		    (void) fprintf(stderr,
				   "Illegal use-air specification: '%s'\n", bu_optarg);
		    return 1;
		}
		break;
	    case 'H':
		if (sscanf(bu_optarg, "%d", &print_ident_flag) != 1) {
		    (void) fprintf(stderr,
				   "Illegal header output option specified: '%s'\n", bu_optarg);
		    return 1;
		}
		break;
	    default:
		printusage();
		bu_exit (Ch != 'h', NULL);
	}
    } /* end while getopt */

    if (argc - bu_optind < 2) {
	printusage();
	return 1;
    }

    if (isatty(0)) {
	if (silent_flag != SILENT_YES)
	    silent_flag = SILENT_NO;
    } else {
	/* stdin is not a TTY */
	if (silent_flag != SILENT_NO)
	    silent_flag = SILENT_YES;
    }
    if (silent_flag != SILENT_YES && print_ident_flag)
	(void) fputs(brlcad_ident("Natalie's Interactive Ray Tracer"), stdout);

    if (use_of_air && (use_of_air != 1)) {
	fprintf(stderr,
		"Warning: useair=%d specified, will set to 1\n", use_of_air);
	use_of_air = 1;
    }

    switch (*ocastring) {
	case '\0':
	    overlap_claims = OVLP_RESOLVE;
	    break;
	case '0':
	case '1':
	case '2':
	case '3':
	    if (ocastring[1] == '\0') {
		sscanf(ocastring, "%d", &overlap_claims);
	    } else {
		fprintf(stderr,
			"Illegal overlap_claims specification: '%s'\n", ocastring);
		return 1;
	    }
	    break;
	case 'r':
	    if (BU_STR_EQUAL(ocastring, "resolve"))
		overlap_claims = OVLP_RESOLVE;
	    else if (BU_STR_EQUAL(ocastring, "rebuild_fastgen"))
		overlap_claims = OVLP_REBUILD_FASTGEN;
	    else if (BU_STR_EQUAL(ocastring, "rebuild_all"))
		overlap_claims = OVLP_REBUILD_ALL;
	    else if (BU_STR_EQUAL(ocastring, "retain"))
		overlap_claims = OVLP_RETAIN;
	    else {
		fprintf(stderr,
			"Illegal overlap_claims specification: '%s'\n", ocastring);
		return 1;
	    }
	    break;
	default:
	    fprintf(stderr,
		    "Illegal overlap_claims specification: '%s'\n", ocastring);
	    return 1;
    }

    db_name = argv[bu_optind];

    /* build directory for target object */
    if (silent_flag != SILENT_YES) {
	printf("Database file:  '%s'\n", db_name);
	printf("Building the directory...");
    }
    if ((rtip = rt_dirbuild(db_name, db_title, TITLE_LEN)) == RTI_NULL) {
	fflush(stdout);
	fprintf(stderr, "Could not load file %s\n", db_name);
	return 1;
    }

    rti_tab[use_of_air] = rtip;
    rti_tab[1 - use_of_air] = RTI_NULL;
    rtip->useair = use_of_air;
    rtip->rti_save_overlaps = (overlap_claims > 0);

    ++bu_optind;
    do_rt_gettrees(rtip, argv + bu_optind, argc - bu_optind, &need_prep);

    /* Initialize the table of resource structures */
    rt_init_resource(&res_tab, 0, rtip);

    /* initialization of the application structure */
    RT_APPLICATION_INIT(&ap);
    ap.a_hit = if_hit;        /* branch to if_hit routine */
    ap.a_miss = if_miss;      /* branch to if_miss routine */
    ap.a_overlap = if_overlap;/* branch to if_overlap routine */
    ap.a_logoverlap = rt_silent_logoverlap;
    ap.a_onehit = 0;          /* continue through shotline after hit */
    ap.a_resource = &res_tab;
    ap.a_purpose = "NIRT ray";
    ap.a_rt_i = rtip;         /* rt_i pointer */
    ap.a_zero1 = 0;           /* sanity check, sayth raytrace.h */
    ap.a_zero2 = 0;           /* sanity check, sayth raytrace.h */
    ap.a_uptr = (void *)a_tab.attrib;

    /* initialize variables */
    azimuth() = 0.0;
    elevation() = 0.0;
    direct(X) = -1.0;
    direct(Y) = 0.0;
    direct(Z) = 0.0;
    grid(HORZ) = 0.0;
    grid(VERT) = 0.0;
    grid(DIST) = 0.0;
    grid2targ();
    set_diameter(rtip);

    /* initialize the output specification */
    default_ospec();

    /* initialize NIRT's local units */
    base2local = rtip->rti_dbip->dbi_base2local;
    local2base = rtip->rti_dbip->dbi_local2base;
    tmp_str = bu_units_string(local2base);
    if (tmp_str) {
	bu_strlcpy(local_u_name, tmp_str, sizeof(local_u_name));
    } else {
	bu_strlcpy(local_u_name, "Unknown units", sizeof(local_u_name));
    }

    if (silent_flag != SILENT_YES) {
	printf("Database title: '%s'\n", db_title);
	printf("Database units: '%s'\n", local_u_name);
	printf("model_min = (%g, %g, %g)    model_max = (%g, %g, %g)\n",
	       rtip->mdl_min[X] * base2local,
	       rtip->mdl_min[Y] * base2local,
	       rtip->mdl_min[Z] * base2local,
	       rtip->mdl_max[X] * base2local,
	       rtip->mdl_max[Y] * base2local,
	       rtip->mdl_max[Z] * base2local);
    }

    /* Run the run-time configuration file, if it exists */
    if ((fPtr = fopenrc()) != NULL) {
	interact(READING_FILE, fPtr, rtip);
	fclose(fPtr);
    }

    /* Run all scripts specified on the command line */
    run_scripts(&script_list, rtip);

    /* Perform the user interface */
    if (mat_flag) {
	read_mat(rtip);
	return 0;
    } else {
	interact(READING_FILE, stdin, rtip);
    }

    return 0;
}
HIDDEN int
_rt_generate_points(int **faces, int *num_faces, point_t **points, int *num_pnts, struct bu_ptbl *hit_pnts, struct db_i *dbip, const char *obj, fastf_t delta)
{
    int i, dir1, j;
    point_t min, max;
    int ncpus = bu_avail_cpus();
    struct rt_parallel_container *state;
    struct bu_vls vlsstr;
    bu_vls_init(&vlsstr);

    if (!hit_pnts || !dbip || !obj) return -1;

    BU_GET(state, struct rt_parallel_container);

    state->rtip = rt_new_rti(dbip);
    state->delta = delta;

    if (rt_gettree(state->rtip, obj) < 0) return -1;
    rt_prep_parallel(state->rtip, 1);

    state->resp = (struct resource *)bu_calloc(ncpus+1, sizeof(struct resource), "resources");
    for (i = 0; i < ncpus+1; i++) {
	rt_init_resource(&(state->resp[i]), i, state->rtip);
    }

    state->npts = (struct rt_point_container *)bu_calloc(ncpus+1, sizeof(struct rt_point_container), "point container arrays");
    int n[3];
    VMOVE(min, state->rtip->mdl_min);
    VMOVE(max, state->rtip->mdl_max);
    for (i = 0; i < 3; i++) {
	n[i] = (int)((max[i] - min[i])/state->delta) + 2;
	if(n[i] < 12) n[i] = 12;
    }
    int total = 0;
    for (i = 0; i < 3; i++) total += n[i]*n[(i+1)%3];
    if (total > 1e6) total = 1e6;
    for (i = 0; i < ncpus+1; i++) {
	state->npts[i].pts = (struct npoints *)bu_calloc(total, sizeof(struct npoints), "npoints arrays");
	state->npts[i].pnt_cnt = 0;
	state->npts[i].capacity = total;
    }

    for (dir1 = 0; dir1 < 3; dir1++) {
	state->ray_dir = dir1;
	state->ncpus = ncpus;
	state->delta = delta;
	bu_parallel(_rt_gen_worker, ncpus, (void *)state);
    }

    int out_cnt = 0;
    for (i = 0; i < ncpus+1; i++) {
	bu_log("%d, pnt_cnt: %d\n", i, state->npts[i].pnt_cnt);
	for (j = 0; j < state->npts[i].pnt_cnt; j++) {
	    struct npoints *npt = &(state->npts[i].pts[j]);
	    if (npt->in.is_set) out_cnt++;
	    if (npt->out.is_set) out_cnt++;
	}
    }

    struct rt_vert **rt_verts = (struct rt_vert **)bu_calloc(out_cnt, sizeof(struct rt_vert *), "output array");
    int curr_ind = 0;
    for (i = 0; i < ncpus+1; i++) {
	for (j = 0; j < state->npts[i].pnt_cnt; j++) {
	    struct npoints *npt = &(state->npts[i].pts[j]);
	    if (npt->in.is_set) {
		rt_verts[curr_ind] = &(npt->in);
		curr_ind++;
	    }
	    if (npt->out.is_set) {
		rt_verts[curr_ind] = &(npt->out);
		curr_ind++;
	    }
	}
    }

    struct spr_options opts = SPR_OPTIONS_DEFAULT_INIT;
    (void)spr_surface_build(faces, num_faces, (double **)points, num_pnts, (const struct cvertex **)rt_verts, out_cnt, &opts);

    return 0;
}
예제 #9
0
파일: g-dxf.c 프로젝트: kanzure/brlcad
/**
 * This is the gist for what is going on (not verified):
 *
 * 1. initialize tree_state (db_tree_state)
 * 2. Deal with command line arguments. Strip off everything but regions for processing.
 * 3. Open geometry (.g) file and build directory db_dirbuild
 * 4. db_walk_tree (get_layer) for layer names only
 * 5. Initialize tree_state
 * 6. Initialize model (nmg)\
 * 7. db_walk_tree (gcv_region_end)
 * 8. Cleanup
 */
int
main(int argc, char *argv[])
{
    int c;
    double percent;

    bu_setlinebuf(stderr);

    tree_state = rt_initial_tree_state;	/* struct copy */
    tree_state.ts_tol = &tol;
    tree_state.ts_ttol = &ttol;
    tree_state.ts_m = &the_model;

    /* Set up tessellation tolerance defaults */
    ttol.magic = RT_TESS_TOL_MAGIC;
    /* Defaults, updated by command line options. */
    ttol.abs = 0.0;
    ttol.rel = 0.01;
    ttol.norm = 0.0;

    /* Set up calculation tolerance defaults */
    /* FIXME: These need to be improved */
    tol.magic = BN_TOL_MAGIC;
    tol.dist = 0.0005;
    tol.dist_sq = tol.dist * tol.dist;
    tol.perp = 1e-6;
    tol.para = 1 - tol.perp;

    /* init resources we might need */
    rt_init_resource(&rt_uniresource, 0, NULL);

    BU_LIST_INIT(&RTG.rtg_vlfree);	/* for vlist macros */

    /* Get command line arguments. */
    while ((c = bu_getopt(argc, argv, "a:n:o:pr:vx:D:P:X:ih?")) != -1) {
	switch (c) {
	    case 'a':		/* Absolute tolerance. */
		ttol.abs = atof(bu_optarg);
		ttol.rel = 0.0;
		break;
	    case 'n':		/* Surface normal tolerance. */
		ttol.norm = atof(bu_optarg);
		ttol.rel = 0.0;
		break;
	    case 'o':		/* Output file name. */
		output_file = bu_optarg;
		break;
	    case 'p':
		polyface_mesh = 1;
		break;
	    case 'r':		/* Relative tolerance. */
		ttol.rel = atof(bu_optarg);
		break;
	    case 'v':
		verbose++;
		break;
	    case 'P':
		ncpu = atoi(bu_optarg);
		break;
	    case 'x':
		sscanf(bu_optarg, "%x", (unsigned int *)&RTG.debug);
		break;
	    case 'D':
		tol.dist = atof(bu_optarg);
		tol.dist_sq = tol.dist * tol.dist;
		rt_pr_tol(&tol);
		break;
	    case 'X':
		sscanf(bu_optarg, "%x", (unsigned int *)&RTG.NMG_debug);
		NMG_debug = RTG.NMG_debug;
		break;
	    case 'i':
		inches = 1;
		break;
	    default:
		usage(argv[0]);
		bu_exit(1, "%s\n", brlcad_ident("BRL-CAD to DXF Exporter"));
		break;
	}
    }

    if (bu_optind+1 >= argc) {
	usage(argv[0]);
	bu_exit(1, "%s\n", brlcad_ident("BRL-CAD to DXF Exporter"));
    }

    if (!output_file) {
	fp = stdout;
	setmode(fileno(fp), O_BINARY);
    } else {
	/* Open output file */
	if ((fp=fopen(output_file, "w+b")) == NULL) {
	    perror(argv[0]);
	    bu_exit(1, " Cannot open output file (%s) for writing\n", output_file);
	}
    }

    /* Open BRL-CAD database */
    argc -= bu_optind;
    argv += bu_optind;
    if ((dbip = db_open(argv[0], DB_OPEN_READONLY)) == DBI_NULL) {
	perror(argv[0]);
	bu_exit(1, "Unable to open geometry database file (%s)\n", argv[0]);
    }

    if (db_dirbuild(dbip)) {
	bu_exit(1, "db_dirbuild failed\n");
    }

    BN_CK_TOL(tree_state.ts_tol);
    RT_CK_TESS_TOL(tree_state.ts_ttol);

    if (verbose) {
	int i;

	bu_log("Model: %s\n", argv[0]);
	bu_log("Objects:");
	for (i = 1; i < argc; i++)
	    bu_log(" %s", argv[i]);
	bu_log("\nTessellation tolerances:\n\tabs = %g mm\n\trel = %g\n\tnorm = %g\n",
		tree_state.ts_ttol->abs, tree_state.ts_ttol->rel, tree_state.ts_ttol->norm);
	bu_log("Calculational tolerances:\n\tdist = %g mm perp = %g\n",
		tree_state.ts_tol->dist, tree_state.ts_tol->perp);
    }

    /* output DXF header and start of TABLES section */
    fprintf(fp,
	    "0\nSECTION\n2\nHEADER\n999\n%s\n0\nENDSEC\n0\nSECTION\n2\nTABLES\n0\nTABLE\n2\nLAYER\n",
	    argv[argc-1]);

    /* Walk indicated tree(s) just for layer names to put in TABLES section */
    (void)db_walk_tree(dbip, argc-1, (const char **)(argv+1),
		       1,			/* ncpu */
		       &tree_state,
		       0,			/* take all regions */
		       get_layer,
		       NULL,
		       (void *)NULL);	/* in librt/nmg_bool.c */

    /* end of layers section, start of ENTITIES SECTION */
    fprintf(fp, "0\nENDTAB\n0\nENDSEC\n0\nSECTION\n2\nENTITIES\n");

    /* Walk indicated tree(s).  Each region will be output separately */
    tree_state = rt_initial_tree_state;	/* struct copy */
    tree_state.ts_tol = &tol;
    tree_state.ts_ttol = &ttol;
    /* make empty NMG model */
    the_model = nmg_mm();
    tree_state.ts_m = &the_model;
    (void) db_walk_tree(dbip, argc-1, (const char **)(argv+1),
			1,			/* ncpu */
			&tree_state,
			0,			/* take all regions */
			gcv_region_end,
			nmg_booltree_leaf_tess,
			(void *)&gcvwriter);	/* callback for gcv_region_end */

    percent = 0;
    if (regions_tried>0) {
	percent = ((double)regions_converted * 100) / regions_tried;
	if (verbose)
	    bu_log("Tried %d regions, %d converted to NMG's successfully.  %g%%\n",
		   regions_tried, regions_converted, percent);
    }
    percent = 0;

    if (regions_tried > 0) {
	percent = ((double)regions_written * 100) / regions_tried;
	if (verbose)
	    bu_log("                  %d triangulated successfully. %g%%\n",
		    regions_written, percent);
    }

    bu_log("%ld triangles written\n", (long int)tot_polygons);

    fprintf(fp, "0\nENDSEC\n0\nEOF\n");

    if (output_file) {
	fclose(fp);
    }

    /* Release dynamic storage */
    nmg_km(the_model);
    rt_vlist_cleanup();
    db_close(dbip);

    return 0;
}