示例#1
0
extern "C" DLLEXPORT miBoolean mib_texture_filter_lookup(
	miColor		*result,
	miState		*state,
	struct mib_texture_filter_lookup *paras)
{
	miTag		tex = *mi_eval_tag(&paras->tex);
	miVector	*coord;
	miUint		space;
	miTag		remap;
	miVector	p[3], t[3];
	miMatrix	ST;
	miTexfilter	ell_opt;
	miScalar	disc_r;

	if (!tex) {
		result->r = result->g = result->b = result->a = 0;
		return(miFALSE);
	}
	coord  = mi_eval_vector(&paras->coord);
	space  = *mi_eval_integer(&paras->space);
	disc_r = *mi_eval_scalar(&paras->disc_r);
	if (disc_r <= 0)
		disc_r = DISC_R;
	if (state->reflection_level == 0 &&
	    mi_texture_filter_project(p, t, state, disc_r, space) &&
	    (remap = *mi_eval_tag(&paras->remap))) {
		mi_call_shader_x((miColor*)&t[0], miSHADER_TEXTURE,
						state, remap, &t[0]);
		mi_call_shader_x((miColor*)&t[1], miSHADER_TEXTURE,
						state, remap, &t[1]);
		mi_call_shader_x((miColor*)&t[2], miSHADER_TEXTURE,
						state, remap, &t[2]);
		if (mi_texture_filter_transform(ST, p, t)) {
			ell_opt.eccmax	  = *mi_eval_scalar(&paras->eccmax);
			ell_opt.max_minor = *mi_eval_scalar(&paras->maxminor);
			ell_opt.bilinear  = *mi_eval_boolean(&paras->bilinear);
			ell_opt.circle_radius = CIRCLE_R;
			/*
			 * when no bump-mapping is used, coord and ST[..]
			 * are identical. for bump mapping, the projection
			 * matrix is calculated for the current raster
			 * position, the ellipse is translated to the
			 * bump position
			 */
			ST[2*4+0] = coord->x;
			ST[2*4+1] = coord->y;
			if (mi_lookup_filter_color_texture(result, state,
							tex, &ell_opt, ST))
				return(miTRUE);
		}
	}
	/* fallback to standard pyramid or nonfiltered texture lookup */
	return(mi_lookup_color_texture(result, state, tex, coord));
}
示例#2
0
extern "C" DLLEXPORT miBoolean mib_texture_lookup(
	miColor		*result,
	miState		*state,
	struct mib_texture_lookup *paras)
{
	miTag		tex   = *mi_eval_tag(&paras->tex);
	miVector	*coord = mi_eval_vector(&paras->coord);

	if (tex && coord->x >= 0 && coord->x < 1
		&& coord->y >= 0 && coord->y < 1
		&& mi_lookup_color_texture(result, state, tex, coord))

		return(miTRUE);

	result->r = result->g = result->b = result->a = 0;
	return(miFALSE);
}
示例#3
0
extern "C" DLLEXPORT miBoolean mib_lens_stencil(
	miColor*	result,
	miState*	state,
	mibStencil_t*	paras)
{
	miScalar 	f  = *mi_eval_scalar(&paras->floor);
	miScalar 	c  = *mi_eval_scalar(&paras->ceiling);
	miColor  	fc = *mi_eval_color(&paras->floor_color);
	miColor  	cc = *mi_eval_color(&paras->ceil_color);
	miTag    	st = *mi_eval_tag(&paras->stencil);

	miScalar 	s;
	miVector 	coord;

	/* handle default parameter values */
	if (c == 0.0f) {
		c = 1.0f;
	}

	if (!st || f >= c) {
		return mi_trace_eye(result, state, &state->org, &state->dir);
	} 

	coord.x = state->raster_x / state->camera->x_resolution;
	coord.y = state->raster_y / state->camera->y_resolution;
	coord.z = 0.0f;

	mi_lookup_scalar_texture(&s, state, st, &coord);
	s = (s-f)/(c-f);
	if (s < 0.0f) {
		*result = fc;
	} else if ( s > 1.0f) {
		*result = cc;
	} else {
		miColor col = { 0.0, 0.0, 0.0, 1.0};
        	miScalar sn = 1.0f - s;

		(void) mi_trace_eye(&col, state, &state->org, &state->dir);

		result->r = s * col.r + sn * fc.r;
		result->g = s * col.g + sn * fc.g;
		result->b = s * col.b + sn * fc.b;
		result->a =     col.a;
	}
	return miTRUE;
}
示例#4
0
miBoolean contour_shader_widthfromlight(
	miContour_endpoint *result,
	miStdInfo	   *info_near,
	miStdInfo	   *info_far,
	miState		   *state,
	Light_Parameters   *paras)
{
	miVector	   orgp;	/* light source origin */
	miVector	   dirp;	/* light source direction */
	miVector	   dir;
	double		   d;
	miScalar	   min_width;
	miScalar	   max_width;

	/* Contour color given by a parameter */
	result->color = *mi_eval_color(&paras->color);

	/* Get light origin or direction */
	mi_light_info(*mi_eval_tag(&paras->light), &orgp, &dirp, 0);
	/* Now orgp or dirp is different from the null vector */

	/* Compute direction from light to point */
	if (mi_vector_dot(&orgp, &orgp) > miEPS) {   /* point light source */
		mi_vector_sub(&dir, &info_near->point, &orgp);

	} else {				/* directional light source */
		miASSERT(mi_vector_dot(&dirp, &dirp) > miEPS);
		dir = dirp;
	}
	mi_vector_normalize(&dir);

	/* The contour gets wider the more the normal is pointing in the same
	   direction as the light source */
	d = mi_vector_dot(&dir, &info_near->normal);
	min_width = *mi_eval_scalar(&paras->min_width);
	max_width = *mi_eval_scalar(&paras->max_width);
	result->width = min_width + 0.5 * (max_width - min_width) * (d+1.0);

	miASSERT(min_width <= result->width && result->width <= max_width);
	return(miTRUE);
}
示例#5
0
extern "C" DLLEXPORT miBoolean mib_texture_lookup2(
    miColor		*result,
    miState		*state,
    struct mib_texture_lookup2 *paras)
{
    miTag	tex   = *mi_eval_tag(&paras->tex);
    miVector	coord;
    miScalar	factor = *mi_eval_scalar(&paras->factor);

    if (tex )
    {
	coord.x = state->tex_list[0].x * factor;
	coord.y = state->tex_list[0].y * factor;
	mi_lookup_color_texture(result, state, tex, &coord);
	return(miTRUE);
    }
	

    result->r = result->g = result->b = result->a = 0;
    return(miFALSE);
}
示例#6
0
extern "C" DLLEXPORT miBoolean mib_ray_marcher(
	miColor		*result,
	miState		*state,
	struct mrm	*p)
{
	struct mrm	pe;
	miScalar	scale;

	result->r = result->g = result->b = result->a = 0.0;

	/*
	 * copy all parameters to a static structure to
	 * avoid all the mi_eval_* calls in the code
	 */
	pe.s        = *mi_eval_tag(&p->s);
	pe.distance = *mi_eval_scalar(&p->distance);
	pe.num      = *mi_eval_integer(&p->num);
	pe.subdiv   = *mi_eval_integer(&p->subdiv);
	pe.contrast = *mi_eval_color(&p->contrast);

	if (pe.num == 0.0)
		if (pe.distance > 0.0)
			pe.num = state->dist / pe.distance;
		else
			pe.num = 4; /* default #samples */
	if (pe.num < 2)
		pe.num = 2;

	/* go! */
	raymarch(result, state, &pe);

	/* normalize result */
	scale = 1.0 / (miScalar)pe.num;
	result->r *= scale;
	result->g *= scale;
	result->b *= scale;
	result->a *= scale;
	return(miTRUE);
}
extern "C" DLLEXPORT miBoolean mrParticleGeoShader(
	miTag             *result,
	miState                 *state,
	mrParticleGeoShader_paras   *paras)
{
	
	mi_info("mrParticleGeoShader: Version %s", VERSION);

	int			geometryType = *mi_eval_integer(&paras->geometryType);
	miScalar	minPixelSize = *mi_eval_scalar(&paras->minPixelSize);
	miScalar	maxPixelSize = *mi_eval_scalar(&paras->maxPixelSize);
	int i_m = *mi_eval_integer(&paras->i_particleFiles);
	int n_m = *mi_eval_integer(&paras->n_particleFiles);
	miTag *particleFiles = mi_eval_tag(paras->particleFiles) + i_m;

	for(int i = 0; i < n_m; i++)
	{
		if (particleFiles[i])
		{
			std::string fileName = tag_to_string(particleFiles[i]);
			std::string correctedFileName = getCorrectFileName(state, paras, fileName);
			mi_info("reading cacheFile %s", correctedFileName.c_str());
			PartioContainer pc(correctedFileName);
			if( geometryType == 0)
			{
				miTag particleTag = createMeshParticles(state, paras, pc);
				if( particleTag != miNULLTAG)
					miBoolean done = mi_geoshader_add_result( result, particleTag);
			}else{
				miTag particleTag = createNativeParticles(state, paras, pc);
				if( particleTag != miNULLTAG)
					miBoolean done = mi_geoshader_add_result( result, particleTag);
			}
		}
	}
	return miTRUE;
}
示例#8
0
miBoolean contour_shader_combi(
	miContour_endpoint *result,
	miStdInfo	   *info_near,
	miStdInfo	   *info_far,
	miState		   *state,
	Combi_Parameters   *paras)
{
	miScalar	   depth = info_near->point.z;
	double		   near_z, far_z, w_near, w_far;
	miVector	   orgp;		/* light source origin */
	miVector	   dirp;		/* light source direction */
	miVector	   dir;
	double		   d;
	double		   factor;
	miTag		   light;

	/* Ensure that near_z and far_z are negative as they should be */
	near_z = -fabs(*mi_eval_scalar(&paras->near_z));
	far_z  = -fabs(*mi_eval_scalar(&paras->far_z));

	if (depth > near_z) {		/* contour is closer than near_z */
		result->color = *mi_eval_color(&paras->near_color);
		result->width = *mi_eval_scalar(&paras->near_width);

	} else if (depth < far_z) {	/* contour is more distant than far_z*/
		result->color = *mi_eval_color(&paras->far_color);
		result->width = *mi_eval_scalar(&paras->far_width);
	} else {			/* contour is betwn near_z and far_z */
		miColor near_color = *mi_eval_color(&paras->near_color);
		miColor far_color  = *mi_eval_color(&paras->far_color);
		/* Weights w_near and w_far depend on depth */
		w_near = (depth - far_z) / (near_z - far_z);
		miASSERT(0.0 <= w_near && w_near <= 1.0);
		w_far = 1.0 - w_near;

		/* Mix of near_color and far_color according to weights */
		result->color.r = w_near * near_color.r + w_far * far_color.r;
		result->color.g = w_near * near_color.g + w_far * far_color.g;
		result->color.b = w_near * near_color.b + w_far * far_color.b;
		result->color.a = w_near * near_color.a + w_far * far_color.a;

		/* Width depending on weights */
		result->width   = w_near * *mi_eval_scalar(&paras->near_width) 
				+ w_far  * *mi_eval_scalar(&paras->far_width);
	}

	/* Width decreases by factor for each refraction_level */
	factor = *mi_eval_scalar(&paras->factor);
	if (factor > miEPS)
		result->width *= pow(factor, (double)info_near->level - 1.0);

	light = *mi_eval_tag(&paras->light);
	if (light) {
		miScalar light_min_factor = 
				*mi_eval_scalar(&paras->light_min_factor);
		/* Get light origin or direction */
		mi_light_info(light, &orgp, &dirp, 0);
		/* Now orgp or dirp is different from the null vector */

		/* Compute direction from light to point */
		if (mi_vector_dot(&orgp, &orgp) > miEPS) /* point light */
			mi_vector_sub(&dir, &info_near->point, &orgp);

		else {				/* directional light source */
			miASSERT(mi_vector_dot(&dirp, &dirp) > miEPS);
			dir = dirp;
		}
		mi_vector_normalize(&dir);

		/* The contour gets wider the more the normal is pointing in
		   the same direction as the light source */
		d = mi_vector_dot(&dir, &info_near->normal);
		result->width *= 0.5 * (d + 1.0) * (1.0 - light_min_factor) +
						light_min_factor;
	}
	miASSERT(result->width <= *mi_eval_scalar(&paras->near_width));
	return(miTRUE);
}
示例#9
0
extern "C" DLLEXPORT miBoolean mib_illum_lambert(
	miColor		*result,
	miState		*state,
	struct mib_illum_lambert *paras)
{
	miColor		*ambi, *diff;
	miTag		*light;		/* tag of light instance */
	int		n_l;		/* number of light sources */
	int		i_l;		/* offset of light sources */
	int		m;		/* light mode: 0=all, 1=incl, 2=excl */
	int		samples;	/* # of samples taken */
	miColor		color;		/* color from light source */
	miColor		sum;		/* summed sample colors */
	miScalar	dot_nl;		/* dot prod of normal and dir*/

       
        /* check for illegal calls */
        if (state->type == miRAY_SHADOW || state->type == miRAY_DISPLACE ) {
		return(miFALSE);
	}
 
	ambi =  mi_eval_color(&paras->ambient);
	diff =  mi_eval_color(&paras->diffuse);
	m    = *mi_eval_integer(&paras->mode);

	*result    = *mi_eval_color(&paras->ambience);	/* ambient term */
	result->r *= ambi->r;
	result->g *= ambi->g;
	result->b *= ambi->b;

	n_l   = *mi_eval_integer(&paras->n_light);
	i_l   = *mi_eval_integer(&paras->i_light);
	light =  mi_eval_tag(paras->light) + i_l;

	if (m == 1)		/* modify light list (inclusive mode) */
		mi_inclusive_lightlist(&n_l, &light, state);
	else if (m == 2)	/* modify light list (exclusive mode) */
		mi_exclusive_lightlist(&n_l, &light, state);
	else if (m == 4) {
		n_l = 0;
		light = 0;
	}

	/* Loop over all light sources */
	if (m==4 || n_l) {
		for (mi::shader::LightIterator iter(state, light, n_l);
		     !iter.at_end(); ++iter) {
			sum.r = sum.g = sum.b = 0;
			while (iter->sample()) {
				dot_nl = iter->get_dot_nl();
				iter->get_contribution(&color);
				sum.r += dot_nl * diff->r * color.r;
				sum.g += dot_nl * diff->g * color.g;
				sum.b += dot_nl * diff->b * color.b;
			}
			samples = iter->get_number_of_samples();
			if (samples) {
				result->r += sum.r / samples;
				result->g += sum.g / samples;
				result->b += sum.b / samples;
			}
		}
	}

	/* add contribution from indirect illumination (caustics) */
	mi_compute_irradiance(&color, state);
	result->r += color.r * diff->r;
	result->g += color.g * diff->g;
	result->b += color.b * diff->b;
	result->a  = 1;
	return(miTRUE);
}
示例#10
0
extern "C" DLLEXPORT miBoolean mib_illum_cooktorr(
	miColor		*result,
	miState		*state,
	struct mib_illum_cooktorr *paras)
{
	miColor		*ambi, *diff, *spec;
	miScalar	roughness;	/* average microfacet slope */
	miColor		*ior;		/* index of refraction */
	miTag		*light;		/* tag of light instance */
	int		n_l;		/* number of light sources */
	int		i_l;		/* offset of light sources */
	int		mode;		/* light mode: 0=all, 1=incl, 2=excl */
	int		samples;	/* # of samples taken */
	miColor		color;		/* color from light source */
	miColor		sum;		/* summed sample colors */
	miVector	dir;		/* direction towards light */
	miScalar	dot_nl;		/* dot prod of normal and dir */
	miColor		refl;		/* specular reflection color */

        /* check for illegal calls */
        if (state->type == miRAY_SHADOW || state->type == miRAY_DISPLACE ) {
		return(miFALSE);
	}

        
	ambi      = mi_eval_color(&paras->ambient);
	diff      = mi_eval_color(&paras->diffuse);
	spec      = mi_eval_color(&paras->specular);
	roughness = *mi_eval_scalar(&paras->roughness);
	ior       = mi_eval_color(&paras->ior);

	*result    = *mi_eval_color(&paras->ambience);	/* ambient term */
	result->r *= ambi->r;
	result->g *= ambi->g;
	result->b *= ambi->b;

	mode  = *mi_eval_integer(&paras->mode);
	n_l   = *mi_eval_integer(&paras->n_light);
	i_l   = *mi_eval_integer(&paras->i_light);
	light =  mi_eval_tag(paras->light) + i_l;

	if (mode == 1)		/* modify light list (inclusive mode) */
		mi_inclusive_lightlist(&n_l, &light, state);
	else if (mode == 2)	/* modify light list (exclusive mode) */
		mi_exclusive_lightlist(&n_l, &light, state);
	else if (mode == 4) {
		n_l = 0;
		light = 0;
	}

	/* Loop over all light sources */
	if (mode == 4 || n_l) {
		for (mi::shader::LightIterator iter(state, light, n_l);
		     !iter.at_end(); ++iter) {
			sum.r = sum.g = sum.b = 0;
			samples = 0;
			while (iter->sample()) {
				iter->get_contribution(&color);
				dot_nl = iter->get_dot_nl();
				/* Diffuse reflection: Lambert's cosine law */
				sum.r += dot_nl * diff->r * color.r;
				sum.g += dot_nl * diff->g * color.g;
				sum.b += dot_nl * diff->b * color.b;

				/* Specular reflection: Cook-Torrance reflection */
				dir = iter->get_direction();
				if (mi_cooktorr_specular(&refl, &state->dir, &dir,
							 &state->normal, roughness, ior)) {
					sum.r += refl.r * spec->r * color.r;
					sum.g += refl.g * spec->g * color.g;
					sum.b += refl.b * spec->b * color.b;
				}
			}
			samples = iter->get_number_of_samples();
			if (samples) {
				result->r += sum.r / samples;
				result->g += sum.g / samples;
				result->b += sum.b / samples;
			}
		}
	}

	/* add contribution from indirect illumination (caustics) */
	mi_compute_irradiance(&color, state);
	result->r += color.r * diff->r;
	result->g += color.g * diff->g;
	result->b += color.b * diff->b;
	result->a  = 1;
	return(miTRUE);
}
示例#11
0
文件: baseocc.cpp 项目: OpenXRay/xray
extern "C" DLLEXPORT miBoolean mib_bent_normal_env(
	miColor     *result,
	miState     *state,
	struct mib_bent_normal_env_p *paras)
{
	miTag  original_env = state->environment;
	miTag  environment  = *mi_eval_tag(&paras->environment);
	miColor   normal    = *mi_eval_color(&paras->bent_normals);
	miColor   occlus    = *mi_eval_color(&paras->occlusion);
	miScalar  strength  = *mi_eval_scalar(&paras->strength);
	miColor   color;      /* Work color */
	miVector  bent;       /* Bent normals */
	miVector  bent_i;     /* Bent normals in internal space */
	miUint	  samples;    /* # of samples */

	/* Displace or light - makes no sense */
	if (state->type == miRAY_DISPLACE || state->type == miRAY_LIGHT)
	    return miFALSE;

	if (strength == 0.0) {
	    result->r = result->g = result->b = 0.0;
	    result->a = 1.0;
	    return miTRUE;
	}

	color.r = color.b = color.g = 0.0;

	/* Does occlusion live in "alpha" component of bn data? */
	if (*mi_eval_boolean(&paras->occlusion_in_alpha))
	    strength *= normal.a;
    
	bent.x = (normal.r * 2.0) - 1.0;
	bent.y = (normal.g * 2.0) - 1.0;
	bent.z = (normal.b * 2.0) - 1.0;

	mi_vector_normalize(&bent);

	/* The different coordinate spaces */
	switch(*mi_eval_integer(&paras->coordinate_space)) {
		case 0: /* No change */
			bent_i = bent;
			break;
		case 1: /* By matrix */
			mi_vector_transform(&bent_i,
				&bent,
				mi_eval_transform(&paras->matrix));
			break;
		case 2: /* World */
			mi_normal_from_world(state, &bent_i, &bent);
			break;
		case 3: /* Camera */
			mi_normal_from_camera(state, &bent_i, &bent);
			break;
		case 4: /* Object */
			mi_normal_from_object(state, &bent_i, &bent);
			break;
	}
    
	samples = *mi_eval_integer(&paras->env_samples);

	/* Temporarily override the environment */
	if (environment)
	    state->environment = environment;

	if (samples <= 1) {
		/* Single sampling */		      
		mi_trace_environment(&color, state, &bent_i);
	} else {
		/* Multisampling */
		double	 sample[3];
		int	 counter = 0;
		miScalar spread  = *mi_eval_scalar(&paras->samples_spread);
		miColor  work_color;

		/* Clear color */
		color.r = color.g = color.b = 0.0;
			
		while (mi_sample(sample, &counter, state, 3, &samples)) {
			miVector trace_dir;
			trace_dir.x = bent_i.x + (sample[0] - 0.5) * spread;
			trace_dir.y = bent_i.y + (sample[1] - 0.5) * spread;
			trace_dir.z = bent_i.z + (sample[2] - 0.5) * spread;
			
			mi_vector_normalize(&trace_dir);

			mi_trace_environment(&work_color, state, &trace_dir);
			color.r += work_color.r;
			color.g += work_color.g;
			color.b += work_color.b;
		}

		color.r /= samples;
		color.g /= samples;
		color.b /= samples;
	}

	/* Reset original environment */
	state->environment = original_env;

	result->r = color.r * occlus.r * strength;
	result->g = color.g * occlus.g * strength;
	result->b = color.b * occlus.b * strength;
	result->a = 1.0;

	return miTRUE;
}
miTag createNativeParticles(miState *state, mrParticleGeoShader_paras *paras, PartioContainer& pc)
{
	miBoolean useAllAttributes = *mi_eval_boolean(&paras->useAllAttributes);
	int i_a = *mi_eval_integer(&paras->i_attributeNames);
	int n_a = *mi_eval_integer(&paras->n_attributeNames);
	miTag *attributeNames = mi_eval_tag(paras->attributeNames) + i_a;

	if( !pc.good())
	{
		mi_info("createNativeParticles: Invalid patioContainer");
		return miNULLTAG;
	}

	Partio::ParticleAttribute posAttr;
	if(!pc.assertAttribute("position", posAttr))
	{
		mi_info("createNativeParticles: partioContainer: no position.");
		return miNULLTAG;
	}

	Partio::ParticleAttribute idAttr;
	bool hasId = true;
	if(!pc.assertAttribute("id", idAttr))
		hasId = false;

	Partio::ParticleAttribute radiusPPAttr;
	bool hasRadiusPP = true;
	if(!pc.assertAttribute("radiusPP", radiusPPAttr))
		hasRadiusPP = false;

	Partio::ParticleAttribute radiusRGBPPAttr;
	bool hasRgbPP = true;
	if(!pc.assertAttribute("rgbPP", radiusRGBPPAttr))
		hasRgbPP = false;

	mi_info("Creating native particles for cache file: %s", pc.cacheFileName.c_str());

	// declare the map as a 3-dimensional map
	mi_api_map_decl_dim ( 3 );

	// the 'mi_api_map_field_decl' function takes four arguments:
	//
	// miParam_type type: basic type of the field (miTYPE_SCALAR or miTYPE_INTEGER)
	// char *name : field name
	// int dimension : dimension of the field, 0 for single values, > 0 for arrays
	// miBoolean global : miTRUE if it's a global field, miFALSE otherwise

	// add the "extension" field as a single float
	miParameter *extension_field = mi_api_map_field_decl (
	miTYPE_SCALAR , mi_mem_strdup("extension") , 0 , miFALSE );

	// add the "color" field as an array of 1 color
	miParameter *color_field = mi_api_map_field_decl (
	miTYPE_SCALAR , mi_mem_strdup("color") , 3 , miFALSE );

	// append the color to the extension for the declaration
	// (this also frees the 'color_field' miParameter)
	miParameter *fields_list = mi_api_map_field_append ( extension_field , color_field );

	// create a declaration called "particles" with the given fields list
	// (this also frees the 'fields_list' miParameter)
	miMap_decl *decl = mi_api_map_decl_begin ( mi_mem_strdup("particles") , fields_list );

	// ends the declaration
	mi_api_map_decl_end ();

//	Then you begin the object definition, by calling 'mi_api_object_begin' and possibly setting the object flags as needed, then you begin the definition of the particle object as a set of spheres:
	miObject *obj = mi_api_object_begin(mi_mem_strdup("TestParticleObject"));
	obj->visible = miTRUE;

	// begin the definition of the particle object as spheres
	mi_api_map_obj_type ( mi_mem_strdup("spheres") );

	// the 'mi_api_map_obj_field' function takes 2 arguments:
	//
	// char *field_name : name of the field to map ("radius" in this case)
	// char *mapped_name : name of the mapped field ("extension" in this case)

	// maps the "radius" field to the "extension" field of this map
	mi_api_map_obj_field( mi_mem_strdup("radius") , mi_mem_strdup("extension") );	

	// begins the definition of the map, taking "particles" as the declaration name
	mi_api_map_begin ( mi_mem_strdup("particles") );

	int num_elements = pc.data->numParticles();

	for ( int i = 0 ; i < num_elements ; ++i ) 
	{
		
		float pos[3];
		pc.getPosition(i, pos);

		// define the position of this element
		mi_api_map_value ( miTYPE_SCALAR , &pos[0] );
		mi_api_map_value ( miTYPE_SCALAR , &pos[1] );
		mi_api_map_value ( miTYPE_SCALAR , &pos[2] );
		mi_api_map_field_end ();

		float radiusPP = 1.0f;
		if( hasRadiusPP )
			radiusPP = *pc.data->data<float>(radiusPPAttr, i);
		radiusPP = rnd() * 0.3;
		// define the radius of this element
		mi_api_map_value ( miTYPE_SCALAR , &radiusPP );
		mi_api_map_field_end ();

		//
		// compute the color in r, g and b
		//
		miScalar r = rnd();
		miScalar g = rnd();
		miScalar b = rnd();
		miColor col;
		col.r = r;
		col.g = g;
		col.b = b;
		// define the color of this element
		//mi_api_map_value ( miTYPE_COLOR , &col );
		mi_api_map_value ( miTYPE_SCALAR , &r );
		mi_api_map_value ( miTYPE_SCALAR , &g );
		mi_api_map_value ( miTYPE_SCALAR , &b );
		mi_api_map_field_end();

		// end the definition of this element
		mi_api_map_element_end ();
	}

	// terminates the map definition and stores it in the DB
	miTag map_tag = mi_api_map_end ( 0 );

	miTag particleObjTag = mi_api_object_end();

	miEchoOptions options;
	memset(&options, 0, sizeof(options));
	options.ascii_output = true;
	options.compressed_output = false;
	options.dont_echo = false;
	
	mi_info("Writing to geodump.mi file.");
	const char *mode = "w";
	FILE *fh = fopen("C:/daten/3dprojects/Maya2013/scenes/geodump.mi", mode);
	//mi_geoshader_echo_tag(fh, particleObjTag, &options);
	fclose(fh);

	mi::shader::Access_map  map(map_tag);
	mi::shader::Map_status	    status;
	mi::shader::Map_declaration map_declaration(map, &status);
	mi::shader::Map_field_id field_id = map_declaration->get_field_id(mi_mem_strdup("color"), &status);
	if (!status.is_ok())
	{
		mi_error("problems getting field_id for color");
		return particleObjTag;
	}
	mi_info("Field id %d", field_id);
	mi::shader::Map_field_type f_type;
	miUint f_dimension;
	bool f_is_global;
	status = map_declaration->get_field_info(field_id, f_type, f_dimension, f_is_global);
	if (!status.is_ok())
	{
		mi_error("problems get_field_info");
		return particleObjTag;
	}
	mi_info("Field type %d is global %d", f_type.type(), f_is_global);
	return particleObjTag;
}