示例#1
0
文件: vls.c 项目: cciechad/brlcad
/**
 * b u _ v l s _ s t r l e n
 *
 * Return length of the string, in bytes, not including the null
 * terminator.
 */
int
bu_vls_strlen(register const struct bu_vls *vp)
{
    BU_CK_VLS(vp);

    if ( vp->vls_len <= 0 )
	return 0;

    return vp->vls_len;
}
示例#2
0
文件: pr.c 项目: kanzure/brlcad
void
rt_pr_fallback_angle(struct bu_vls *str, const char *prefix, const double *angles)
{
    BU_CK_VLS(str);

    bu_vls_printf(str, "%s direction cosines=(%1.f, %1.f, %1.f)\n",
		  prefix, INTCLAMP(angles[0]), INTCLAMP(angles[1]), INTCLAMP(angles[2]));

    bu_vls_printf(str, "%s rotation angle=%1.f, fallback angle=%1.f\n",
		  prefix, INTCLAMP(angles[3]), INTCLAMP(angles[4]));
}
示例#3
0
文件: vls.c 项目: cciechad/brlcad
/**
 * b u _ v l s _ p u t c
 *
 * Append the given character to the vls.
 */
void
bu_vls_putc(register struct bu_vls *vp, int c)
{
    BU_CK_VLS(vp);

    if ( vp->vls_offset + vp->vls_len+1 >= vp->vls_max )
	bu_vls_extend( vp, _VLS_ALLOC_STEP );

    vp->vls_str[vp->vls_offset + vp->vls_len++] = (char)c;
    vp->vls_str[vp->vls_offset + vp->vls_len] = '\0'; /* force null termination */
}
示例#4
0
文件: vls.c 项目: cciechad/brlcad
/**
 * b u _ v l s _ s e t l e n
 *
 * Ensure that the vls has a length of at least 'newlen', and make
 * that the current length.
 *
 * Useful for subroutines that are planning on mucking with the data
 * array themselves.  Not advisable, but occasionally useful.
 *
 * Does not change the offset from the front of the buffer, if any.
 * Does not initialize the value of any of the new bytes.
 */
void
bu_vls_setlen(struct bu_vls *vp, int newlen)
{
    BU_CK_VLS(vp);

    if ( vp->vls_len >= newlen )
	return;

    bu_vls_extend( vp, (unsigned)newlen - vp->vls_len );
    vp->vls_len = newlen;
}
示例#5
0
文件: vls.c 项目: cciechad/brlcad
/**
 * b u _ v l s _ s t r c m p
 *
 * Lexicographically compare to vls strings.  Returns an integer
 * greater than, equal to, or less than 0, according as the string s1
 * is greater than, equal to, or less than the string s2.
 */
int
bu_vls_strcmp(struct bu_vls *s1, struct bu_vls *s2)
{
    BU_CK_VLS(s1);
    BU_CK_VLS(s2);

    /* A zero-length VLS is a null string, account for it */
    if ( s1->vls_max == 0 || s1->vls_str == (char *)NULL ) {
	/* s1 is empty */
	/* ensure first-time allocation for null-termination */
	bu_vls_extend(s1, 1);
    }
    if ( s2->vls_max == 0 || s2->vls_str == (char *)NULL ) {
	/* s2 is empty */
	/* ensure first-time allocation for null-termination */
	bu_vls_extend(s2, 1);
    }

    /* neither empty, straight up comparison */
    return strcmp(s1->vls_str+s1->vls_offset, s2->vls_str+s2->vls_offset);
}
示例#6
0
文件: pr.c 项目: kanzure/brlcad
void
rt_pr_hit_vls(struct bu_vls *v, const char *str, register const struct hit *hitp)
{
    BU_CK_VLS(v);
    RT_CK_HIT(hitp);

    bu_log_indent_vls(v);
    bu_vls_strcat(v, str);

    bu_vls_printf(v, "HIT dist=%g (surf %d)\n",
		  hitp->hit_dist, hitp->hit_surfno);
}
示例#7
0
文件: vls.c 项目: cciechad/brlcad
/**
 * 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 );
}
示例#8
0
文件: vls.c 项目: cciechad/brlcad
/**
 * b u _ v l s _ f r e e
 *
 * Releases the memory used for the string buffer.
 */
void
bu_vls_free(register struct bu_vls *vp)
{
    BU_CK_VLS(vp);

    if ( vp->vls_str )  {
	vp->vls_str[0] = '?'; /* Sanity */
	bu_free( vp->vls_str, "bu_vls_free" );
	vp->vls_str = (char *)0;
    }

    vp->vls_offset = vp->vls_len = vp->vls_max = 0;
}
示例#9
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;
}
示例#10
0
文件: vls.c 项目: cciechad/brlcad
/**
 * 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;
}
示例#11
0
文件: vls.c 项目: cciechad/brlcad
/**
 * b u _ v l s _ n i b b l e
 *
 * "Nibble" 'len' characters off the front of the string.  Changes the
 * length and offset; no data is copied.
 *
 * 'len' may be positive or negative. If negative, characters are
 * un-nibbled.
 */
void
bu_vls_nibble(register struct bu_vls *vp, int len)
{
    BU_CK_VLS(vp);

    if ( len < 0 && (-len) > vp->vls_offset )
	len = -vp->vls_offset;
    if (len >= vp->vls_len) {
	bu_vls_trunc( vp, 0 );
	return;
    }

    vp->vls_len -= len;
    vp->vls_offset += len;
}
HIDDEN int osl_setup(register struct region *rp, struct bu_vls *matparm,
		     void **dpp, const struct mfuncs *mfp,
		     struct rt_i *rtip)
{
    register struct osl_specific *osl_sp;

    /* check the arguments */
    RT_CHECK_RTI(rtip);
    BU_CK_VLS(matparm);
    RT_CK_REGION(rp);

    if (rdebug&RDEBUG_SHADE)
	bu_log("osl_setup(%s)\n", rp->reg_name);

    /* Get memory for the shader parameters and shader-specific data */
    BU_GET(osl_sp, struct osl_specific);
    *dpp = (char *)osl_sp;

    /* -----------------------------------
     * Initialize the osl specific values
     * -----------------------------------
     */

    osl_sp->magic = OSL_MAGIC;

    /* Parse the user's arguments to fill osl specifics */
    ShaderGroupInfo group_info;
    if (osl_parse(matparm, group_info) < 0) {
	return -1;
    }

    /* -----------------------------------
     * Initialize osl render system
     * -----------------------------------
     */
    /* If OSL system was not initialized yet, do it */
    if (oslr == NULL) {
	oslr = new OSLRenderer();
    }
    /* Add this shader to OSL system */
    osl_sp->shader_ref = oslr->AddShader(group_info);

    if (rdebug&RDEBUG_SHADE) {
	bu_struct_print(" Parameters:", osl_print_tab, (char *)osl_sp);
    }

    return 1;
}
示例#13
0
void
db_path_to_vls(struct bu_vls *str, const struct db_full_path *pp)
{
    size_t i;

    BU_CK_VLS(str);
    RT_CK_FULL_PATH(pp);

    for (i = 0; i < pp->fp_len; i++) {
	bu_vls_putc(str, '/');
	if (pp->fp_names[i])
	    bu_vls_strcat(str, pp->fp_names[i]->d_namep);
	else
	    bu_vls_strcat(str, "**NULL**");
    }
}
示例#14
0
文件: vls.c 项目: cciechad/brlcad
/**
 * b u _ v l s _ t r u n c 2
 *
 * Son of bu_vls_trunc().  Same as bu_vls_trunc() except that it
 * doesn't truncate (or do anything) if the len is negative.
 */
void
bu_vls_trunc2(register struct bu_vls *vp, int len)
{
    BU_CK_VLS(vp);

    if ( vp->vls_len <= len )
	return;

    if ( len < 0 )
	len = 0;
    if ( len == 0 )
	vp->vls_offset = 0;

    vp->vls_str[len+vp->vls_offset] = '\0'; /* force null termination */
    vp->vls_len = len;
}
示例#15
0
文件: pr.c 项目: kanzure/brlcad
void
rt_pr_seg_vls(struct bu_vls *v, register const struct seg *segp)
{
    BU_CK_VLS(v);
    RT_CK_SEG(segp);

    bu_log_indent_vls(v);
    bu_vls_printf(v,
		  "%p: SEG %s (%g, %g) st_bit=%ld xray#=%d\n",
		  (void *)segp,
		  segp->seg_stp->st_dp->d_namep,
		  segp->seg_in.hit_dist,
		  segp->seg_out.hit_dist,
		  segp->seg_stp->st_bit,
		  segp->seg_in.hit_rayp->index);
}
示例#16
0
文件: pr.c 项目: kanzure/brlcad
void
rt_pr_hitarray_vls(struct bu_vls *v, const char *str, register const struct hit *hitp, int count)
{
    int i;

    BU_CK_VLS(v);
    RT_CK_HIT(hitp);

    bu_log_indent_vls(v);
    bu_vls_strcat(v, str);

    for (i=0; i<count; i++, hitp++) {
	bu_vls_printf(v, "HIT%d dist=%g (surf %d)\n", i,
		      hitp->hit_dist, hitp->hit_surfno);
    }
}
void
rt_vls_color_map(struct bu_vls *str)
{
    struct mater *mp;

    BU_CK_VLS(str);

    for (mp = material_head; mp != MATER_NULL; mp = mp->mt_forw) {
	bu_vls_printf(str,
		      "{%d %d %d %d %d} ",
		      mp->mt_low,
		      mp->mt_high,
		      mp->mt_r,
		      mp->mt_g,
		      mp->mt_b);
    }
}
示例#18
0
文件: vls.c 项目: cciechad/brlcad
/**
 * b u _ v l s _ t r u n c
 *
 * Truncate string to at most 'len' characters.  If 'len' is negative,
 * trim off that many from the end.  If 'len' is zero, don't release
 * storage -- user is probably just going to refill it again,
 * e.g. with bu_vls_gets().
 */
void
bu_vls_trunc(register struct bu_vls *vp, int len)
{
    BU_CK_VLS(vp);

    if ( len < 0 ) {
	/* now an absolute length */
	len = vp->vls_len + len;
    }
    if ( vp->vls_len <= len )
	return;
    if ( len == 0 )
	vp->vls_offset = 0;

    vp->vls_str[len+vp->vls_offset] = '\0'; /* force null termination */
    vp->vls_len = len;
}
示例#19
0
文件: vls.c 项目: cciechad/brlcad
/**
 * b u _ v l s _ s t r c a t
 *
 * Concatenate a new string onto the end of the existing vls string.
 */
void
bu_vls_strcat(register struct bu_vls *vp, const char *s)
{
    register size_t len;

    BU_CK_VLS(vp);

    if ( s == (const char *)NULL )
	return;
    if ( (len = strlen(s)) <= 0 )
	return;

    if ( (size_t)vp->vls_offset + (size_t)vp->vls_len + len+1 >= (size_t)vp->vls_max )
	bu_vls_extend( vp, len+1 );

    memcpy(vp->vls_str +vp->vls_offset + vp->vls_len, s, len+1); /* include null */
    vp->vls_len += len;
}
示例#20
0
文件: vls.c 项目: cciechad/brlcad
/**
 * b u _ v l s _ s t r g r a b
 *
 * Like bu_vls_strdup(), but destructively grab the string from the
 * source argument 'vp'.  This is more efficient than bu_vls_strdup()
 * for those instances where the source argument 'vp' is no longer
 * needed by the caller, as it avoides a potentially long buffer copy.
 *
 * The source string is destroyed, as if bu_vls_free() had been
 * called.
 */
char *
bu_vls_strgrab(register struct bu_vls *vp)
{
    register char *str;

    BU_CK_VLS(vp);

    if ( vp->vls_offset != 0 )  {
	str = bu_vls_strdup( vp );
	bu_vls_free( vp );
	return str;
    }

    str = bu_vls_addr( vp );
    vp->vls_str = (char *)0;
    vp->vls_offset = vp->vls_len = vp->vls_max = 0;
    return str;
}
示例#21
0
文件: vls.c 项目: cciechad/brlcad
/**
 * b u _ v l s _ w r i t e
 *
 * Write the VLS to the provided file descriptor.
 */
void
bu_vls_write( int fd, const struct bu_vls *vp )
{
    int status;

    BU_CK_VLS(vp);

    if ( vp->vls_len <= 0 )
	return;

    bu_semaphore_acquire(BU_SEM_SYSCALL);
    status = write( fd, vp->vls_str + vp->vls_offset, (size_t)vp->vls_len );
    bu_semaphore_release(BU_SEM_SYSCALL);
    
    if ( status != vp->vls_len ) {
	perror("write");
	bu_bomb("bu_vls_write() write error\n");
    }
}
示例#22
0
文件: vls.c 项目: cciechad/brlcad
/**
 * b u _ v l s _ f w r i t e
 *
 * Write the VLS to the provided file pointer.
 */
void
bu_vls_fwrite(FILE *fp, const struct bu_vls *vp)
{
    int status;

    BU_CK_VLS(vp);

    if ( vp->vls_len <= 0 )
	return;

    bu_semaphore_acquire(BU_SEM_SYSCALL);
    status = fwrite( vp->vls_str + vp->vls_offset, (size_t)vp->vls_len, 1, fp );
    bu_semaphore_release(BU_SEM_SYSCALL);

    if ( status != 1 ) {
	perror("fwrite");
	bu_bomb("bu_vls_fwrite() write error\n");
    }
}
示例#23
0
文件: sh_flat.c 项目: kanzure/brlcad
/*
 * This routine is called (at prep time) once for each region which uses this
 * shader.  The shader specific flat_specific structure is allocated and
 * default values are set.  Then any user-given values override.
 */
HIDDEN int
flat_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *rtip)
{

    register struct flat_specific *flat_sp;

    /* check the arguments */
    RT_CHECK_RTI(rtip);
    BU_CK_VLS(matparm);
    RT_CK_REGION(rp);

    if (rdebug&RDEBUG_SHADE)
	bu_log("flat_setup(%s)\n", rp->reg_name);

    /* Get memory for the shader parameters and shader-specific data */
    BU_GET(flat_sp, struct flat_specific);
    *dpp = flat_sp;

    /* color priority:
     *
     * priority goes first to the flat shader's color parameter
     * second priority is to the material color value
     * third priority is to the flat shader's default color (white)
     */

    /* initialize the default values for the shader */
    memcpy(flat_sp, &flat_defaults, sizeof(struct flat_specific));

    /* load the material color if it was set */
    if (rp->reg_mater.ma_color_valid) {
	VMOVE(flat_sp->color, rp->reg_mater.ma_color);
    }

    /* parse the user's arguments for this use of the shader. */
    if (bu_struct_parse(matparm, flat_parse_tab, (char *)flat_sp) < 0)
	return -1;

    if (rdebug&RDEBUG_SHADE) {
	bu_struct_print(" Parameters:", flat_parse_tab, (char *)flat_sp);
    }

    return 1;
}
示例#24
0
double
rt_get_timer(struct bu_vls *vp, double *elapsed)
{
    time_t now;
    double user_cpu_secs;
    double sys_cpu_secs;
    double elapsed_secs;
    double percent;
    struct tms tmsnow;

    /* Real time.  1 second resolution. */
    (void)time(&now);
    elapsed_secs = now-time0;

    /* CPU time */
    (void)times(&tmsnow);
    user_cpu_secs = (tmsnow.tms_utime + tmsnow.tms_cutime) -
	(tms0.tms_utime + tms0.tms_cutime);
    user_cpu_secs /= HZ;
    sys_cpu_secs = (tmsnow.tms_stime + tmsnow.tms_cstime) -
	(tms0.tms_stime + tms0.tms_cstime);
    sys_cpu_secs /= HZ;
    if (user_cpu_secs < 0.00001) user_cpu_secs = 0.00001;
    if (elapsed_secs < 0.00001) elapsed_secs = user_cpu_secs;	/* It can't be any less! */

    if (elapsed)  *elapsed = elapsed_secs;

    if (vp) {
	percent = user_cpu_secs/elapsed_secs*100.0;
	BU_CK_VLS(vp);
#ifdef DEFAULT_HZ
	bu_vls_printf(vp,
		      "%g user + %g sys in %g elapsed secs (%g%%) WARNING: HZ=60 assumed, fix librt/timerunix.c",
		      user_cpu_secs, sys_cpu_secs, elapsed_secs, percent);
#else
	bu_vls_printf(vp,
		      "%g user + %g sys in %g elapsed secs (%g%%)",
		      user_cpu_secs, sys_cpu_secs, elapsed_secs, percent);
#endif
    }
    return user_cpu_secs;
}
示例#25
0
/*
 *			E X T _ S E T U P
 *
 *  Returns 0 on failure, 1 on success.
 */
HIDDEN int
ext_setup(register struct region *rp, struct bu_vls *matparm, char **dpp, struct mfuncs *mf_p, struct rt_i *rtip, struct mfuncs **headp)

    /* parameter string */
    /* pointer to user data pointer */


{
    struct bu_mapped_file	*parameter_file;
    struct bu_vls		parameter_data;
    char			*filename;
    int			status;

    RT_CHECK_RTI(rtip);
    BU_CK_VLS( matparm );
    RT_CK_REGION(rp);

    filename = bu_vls_addr(matparm);
    parameter_file = bu_open_mapped_file( filename, (char *)NULL );
    if (!parameter_file) {
	bu_log("cannot open external shader file \"%s\"\n", filename);
	bu_bomb("ext_setup()\n");
    }

    bu_vls_init(&parameter_data);
    bu_vls_strncpy( &parameter_data, (char *)parameter_file->buf,
		    parameter_file->buflen );

    if (rdebug&RDEBUG_SHADE ) {
	bu_log("ext_setup(%s): {%s}\n",
	       filename, bu_vls_addr(&parameter_data));
    }

    bu_close_mapped_file( parameter_file );

    status = sh_stk_setup(rp, &parameter_data, dpp, mf_p, rtip, headp);

    bu_vls_free( &parameter_data );

    return status;
}
示例#26
0
文件: sh_fbm.c 项目: cciechad/brlcad
/*
 *	F B M _ S E T U P
 */
HIDDEN int
fbm_setup(register struct region *rp, struct bu_vls *matparm, char **dpp)
{
    register struct fbm_specific *fbm;

    BU_CK_VLS( matparm );
    BU_GETSTRUCT( fbm, fbm_specific );
    *dpp = (char *)fbm;

    memcpy(fbm, &fbm_defaults, sizeof(struct fbm_specific));
    if (rdebug&RDEBUG_SHADE)
	bu_log("fbm_setup\n");

    if (bu_struct_parse( matparm, fbm_parse, (char *)fbm ) < 0 )
	return(-1);

    if (rdebug&RDEBUG_SHADE)
	bu_struct_print( rp->reg_name, fbm_parse, (char *)fbm );

    return(1);
}
示例#27
0
文件: vls.c 项目: cciechad/brlcad
/**
 * b u _ v l s _ s t r n c a t
 *
 * Concatenate a new string onto the end of the existing vls string.
 */
void
bu_vls_strncat(register struct bu_vls *vp, const char *s, size_t n)
{
    register size_t len;

    BU_CK_VLS(vp);

    if ( s == (const char *)NULL )
	return;

    len = strlen(s);
    if ( len > n )
	len = n;
    if ( len <= 0 )
	return;

    if ( (size_t)vp->vls_offset + (size_t)vp->vls_len + len+1 >= (size_t)vp->vls_max )
	bu_vls_extend( vp, len+1 );

    memcpy(vp->vls_str + vp->vls_offset + vp->vls_len, s, len);
    vp->vls_len += len;
    vp->vls_str[vp->vls_offset + vp->vls_len] = '\0'; /* force null termination */
}
示例#28
0
int
rt_obj_adjust(struct bu_vls *logstr, struct rt_db_internal *ip, int argc, const char **argv)
{
    int id;
    const struct rt_functab *ft;

    if (!logstr || !ip)
	return -1;

    BU_CK_VLS(logstr);
    RT_CK_DB_INTERNAL(ip);

    id = ip->idb_minor_type;
    if (id < 0)
	return -2;

    ft = &rt_functab[id];
    if (!ft)
	return -3;
    if (!ft->ft_adjust)
	return -4;

    return ft->ft_adjust(logstr, ip, argc, argv);
}
示例#29
0
void
db_fullpath_to_vls(struct bu_vls *vls, const struct db_full_path *full_path, const struct db_i *dbip, int fp_flags)
{
    size_t i;
    int type;
    const struct bn_tol tol = {BN_TOL_MAGIC, BN_TOL_DIST, BN_TOL_DIST * BN_TOL_DIST, 1e-6, 1.0 - 1e-6 };
    BU_CK_VLS(vls);
    RT_CK_FULL_PATH(full_path);

    if (!full_path->fp_names[0]) {
	bu_vls_strcat(vls, "**NULL**");
	return;
    }

    if ((fp_flags & DB_FP_PRINT_TYPE) && !dbip) {
	bu_log("Warning - requested object type printing, but dbip is NULL - object types will not be printed!");
    }

    for (i = 0; i < full_path->fp_len; i++) {
	bu_vls_putc(vls, '/');
	if (fp_flags & DB_FP_PRINT_BOOL) {
	    switch (full_path->fp_bool[i]) {
		case 2:
		    bu_vls_strcat(vls, "u ");
		    break;
		case 3:
		    bu_vls_strcat(vls, "+ ");
		    break;
		case 4:
		    bu_vls_strcat(vls, "- ");
		    break;
	    }
	}
	if (fp_flags & DB_FP_PRINT_MATRIX) {
	    if (full_path->fp_mat[i]) {
		bu_vls_strcat(vls, "(M)");
	    }
	}

	bu_vls_strcat(vls, full_path->fp_names[i]->d_namep);
	if ((fp_flags & DB_FP_PRINT_TYPE) && dbip) {
	    struct rt_db_internal intern;
	    if (!(rt_db_get_internal(&intern, full_path->fp_names[i], dbip, NULL, &rt_uniresource) < 0)) {
		if (intern.idb_meth->ft_label) {
		    bu_vls_putc(vls, '(');
		    switch (intern.idb_minor_type) {
			case DB5_MINORTYPE_BRLCAD_ARB8:
			    type = rt_arb_std_type(&intern, &tol);
			    switch (type) {
				case 4:
				    bu_vls_strcat(vls, "arb4");
				    break;
				case 5:
				    bu_vls_strcat(vls, "arb5");
				    break;
				case 6:
				    bu_vls_strcat(vls, "arb6");
				    break;
				case 7:
				    bu_vls_strcat(vls, "arb7");
				    break;
				case 8:
				    bu_vls_strcat(vls, "arb8");
				    break;
				default:
				    break;
			    }
			    break;
			case DB5_MINORTYPE_BRLCAD_COMBINATION:
			    if (full_path->fp_names[i]->d_flags & RT_DIR_REGION) {
				bu_vls_putc(vls, 'r');
			    } else {
				bu_vls_putc(vls, 'c');
			    }
			    break;
			default:
			    bu_vls_strcat(vls, intern.idb_meth->ft_label);
			    break;
		    }

		}
		bu_vls_putc(vls, ')');
		rt_db_free_internal(&intern);
	    }
	}

    }
}
示例#30
0
HIDDEN int
scloud_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip)


/* pointer to reg_udata in *rp */


{
    register struct scloud_specific *scloud;
    struct db_full_path full_path;
    mat_t region_to_model;
    mat_t model_to_region;
    mat_t tmp;

    BU_CK_VLS(matparm);
    BU_GET(scloud, struct scloud_specific);
    *dpp = scloud;

    if (rp->reg_aircode == 0) {
        bu_log("WARNING(%s): air shader '%s' applied to non-air region.\n%s\n",
               rp->reg_name,
               mfp->mf_name,
               " Set air flag with \"edcodes\" in mged");
        bu_bomb("");
    }

    memcpy(scloud, &scloud_defaults, sizeof(struct scloud_specific));
    if (rdebug&RDEBUG_SHADE)
        bu_log("scloud_setup\n");

    if (bu_struct_parse(matparm, scloud_parse, (char *)scloud) < 0)
        return -1;

    if (rdebug&RDEBUG_SHADE)
        (void)bu_struct_print(rp->reg_name, scloud_parse, (char *)scloud);

    /* get transformation between world and "region" coordinates */
    if (db_string_to_path(&full_path, rtip->rti_dbip, rp->reg_name)) {
        /* bad thing */
        bu_bomb("db_string_to_path() error");
    }
    if (! db_path_to_mat(rtip->rti_dbip, &full_path, region_to_model, 0, &rt_uniresource)) {
        /* bad thing */
        bu_bomb("db_path_to_mat() error");
    }

    /* get matrix to map points from model space to "region" space */
    bn_mat_inv(model_to_region, region_to_model);

    /* add the noise-space scaling */
    MAT_IDN(tmp);
    if (!EQUAL(scloud->scale, 1.0)) {
        tmp[0] = tmp[5] = tmp[10] = 1.0 / scloud->scale;
    } else {
        tmp[0] = 1.0 / (scloud->vscale[0]);
        tmp[5] = 1.0 / (scloud->vscale[1]);
        tmp[10] = 1.0 / (scloud->vscale[2]);
    }

    bn_mat_mul(scloud->mtos, tmp, model_to_region);

    /* add the translation within noise space */
    MAT_IDN(tmp);
    tmp[MDX] = scloud->delta[0];
    tmp[MDY] = scloud->delta[1];
    tmp[MDZ] = scloud->delta[2];
    bn_mat_mul2(tmp, scloud->mtos);
    bn_mat_inv(scloud->stom, scloud->mtos);

    return 1;
}