Ejemplo n.º 1
0
/*
 * Gets the output from bu_log and appends it to clientdata vls.
 */
static int
output_catch(void *clientdata, void *str)
{
    struct bu_vls *vp = (struct bu_vls *)clientdata;
    int len;

    BU_CK_VLS(vp);
    len = bu_vls_strlen(vp);
    bu_vls_strcat(vp, (const char *)str);
    len = bu_vls_strlen(vp) - len;

    return len;
}
Ejemplo n.º 2
0
HIDDEN int
extract_format_prefix(struct bu_vls *format, const char *input)
{
    struct bu_vls wformat = BU_VLS_INIT_ZERO;
    char *colon_pos = NULL;
    char *inputcpy = NULL;
    if (UNLIKELY(!input)) return 0;
    inputcpy = bu_strdup(input);
    colon_pos = strchr(inputcpy, ':');
    if (colon_pos) {
	int ret = 0;
	bu_vls_sprintf(&wformat, "%s", input);
	bu_vls_trunc(&wformat, -1 * strlen(colon_pos));
	if (bu_vls_strlen(&wformat) > 0) {
	    ret = 1;
	    if (format) bu_vls_sprintf(format, "%s", bu_vls_addr(&wformat));
	}
	bu_vls_free(&wformat);
	if (inputcpy) bu_free(inputcpy, "input copy");
	return ret;
    } else {
	if (inputcpy) bu_free(inputcpy, "input copy");
	return 0;
    }
    /* Shouldn't get here */
    return 0;
}
Ejemplo n.º 3
0
int
wdb_track_cmd(void *data,
	      int argc,
	      const char *argv[])
{
    struct bu_vls log_str = BU_VLS_INIT_ZERO;
    struct rt_wdb *wdbp = (struct rt_wdb *)data;
    int retval;

    if (argc != 15) {
	bu_log("ERROR: expecting 15 arguments\n");
	return TCL_ERROR;
    }

    retval = _ged_track(&log_str, wdbp, argv);

    if (bu_vls_strlen(&log_str) > 0) {
	bu_log("%s", bu_vls_addr(&log_str));
    }

    switch (retval) {
	case GED_OK:
	    return TCL_OK;
	case GED_ERROR:
	    return TCL_ERROR;
    }

    /* This should never happen */
    return TCL_ERROR;
}
Ejemplo n.º 4
0
HIDDEN void
reassemble_argstr(struct bu_vls *instr, struct bu_vls *outstr, option::Option *unknowns)
{
    for (option::Option* opt = unknowns; opt; opt = opt->next()) {
	int input_only = 0;
	int output_only = 0;
	char *inputcpy = NULL;
	if (!instr || !outstr) return;
	inputcpy = bu_strdup(opt->name);
	if (!bu_strncmp(inputcpy, "--in-", 5)) input_only = 1;
	if (!bu_strncmp(inputcpy, "--out-", 5)) output_only = 1;
	char *equal_pos = strchr(inputcpy, '=');
	if (equal_pos) {
	    struct bu_vls vopt = BU_VLS_INIT_ZERO;
	    struct bu_vls varg = BU_VLS_INIT_ZERO;
	    bu_vls_sprintf(&vopt, "%s", inputcpy);
	    bu_vls_trunc(&vopt, -1 * strlen(equal_pos));
	    bu_vls_sprintf(&varg, "%s", inputcpy);
	    bu_vls_nibble(&varg, strlen(inputcpy) - strlen(equal_pos) + 1);
	    if (!output_only) {
		(bu_vls_strlen(&vopt) == 1) ? bu_vls_printf(instr, "-%s ", bu_vls_addr(&vopt)) : bu_vls_printf(instr, "%s ", bu_vls_addr(&vopt));
		if (bu_vls_strlen(&varg)) bu_vls_printf(instr, "%s ", bu_vls_addr(&varg));
	    }
	    if (!input_only) {
		(bu_vls_strlen(&vopt) == 1) ? bu_vls_printf(outstr, "-%s ", bu_vls_addr(&vopt)) : bu_vls_printf(outstr, "%s ", bu_vls_addr(&vopt));
		if (bu_vls_strlen(&varg)) bu_vls_printf(outstr, "%s ", bu_vls_addr(&varg));
	    }
	    bu_vls_free(&vopt);
	    bu_vls_free(&varg);
	} else {
	    if (!output_only) {
		(strlen(opt->name) == 1) ? bu_vls_printf(instr, "-%s ", opt->name) : bu_vls_printf(instr, "%s ", opt->name);
		if (opt->arg) bu_vls_printf(instr, "%s ", opt->arg);
	    }
	    if (!input_only) {
		(strlen(opt->name) == 1) ? bu_vls_printf(outstr, "-%s ", opt->name) : bu_vls_printf(outstr, "%s ", opt->name);
		if (opt->arg) bu_vls_printf(outstr, "%s ", opt->arg);
	    }
	}
	bu_free(inputcpy, "input cpy");
    }
}
Ejemplo n.º 5
0
/**
 * Checks for the existence of a specified object.
 */
int
ged_exists(struct ged *gedp, int argc, const char *argv_orig[])
{
    /* struct directory *dp;*/
    static const char *usage = "object";
    struct exists_data ed;
    struct bu_vls message = BU_VLS_INIT_ZERO;
    int result;
    char **argv = bu_dup_argv(argc, argv_orig);

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);

    /* initialize result */
    bu_vls_trunc(gedp->ged_result_str, 0);

    /* must be wanting help */
    if (argc == 1) {
        bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv_orig[0], usage);
        return GED_HELP;
    }
    /*
      if (argc != 2) {
      bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv_orig[0], usage);
      return GED_ERROR;
      }
    */

    ed.t_wp = &argv[1];
    ed.gedp = gedp;
    ed.t_wp_op = NULL;
    ed.message = &message;
    result = oexpr(t_lex(*(ed.t_wp), &ed), &ed);

    if (result)
        bu_vls_printf(gedp->ged_result_str, "1");
    else
        bu_vls_printf(gedp->ged_result_str, "0");

    if (bu_vls_strlen(ed.message) > 0) {
        bu_vls_printf(gedp->ged_result_str, "%s", bu_vls_addr(ed.message));
        bu_vls_free(&message);
        return GED_ERROR;
    }

    bu_vls_free(&message);
    if (*(ed.t_wp) != NULL && *++(ed.t_wp) != NULL) {
        return GED_ERROR;
    } else {
        return GED_OK;
    }
}
Ejemplo n.º 6
0
HIDDEN int
txt_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip)
{
    register struct txt_specific *tp;
    int pixelbytes = 3;

    BU_CK_VLS(matparm);
    BU_GET(tp, struct txt_specific);
    *dpp = tp;

    bu_vls_init(&tp->tx_name);

    /* defaults */
    tp->tx_w = tp->tx_n = -1;
    tp->tx_trans_valid = 0;
    tp->tx_scale[X] = 1.0;
    tp->tx_scale[Y] = 1.0;
    tp->tx_mirror = 0;
    tp->tx_datasrc = 0; /* source is auto-located by default */
    tp->tx_binunifp = NULL;
    tp->tx_mp = NULL;

    /* load given values */
    if (bu_struct_parse(matparm, txt_parse, (char *)tp) < 0) {
	BU_PUT(tp, struct txt_specific);
	return -1;
    }

    /* validate values */
    if (tp->tx_w < 0) tp->tx_w = 512;
    if (tp->tx_n < 0) tp->tx_n = tp->tx_w;
    if (tp->tx_trans_valid) rp->reg_transmit = 1;
    BU_CK_VLS(&tp->tx_name);
    if (bu_vls_strlen(&tp->tx_name) <= 0) return -1;
    /* !?! if (tp->tx_name[0] == '\0') return -1;	*/ /* FAIL, no file */

    if (BU_STR_EQUAL(mfp->mf_name, "bwtexture")) pixelbytes = 1;

    /* load the texture from its datasource */
    if (txt_load_datasource(tp, rtip->rti_dbip, tp->tx_w * tp->tx_n * pixelbytes)<0) {
	bu_log("\nERROR: txt_setup() %s %s could not be loaded [source was %s]\n", rp->reg_name, bu_vls_addr(&tp->tx_name), tp->tx_datasrc==TXT_SRC_OBJECT?"object":tp->tx_datasrc==TXT_SRC_FILE?"file":"auto");
	return -1;
    }


    if (rdebug & RDEBUG_SHADE) {
	bu_log("txt_setup: texture loaded!  type=%s name=%s\n", tp->tx_datasrc==TXT_SRC_AUTO?"auto":tp->tx_datasrc==TXT_SRC_OBJECT?"object":tp->tx_datasrc==TXT_SRC_FILE?"file":"unknown", bu_vls_addr(&tp->tx_name));
	bu_struct_print("texture", txt_parse, (char *)tp);
    }

    return 1;				/* OK */
}
Ejemplo n.º 7
0
/**
 * Export an REVOLVE from internal form to external format.  Note that
 * this means converting all integers to Big-Endian format and
 * floating point data to IEEE double.
 *
 * Apply the transformation to mm units as well.
 */
int
rt_revolve_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
{
    struct rt_revolve_internal *rip;

    /* must be double for import and export */
    double vec[ELEMENTS_PER_VECT*3 + 1];

    unsigned char *ptr;

    if (dbip) RT_CK_DBI(dbip);

    RT_CK_DB_INTERNAL(ip);
    if (ip->idb_type != ID_REVOLVE) return -1;
    rip = (struct rt_revolve_internal *)ip->idb_ptr;
    RT_REVOLVE_CK_MAGIC(rip);

    BU_CK_EXTERNAL(ep);
    ep->ext_nbytes = SIZEOF_NETWORK_DOUBLE * (ELEMENTS_PER_VECT*3 + 1) + bu_vls_strlen(&rip->sketch_name) + 1;
    ep->ext_buf = (uint8_t *)bu_calloc(1, ep->ext_nbytes, "revolve external");

    ptr = (unsigned char *)ep->ext_buf;

    /* Since libwdb users may want to operate in units other than mm,
     * we offer the opportunity to scale the solid (to get it into mm)
     * on the way out.
     */
    VSCALE(&vec[0*3], rip->v3d, local2mm);
    VSCALE(&vec[1*3], rip->axis3d, local2mm);
    VSCALE(&vec[2*3], rip->r, local2mm);
    vec[9] = rip->ang;

    bu_cv_htond(ptr, (unsigned char *)vec, ELEMENTS_PER_VECT*3 + 1);
    ptr += (ELEMENTS_PER_VECT*3 + 1) * SIZEOF_NETWORK_DOUBLE;

    bu_strlcpy((char *)ptr, bu_vls_addr(&rip->sketch_name), bu_vls_strlen(&rip->sketch_name) + 1);

    return 0;
}
Ejemplo n.º 8
0
/**
 * b u _ v l s _ t r i m s p a c e
 *
 * Remove leading and trailing white space from a vls string.
 */
void
bu_vls_trimspace( struct bu_vls *vp )
{
    BU_CK_VLS(vp);

    /* Remove trailing white space */
    while ( isspace( bu_vls_addr(vp)[bu_vls_strlen(vp)-1] ) )
	bu_vls_trunc( vp, -1 );

    /* Remove leading white space */
    while ( isspace( *bu_vls_addr(vp) ) )
	bu_vls_nibble( vp, 1 );
}
Ejemplo n.º 9
0
/**
 * b u _ v l s _ s t r d u p
 *
 * Make an "ordinary" string copy of a vls string.  Storage for the
 * regular string is acquired using malloc.
 *
 * The source string is not affected.
 */
char *
bu_vls_strdup(register const struct bu_vls *vp)
{
    register char *str;
    register size_t len;

    BU_CK_VLS(vp);

    len = bu_vls_strlen(vp);
    str = bu_malloc(len+1, bu_strdup_message );
    strncpy(str, bu_vls_addr(vp), len);
    str[len] = '\0'; /* sanity */
    return str;
}
Ejemplo n.º 10
0
/* Test for bu_vls_encode/bu_vls_decode for reversibility:
 *
 *   1. encode the input string
 *   2. decode the encoded string
 *   3. decoded string should be the same as input
 *
 */
int
test_encode(const char *str)
{
    int status = 0;
    int len_s = str ? strlen(str) : 0;
    int len_d = 0; /* for length of decoded */
    int f_wid = 28; /* desired total field width */
    struct bu_vls encoded = BU_VLS_INIT_ZERO;
    struct bu_vls decoded = BU_VLS_INIT_ZERO;

    bu_vls_encode(&encoded, str);
    bu_vls_decode(&decoded, bu_vls_addr(&encoded)); /* should be same as input string */

    len_d = bu_vls_strlen(&decoded);
    if (f_wid < len_s)
	f_wid = len_s + 1;
    if (f_wid < len_d)
	f_wid = len_d + 1;

    if (BU_STR_EQUAL(str, bu_vls_addr(&decoded))
	/* && !BU_STR_EQUAL(str, bu_vls_addr(&encoded)) */
	) {
	/* a hack for str showing '(null)' in printf if zero length */
	if (len_s == 0)
	    len_s = 6;
	printf("{%*s}%*s -> {%*s}%*s [PASS]\n",
	       len_s, str, f_wid - len_s, " ",
	       len_d, bu_vls_addr(&decoded), f_wid - len_d, " "
	       );
    } else {
	/* a hack for str showing '(null)' in printf if zero length */
	if (len_s == 0)
	    len_s = 6;
	printf("{%*s}%*s -> {%*s}%*s [FAIL]  (should be: {%s})\n",
	       len_s, str, f_wid - len_s, " ",
	       len_d, bu_vls_addr(&decoded), f_wid - len_d, " ",
	       str
	       );
	status = 1;
    }

    bu_vls_free(&encoded);
    bu_vls_free(&decoded);

    return status;
}
Ejemplo n.º 11
0
double
rt_read_timer(char *str, int len)
{
    struct bu_vls vls = BU_VLS_INIT_ZERO;
    double cpu;
    int todo;

    if (!str)
	return rt_get_timer((struct bu_vls *)0, (double *)0);

    cpu = rt_get_timer(&vls, (double *)0);
    todo = bu_vls_strlen(&vls);

    if (todo > len)
	todo = len;
    bu_strlcpy(str, bu_vls_addr(&vls), todo);

    return cpu;
}
Ejemplo n.º 12
0
int
main(int argc, char *argv[])
{
    int i, j;
    int db_index;
    int c;
    const char **av;
    struct ged *gedp;

    bu_opterr = 0;
    bu_optind = 1;

    /* Get past command line options. */
    while ((c = bu_getopt(argc, argv, "A:a:de:f:g:Gn:N:pP:qrS:t:U:u:vV:W:h?")) != -1) {
	switch (c) {
	    case 'A':
	    case 'a':
	    case 'e':
	    case 'd':
	    case 'f':
	    case 'g':
	    case 'G':
	    case 'n':
	    case 'N':
	    case 'p':
	    case 'P':
	    case 'q':
	    case 'r':
	    case 'S':
	    case 't':
	    case 'v':
	    case 'V':
	    case 'W':
	    case 'U':
	    case 'u':
		break;
	    default:
		bu_exit(1, usage, argv[0]);
		break;
	}
    }

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

    av = (const char **)bu_calloc(argc, sizeof(char *), "av");

    db_index = bu_optind;
    for (i = j = 0; i < argc; ++i) {
	if (i == db_index)
	    continue;

	av[j] = argv[i];
	++j;
    }
    av[j] = (char *)0;

    if ((gedp = ged_open("db", argv[db_index], 1)) == GED_NULL) {
	bu_free((void *)av, "av");
	bu_exit(1, usage, argv[0]);
    }

    (void)ged_gqa(gedp, j, av);
    if (bu_vls_strlen(gedp->ged_result_str) > 0)
	bu_log("%s", bu_vls_addr(gedp->ged_result_str));
    ged_close(gedp);
    if (gedp)
	BU_PUT(gedp, struct ged);

    bu_free((void *)av, "av");

    return 0;
}
Ejemplo n.º 13
0
void
db_update_nref( struct db_i *dbip, struct resource *resp )
{
    register int			i;
    register struct directory      *dp;
    struct rt_db_internal		intern;
    struct rt_comb_internal	       *comb;

    RT_CK_DBI( dbip );
    RT_CK_RESOURCE(resp);

    /* First, clear any existing counts */
    for ( i = 0; i < RT_DBNHASH; i++ )
	for ( dp = dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw )
	    dp->d_nref = 0;

    /* Examine all COMB nodes */
    for ( i = 0; i < RT_DBNHASH; i++ )  {
	for ( dp = dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw ) {

	    /* handle non-combination objects that reference other objects */
	    if ( dp->d_major_type == DB5_MAJORTYPE_BRLCAD ) {
		struct directory *dp2;

		if ( dp->d_minor_type == DB5_MINORTYPE_BRLCAD_EXTRUDE ) {
		    struct rt_extrude_internal *extr;

		    if ( rt_db_get_internal(&intern, dp, dbip, (fastf_t *)NULL, resp) < 0 )
			continue;
		    extr = (struct rt_extrude_internal *)intern.idb_ptr;
		    RT_EXTRUDE_CK_MAGIC( extr );
		    if ( extr->sketch_name ) {
			dp2 = db_lookup( dbip, extr->sketch_name, LOOKUP_QUIET );
			if ( dp2 != DIR_NULL ) {
			    dp2->d_nref++;
			}
		    }
		    rt_db_free_internal( &intern, resp );
		} else if ( dp->d_minor_type ==  DB5_MINORTYPE_BRLCAD_DSP ) {
		    struct rt_dsp_internal *dsp;

		    if ( rt_db_get_internal(&intern, dp, dbip, (fastf_t *)NULL, resp) < 0 )
			continue;
		    dsp = (struct rt_dsp_internal *)intern.idb_ptr;
		    RT_DSP_CK_MAGIC( dsp );
		    if ( dsp->dsp_datasrc == RT_DSP_SRC_OBJ && bu_vls_strlen( &dsp->dsp_name) > 0 ) {
			dp2 = db_lookup( dbip, bu_vls_addr( &dsp->dsp_name ), LOOKUP_QUIET );
			if ( dp2 != DIR_NULL ) {
			    dp2->d_nref++;
			}
		    }
		    rt_db_free_internal( &intern, resp );
		}
	    }
	    if ( !(dp->d_flags & DIR_COMB) )
		continue;
	    if ( rt_db_get_internal(&intern, dp, dbip, (fastf_t *)NULL, resp) < 0 )
		continue;
	    if ( intern.idb_type != ID_COMBINATION )  {
		bu_log("NOTICE: %s was marked a combination, but isn't one?  Clearing flag\n",
		       dp->d_namep);
		dp->d_flags &= ~DIR_COMB;
		rt_db_free_internal( &intern, resp );
		continue;
	    }
	    comb = (struct rt_comb_internal *)intern.idb_ptr;
	    db_tree_funcleaf( dbip, comb, comb->tree,
			      db_count_refs, (genptr_t)NULL,
			      (genptr_t)NULL, (genptr_t)NULL );
	    rt_db_free_internal( &intern, resp );
	}
    }
}
Ejemplo n.º 14
0
/**
 * Called at the start of a run.
 *
 * Returns 1 if framebuffer should be opened, else 0.
 */
int
view_init(struct application *ap, char *file, char *UNUSED(obj), int minus_o, int minus_F)
{
    /*
     * Allocate a scanline for each processor.
     */
    ap->a_hit = rayhit;
    ap->a_miss = raymiss;
    ap->a_onehit = 1;

    /*
     * Does the user want occlusion checking?
     *
     * If so, load and prep.
     */
    if (bu_vls_strlen(&occlusion_objects) != 0) {
	struct db_i *dbip;
	int nObjs;
	const char **objs;
	int i;

	bu_log("rtedge: loading occlusion geometry from %s.\n", file);

	if (Tcl_SplitList(NULL, bu_vls_addr(&occlusion_objects), &nObjs,
			  &objs) == TCL_ERROR) {
	    bu_log("rtedge: occlusion list = %s\n",
		   bu_vls_addr(&occlusion_objects));
	    bu_exit(EXIT_FAILURE, "rtedge: could not parse occlusion objects list.\n");
	}

	for (i=0; i<nObjs; ++i) {
	    bu_log("rtedge: occlusion object %d = %s\n", i, objs[i]);
	}


	if ((dbip = db_open(file, DB_OPEN_READONLY)) == DBI_NULL)
	    bu_exit(EXIT_FAILURE, "rtedge: could not open geometry database file %s.\n", file);
	RT_CK_DBI(dbip);

#if 0
	/* FIXME: calling this when db_open()'s mapped file doesn't
	 * fail will cause duplicate directory entries.  need to make
	 * sure db_dirbuild rebuilds from scratch or only updates
	 * existing entries when they exist.
	 */
	if (db_dirbuild(dbip) < 0)
	    bu_exit(EXIT_FAILURE, "rtedge: could not read database.\n");
#endif

	occlusion_rtip = rt_new_rti(dbip); /* clones dbip */

	for (i=0; i < MAX_PSW; i++) {
	    rt_init_resource(&occlusion_resources[i], i, occlusion_rtip);
	    bn_rand_init(occlusion_resources[i].re_randptr, i);
	}

	db_close(dbip);			 /* releases original dbip */

	for (i=0; i<nObjs; ++i)
	    if (rt_gettree(occlusion_rtip, objs[i]) < 0)
		bu_log("rtedge: gettree failed for %s\n", objs[i]);
	    else
		bu_log("rtedge: got tree for object %d = %s\n", i, objs[i]);

	bu_log("rtedge: occlusion rt_gettrees done.\n");

	rt_prep(occlusion_rtip);

	bu_log("rtedge: occlusion prep done.\n");

	/*
	 * Create a set of application structures for the occlusion
	 * geometry. Need one per cpu, the upper half does the per-
	 * thread allocation in worker, but that's off limits.
	 */
	occlusion_apps = (struct application **)bu_calloc(npsw, sizeof(struct application *),
							  "occlusion application structure array");
	for (i=0; i<npsw; ++i) {
	    BU_ALLOC(occlusion_apps[i], struct application);
	    RT_APPLICATION_INIT(occlusion_apps[i]);

	    occlusion_apps[i]->a_rt_i = occlusion_rtip;
	    occlusion_apps[i]->a_resource = (struct resource *)BU_PTBL_GET(&occlusion_rtip->rti_resources, i);
	    occlusion_apps[i]->a_onehit = 1;
	    occlusion_apps[i]->a_hit = occlusion_hit;
	    occlusion_apps[i]->a_miss = occlusion_miss;
	    if (rpt_overlap)
		occlusion_apps[i]->a_logoverlap = (void (*)(struct application *, const struct partition *, const struct bu_ptbl *, const struct partition *))NULL;
	    else
		occlusion_apps[i]->a_logoverlap = rt_silent_logoverlap;

	}
	bu_log("rtedge: will perform occlusion testing.\n");

	/*
	 * If an inclusion mode has not been specified, use the default.
	 */
	if (occlusion_mode == OCCLUSION_MODE_NONE) {
	    occlusion_mode = OCCLUSION_MODE_DEFAULT;
	    bu_log("rtedge: occlusion mode = %d\n", occlusion_mode);
	}

	if ((occlusion_mode != OCCLUSION_MODE_NONE) &&
	    (overlay == OVERLAY_MODE_UNSET)) {
	    bu_log("rtedge: automagically activating overlay mode.\n");
	    overlay = OVERLAY_MODE_DOIT;
	}

    }

    if (occlusion_mode != OCCLUSION_MODE_NONE &&
	bu_vls_strlen(&occlusion_objects) == 0) {
	bu_exit(EXIT_FAILURE, "rtedge: occlusion mode set, but no objects were specified.\n");
    }

    /* if non-default/inverted background was requested, swap the
     * foreground and background colors.
     */
    if (!default_background) {
	color tmp;
	tmp[RED] = fgcolor[RED];
	tmp[GRN] = fgcolor[GRN];
	tmp[BLU] = fgcolor[BLU];
	fgcolor[RED] = bgcolor[RED];
	fgcolor[GRN] = bgcolor[GRN];
	fgcolor[BLU] = bgcolor[BLU];
	bgcolor[RED] = tmp[RED];
	bgcolor[GRN] = tmp[GRN];
	bgcolor[BLU] = tmp[BLU];
    }

    if (minus_o && (overlay || blend)) {
	/*
	 * Output is to a file stream.  Do not allow parallel
	 * processing since we can't seek to the rows.
	 */
	RTG.rtg_parallel = 0;
	bu_log("view_init: deactivating parallelism due to -o option.\n");
	/*
	 * The overlay and blend cannot be used in -o mode.  Note that
	 * the overlay directive takes precedence, they can't be used
	 * together.
	 */
	overlay = 0;
	blend = 0;
	bu_log("view_init: deactivating overlay and blending due to -o option.\n");
    }

    if (overlay)
	bu_log("view_init: will perform simple overlay.\n");
    else if (blend)
	bu_log("view_init: will perform blending.\n");

    return minus_F || (!minus_o && !minus_F); /* we need a framebuffer */
}
Ejemplo n.º 15
0
/*
 * 'make_pnts' command for importing point-cloud data into a 'pnts'
 * primitive.
 *
 * Input values:
 * argv[1] object name
 * argv[2] filename with path
 * argv[3] point data file format string
 * argv[4] point data file units string or conversion factor to millimeters
 * argv[5] default size of each point
 *
 */
int
ged_make_pnts(struct ged *gedp, int argc, const char *argv[])
{
    struct directory *dp;
    struct rt_db_internal internal;

    rt_pnt_type type;
    double local2base;
    unsigned long numPoints = 0;
    struct rt_pnts_internal *pnts;

    double defaultSize = 0.0;
    void *headPoint = NULL;

    FILE *fp;

    int temp_string_index = 0; /* index into temp_string, set to first character in temp_string, i.e. the start */
    unsigned long int num_doubles_read = 0; /* counters of double read from file */

    int current_character_double = 0; /* flag indicating if current character read is part of a double or delimiter */
    int previous_character_double = 0; /* flag indicating if previously read character was part of a double or delimiter */

    unsigned long int num_characters_read_from_file = 0;  /* counter of number of characters read from file */
    unsigned long int start_offset_of_current_double = 0; /* character offset from start of file for current double */
    int found_double = 0; /* flag indicating if double encountered in file and needs to be processed */
    int found_eof = 0; /* flag indicating if end-of-file encountered when reading file */
    int done_processing_format_string = 0; /* flag indicating if loop processing format string should be exited */

    char *temp_char_ptr = (char *)NULL;

    int buf = 0; /* raw character read from file */
    double temp_double = 0.0;
    char temp_string[1024];
    int temp_string_size = 1024;  /* number of characters that can be stored in temp_string including null terminator character */
    /* it is expected that the character representation of a double will never exceed this size string */
    char *endp = (char *)NULL;

    struct bu_vls format_string = BU_VLS_INIT_ZERO;
    size_t format_string_index = 0;

    unsigned int num_doubles_per_point = 0;

    void *point = NULL;

    char **prompt;

    static const char *usage = "point_cloud_name filename_with_path file_format file_data_units default_point_size";

    prompt = &p_make_pnts[0];

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);

    /* initialize result */
    bu_vls_trunc(gedp->ged_result_str, 0);

    if (argc > 6) {
        bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
        return GED_ERROR;
    }

    /* prompt for point-cloud name */
    if (argc < 2) {
        bu_vls_printf(gedp->ged_result_str, "%s", prompt[0]);
        return GED_MORE;
    }

    GED_CHECK_EXISTS(gedp, argv[1], LOOKUP_QUIET, GED_ERROR);

    /* prompt for data file name with path */
    if (argc < 3) {
        bu_vls_printf(gedp->ged_result_str, "%s", prompt[1]);
        return GED_MORE;
    }

    /* prompt for data file format */
    if (argc < 4) {
        bu_vls_printf(gedp->ged_result_str, "%s", prompt[2]);
        return GED_MORE;
    }

    /* Validate 'point file data format string' and return point-cloud type. */
    if (str2type(argv[3], &type, gedp->ged_result_str) == GED_ERROR) {
        return GED_ERROR;
    }

    /* prompt for data file units */
    if (argc < 5) {
        bu_vls_printf(gedp->ged_result_str, "%s", prompt[3]);
        return GED_MORE;
    }

    /* Validate the unit string and return conversion factor to millimeters. */
    if (str2mm(argv[4], &local2base, gedp->ged_result_str) == GED_ERROR) {
        return GED_ERROR;
    }

    /* prompt for default point size */
    if (argc < 6) {
        bu_vls_printf(gedp->ged_result_str, "%s", prompt[4]);
        return GED_MORE;
    }

    defaultSize = strtod(argv[5], &endp);
    if ((endp != argv[5]) && (*endp == '\0')) {
        /* convert to double success */
        if (defaultSize < 0.0) {
            bu_vls_printf(gedp->ged_result_str, "Default point size '%lf' must be non-negative.\n", defaultSize);
            return GED_ERROR;
        }
    } else {
        bu_vls_printf(gedp->ged_result_str, "Invalid default point size '%s'\n", argv[5]);
        return GED_ERROR;
    }

    bu_vls_strcat(&format_string, argv[3]);
    bu_vls_trimspace(&format_string);

    /* init database structure */
    RT_DB_INTERNAL_INIT(&internal);
    internal.idb_major_type = DB5_MAJORTYPE_BRLCAD;
    internal.idb_type = ID_PNTS;
    internal.idb_meth = &OBJ[ID_PNTS];
    BU_ALLOC(internal.idb_ptr, struct rt_pnts_internal);

    /* init internal structure */
    pnts = (struct rt_pnts_internal *) internal.idb_ptr;
    pnts->magic = RT_PNTS_INTERNAL_MAGIC;
    pnts->scale = defaultSize;
    pnts->type = type;
    pnts->count = numPoints;  /* set again later */
    pnts->point = NULL;

    /* empty list head */
    switch (type) {
    case RT_PNT_TYPE_PNT:
        BU_ALLOC(headPoint, struct pnt);
        BU_LIST_INIT(&(((struct pnt *)headPoint)->l));
        num_doubles_per_point = 3;
        break;
    case RT_PNT_TYPE_COL:
        BU_ALLOC(headPoint, struct pnt_color);
        BU_LIST_INIT(&(((struct pnt_color *)headPoint)->l));
        num_doubles_per_point = 6;
        break;
    case RT_PNT_TYPE_SCA:
        BU_ALLOC(headPoint, struct pnt_scale);
        BU_LIST_INIT(&(((struct pnt_scale *)headPoint)->l));
        num_doubles_per_point = 4;
        break;
    case RT_PNT_TYPE_NRM:
        BU_ALLOC(headPoint, struct pnt_normal);
        BU_LIST_INIT(&(((struct pnt_normal *)headPoint)->l));
        num_doubles_per_point = 6;
        break;
    case RT_PNT_TYPE_COL_SCA:
        BU_ALLOC(headPoint, struct pnt_color_scale);
        BU_LIST_INIT(&(((struct pnt_color_scale *)headPoint)->l));
        num_doubles_per_point = 7;
        break;
    case RT_PNT_TYPE_COL_NRM:
        BU_ALLOC(headPoint, struct pnt_color_normal);
        BU_LIST_INIT(&(((struct pnt_color_normal *)headPoint)->l));
        num_doubles_per_point = 9;
        break;
    case RT_PNT_TYPE_SCA_NRM:
        BU_ALLOC(headPoint, struct pnt_scale_normal);
        BU_LIST_INIT(&(((struct pnt_scale_normal *)headPoint)->l));
        num_doubles_per_point = 7;
        break;
    case RT_PNT_TYPE_COL_SCA_NRM:
        BU_ALLOC(headPoint, struct pnt_color_scale_normal);
        BU_LIST_INIT(&(((struct pnt_color_scale_normal *)headPoint)->l));
        num_doubles_per_point = 10;
        break;
    }
    BU_ASSERT_PTR(headPoint, !=, NULL);
    pnts->point = headPoint;

    if ((fp=fopen(argv[2], "rb")) == NULL) {
        bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]);
        bu_vls_printf(gedp->ged_result_str, "Could not open file '%s'.\n", argv[2]);
        bu_vls_free(&format_string);
        rt_db_free_internal(&internal);
        return GED_ERROR;
    }

    while (!found_eof) {
        /* points_loop */
        /* allocate memory for single point structure for current point-cloud type */
        switch (type) {
        case RT_PNT_TYPE_PNT:
            BU_ALLOC(point, struct pnt);
            break;
        case RT_PNT_TYPE_COL:
            BU_ALLOC(point, struct pnt_color);
            break;
        case RT_PNT_TYPE_SCA:
            BU_ALLOC(point, struct pnt_scale);
            break;
        case RT_PNT_TYPE_NRM:
            BU_ALLOC(point, struct pnt_normal);
            break;
        case RT_PNT_TYPE_COL_SCA:
            BU_ALLOC(point, struct pnt_color_scale);
            break;
        case RT_PNT_TYPE_COL_NRM:
            BU_ALLOC(point, struct pnt_color_normal);
            break;
        case RT_PNT_TYPE_SCA_NRM:
            BU_ALLOC(point, struct pnt_scale_normal);
            break;
        case RT_PNT_TYPE_COL_SCA_NRM:
            BU_ALLOC(point, struct pnt_color_scale_normal);
            break;
        }

        /* make sure we have something */
        BU_ASSERT_PTR(point, !=, NULL);

        while (!found_eof && !done_processing_format_string) {
            /* format_string_loop */
            char format = '\0';

            while (!found_eof  && !found_double) {
                /* find_doubles_loop */
                format = bu_vls_addr(&format_string)[format_string_index];

                buf = fgetc(fp);

                num_characters_read_from_file++;

                if (feof(fp)) {
                    if (ferror(fp)) {
                        perror("ERROR: Problem reading file, system error message");
                        fclose(fp);
                        bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]);
                        bu_vls_printf(gedp->ged_result_str, "Unable to read file at byte '%lu'.\n", num_characters_read_from_file);
                        bu_vls_free(&format_string);
                        rt_db_free_internal(&internal);
                        return GED_ERROR;
                    } else {
                        found_eof = 1;
                    }
                }

                if (found_eof) {
                    fclose(fp);
                    current_character_double = 0;
                    if (num_doubles_read == 0) {
                        bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]);
                        bu_vls_printf(gedp->ged_result_str, "No data in file '%s'.\n", argv[2]);
                        bu_vls_free(&format_string);
                        rt_db_free_internal(&internal);
                        return GED_ERROR;
                    }
                } else {
                    temp_char_ptr = strchr("0123456789.+-eE", buf);
                    if (temp_char_ptr != NULL) {
                        /* character read is part of a double */
                        current_character_double = 1;
                    } else {
                        current_character_double = 0;
                    }
                }

                if (previous_character_double && current_character_double) {
                    if (temp_string_index >= temp_string_size) {
                        fclose(fp);
                        bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]);
                        bu_vls_printf(gedp->ged_result_str, "String representing double too large, exceeds '%d' character limit. ", temp_string_size - 1);
                        report_import_error_location(num_doubles_read, num_doubles_per_point, start_offset_of_current_double,
                                                     format, gedp->ged_result_str);
                        bu_vls_free(&format_string);
                        rt_db_free_internal(&internal);
                        return GED_ERROR;
                    }
                    temp_string[temp_string_index] = (char)buf;
                    temp_string_index++;
                }

                if (previous_character_double && !current_character_double) {
                    if (temp_string_index >= temp_string_size) {
                        fclose(fp);
                        bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]);
                        bu_vls_printf(gedp->ged_result_str, "String representing double too large, exceeds '%d' character limit. ", temp_string_size - 1);
                        report_import_error_location(num_doubles_read, num_doubles_per_point, start_offset_of_current_double,
                                                     format, gedp->ged_result_str);
                        bu_vls_free(&format_string);
                        rt_db_free_internal(&internal);
                        return GED_ERROR;
                    }
                    temp_string[temp_string_index] = '\0';

                    /* do not convert string to double for format character '?' */
                    if (format != '?') {
                        temp_double = strtod(temp_string, &endp);
                        if (!((endp != temp_string) && (*endp == '\0'))) {
                            fclose(fp);
                            bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]);
                            bu_vls_printf(gedp->ged_result_str, "Unable to convert string '%s' to double. ", temp_string);
                            report_import_error_location(num_doubles_read, num_doubles_per_point, start_offset_of_current_double,
                                                         format, gedp->ged_result_str);
                            bu_vls_free(&format_string);
                            rt_db_free_internal(&internal);
                            return GED_ERROR;
                        }
                        num_doubles_read++;
                    } else {
                        temp_double = 0.0;
                    }

                    temp_string_index = 0;
                    found_double = 1;
                    previous_character_double = current_character_double;
                }

                if (!previous_character_double && current_character_double) {
                    temp_string[temp_string_index] = (char)buf;
                    temp_string_index++;
                    start_offset_of_current_double = num_characters_read_from_file;
                    previous_character_double = current_character_double;
                }

            } /* loop exits when eof encountered (and/or) double found */

            if (found_double) {

                /* insert double into point structure for current point-cloud type */
                /* do not attempt to insert double into point structure for format character '?' */
                if (format != '?') {
                    switch (type) {
                    case RT_PNT_TYPE_PNT:
                        INSERT_COORDINATE_INTO_STRUCTURE(pnt, format, (temp_double * local2base));
                        break;
                    case RT_PNT_TYPE_COL:
                        INSERT_COORDINATE_INTO_STRUCTURE(pnt_color, format, (temp_double * local2base));
                        INSERT_COLOR_INTO_STRUCTURE(pnt_color, format, temp_double);
                        break;
                    case RT_PNT_TYPE_SCA:
                        INSERT_COORDINATE_INTO_STRUCTURE(pnt_scale, format, (temp_double * local2base));
                        INSERT_SCALE_INTO_STRUCTURE(pnt_scale, format, (temp_double * local2base));
                        break;
                    case RT_PNT_TYPE_NRM:
                        INSERT_COORDINATE_INTO_STRUCTURE(pnt_normal, format, (temp_double * local2base));
                        INSERT_NORMAL_INTO_STRUCTURE(pnt_normal, format, (temp_double * local2base));
                        break;
                    case RT_PNT_TYPE_COL_SCA:
                        INSERT_COORDINATE_INTO_STRUCTURE(pnt_color_scale, format, (temp_double * local2base));
                        INSERT_COLOR_INTO_STRUCTURE(pnt_color_scale, format, temp_double);
                        INSERT_SCALE_INTO_STRUCTURE(pnt_color_scale, format, (temp_double * local2base));
                        break;
                    case RT_PNT_TYPE_COL_NRM:
                        INSERT_COORDINATE_INTO_STRUCTURE(pnt_color_normal, format, (temp_double * local2base));
                        INSERT_COLOR_INTO_STRUCTURE(pnt_color_normal, format, temp_double);
                        INSERT_NORMAL_INTO_STRUCTURE(pnt_color_normal, format, (temp_double * local2base));
                        break;
                    case RT_PNT_TYPE_SCA_NRM:
                        INSERT_COORDINATE_INTO_STRUCTURE(pnt_scale_normal, format, (temp_double * local2base));
                        INSERT_SCALE_INTO_STRUCTURE(pnt_scale_normal, format, (temp_double * local2base));
                        INSERT_NORMAL_INTO_STRUCTURE(pnt_scale_normal, format, (temp_double * local2base));
                        break;
                    case RT_PNT_TYPE_COL_SCA_NRM:
                        INSERT_COORDINATE_INTO_STRUCTURE(pnt_color_scale_normal, format, (temp_double * local2base));
                        INSERT_COLOR_INTO_STRUCTURE(pnt_color_scale_normal, format, temp_double);
                        INSERT_SCALE_INTO_STRUCTURE(pnt_color_scale_normal, format, (temp_double * local2base));
                        INSERT_NORMAL_INTO_STRUCTURE(pnt_color_scale_normal, format, (temp_double * local2base));
                        break;
                    }
                }
                found_double = 0;  /* allows loop to continue */
                format_string_index++;
                if (format_string_index >= bu_vls_strlen(&format_string)) {
                    done_processing_format_string = 1;
                }
            }

        } /* loop exits when eof encountered (and/or) all doubles for
	   * a single point are stored in point structure
	   */

        if (done_processing_format_string) {
            /* push single point structure onto linked-list of points
             * which makeup the point-cloud.
             */
            switch (type) {
            case RT_PNT_TYPE_PNT:
                BU_LIST_PUSH(&(((struct pnt *)headPoint)->l), &((struct pnt *)point)->l);
                break;
            case RT_PNT_TYPE_COL:
                BU_LIST_PUSH(&(((struct pnt_color *)headPoint)->l), &((struct pnt_color *)point)->l);
                break;
            case RT_PNT_TYPE_SCA:
                BU_LIST_PUSH(&(((struct pnt_scale *)headPoint)->l), &((struct pnt_scale *)point)->l);
                break;
            case RT_PNT_TYPE_NRM:
                BU_LIST_PUSH(&(((struct pnt_normal *)headPoint)->l), &((struct pnt_normal *)point)->l);
                break;
            case RT_PNT_TYPE_COL_SCA:
                BU_LIST_PUSH(&(((struct pnt_color_scale *)headPoint)->l), &((struct pnt_color_scale *)point)->l);
                break;
            case RT_PNT_TYPE_COL_NRM:
                BU_LIST_PUSH(&(((struct pnt_color_normal *)headPoint)->l), &((struct pnt_color_normal *)point)->l);
                break;
            case RT_PNT_TYPE_SCA_NRM:
                BU_LIST_PUSH(&(((struct pnt_scale_normal *)headPoint)->l), &((struct pnt_scale_normal *)point)->l);
                break;
            case RT_PNT_TYPE_COL_SCA_NRM:
                BU_LIST_PUSH(&(((struct pnt_color_scale_normal *)headPoint)->l), &((struct pnt_color_scale_normal *)point)->l);
                break;
            }
            numPoints++;
            format_string_index = 0;
            done_processing_format_string = 0;
        }

    } /* loop exits when eof encountered */

    if (num_doubles_read < num_doubles_per_point) {
        bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. Number of values read inconsistent with point-cloud type ", argv[1]);
        bu_vls_printf(gedp->ged_result_str, "defined by format string '%V'. The number of values read must be an even ", format_string);
        bu_vls_printf(gedp->ged_result_str, "multiple of %d but read %lu values.\n", num_doubles_per_point, num_doubles_read);
        bu_vls_free(&format_string);
        rt_db_free_internal(&internal);
        return GED_ERROR;
    }

    if (num_doubles_read % num_doubles_per_point) {
        bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. Number of values read inconsistent with point-cloud type ", argv[1]);
        bu_vls_printf(gedp->ged_result_str, "defined by format string '%V'. The number of values read must be an even ", format_string);
        bu_vls_printf(gedp->ged_result_str, "multiple of %d but read %lu values.\n", num_doubles_per_point, num_doubles_read);
        bu_vls_free(&format_string);
        rt_db_free_internal(&internal);
        return GED_ERROR;
    }

    pnts->count = numPoints;

    GED_DB_DIRADD(gedp, dp, argv[1], RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&internal.idb_type, GED_ERROR);
    GED_DB_PUT_INTERNAL(gedp, dp, &internal, &rt_uniresource, GED_ERROR);

    bu_vls_free(&format_string);

    bu_vls_printf(gedp->ged_result_str, "Make '%s' success, %lu values read, %lu points imported.\n", argv[1], num_doubles_read, numPoints);

    return GED_OK;
}
Ejemplo n.º 16
0
int
ged_concat(struct ged *gedp, int argc, const char *argv[])
{
    struct db_i *newdbp;
    struct directory *dp;
    Tcl_HashTable name_tbl;
    Tcl_HashTable used_names_tbl;
    Tcl_HashEntry *ptr;
    Tcl_HashSearch search;
    struct bu_attribute_value_set g_avs;
    const char *cp;
    char *colorTab;
    struct ged_concat_data cc_data;
    const char *oldfile;
    static const char *usage = "[-u] [-t] [-c] [-s|-p] file.g [suffix|prefix]";
    int importUnits = 0;
    int importTitle = 0;
    int importColorTable = 0;
    int saveGlobalAttrs = 0;
    int c;
    const char *commandName;

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);

    /* initialize result */
    bu_vls_trunc(gedp->ged_result_str, 0);

    if (argc < 2) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

    bu_vls_init(&cc_data.affix);
    cc_data.copy_mode = 0;
    commandName = argv[0];

    /* process args */
    bu_optind = 1;
    bu_opterr = 0;
    while ((c=bu_getopt(argc, (char * const *)argv, "utcsp")) != -1) {
	switch (c) {
	    case 'u':
		importUnits = 1;
		break;
	    case 't':
		importTitle = 1;
		break;
	    case 'c':
		importColorTable = 1;
		break;
	    case 'p':
		cc_data.copy_mode |= AUTO_PREFIX;
		break;
	    case 's':
		cc_data.copy_mode |= AUTO_SUFFIX;
		break;
	    default: {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage);
		    bu_vls_free(&cc_data.affix);
		    return GED_ERROR;
		}
	}
    }
    argc -= bu_optind;
    argv += bu_optind;

    if (argc == 0) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage);
	return GED_ERROR;
    }

    oldfile = argv[0];

    argc--;
    argv++;

    if (cc_data.copy_mode) {
	/* specified suffix or prefix explicitly */

	if (cc_data.copy_mode & AUTO_PREFIX) {

	    if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) {
		cc_data.copy_mode = NO_AFFIX | CUSTOM_PREFIX;
	    } else {
		(void)bu_vls_strcpy(&cc_data.affix, argv[0]);
		cc_data.copy_mode |= CUSTOM_PREFIX;
	    }

	} else if (cc_data.copy_mode & AUTO_SUFFIX) {

	    if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) {
		cc_data.copy_mode = NO_AFFIX | CUSTOM_SUFFIX;
	    } else {
		(void)bu_vls_strcpy(&cc_data.affix, argv[0]);
		cc_data.copy_mode |= CUSTOM_SUFFIX;
	    }

	} else {
	    bu_vls_free(&cc_data.affix);
	    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage);
	    return GED_ERROR;
	}

    } else {
	/* no prefix/suffix preference, use prefix */

	cc_data.copy_mode |= AUTO_PREFIX;

	if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) {
	    cc_data.copy_mode = NO_AFFIX | CUSTOM_PREFIX;
	} else {
	    (void)bu_vls_strcpy(&cc_data.affix, argv[0]);
	    cc_data.copy_mode |= CUSTOM_PREFIX;
	}

    }

    if (db_version(gedp->ged_wdbp->dbip) < 5) {
	if (bu_vls_strlen(&cc_data.affix) > _GED_V4_MAXNAME-1) {
	    bu_log("ERROR: affix [%s] is too long for v%d\n", bu_vls_addr(&cc_data.affix), db_version(gedp->ged_wdbp->dbip));
	    bu_vls_free(&cc_data.affix);
	    return GED_ERROR;
	}
    }

    /* open the input file */
    if ((newdbp = db_open(oldfile, DB_OPEN_READONLY)) == DBI_NULL) {
	bu_vls_free(&cc_data.affix);
	perror(oldfile);
	bu_vls_printf(gedp->ged_result_str, "%s: Can't open geometry database file %s", commandName, oldfile);
	return GED_ERROR;
    }

    if (db_version(newdbp) > 4 && db_version(gedp->ged_wdbp->dbip) < 5) {
	bu_vls_free(&cc_data.affix);
	bu_vls_printf(gedp->ged_result_str, "%s: databases are incompatible, use dbupgrade on %s first",
		      commandName, gedp->ged_wdbp->dbip->dbi_filename);
	return GED_ERROR;
    }

    db_dirbuild(newdbp);

    cc_data.new_dbip = newdbp;
    cc_data.old_dbip = gedp->ged_wdbp->dbip;

    /* visit each directory pointer in the input database */
    Tcl_InitHashTable(&name_tbl, TCL_STRING_KEYS);
    Tcl_InitHashTable(&used_names_tbl, TCL_STRING_KEYS);

    if (importUnits || importTitle || importColorTable) {
	saveGlobalAttrs = 1;
    }
    FOR_ALL_DIRECTORY_START(dp, newdbp) {
	if (dp->d_major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY) {
	    if (saveGlobalAttrs) {
		if (db5_get_attributes(newdbp, &g_avs, dp)) {
		    bu_vls_printf(gedp->ged_result_str, "%s: Can't get global attributes from %s", commandName, oldfile);
		    return GED_ERROR;
		}
	    }
	    continue;
	}
	copy_object(gedp, dp, newdbp, gedp->ged_wdbp->dbip, &name_tbl, &used_names_tbl, &cc_data);
    } FOR_ALL_DIRECTORY_END;

    bu_vls_free(&cc_data.affix);
    rt_mempurge(&(newdbp->dbi_freep));

    /* Free all the directory entries, and close the input database */
    db_close(newdbp);

    if (importColorTable) {
	colorTab = bu_strdup(bu_avs_get(&g_avs, "regionid_colortable"));
	db5_import_color_table(colorTab);
	bu_free(colorTab, "colorTab");
    } else if (saveGlobalAttrs) {
	bu_avs_remove(&g_avs, "regionid_colortable");
    }

    if (importTitle) {
	if ((cp = bu_avs_get(&g_avs, "title")) != NULL) {
	    char *oldTitle = gedp->ged_wdbp->dbip->dbi_title;
	    gedp->ged_wdbp->dbip->dbi_title = bu_strdup(cp);
	    if (oldTitle) {
		bu_free(oldTitle, "old title");
	    }
	}
    } else if (saveGlobalAttrs) {
	bu_avs_remove(&g_avs, "title");
    }

    if (importUnits) {
	if ((cp = bu_avs_get(&g_avs, "units")) != NULL) {
	    double dd;
	    if (sscanf(cp, "%lf", &dd) != 1 || NEAR_ZERO(dd, VUNITIZE_TOL)) {
		bu_log("copy_object(%s): improper database, %s object attribute 'units'=%s is invalid\n",
		       oldfile, DB5_GLOBAL_OBJECT_NAME, cp);
		bu_avs_remove(&g_avs, "units");
	    } else {
		gedp->ged_wdbp->dbip->dbi_local2base = dd;
		gedp->ged_wdbp->dbip->dbi_base2local = 1 / dd;
	    }
	}
    } else if (saveGlobalAttrs) {
	bu_avs_remove(&g_avs, "units");
    }

    if (saveGlobalAttrs) {
	dp = db_lookup(gedp->ged_wdbp->dbip, DB5_GLOBAL_OBJECT_NAME, LOOKUP_NOISY);
	db5_update_attributes(dp, &g_avs, gedp->ged_wdbp->dbip);
    }

    db_sync(gedp->ged_wdbp->dbip);	/* force changes to disk */

    /* Free the Hash tables */
    ptr = Tcl_FirstHashEntry(&name_tbl, &search);
    while (ptr) {
	bu_free((char *)Tcl_GetHashValue(ptr), "new name");
	ptr = Tcl_NextHashEntry(&search);
    }
    Tcl_DeleteHashTable(&name_tbl);
    Tcl_DeleteHashTable(&used_names_tbl);

    return GED_OK;
}
Ejemplo n.º 17
0
/**
 * find a new unique name given a list of previously used names, and
 * the type of naming mode that described what type of affix to use.
 */
static char *
get_new_name(const char *name,
		 struct db_i *dbip,
		 Tcl_HashTable *name_tbl,
		 Tcl_HashTable *used_names_tbl,
		 struct ged_concat_data *cc_data)
{
    struct bu_vls new_name = BU_VLS_INIT_ZERO;
    Tcl_HashEntry *ptr = NULL;
    char *aname = NULL;
    char *ret_name = NULL;
    int int_new=0;
    long num=0;

    RT_CK_DBI(dbip);
    BU_ASSERT(name_tbl);
    BU_ASSERT(used_names_tbl);
    BU_ASSERT(cc_data);

    if (!name) {
	bu_log("WARNING: encountered NULL name, renaming to \"UNKNOWN\"\n");
	name = "UNKNOWN";
    }

    ptr = Tcl_CreateHashEntry(name_tbl, name, &int_new);

    if (!int_new) {
	return (char *)Tcl_GetHashValue(ptr);
    }

    do {
	/* iterate until we find an object name that is not in
	 * use, trying to accommodate the user's requested affix
	 * naming mode.
	 */

	bu_vls_trunc(&new_name, 0);

	if (cc_data->copy_mode & NO_AFFIX) {
	    if (num > 0 && cc_data->copy_mode & CUSTOM_PREFIX) {
		/* auto-increment prefix */
		bu_vls_printf(&new_name, "%ld_", num);
	    }
	    bu_vls_strcat(&new_name, name);
	    if (num > 0 && cc_data->copy_mode & CUSTOM_SUFFIX) {
		/* auto-increment suffix */
		bu_vls_printf(&new_name, "_%ld", num);
	    }
	} else if (cc_data->copy_mode & CUSTOM_SUFFIX) {
	    /* use custom suffix */
	    bu_vls_strcpy(&new_name, name);
	    if (num > 0) {
		bu_vls_printf(&new_name, "_%ld_", num);
	    }
	    bu_vls_vlscat(&new_name, &cc_data->affix);
	} else if (cc_data->copy_mode & CUSTOM_PREFIX) {
	    /* use custom prefix */
	    bu_vls_vlscat(&new_name, &cc_data->affix);
	    if (num > 0) {
		bu_vls_printf(&new_name, "_%ld_", num);
	    }
	    bu_vls_strcat(&new_name, name);
	} else if (cc_data->copy_mode & AUTO_SUFFIX) {
	    /* use auto-incrementing suffix */
	    bu_vls_strcat(&new_name, name);
	    bu_vls_printf(&new_name, "_%ld", num);
	} else if (cc_data->copy_mode & AUTO_PREFIX) {
	    /* use auto-incrementing prefix */
	    bu_vls_printf(&new_name, "%ld_", num);
	    bu_vls_strcat(&new_name, name);
	} else {
	    /* no custom suffix/prefix specified, use prefix */
	    if (num > 0) {
		bu_vls_printf(&new_name, "_%ld", num);
	    }
	    bu_vls_strcpy(&new_name, name);
	}

	/* make sure it fits for v4 */
	if (db_version(cc_data->old_dbip) < 5) {
	    if (bu_vls_strlen(&new_name) > _GED_V4_MAXNAME) {
		bu_log("ERROR: generated new name [%s] is too long (%zu > %d)\n", bu_vls_addr(&new_name), bu_vls_strlen(&new_name), _GED_V4_MAXNAME);
	    }
	    return NULL;
	}
	aname = bu_vls_addr(&new_name);

	num++;

    } while (db_lookup(dbip, aname, LOOKUP_QUIET) != RT_DIR_NULL ||
	     Tcl_FindHashEntry(used_names_tbl, aname) != NULL);

    /* if they didn't get what they asked for, warn them */
    if (num > 1) {
	if (cc_data->copy_mode & NO_AFFIX) {
	    bu_log("WARNING: unable to import [%s] without an affix, imported as [%s]\n", name, bu_vls_addr(&new_name));
	} else if (cc_data->copy_mode & CUSTOM_SUFFIX) {
	    bu_log("WARNING: unable to import [%s] as [%s%s], imported as [%s]\n", name, name, bu_vls_addr(&cc_data->affix), bu_vls_addr(&new_name));
	} else if (cc_data->copy_mode & CUSTOM_PREFIX) {
	    bu_log("WARNING: unable to import [%s] as [%s%s], imported as [%s]\n", name, bu_vls_addr(&cc_data->affix), name, bu_vls_addr(&new_name));
	}
    }

    /* we should now have a unique name.  store it in the hash */
    ret_name = bu_vls_strgrab(&new_name);
    Tcl_SetHashValue(ptr, (ClientData)ret_name);
    (void)Tcl_CreateHashEntry(used_names_tbl, ret_name, &int_new);
    bu_vls_free(&new_name);

    return ret_name;
}
Ejemplo n.º 18
0
/*
 * Given a u, v coordinate within the texture (0 <= u, v <= 1.0),
 * return a pointer to the relevant pixel.
 *
 * Note that .pix files are stored left-to-right, bottom-to-top,
 * which works out very naturally for the indexing scheme.
 */
HIDDEN int
txt_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
{
    register struct txt_specific *tp =
	(struct txt_specific *)dp;
    fastf_t xmin, xmax, ymin, ymax;
    int dx, dy;
    register fastf_t r, g, b;
    struct uvcoord uvc;
    long tmp;

    RT_CK_AP(ap);
    RT_CHECK_PT(pp);

    uvc = swp->sw_uv;

    if (rdebug & RDEBUG_SHADE)
	bu_log("in txt_render(): du=%g, dv=%g\n",
	       uvc.uv_du, uvc.uv_dv);

    /* take care of scaling U, V coordinates to get the desired amount
     * of replication of the texture
     */
    uvc.uv_u *= tp->tx_scale[X];
    tmp = uvc.uv_u;
    uvc.uv_u -= tmp;
    if (tp->tx_mirror && (tmp & 1))
	uvc.uv_u = 1.0 - uvc.uv_u;

    uvc.uv_v *= tp->tx_scale[Y];
    tmp = uvc.uv_v;
    uvc.uv_v -= tmp;
    if (tp->tx_mirror && (tmp & 1))
	uvc.uv_v = 1.0 - uvc.uv_v;

    uvc.uv_du /= tp->tx_scale[X];
    uvc.uv_dv /= tp->tx_scale[Y];

    /*
     * If no texture file present, or if
     * texture isn't and can't be read, give debug colors
     */

    if ((bu_vls_strlen(&tp->tx_name) <= 0) || (!tp->tx_mp && !tp->tx_binunifp)) {
	bu_log("WARNING: texture [%s] could not be read\n", bu_vls_addr(&tp->tx_name));
	VSET(swp->sw_color, uvc.uv_u, 0, uvc.uv_v);
	if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
	    (void)rr_render(ap, pp, swp);
	return 1;
    }

    /* u is left->right index, v is line number bottom->top */
    /* Don't filter more than 1/8 of the texture for 1 pixel! */
    if (uvc.uv_du > 0.125) uvc.uv_du = 0.125;
    if (uvc.uv_dv > 0.125) uvc.uv_dv = 0.125;

    if (uvc.uv_du < 0 || uvc.uv_dv < 0) {
	bu_log("txt_render uv=%g, %g, du dv=%g %g seg=%s\n",
	       uvc.uv_u, uvc.uv_v, uvc.uv_du, uvc.uv_dv,
	       pp->pt_inseg->seg_stp->st_name);
	uvc.uv_du = uvc.uv_dv = 0;
    }

    xmin = uvc.uv_u - uvc.uv_du;
    xmax = uvc.uv_u + uvc.uv_du;
    ymin = uvc.uv_v - uvc.uv_dv;
    ymax = uvc.uv_v + uvc.uv_dv;
    if (xmin < 0) xmin = 0;
    if (ymin < 0) ymin = 0;
    if (xmax > 1) xmax = 1;
    if (ymax > 1) ymax = 1;

    if (rdebug & RDEBUG_SHADE)
	bu_log("footprint in texture space is (%g %g) <-> (%g %g)\n",
	       xmin * (tp->tx_w-1), ymin * (tp->tx_n-1),
	       xmax * (tp->tx_w-1), ymax * (tp->tx_n-1));

    dx = (int)(xmax * (tp->tx_w-1)) - (int)(xmin * (tp->tx_w-1));
    dy = (int)(ymax * (tp->tx_n-1)) - (int)(ymin * (tp->tx_n-1));

    if (rdebug & RDEBUG_SHADE)
	bu_log("\tdx = %d, dy = %d\n", dx, dy);

    if (dx == 0 && dy == 0) {
	/* No averaging necessary */

	register unsigned char *cp=NULL;

	if (tp->tx_mp) {
	    cp = ((unsigned char *)(tp->tx_mp->buf)) +
		(int)(ymin * (tp->tx_n-1)) * tp->tx_w * 3 +
		(int)(xmin * (tp->tx_w-1)) * 3;
	} else if (tp->tx_binunifp) {
	    cp = ((unsigned char *)(tp->tx_binunifp->u.uint8)) +
		(int)(ymin * (tp->tx_n-1)) * tp->tx_w * 3 +
		(int)(xmin * (tp->tx_w-1)) * 3;
	} else {
	    bu_bomb("sh_text.c -- No texture data found\n");
	}
	r = *cp++;
	g = *cp++;
	b = *cp;
    } else {
	/* Calculate weighted average of cells in footprint */

	fastf_t tot_area = 0.0;
	fastf_t cell_area;
	int start_line, stop_line, line;
	int start_col, stop_col, col;
	fastf_t xstart, xstop, ystart, ystop;

	xstart = xmin * (tp->tx_w-1);
	xstop = xmax * (tp->tx_w-1);
	ystart = ymin * (tp->tx_n-1);
	ystop = ymax * (tp->tx_n-1);

	start_line = ystart;
	stop_line = ystop;
	start_col = xstart;
	stop_col = xstop;

	r = g = b = 0.0;

	if (rdebug & RDEBUG_SHADE) {
	    bu_log("\thit in texture space = (%g %g)\n", uvc.uv_u * (tp->tx_w-1), uvc.uv_v * (tp->tx_n-1));
	    bu_log("\t averaging from  (%g %g) to (%g %g)\n", xstart, ystart, xstop, ystop);
	    bu_log("\tcontributions to average:\n");
	}

	for (line = start_line; line <= stop_line; line++) {
	    register unsigned char *cp=NULL;
	    fastf_t line_factor;
	    fastf_t line_upper, line_lower;

	    line_upper = line + 1.0;
	    if (line_upper > ystop)
		line_upper = ystop;
	    line_lower = line;
	    if (line_lower < ystart)
		line_lower = ystart;
	    line_factor = line_upper - line_lower;

	    if (tp->tx_mp) {
		cp = ((unsigned char *)(tp->tx_mp->buf)) +
		    line * tp->tx_w * 3 + (int)(xstart) * 3;
	    } else if (tp->tx_binunifp) {
		cp = ((unsigned char *)(tp->tx_binunifp->u.uint8)) +
		    line * tp->tx_w * 3 + (int)(xstart) * 3;
	    } else {
		/* not reachable */
		bu_bomb("sh_text.c -- Unable to read datasource\n");
	    }

	    for (col = start_col; col <= stop_col; col++) {
		fastf_t col_upper, col_lower;

		col_upper = col + 1.0;
		if (col_upper > xstop) col_upper = xstop;
		col_lower = col;
		if (col_lower < xstart) col_lower = xstart;

		cell_area = line_factor * (col_upper - col_lower);
		tot_area += cell_area;

		if (rdebug & RDEBUG_SHADE)
		    bu_log("\t %d %d %d weight=%g (from col=%d line=%d)\n", *cp, *(cp+1), *(cp+2), cell_area, col, line);

		r += (*cp++) * cell_area;
		g += (*cp++) * cell_area;
		b += (*cp++) * cell_area;
	    }

	}
	r /= tot_area;
	g /= tot_area;
	b /= tot_area;
    }

    if (rdebug & RDEBUG_SHADE)
	bu_log(" average: %g %g %g\n", r, g, b);

    if (!tp->tx_trans_valid) {
    opaque:
	VSET(swp->sw_color,
	     r / 255.0,
	     g / 255.0,
	     b / 255.0);

	if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
	    (void)rr_render(ap, pp, swp);
	return 1;
    }
    /* This circumlocution needed to keep expression simple for Cray,
     * and others
     */
    if (!EQUAL(r, ((long)tp->tx_transp[0]))) goto opaque;
    if (!EQUAL(g, ((long)tp->tx_transp[1]))) goto opaque;
    if (!EQUAL(b, ((long)tp->tx_transp[2]))) goto opaque;

    /*
     * Transparency mapping is enabled, and we hit a transparent spot.
     * Let higher level handle it in reflect/refract code.
     */
    swp->sw_transmit = 1.0;
    swp->sw_reflect = 0.0;

    bu_log("leaving txt_render()\n");

    if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
	(void)rr_render(ap, pp, swp);
    return 1;
}
Ejemplo n.º 19
0
/*
 *			D O _ R E G I O N _ E N D
 *
 *  Called from db_walk_tree().
 *
 *  This routine must be prepared to run in parallel.
 */
union tree *do_region_end(struct db_tree_state *tsp, const struct db_full_path *pathp, union tree *curtree, genptr_t UNUSED(client_data))
{
    union tree		*ret_tree;
    struct nmgregion	*r;

    RT_CK_TESS_TOL(tsp->ts_ttol);
    BN_CK_TOL(tsp->ts_tol);
    NMG_CK_MODEL(*tsp->ts_m);

    if (RT_G_DEBUG&DEBUG_TREEWALK || verbose) {
	char	*sofar = db_path_to_string(pathp);
	bu_log("\ndo_region_end(%d %d%%) %s\n",
	       regions_tried,
	       regions_tried>0 ? (regions_done * 100) / regions_tried : 0,
	       sofar);
	bu_free(sofar, "path string");
    }

    if (curtree->tr_op == OP_NOP)
	return curtree;

    regions_tried++;

    ret_tree = process_boolean(curtree, tsp, pathp);

    if ( ret_tree )
	r = ret_tree->tr_d.td_r;
    else
	r = (struct nmgregion *)NULL;

    regions_done++;

    if (r != 0) {
	FILE	*fp_psurf;
	size_t	i;
	struct bu_vls	file_base = BU_VLS_INIT_ZERO;
	struct bu_vls	file = BU_VLS_INIT_ZERO;

	bu_vls_strcpy(&file_base, prefix);
	bu_vls_strcat(&file_base, DB_FULL_PATH_CUR_DIR(pathp)->d_namep);
	/* Dots confuse Jack's Peabody language.  Change to '_'. */
	for (i = 0; i < file_base.vls_len; i++)
	    if (file_base.vls_str[i] == '.')
		file_base.vls_str[i] = '_';

	/* Write color attribute to .fig figure file. */
	if (tsp->ts_mater.ma_color_valid != 0) {
	    fprintf(fp_fig, "\tattribute %s {\n",
		    bu_vls_addr(&file_base));
	    fprintf(fp_fig, "\t\trgb = (%f, %f, %f);\n",
		    V3ARGS(tsp->ts_mater.ma_color));
	    fprintf(fp_fig, "\t\tambient = 0.18;\n");
	    fprintf(fp_fig, "\t\tdiffuse = 0.72;\n");
	    fprintf(fp_fig, "\t}\n");
	}

	/* Write segment attributes to .fig figure file. */
	fprintf(fp_fig, "\tsegment %s_seg {\n", bu_vls_addr(&file_base));
	fprintf(fp_fig, "\t\tpsurf=\"%s.pss\";\n", bu_vls_addr(&file_base));
	if (tsp->ts_mater.ma_color_valid != 0)
	    fprintf(fp_fig,
		    "\t\tattribute=%s;\n", bu_vls_addr(&file_base));
	fprintf(fp_fig, "\t\tsite base->location=trans(0, 0, 0);\n");
	fprintf(fp_fig, "\t}\n");

	if ( bu_vls_strlen(&base_seg) <= 0 )  {
	    bu_vls_vlscat( &base_seg, &file_base );
	} else {
	    fprintf(fp_fig, "\tjoint %s_jt {\n",
		    bu_vls_addr(&file_base));
	    fprintf(fp_fig,
		    "\t\tconnect %s_seg.base to %s_seg.base;\n",
		    bu_vls_addr(&file_base),
		    bu_vls_addr(&base_seg) );
	    fprintf(fp_fig, "\t}\n");
	}

	bu_vls_vlscat(&file, &file_base);
	bu_vls_strcat(&file, ".pss");	/* Required Jack suffix. */

	/* Write psurf to .pss file. */
	if ((fp_psurf = fopen(bu_vls_addr(&file), "wb")) == NULL)
	    perror(bu_vls_addr(&file));
	else {
	    nmg_to_psurf(r, fp_psurf);
	    fclose(fp_psurf);
	    if (verbose) bu_log("*** Wrote %s\n", bu_vls_addr(&file));
	}
	bu_vls_free(&file);

	/* Also write as UNIX-plot file, if desired */
	if ( debug_plots )  {
	    FILE	*fp;
	    bu_vls_vlscat(&file, &file_base);
	    bu_vls_strcat(&file, ".pl");

	    if ((fp = fopen(bu_vls_addr(&file), "wb")) == NULL)
		perror(bu_vls_addr(&file));
	    else {
		struct bu_list	vhead;
		pl_color( fp,
			  (int)(tsp->ts_mater.ma_color[0] * 255),
			  (int)(tsp->ts_mater.ma_color[1] * 255),
			  (int)(tsp->ts_mater.ma_color[2] * 255) );
		/* nmg_pl_r( fp, r ); */
		BU_LIST_INIT( &vhead );
		nmg_r_to_vlist( &vhead, r, 0 );
		rt_vlist_to_uplot( fp, &vhead );
		fclose(fp);
		if (verbose) bu_log("*** Wrote %s\n", bu_vls_addr(&file));
	    }
	    bu_vls_free(&file);
	}

	/* NMG region is no longer necessary */
	nmg_kr(r);
    }

    /*
     *  Dispose of original tree, so that all associated dynamic
     *  memory is released now, not at the end of all regions.
     *  A return of TREE_NULL from this routine signals an error,
     *  so we need to cons up an OP_NOP node to return.
     */
    db_free_tree(curtree, &rt_uniresource);		/* Does an nmg_kr() */

    BU_ALLOC(curtree, union tree);
    RT_TREE_INIT(curtree);
    curtree->tr_op = OP_NOP;
    return curtree;
}
Ejemplo n.º 20
0
int
make_hole(struct rt_wdb *wdbp,		/* database to be modified */
	  point_t hole_start,		/* center of start of hole */
	  vect_t hole_depth,		/* depth and direction of hole */
	  fastf_t hole_radius,		/* radius of hole */
	  int num_objs,			/* number of objects that this hole affects */
	  struct directory **dp)	/* array of directory pointers
					 * [num_objs] of objects to
					 * get this hole applied
					 */
{
    struct bu_vls tmp_name = BU_VLS_INIT_ZERO;
    int i, base_len, count=0;

    RT_CHECK_WDB(wdbp);

    /* make sure we are only making holes in combinations, they do not
     * have to be regions
     */
    for (i=0; i<num_objs; i++) {
	RT_CK_DIR(dp[i]);
	if (!(dp[i]->d_flags & RT_DIR_COMB)) {
	    bu_log("make_hole(): can only make holes in combinations\n");
	    bu_log("\t%s is not a combination\n", dp[i]->d_namep);
	    return 4;
	}
    }

    /* make a unique name for the RCC we will use (of the form
     * "make_hole_%d")
     */
    bu_vls_strcat(&tmp_name, "make_hole_");
    base_len = bu_vls_strlen(&tmp_name);
    bu_vls_strcat(&tmp_name, "0");
    while ((db_lookup(wdbp->dbip, bu_vls_addr(&tmp_name), LOOKUP_QUIET)) != RT_DIR_NULL) {
	count++;
	bu_vls_trunc(&tmp_name, base_len);
	bu_vls_printf(&tmp_name, "%d", count);
    }

    /* build the RCC based on parameters passed in */
    if (mk_rcc(wdbp, bu_vls_addr(&tmp_name), hole_start, hole_depth, hole_radius)) {
	bu_log("Failed to create hole cylinder!!!\n");
	bu_vls_free(&tmp_name);
	return 2;
    }

    /* subtract this RCC from each combination in the list passed in */
    for (i=0; i<num_objs; i++) {
	struct rt_db_internal intern;
	struct rt_comb_internal *comb;
	union tree *tree;

	/* get the internal form of the combination */
	if (rt_db_get_internal(&intern, dp[i], wdbp->dbip, NULL, wdbp->wdb_resp) < 0) {
	    bu_log("Failed to get %s\n", dp[i]->d_namep);
	    bu_vls_free(&tmp_name);
	    return 3;
	}
	comb = (struct rt_comb_internal *)intern.idb_ptr;

	/* Build a new "subtract" node (will be the root of the new tree) */
	BU_ALLOC(tree, union tree);
	RT_TREE_INIT(tree);
	tree->tr_b.tb_op = OP_SUBTRACT;
	tree->tr_b.tb_left = comb->tree;	/* subtract from the original tree */
	comb->tree = tree;

	/* Build a node for the RCC to be subtracted */
	BU_ALLOC(tree, union tree);
	RT_TREE_INIT(tree);
	tree->tr_l.tl_op = OP_DB_LEAF;
	tree->tr_l.tl_mat = NULL;
	tree->tr_l.tl_name = bu_strdup(bu_vls_addr(&tmp_name)); /* copy name of RCC */

	/* Put the RCC node to the right of the root */
	comb->tree->tr_b.tb_right = tree;

	/* Save the modified combination.  This will overwrite the
	 * original combination if wdbp was opened with the
	 * RT_WDB_TYPE_DB_DISK flag. If wdbp was opened with the
	 * RT_WDB_TYPE_DB_INMEM flag, then the combination will be
	 * temporarily over-written in memory only and the disk file
	 * will not be modified.
	 */
	wdb_put_internal(wdbp, dp[i]->d_namep, &intern, 1.0);
    }
    return 0;
}
Ejemplo n.º 21
0
int
make_hole_in_prepped_regions(struct rt_wdb *wdbp,	/* database to be modified */
			     struct rt_i *rtip,		/* rt_i pointer for the same database */
			     point_t hole_start,	/* center of start of hole */
			     vect_t hole_depth,		/* depth and direction of hole */
			     fastf_t radius,		/* radius of hole */
			     struct bu_ptbl *regions)	/* list of region structures to which this hole
							 * is to be applied
							 */
{
    struct bu_vls tmp_name = BU_VLS_INIT_ZERO;
    size_t i, base_len, count=0;
    struct directory *dp;
    struct rt_db_internal intern;
    struct soltab *stp;

    RT_CHECK_WDB(wdbp);

    /* make a unique name for the RCC we will use (of the form "make_hole_%d") */
    bu_vls_strcat(&tmp_name, "make_hole_");
    base_len = bu_vls_strlen(&tmp_name);
    bu_vls_strcat(&tmp_name, "0");
    while ((db_lookup(wdbp->dbip, bu_vls_addr(&tmp_name), LOOKUP_QUIET)) != RT_DIR_NULL) {
	count++;
	bu_vls_trunc(&tmp_name, base_len);
	bu_vls_printf(&tmp_name, "%zu", count);
    }

    /* build the RCC based on parameters passed in */
    if (mk_rcc(wdbp, bu_vls_addr(&tmp_name), hole_start, hole_depth, radius)) {
	bu_log("Failed to create hole cylinder!!!\n");
	bu_vls_free(&tmp_name);
	return 2;
    }

    /* lookup the newly created RCC */
    dp=db_lookup(wdbp->dbip, bu_vls_addr(&tmp_name), LOOKUP_QUIET);
    if (dp == RT_DIR_NULL) {
      bu_log("Failed to lookup RCC (%s) just made by make_hole_in_prepped_regions()!!!\n",
	       bu_vls_addr(&tmp_name));
	bu_bomb("Failed to lookup RCC just made by make_hole_in_prepped_regions()!!!\n");
    }

    /* get the internal form of the new RCC */
    if (rt_db_get_internal(&intern, dp, wdbp->dbip, NULL, wdbp->wdb_resp) < 0) {
	bu_log("Failed to get internal form of RCC (%s) just made by make_hole_in_prepped_regions()!!!\n",
	       bu_vls_addr(&tmp_name));
	bu_bomb("Failed to get internal form of RCC just made by make_hole_in_prepped_regions()!!!\n");
    }

    /* Build a soltab structure for the new RCC */
    BU_ALLOC(stp, struct soltab);
    stp->l.magic = RT_SOLTAB_MAGIC;
    stp->l2.magic = RT_SOLTAB2_MAGIC;
    stp->st_uses = 1;
    stp->st_dp = dp;
    stp->st_bit = rtip->nsolids++;

    /* Add the new soltab structure to the rt_i structure */
    rtip->rti_Solids = (struct soltab **)bu_realloc(rtip->rti_Solids,
						    rtip->nsolids * sizeof(struct soltab *),
						    "new rti_Solids");
    rtip->rti_Solids[stp->st_bit] = stp;

    /* actually prep the new RCC */
    if (intern.idb_meth->ft_prep(stp, &intern, rtip)) {
	bu_log("Failed to prep RCC (%s) just made by make_hole_in_prepped_regions()!!!\n",
	       bu_vls_addr(&tmp_name));
	bu_bomb("Failed to prep RCC just made by make_hole_in_prepped_regions()!!!\n");
    }

    /* initialize the soltabs list of containing regions */
    bu_ptbl_init(&stp->st_regions, BU_PTBL_LEN(regions), "stp->st_regions");

    /* Subtract the new RCC from each region structure in the list provided */
    for (i=0; i<BU_PTBL_LEN(regions); i++) {
	struct region *rp;
	union tree *treep;

	/* get the next region structure */
	rp = (struct region *)BU_PTBL_GET(regions, i);

	RT_CK_REGION(rp);

	/* create a tree node for the subtraction operation, this will be the new tree root */
	BU_ALLOC(treep, union tree);
	RT_TREE_INIT(treep);
	treep->tr_b.tb_op = OP_SUBTRACT;
	treep->tr_b.tb_left = rp->reg_treetop;	/* subtract from the old treetop */
	treep->tr_b.tb_regionp = rp;

	/* make the new node the new treetop */
	rp->reg_treetop = treep;

	/* create a tree node for the new RCC */
	BU_ALLOC(treep, union tree);
	RT_TREE_INIT(treep);
	treep->tr_a.tu_op = OP_SOLID;
	treep->tr_a.tu_stp = stp;
	treep->tr_a.tu_regionp = rp;

	/* the new RCC gets hung on the right of the subtract node */
	rp->reg_treetop->tr_b.tb_right = treep;

	/* make sure the "all unions" flag is not set on this region */
	rp->reg_all_unions = 0;

	/* Add this region to the list of containing regions for the new RCC */
	bu_ptbl_ins(&stp->st_regions, (long *)rp);
    }

    /* insert the new RCC soltab structure into the already existing space partitioning tree */
    insert_in_bsp(stp, &rtip->rti_CutHead);

    return 0;
}
Ejemplo n.º 22
0
int
parse_model_string(struct bu_vls *format, struct bu_vls *log, const char *opt, const char *input)
{
    int type_int = 0;
    mime_model_t type = MIME_MODEL_UNKNOWN;

    struct bu_vls format_cpy = BU_VLS_INIT_ZERO;
    struct bu_vls path = BU_VLS_INIT_ZERO;

    if (UNLIKELY(!input) || UNLIKELY(strlen(input) == 0)) return MIME_MODEL_UNKNOWN;

    /* If an external routine has specified a format string, that string will
     * override the file extension (but not an explicit option or format prefix.
     * Stash any local format string here for later processing.  The idea is
     * to allow some other routine (say, an introspection of a file looking for
     * some signature string) to override a file extension based type identification.
     * Such introspection is beyond the scope of this function, but should override
     * the file extension mechanism. */
    if (format) bu_vls_sprintf(&format_cpy, "%s", bu_vls_addr(format));

    /* If we have an explicit option, that overrides any other format specifiers */
    if (opt) {
	type_int = bu_file_mime(opt, MIME_MODEL);
	type = (type_int < 0) ? MIME_MODEL_UNKNOWN : (mime_model_t)type_int;
	if (type == MIME_MODEL_UNKNOWN) {
	    /* Have prefix, but doesn't result in a known format - that's an error */
	    if (log) bu_vls_printf(log, "Error: unknown model format \"%s\" specified as an option.\n", opt);
	    bu_vls_free(&format_cpy);
	    return -1;
	}
    }

    /* Try for a format prefix */
    if (extract_format_prefix(format, input)) {
	/* If we don't already have a valid type and we had a format prefix,
	 * find out if it maps to a valid type */
	if (type == MIME_MODEL_UNKNOWN && format) {
	    /* Yes - see if the prefix specifies a model format */
	    type_int = bu_file_mime(bu_vls_addr(format), MIME_MODEL);
	    type = (type_int < 0) ? MIME_MODEL_UNKNOWN : (mime_model_t)type_int;
	    if (type == MIME_MODEL_UNKNOWN) {
		/* Have prefix, but doesn't result in a known format - that's an error */
		if (log) bu_vls_printf(log, "Error: unknown model format \"%s\" specified as a format prefix.\n", bu_vls_addr(format));
		bu_vls_free(&format_cpy);
		return -1;
	    }
	}
    }

    /* If we don't already have a type and we were passed a format string, give it a try */
    if (type == MIME_MODEL_UNKNOWN && format && bu_vls_strlen(&format_cpy) > 0) {
	bu_vls_sprintf(format, "%s", bu_vls_addr(&format_cpy));
	type_int = bu_file_mime(bu_vls_addr(&format_cpy), MIME_MODEL);
	type = (type_int < 0) ? MIME_MODEL_UNKNOWN : (mime_model_t)type_int;
	if (type == MIME_MODEL_UNKNOWN) {
	    /* Have prefix, but doesn't result in a known format - that's an error */
	    if (log) bu_vls_printf(log, "Error: unknown model format \"%s\" passed to parse_model_string.\n", bu_vls_addr(format));
	    bu_vls_free(&format_cpy);
	    return -1;
	}
    }

    /* If we have no prefix or the prefix didn't map to a model type, try file extension */
    if (type == MIME_MODEL_UNKNOWN && extract_path(&path, input)) {
	if (bu_path_component(format, bu_vls_addr(&path), PATH_EXTENSION)) {
	    type_int = bu_file_mime(bu_vls_addr(format), MIME_MODEL);
	    type = (type_int < 0) ? MIME_MODEL_UNKNOWN : (mime_model_t)type_int;
	    if (type == MIME_MODEL_UNKNOWN) {
		/* Have file extension, but doesn't result in a known format - that's an error */
		if (log) bu_vls_printf(log, "Error: file extension \"%s\" does not map to a known model format.\n", bu_vls_addr(format));
		bu_vls_free(&format_cpy);
		bu_vls_free(&path);
		return -1;
	    }
	}
    }
    bu_vls_free(&path);
    bu_vls_free(&format_cpy);
    return (int)type;
}
Ejemplo n.º 23
0
int
main(int ac, char **av)
{
    int fmt = 0;
    int ret = 0;
    int ac_offset = 0;
    const char *in_fmt = NULL;
    const char *out_fmt = NULL;
    mime_model_t in_type = MIME_MODEL_UNKNOWN;
    mime_model_t out_type = MIME_MODEL_UNKNOWN;
    struct bu_vls in_format = BU_VLS_INIT_ZERO;
    struct bu_vls in_path = BU_VLS_INIT_ZERO;
    struct bu_vls out_format = BU_VLS_INIT_ZERO;
    struct bu_vls out_path = BU_VLS_INIT_ZERO;
    struct bu_vls log = BU_VLS_INIT_ZERO;
    struct bu_vls input_opts = BU_VLS_INIT_ZERO;
    struct bu_vls output_opts = BU_VLS_INIT_ZERO;

    ac-=(ac>0); av+=(ac>0); // skip program name argv[0] if present
    ac_offset = (ac > 2) ? 2 : 0;  // The last two argv entries must always be the input and output paths

    /* Handle anything else as options */
    option::Stats stats(TopUsage, ac - ac_offset, av);
    option::Option *options = (option::Option *)bu_calloc(stats.options_max, sizeof(option::Option), "options");
    option::Option *buffer= (option::Option *)bu_calloc(stats.buffer_max, sizeof(option::Option), "options");
    option::Parser parse(TopUsage, ac - ac_offset, av, options, buffer);

    /* Now that we've parsed them, start using them */
    if (options[HELP] || ac == 0) {
	if (options[HELP].arg) {
	    int help_type_int = bu_file_mime(options[HELP].arg, MIME_MODEL);
	    switch (help_type_int) {
		case MIME_MODEL_VND_FASTGEN:
		    option::printUsage(std::cout, Fast4Usage);
		    break;
		case MIME_MODEL_STL:
		    option::printUsage(std::cout, STLUsage);
		    break;
		default:
		    option::printUsage(std::cout, TopUsage);
		    break;
	    }
	} else {
	    option::printUsage(std::cout, TopUsage);
	    // TODO - figure out how to get this info from each plugin to construct this table
	    // on the fly...
	    bu_log("\nSupported formats:\n");
	    bu_log(" ------------------------------------------------------------\n");
	    bu_log(" | Extension  |          File Format      |  Input | Output |\n");
	    bu_log(" |----------------------------------------------------------|\n");
	    bu_log(" |    stl     |   STereoLithography       |   Yes  |   Yes  |\n");
	    bu_log(" |------------|---------------------------|--------|--------|\n");
	    bu_log(" |    obj     |   Wavefront Object        |   Yes  |   Yes  |\n");
	    bu_log(" |------------|---------------------------|--------|--------|\n");
	    bu_log(" |    step    |   STEP (AP203)            |   Yes  |   Yes  |\n");
	    bu_log(" |------------|---------------------------|--------|--------|\n");
	    bu_log(" |    iges    |   Initial Graphics        |   Yes  |   No   |\n");
	    bu_log(" |            |   Exchange Specification  |        |        |\n");
	    bu_log(" |----------------------------------------------------------|\n");
	}
	goto cleanup;
    }

    /* Any args that weren't top level args will get passed to the
     * format specific arg processing routines, after we use the known
     * top level options and the path inputs to determine what the file
     * types in question are.  Steps:
     *
     * 1.  Reassemble the unknown args into strings. */
    reassemble_argstr(&input_opts, &output_opts, options[UNKNOWN]);
    if (bu_vls_strlen(&input_opts) > 0) bu_log("Unknown options (input): %s\n", bu_vls_addr(&input_opts));
    if (bu_vls_strlen(&output_opts) > 0) bu_log("Unknown options (output): %s\n", bu_vls_addr(&output_opts));
    /*
     * 2.  Use bu_argv_from_string to create new
     * arrays to be fed to the format specific option parsers.*/

    /* TODO - determine whether we want to have a specific option prefix,
     * such as in- and out-, to identify an option as specific to the
     * input file format suboption parser only.  i.e.:
     *
     * --in-tol=1.0  -> --tol=1.0 to the input file's suboptions only
     * --out-tol=2.0 -> --tol=2.0 to the input file's suboptions only
     * --tol=1.5     -> --tol=1.5 to both input and output suboptions
     *
     *  consistent with top level --in-format and --out-format options
     *
     */

    /* See if we have input and output files specified */
    if (!extract_path(&in_path, av[ac-2])) {
	bu_vls_printf(&log, "Error: no input path identified: %s\n", av[ac-2]);
	ret = 1;
    }
    if (!extract_path(&out_path, av[ac-1])) {
	bu_vls_printf(&log, "Error: no output path identified: %s\n", av[ac-1]);
	ret = 1;
    }

    /* Make sure we have distinct input and output paths */
    if (bu_vls_strlen(&in_path) > 0 && BU_STR_EQUAL(bu_vls_addr(&in_path), bu_vls_addr(&out_path))) {
	bu_vls_printf(&log, "Error: identical path specified for both input and output: %s\n", bu_vls_addr(&out_path));
	ret = 1;
    }

    /* Find out what input file type we are dealing with */
    if (options[IN_FORMAT]) {
	in_fmt = options[IN_FORMAT].arg;
    } else {
	/* If we aren't overridden by an option, it's worth doing file
	 * introspection to see if the file contents identify the input
	 * type solidly, provided we have that capability.*/

	/* fake type introspection for testing: */
	//bu_vls_sprintf(&in_format, "step");
    }
    fmt = parse_model_string(&in_format, &log, in_fmt, av[ac-2]);
    in_type = (fmt < 0) ? MIME_MODEL_UNKNOWN : (mime_model_t)fmt;
    in_fmt = NULL;

    /* Identify output file type */
    if (options[OUT_FORMAT]) out_fmt = options[OUT_FORMAT].arg;
    fmt = parse_model_string(&out_format, &log, out_fmt, av[ac-1]);
    out_type = (fmt < 0) ? MIME_MODEL_UNKNOWN : (mime_model_t)fmt;
    out_fmt = NULL;

    /* If we get to this point without knowing both input and output types, we've got a problem */
    if (in_type == MIME_MODEL_UNKNOWN) {
	bu_vls_printf(&log, "Error: no format type identified for input path: %s\n", bu_vls_addr(&in_path));
	ret = 1;
    }
    if (out_type == MIME_MODEL_UNKNOWN) {
	bu_vls_printf(&log, "Error: no format type identified for output path: %s\n", bu_vls_addr(&out_path));
	ret = 1;
    }

    /* If everything isn't OK, we're done - report and clean up memory */
    if (ret == 1) goto cleanup;

    /* If we've gotten this far, we know enough to try to convert. Until we
     * hook in conversion calls to libgcv, print a summary of the option
     * parsing results for debugging. */
    in_fmt = bu_file_mime_str((int)in_type, MIME_MODEL);
    out_fmt = bu_file_mime_str((int)out_type, MIME_MODEL);
    bu_log("Input file format: %s\n", in_fmt);
    bu_log("Output file format: %s\n", out_fmt);
    bu_log("Input file path: %s\n", bu_vls_addr(&in_path));
    bu_log("Output file path: %s\n", bu_vls_addr(&out_path));

    switch (in_type) {
	case MIME_MODEL_VND_FASTGEN:
	    fast4_arg_process(bu_vls_addr(&input_opts));
	    break;
	case MIME_MODEL_STL:
	    stl_arg_process(bu_vls_addr(&input_opts));
	default:
	    break;
    }

    switch (out_type) {
	case MIME_MODEL_VND_FASTGEN:
	    fast4_arg_process(bu_vls_addr(&output_opts));
	    break;
	case MIME_MODEL_STL:
	    stl_arg_process(bu_vls_addr(&output_opts));
	default:
	    break;
    }



    /* Clean up */
cleanup:
    if (bu_vls_strlen(&log) > 0) bu_log("%s", bu_vls_addr(&log));
    if (in_fmt) bu_free((char *)in_fmt, "input format string");
    if (out_fmt) bu_free((char *)out_fmt, "output format string");
    bu_free(options, "free options");
    bu_free(buffer, "free buffer");
    bu_vls_free(&in_format);
    bu_vls_free(&in_path);
    bu_vls_free(&out_format);
    bu_vls_free(&out_path);
    bu_vls_free(&log);
    bu_vls_free(&input_opts);
    bu_vls_free(&output_opts);

    return ret;
}
Ejemplo n.º 24
0
/*
 * F _ N I R T
 *
 * Invoke nirt with the current view & stuff
 */
int
dgo_nirt_cmd(struct dg_obj *dgop,
	     struct view_obj *vop,
	     int argc,
	     const char **argv)
{
    const char **vp;
    FILE *fp_in;
    FILE *fp_out, *fp_err;
#ifndef _WIN32
    int ret;
    size_t sret;
    int pid, rpid;
    int retcode;
    int pipe_in[2];
    int pipe_out[2];
    int pipe_err[2];
#else
    HANDLE pipe_in[2], pipe_inDup;
    HANDLE pipe_out[2], pipe_outDup;
    HANDLE pipe_err[2], pipe_errDup;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    char name[1024];
    char line1[2048];
    int rem = 2048;
#endif
    int use_input_orig = 0;
    vect_t center_model;
    vect_t dir;
    vect_t cml;
    int i;
    struct solid *sp;
    char line[RT_MAXLINE];
    char *val;
    struct bu_vls vls = BU_VLS_INIT_ZERO;
    struct bu_vls o_vls = BU_VLS_INIT_ZERO;
    struct bu_vls p_vls = BU_VLS_INIT_ZERO;
    struct bu_vls t_vls = BU_VLS_INIT_ZERO;
    struct bn_vlblock *vbp;
    struct dg_qray_dataList *ndlp;
    struct dg_qray_dataList HeadQRayData;
    int args;

    args = argc + 20 + 2 + dgo_count_tops((struct solid *)&dgop->dgo_headSolid);
    dgop->dgo_rt_cmd = (char **)bu_calloc(args, sizeof(char *), "alloc dgo_rt_cmd");

    vp = (const char **)&dgop->dgo_rt_cmd[0];
    *vp++ = "nirt";

    /* swipe x, y, z off the end if present */
    if (argc > 3) {
	double scan[3];

	if (sscanf(argv[argc-3], "%lf", &scan[X]) == 1 &&
	    sscanf(argv[argc-2], "%lf", &scan[Y]) == 1 &&
	    sscanf(argv[argc-1], "%lf", &scan[Z]) == 1)
	{

	    VMOVE(center_model, scan);
	    use_input_orig = 1;
	    argc -= 3;
	    VSCALE(center_model, center_model, dgop->dgo_wdbp->dbip->dbi_local2base);
	}
    }

    /* Calculate point from which to fire ray */
    if (!use_input_orig) {
	VSET(center_model, -vop->vo_center[MDX],
	     -vop->vo_center[MDY], -vop->vo_center[MDZ]);
    }

    VSCALE(cml, center_model, dgop->dgo_wdbp->dbip->dbi_base2local);
    VMOVEN(dir, vop->vo_rotation + 8, 3);
    VSCALE(dir, dir, -1.0);

    bu_vls_printf(&p_vls, "xyz %lf %lf %lf;",
		  cml[X], cml[Y], cml[Z]);
    bu_vls_printf(&p_vls, "dir %lf %lf %lf; s",
		  dir[X], dir[Y], dir[Z]);

    i = 0;
    if (DG_QRAY_GRAPHICS(dgop)) {

	*vp++ = "-e";
	*vp++ = DG_QRAY_FORMAT_NULL;

	/* first ray ---- returns partitions */
	*vp++ = "-e";
	*vp++ = DG_QRAY_FORMAT_P;

	/* ray start, direction, and 's' command */
	*vp++ = "-e";
	*vp++ = bu_vls_addr(&p_vls);

	/* second ray ---- returns overlaps */
	*vp++ = "-e";
	*vp++ = DG_QRAY_FORMAT_O;

	/* ray start, direction, and 's' command */
	*vp++ = "-e";
	*vp++ = bu_vls_addr(&p_vls);

	if (DG_QRAY_TEXT(dgop)) {
	    char *cp;
	    int count = 0;

	    /* get 'r' format now; prepend its' format string with a newline */
	    val = bu_vls_addr(&dgop->dgo_qray_fmts[0].fmt);

	    /* find first '"' */
	    while (*val != '"' && *val != '\0')
		++val;

	    if (*val == '\0')
		goto done;
	    else
		++val;	    /* skip first '"' */

	    /* find last '"' */
	    cp = (char *)strrchr(val, '"');

	    if (cp != (char *)NULL) /* found it */
		count = cp - val;

	done:
	    if (*val == '\0')
		bu_vls_printf(&o_vls, " fmt r \"\\n\" ");
	    else {
		struct bu_vls tmp = BU_VLS_INIT_ZERO;
		bu_vls_strncpy(&tmp, val, count);
		bu_vls_printf(&o_vls, " fmt r \"\\n%V\" ", &tmp);
		bu_vls_free(&tmp);

		if (count)
		    val += count + 1;
		bu_vls_printf(&o_vls, "%s", val);
	    }

	    i = 1;

	    *vp++ = "-e";
	    *vp++ = bu_vls_addr(&o_vls);
	}
    }

    if (DG_QRAY_TEXT(dgop)) {

	/* load vp with formats for printing */
	for (; dgop->dgo_qray_fmts[i].type != (char)0; ++i)
	    bu_vls_printf(&t_vls, "fmt %c %s; ",
			  dgop->dgo_qray_fmts[i].type,
			  bu_vls_addr(&dgop->dgo_qray_fmts[i].fmt));

	*vp++ = "-e";
	*vp++ = bu_vls_addr(&t_vls);

	/* nirt does not like the trailing ';' */
	bu_vls_trunc(&t_vls, -2);
    }

    /* include nirt script string */
    if (bu_vls_strlen(&dgop->dgo_qray_script)) {
	*vp++ = "-e";
	*vp++ = bu_vls_addr(&dgop->dgo_qray_script);
    }

    *vp++ = "-e";
    *vp++ = bu_vls_addr(&p_vls);

    for (i = 1; i < argc; i++)
	*vp++ = argv[i];
    *vp++ = dgop->dgo_wdbp->dbip->dbi_filename;

    dgop->dgo_rt_cmd_len = (char **)vp - (char **)dgop->dgo_rt_cmd;

    /* Note - dgo_build_tops sets the last vp to (char *)0 */
    dgop->dgo_rt_cmd_len += dgo_build_tops((struct solid *)&dgop->dgo_headSolid,
					   vp,
					   (const char **)&dgop->dgo_rt_cmd[args]);

    if (dgop->dgo_qray_cmd_echo) {
	/* Print out the command we are about to run */
	vp = (const char **)&dgop->dgo_rt_cmd[0];
	while (*vp)
	    Tcl_AppendResult(dgop->interp, *vp++, " ", (char *)NULL);

	Tcl_AppendResult(dgop->interp, "\n", (char *)NULL);
    }

    if (use_input_orig) {
	bu_vls_printf(&vls, "\nFiring from (%lf, %lf, %lf)...\n",
		      center_model[X], center_model[Y], center_model[Z]);
	Tcl_AppendResult(dgop->interp, bu_vls_addr(&vls), (char *)NULL);
	bu_vls_free(&vls);
    } else
	Tcl_AppendResult(dgop->interp, "\nFiring from view center...\n", (char *)NULL);

#ifndef _WIN32
    ret = pipe(pipe_in);
    if (ret < 0)
	perror("pipe");
    ret = pipe(pipe_out);
    if (ret < 0)
	perror("pipe");
    ret = pipe(pipe_err);
    if (ret < 0)
	perror("pipe");
    (void)signal(SIGINT, SIG_IGN);
    if ((pid = fork()) == 0) {
	/* Redirect stdin, stdout, stderr */
	(void)close(0);
	ret = dup(pipe_in[0]);
	if (ret < 0)
	    perror("dup");
	(void)close(1);
	ret = dup(pipe_out[1]);
	if (ret < 0)
	    perror("dup");
	(void)close(2);
	ret = dup(pipe_err[1]);
	if (ret < 0)
	    perror("dup");

	/* close pipes */
	(void)close(pipe_in[0]);
	(void)close(pipe_in[1]);
	(void)close(pipe_out[0]);
	(void)close(pipe_out[1]);
	(void)close(pipe_err[0]);
	(void)close(pipe_err[1]);
	for (i = 3; i < 20; i++)
	    (void)close(i);
	(void)signal(SIGINT, SIG_DFL);
	(void)execvp(dgop->dgo_rt_cmd[0], dgop->dgo_rt_cmd);
	perror (dgop->dgo_rt_cmd[0]);
	exit(16);
    }

    /* use fp_in to feed view info to nirt */
    (void)close(pipe_in[0]);
    fp_in = fdopen(pipe_in[1], "w");

    /* use fp_out to read back the result */
    (void)close(pipe_out[1]);
    fp_out = fdopen(pipe_out[0], "r");

    /* use fp_err to read any error messages */
    (void)close(pipe_err[1]);
    fp_err = fdopen(pipe_err[0], "r");

    /* send quit command to nirt */
    sret = fwrite("q\n", 1, 2, fp_in);
    if (sret != 2)
	bu_log("fwrite failure\n");

    (void)fclose(fp_in);

#else
    memset((void *)&si, 0, sizeof(STARTUPINFO));
    memset((void *)&pi, 0, sizeof(PROCESS_INFORMATION));
    memset((void *)&sa, 0, sizeof(SECURITY_ATTRIBUTES));

    sa.nLength = sizeof(sa);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    /* Create a pipe for the child process's STDOUT. */
    CreatePipe(&pipe_out[0], &pipe_out[1], &sa, 0);

    /* Create noninheritable read handle and close the inheritable read handle. */
    DuplicateHandle(GetCurrentProcess(), pipe_out[0],
		    GetCurrentProcess(),  &pipe_outDup ,
		    0,  FALSE,
		    DUPLICATE_SAME_ACCESS);
    CloseHandle(pipe_out[0]);

    /* Create a pipe for the child process's STDERR. */
    CreatePipe(&pipe_err[0], &pipe_err[1], &sa, 0);

    /* Create noninheritable read handle and close the inheritable read handle. */
    DuplicateHandle(GetCurrentProcess(), pipe_err[0],
		    GetCurrentProcess(),  &pipe_errDup ,
		    0,  FALSE,
		    DUPLICATE_SAME_ACCESS);
    CloseHandle(pipe_err[0]);

    /* The steps for redirecting child process's STDIN:
     *     1.  Save current STDIN, to be restored later.
     *     2.  Create anonymous pipe to be STDIN for child process.
     *     3.  Set STDIN of the parent to be the read handle to the
     *         pipe, so it is inherited by the child process.
     *     4.  Create a noninheritable duplicate of the write handle,
     *         and close the inheritable write handle.
     */

    /* Create a pipe for the child process's STDIN. */
    CreatePipe(&pipe_in[0], &pipe_in[1], &sa, 0);

    /* Duplicate the write handle to the pipe so it is not inherited. */
    DuplicateHandle(GetCurrentProcess(), pipe_in[1],
		    GetCurrentProcess(), &pipe_inDup,
		    0, FALSE,                  /* not inherited */
		    DUPLICATE_SAME_ACCESS);
    CloseHandle(pipe_in[1]);

    si.cb = sizeof(STARTUPINFO);
    si.lpReserved = NULL;
    si.lpReserved2 = NULL;
    si.cbReserved2 = 0;
    si.lpDesktop = NULL;
    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.hStdInput   = pipe_in[0];
    si.hStdOutput  = pipe_out[1];
    si.hStdError   = pipe_err[1];
    si.wShowWindow = SW_HIDE;

    snprintf(line1, rem, "%s ", dgop->dgo_rt_cmd[0]);
    rem -= (int)strlen(line1) - 1;

    for (i = 1; i < dgop->dgo_rt_cmd_len; i++) {
	/* skip commands */
	if (strstr(dgop->dgo_rt_cmd[i], "-e") != NULL)
	    ++i;
	else {
	    /* append other arguments (i.e. options, file and obj(s)) */
	    snprintf(name, 1024, "\"%s\" ", dgop->dgo_rt_cmd[i]);
	    if (rem - strlen(name) < 1) {
		bu_log("Ran out of buffer space!");
		bu_free(dgop->dgo_rt_cmd, "free dgo_rt_cmd");
		dgop->dgo_rt_cmd = NULL;
		return TCL_ERROR;
	    }
	    bu_strlcat(line1, name, sizeof(line1));
	    rem -= (int)strlen(name);
	}
    }

    CreateProcess(NULL, line1, NULL, NULL, TRUE,
		  DETACHED_PROCESS, NULL, NULL,
		  &si, &pi);

    /* use fp_in to feed view info to nirt */
    CloseHandle(pipe_in[0]);
    fp_in = _fdopen(_open_osfhandle((intptr_t)pipe_inDup, _O_TEXT), "wb");
    setmode(fileno(fp_in), O_BINARY);

    /* send commands down the pipe */
    for (i = 1; i < dgop->dgo_rt_cmd_len-2; i++)
	if (strstr(dgop->dgo_rt_cmd[i], "-e") != NULL)
	    fprintf(fp_in, "%s\n", dgop->dgo_rt_cmd[++i]);

    /* use fp_out to read back the result */
    CloseHandle(pipe_out[1]);
    fp_out = _fdopen(_open_osfhandle((intptr_t)pipe_outDup, _O_TEXT), "rb");
    setmode(fileno(fp_out), O_BINARY);

    /* use fp_err to read any error messages */
    CloseHandle(pipe_err[1]);
    fp_err = _fdopen(_open_osfhandle((intptr_t)pipe_errDup, _O_TEXT), "rb");
    setmode(fileno(fp_err), O_BINARY);

    /* send quit command to nirt */
    fwrite("q\n", 1, 2, fp_in);
    (void)fclose(fp_in);

#endif

    bu_vls_free(&p_vls);   /* use to form "partition" part of nirt command above */
    if (DG_QRAY_GRAPHICS(dgop)) {
	double scan[4];

	if (DG_QRAY_TEXT(dgop))
	    bu_vls_free(&o_vls); /* used to form "overlap" part of nirt command above */

	BU_LIST_INIT(&HeadQRayData.l);

	/* handle partitions */
	while (bu_fgets(line, RT_MAXLINE, fp_out) != (char *)NULL) {
	    if (line[0] == '\n') {
		Tcl_AppendResult(dgop->interp, line+1, (char *)NULL);
		break;
	    }

	    BU_ALLOC(ndlp, struct dg_qray_dataList);
	    BU_LIST_APPEND(HeadQRayData.l.back, &ndlp->l);

	    if (sscanf(line, "%le %le %le %le",
		       &scan[0], &scan[1], &scan[2], &scan[3]) != 4)
		break;
	    ndlp->x_in = scan[0];
	    ndlp->y_in = scan[1];
	    ndlp->z_in = scan[2];
	    ndlp->los = scan[3];
	}

	vbp = rt_vlblock_init();
	dgo_qray_data_to_vlist(dgop, vbp, &HeadQRayData, dir, 0);
	bu_list_free(&HeadQRayData.l);
	dgo_cvt_vlblock_to_solids(dgop, vbp, bu_vls_addr(&dgop->dgo_qray_basename), 0);
	rt_vlblock_free(vbp);

	/* handle overlaps */
	while (bu_fgets(line, RT_MAXLINE, fp_out) != (char *)NULL) {
	    if (line[0] == '\n') {
		Tcl_AppendResult(dgop->interp, line+1, (char *)NULL);
		break;
	    }

	    BU_ALLOC(ndlp, struct dg_qray_dataList);
	    BU_LIST_APPEND(HeadQRayData.l.back, &ndlp->l);

	    if (sscanf(line, "%le %le %le %le",
		       &scan[0], &scan[1], &scan[2], &scan[3]) != 4)
		break;
	    ndlp->x_in = scan[0];
	    ndlp->y_in = scan[1];
	    ndlp->z_in = scan[2];
	    ndlp->los = scan[3];
	}
	vbp = rt_vlblock_init();
	dgo_qray_data_to_vlist(dgop, vbp, &HeadQRayData, dir, 1);
	bu_list_free(&HeadQRayData.l);
	dgo_cvt_vlblock_to_solids(dgop, vbp, bu_vls_addr(&dgop->dgo_qray_basename), 0);
	rt_vlblock_free(vbp);
    }

    /*
     * Notify observers, if any, before generating textual output since
     * such an act (observer notification) wipes out whatever gets stuffed
     * into the result.
     */
    dgo_notify(dgop);

    if (DG_QRAY_TEXT(dgop)) {
	bu_vls_free(&t_vls);

	while (bu_fgets(line, RT_MAXLINE, fp_out) != (char *)NULL)
	    Tcl_AppendResult(dgop->interp, line, (char *)NULL);
    }

    (void)fclose(fp_out);

    while (bu_fgets(line, RT_MAXLINE, fp_err) != (char *)NULL)
	Tcl_AppendResult(dgop->interp, line, (char *)NULL);
    (void)fclose(fp_err);


#ifndef _WIN32

    /* Wait for program to finish */
    while ((rpid = wait(&retcode)) != pid && rpid != -1)
	;	/* NULL */

    if (retcode != 0)
	pr_wait_status(dgop->interp, retcode);
#else
    /* Wait for program to finish */
    WaitForSingleObject(pi.hProcess, INFINITE);

#endif

    FOR_ALL_SOLIDS(sp, &dgop->dgo_headSolid)
	sp->s_wflag = DOWN;

    bu_free(dgop->dgo_rt_cmd, "free dgo_rt_cmd");
    dgop->dgo_rt_cmd = NULL;

    return TCL_OK;
}
Ejemplo n.º 25
0
/*
 * Given a u, v coordinate within the texture (0 <= u, v <= 1.0),
 * return the filtered intensity.
 *
 * Note that .bw files are stored left-to-right, bottom-to-top,
 * which works out very naturally for the indexing scheme.
 */
HIDDEN int
bwtxt_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
{
    register struct txt_specific *tp =
	(struct txt_specific *)dp;
    fastf_t xmin, xmax, ymin, ymax;
    int line;
    int dx, dy;
    int x, y;
    register long bw;
    struct uvcoord uvc;
    long tmp;

    uvc = swp->sw_uv;

    /*
     * If no texture file present, or if
     * texture isn't and can't be read, give debug colors
     */
    if ((bu_vls_strlen(&tp->tx_name) <= 0) || (!tp->tx_mp && !tp->tx_binunifp)) {
	VSET(swp->sw_color, uvc.uv_u, 0, uvc.uv_v);
	if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
	    (void)rr_render(ap, pp, swp);
	return 1;
    }

    /* take care of scaling U, V coordinates to get the desired amount
     * of replication of the texture
     */
    uvc.uv_u *= tp->tx_scale[X];
    tmp = uvc.uv_u;
    uvc.uv_u -= tmp;
    if (tp->tx_mirror && (tmp & 1))
	uvc.uv_u = 1.0 - uvc.uv_u;

    uvc.uv_v *= tp->tx_scale[Y];
    tmp = uvc.uv_v;
    uvc.uv_v -= tmp;
    if (tp->tx_mirror && (tmp & 1))
	uvc.uv_v = 1.0 - uvc.uv_v;

    uvc.uv_du /= tp->tx_scale[X];
    uvc.uv_dv /= tp->tx_scale[Y];


    /* u is left->right index, v is line number bottom->top */
    /* Don't filter more than 1/8 of the texture for 1 pixel! */
    if (uvc.uv_du > 0.125) uvc.uv_du = 0.125;
    if (uvc.uv_dv > 0.125) uvc.uv_dv = 0.125;

    if (uvc.uv_du < 0 || uvc.uv_dv < 0) {
	bu_log("bwtxt_render uv=%g, %g, du dv=%g %g seg=%s\n",
	       uvc.uv_u, uvc.uv_v, uvc.uv_du, uvc.uv_dv,
	       pp->pt_inseg->seg_stp->st_name);
	uvc.uv_du = uvc.uv_dv = 0;
    }
    xmin = uvc.uv_u - uvc.uv_du;
    xmax = uvc.uv_u + uvc.uv_du;
    ymin = uvc.uv_v - uvc.uv_dv;
    ymax = uvc.uv_v + uvc.uv_dv;
    if (xmin < 0) xmin = 0;
    if (ymin < 0) ymin = 0;
    if (xmax > 1) xmax = 1;
    if (ymax > 1) ymax = 1;
    x = xmin * (tp->tx_w-1);
    y = ymin * (tp->tx_n-1);
    dx = (xmax - xmin) * (tp->tx_w-1);
    dy = (ymax - ymin) * (tp->tx_n-1);
    if (dx < 1) dx = 1;
    if (dy < 1) dy = 1;
    bw = 0;
    for (line = 0; line < dy; line++) {
	register unsigned char *cp=NULL;
	register unsigned char *ep;

	if (tp->tx_mp) {
	    cp = ((unsigned char *)(tp->tx_mp->buf)) +
		(y+line) * tp->tx_w + x;
	} else if (tp->tx_binunifp) {
	    cp = ((unsigned char *)(tp->tx_binunifp->u.uint8)) +
		(y+line) * tp->tx_w + x;
	} else {
	    /* not reachable */
	    bu_bomb("sh_text.c -- Unable to read datasource\n");
	}

	ep = cp + dx;
	while (cp < ep) {
	    bw += *cp++;
	}
    }

    if (!tp->tx_trans_valid) {
    opaque:
	VSETALL(swp->sw_color,
		(bw / 255.0) / (dx*dy));
	if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
	    (void)rr_render(ap, pp, swp);
	return 1;
    }
    /* This circumlocution needed to keep expression simple for Cray,
     * and others
     */
    if (bw / (dx*dy) != ((long)tp->tx_transp[0])) goto opaque;

    /*
     * Transparency mapping is enabled, and we hit a transparent spot.
     * Let higher level handle it in reflect/refract code.
     */
    swp->sw_transmit = 1.0;
    swp->sw_reflect = 0.0;
    if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
	(void)rr_render(ap, pp, swp);
    return 1;
}
Ejemplo n.º 26
0
/*
 *			D O _ R E G I O N _ E N D
 *
 *  Called from db_walk_tree().
 *
 *  This routine must be prepared to run in parallel.
 */
union tree *do_region_end(register struct db_tree_state *tsp, struct db_full_path *pathp, union tree *curtree, genptr_t client_data)
{
    union tree		*ret_tree;
    struct nmgregion	*r;
    struct bu_list		vhead;

    RT_CK_TESS_TOL(tsp->ts_ttol);
    BN_CK_TOL(tsp->ts_tol);
    NMG_CK_MODEL(*tsp->ts_m);

    BU_LIST_INIT(&vhead);

    if (RT_G_DEBUG&DEBUG_TREEWALK || verbose) {
	char	*sofar = db_path_to_string(pathp);
	bu_log("\ndo_region_end(%d %d%%) %s\n",
	       regions_tried,
	       regions_tried>0 ? (regions_done * 100) / regions_tried : 0,
	       sofar);
	bu_free(sofar, "path string");
    }

    if (curtree->tr_op == OP_NOP)
	return  curtree;

    regions_tried++;

    /* Begin bomb protection */
    if ( ncpu == 1 ) {
	if ( BU_SETJUMP )  {
	    /* Error, bail out */
	    BU_UNSETJUMP;		/* Relinquish the protection */

	    /* Sometimes the NMG library adds debugging bits when
	     * it detects an internal error, before bombing out.
	     */
	    rt_g.NMG_debug = NMG_debug;	/* restore mode */

	    /* Release the tree memory & input regions */
	    db_free_tree(curtree, &rt_uniresource);		/* Does an nmg_kr() */

	    /* Get rid of (m)any other intermediate structures */
	    if ( (*tsp->ts_m)->magic != -1L )
		nmg_km(*tsp->ts_m);

	    /* Now, make a new, clean model structure for next pass. */
	    *tsp->ts_m = nmg_mm();
	    goto out;
	}
    }
    (void)nmg_model_fuse(*tsp->ts_m, tsp->ts_tol);
    ret_tree = nmg_booltree_evaluate(curtree, tsp->ts_tol, &rt_uniresource);	/* librt/nmg_bool.c */
    BU_UNSETJUMP;		/* Relinquish the protection */
    if ( ret_tree )
	r = ret_tree->tr_d.td_r;
    else
	r = (struct nmgregion *)NULL;
    regions_done++;
    if (r != 0) {
	FILE	*fp_psurf;
	int	i;
	struct bu_vls	file_base;
	struct bu_vls	file;

	bu_vls_init(&file_base);
	bu_vls_init(&file);
	bu_vls_strcpy(&file_base, prefix);
	bu_vls_strcat(&file_base, DB_FULL_PATH_CUR_DIR(pathp)->d_namep);
	/* Dots confuse Jack's Peabody language.  Change to '_'. */
	for (i = 0; i < file_base.vls_len; i++)
	    if (file_base.vls_str[i] == '.')
		file_base.vls_str[i] = '_';

	/* Write color attribute to .fig figure file. */
	if (tsp->ts_mater.ma_color_valid != 0) {
	    fprintf(fp_fig, "\tattribute %s {\n",
		    bu_vls_addr(&file_base));
	    fprintf(fp_fig, "\t\trgb = (%f, %f, %f);\n",
		    V3ARGS(tsp->ts_mater.ma_color));
	    fprintf(fp_fig, "\t\tambient = 0.18;\n");
	    fprintf(fp_fig, "\t\tdiffuse = 0.72;\n");
	    fprintf(fp_fig, "\t}\n");
	}

	/* Write segment attributes to .fig figure file. */
	fprintf(fp_fig, "\tsegment %s_seg {\n", bu_vls_addr(&file_base));
	fprintf(fp_fig, "\t\tpsurf=\"%s.pss\";\n", bu_vls_addr(&file_base));
	if (tsp->ts_mater.ma_color_valid != 0)
	    fprintf(fp_fig,
		    "\t\tattribute=%s;\n", bu_vls_addr(&file_base));
	fprintf(fp_fig, "\t\tsite base->location=trans(0, 0, 0);\n");
	fprintf(fp_fig, "\t}\n");

	if ( bu_vls_strlen(&base_seg) <= 0 )  {
	    bu_vls_vlscat( &base_seg, &file_base );
	} else {
	    fprintf(fp_fig, "\tjoint %s_jt {\n",
		    bu_vls_addr(&file_base));
	    fprintf(fp_fig,
		    "\t\tconnect %s_seg.base to %s_seg.base;\n",
		    bu_vls_addr(&file_base),
		    bu_vls_addr(&base_seg) );
	    fprintf(fp_fig, "\t}\n");
	}

	bu_vls_vlscat(&file, &file_base);
	bu_vls_strcat(&file, ".pss");	/* Required Jack suffix. */

	/* Write psurf to .pss file. */
	if ((fp_psurf = fopen(bu_vls_addr(&file), "wb")) == NULL)
	    perror(bu_vls_addr(&file));
	else {
	    nmg_to_psurf(r, fp_psurf);
	    fclose(fp_psurf);
	    if (verbose) bu_log("*** Wrote %s\n", bu_vls_addr(&file));
	}
	bu_vls_free(&file);

	/* Also write as UNIX-plot file, if desired */
	if ( debug_plots )  {
	    FILE	*fp;
	    bu_vls_vlscat(&file, &file_base);
	    bu_vls_strcat(&file, ".pl");

	    if ((fp = fopen(bu_vls_addr(&file), "wb")) == NULL)
		perror(bu_vls_addr(&file));
	    else {
		struct bu_list	vhead;
		pl_color( fp,
			  (int)(tsp->ts_mater.ma_color[0] * 255),
			  (int)(tsp->ts_mater.ma_color[1] * 255),
			  (int)(tsp->ts_mater.ma_color[2] * 255) );
		/* nmg_pl_r( fp, r ); */
		BU_LIST_INIT( &vhead );
		nmg_r_to_vlist( &vhead, r, 0 );
		rt_vlist_to_uplot( fp, &vhead );
		fclose(fp);
		if (verbose) bu_log("*** Wrote %s\n", bu_vls_addr(&file));
	    }
	    bu_vls_free(&file);
	}

	/* NMG region is no longer necessary */
	nmg_kr(r);
    }

    /*
     *  Dispose of original tree, so that all associated dynamic
     *  memory is released now, not at the end of all regions.
     *  A return of TREE_NULL from this routine signals an error,
     *  so we need to cons up an OP_NOP node to return.
     */
    db_free_tree(curtree, &rt_uniresource);		/* Does an nmg_kr() */

 out:
    BU_GETUNION(curtree, tree);
    curtree->magic = RT_TREE_MAGIC;
    curtree->tr_op = OP_NOP;
    return(curtree);
}
Ejemplo n.º 27
0
/*
 * Given a u, v coordinate within the texture (0 <= u, v <= 1.0),
 * compute a new surface normal.
 * For now we come up with a local coordinate system, and
 * make bump perturbations from the red and blue channels of
 * an RGB image.
 *
 * Note that .pix files are stored left-to-right, bottom-to-top,
 * which works out very naturally for the indexing scheme.
 */
HIDDEN int
bmp_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
{
    register struct txt_specific *tp =
	(struct txt_specific *)dp;
    unsigned char *cp=NULL;
    fastf_t pertU, pertV;
    vect_t y;		/* world coordinate axis vectors */
    vect_t u, v;		/* surface coord system vectors */
    int i, j;		/* bump map pixel indices */

    /*
     * If no texture file present, or if
     * texture isn't and can't be read, give debug color.
     */
    if ((bu_vls_strlen(&tp->tx_name) <= 0) || (!tp->tx_mp && !tp->tx_binunifp)) {
	VSET(swp->sw_color, swp->sw_uv.uv_u, 0, swp->sw_uv.uv_v);
	if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
	    (void)rr_render(ap, pp, swp);
	return 1;
    }
    /* u is left->right index, v is line number bottom->top */
    if (swp->sw_uv.uv_u < 0 || swp->sw_uv.uv_u > 1 || swp->sw_uv.uv_v < 0 || swp->sw_uv.uv_v > 1) {
	bu_log("bmp_render:  bad u, v=%g, %g du, dv=%g, %g seg=%s\n",
	       swp->sw_uv.uv_u, swp->sw_uv.uv_v,
	       swp->sw_uv.uv_du, swp->sw_uv.uv_dv,
	       pp->pt_inseg->seg_stp->st_name);
	VSET(swp->sw_color, 0, 1, 0);
	if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
	    (void)rr_render(ap, pp, swp);
	return 1;
    }

    /* Find a local coordinate system */
    VSET(y, 0, 1, 0);
    VCROSS(u, y, swp->sw_hit.hit_normal);
    VUNITIZE(u);
    VCROSS(v, swp->sw_hit.hit_normal, u);

    /* Find our RGB value */
    i = swp->sw_uv.uv_u * (tp->tx_w-1);
    j = swp->sw_uv.uv_v * (tp->tx_n-1);

    if (tp->tx_mp) {
	cp = ((unsigned char *)(tp->tx_mp->buf)) +
	    (j) * tp->tx_w * 3 + i * 3;
    } else if (tp->tx_binunifp) {
	cp = ((unsigned char *)(tp->tx_binunifp->u.uint8)) +
	    (j) * tp->tx_w * 3 + i * 3;
    } else {
	/* not reachable */
	bu_bomb("sh_text.c -- Unreachable code reached while reading datasource\n");
    }
    pertU = ((fastf_t)(*cp) - 128.0) / 128.0;
    pertV = ((fastf_t)(*(cp+2)) - 128.0) / 128.0;

    if (rdebug&RDEBUG_LIGHT) {
	VPRINT("normal", swp->sw_hit.hit_normal);
	VPRINT("u", u);
	VPRINT("v", v);
	bu_log("cu = %d, cv = %d\n", *cp, *(cp+2));
	bu_log("pertU = %g, pertV = %g\n", pertU, pertV);
    }
    VJOIN2(swp->sw_hit.hit_normal, swp->sw_hit.hit_normal, pertU, u, pertV, v);
    VUNITIZE(swp->sw_hit.hit_normal);
    if (rdebug&RDEBUG_LIGHT) {
	VPRINT("after", swp->sw_hit.hit_normal);
    }

    if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
	(void)rr_render(ap, pp, swp);

    return 1;
}
Ejemplo n.º 28
0
int
ged_dup(struct ged *gedp, int argc, const char *argv[])
{
    struct db_i *newdbp = DBI_NULL;
    struct directory **dirp0 = (struct directory **)NULL;
    struct dir_check_stuff dcs;
    static const char *usage = "file.g prefix";

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);

    /* initialize result */
    bu_vls_trunc(gedp->ged_result_str, 0);

    /* must be wanting help */
    if (argc == 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_HELP;
    }

    if (argc > 3) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

    bu_vls_trunc(&gedp->ged_wdbp->wdb_prestr, 0);
    if (argc == 3)
	(void)bu_vls_strcpy(&gedp->ged_wdbp->wdb_prestr, argv[2]);

    gedp->ged_wdbp->wdb_num_dups = 0;
    if (db_version(gedp->ged_wdbp->dbip) < 5) {
	if ((gedp->ged_wdbp->wdb_ncharadd = bu_vls_strlen(&gedp->ged_wdbp->wdb_prestr)) > 12) {
	    gedp->ged_wdbp->wdb_ncharadd = 12;
	    bu_vls_trunc(&gedp->ged_wdbp->wdb_prestr, 12);
	}
    } else {
	gedp->ged_wdbp->wdb_ncharadd = bu_vls_strlen(&gedp->ged_wdbp->wdb_prestr);
    }

    /* open the input file */
    if ((newdbp = db_open(argv[1], DB_OPEN_READONLY)) == DBI_NULL) {
	perror(argv[1]);
	bu_vls_printf(gedp->ged_result_str, "dup: Cannot open geometry database file %s", argv[1]);
	return GED_ERROR;
    }

    bu_vls_printf(gedp->ged_result_str,
		  "\n*** Comparing %s with %s for duplicate names\n",
		  gedp->ged_wdbp->dbip->dbi_filename, argv[1]);
    if (gedp->ged_wdbp->wdb_ncharadd) {
	bu_vls_printf(gedp->ged_result_str,
		      "  For comparison, all names in %s were prefixed with: %s\n",
		      argv[1], bu_vls_addr(&gedp->ged_wdbp->wdb_prestr));
    }

    /* Get array to hold names of duplicates */
    if ((dirp0 = _ged_getspace(gedp->ged_wdbp->dbip, 0)) == (struct directory **) 0) {
	bu_vls_printf(gedp->ged_result_str, "f_dup: unable to get memory\n");
	db_close(newdbp);
	return GED_ERROR;
    }

    /* Scan new database for overlaps */
    dcs.main_dbip = gedp->ged_wdbp->dbip;
    dcs.wdbp = gedp->ged_wdbp;
    dcs.dup_dirp = dirp0;
    if (db_version(newdbp) < 5) {
	if (db_scan(newdbp, dup_dir_check, 0, (void *)&dcs) < 0) {
	    bu_vls_printf(gedp->ged_result_str, "dup: db_scan failure");
	    bu_free((void *)dirp0, "_ged_getspace array");
	    db_close(newdbp);
	    return GED_ERROR;
	}
    } else {
	if (db5_scan(newdbp, dup_dir_check5, (void *)&dcs) < 0) {
	    bu_vls_printf(gedp->ged_result_str, "dup: db_scan failure");
	    bu_free((void *)dirp0, "_ged_getspace array");
	    db_close(newdbp);
	    return GED_ERROR;
	}
    }
    rt_mempurge(&(newdbp->dbi_freep));        /* didn't really build a directory */

    _ged_vls_col_pr4v(gedp->ged_result_str, dirp0, (int)(dcs.dup_dirp - dirp0), 0);
    bu_vls_printf(gedp->ged_result_str, "\n -----  %d duplicate names found  -----", gedp->ged_wdbp->wdb_num_dups);
    bu_free((void *)dirp0, "_ged_getspace array");
    db_close(newdbp);

    return GED_OK;
}