Beispiel #1
0
void plantTrees()
{
	printf("planting trees: ");
	init_noise(treeSeed);
	srand(treeSeedPos);
	int i = 0;
	int j = 0;
	while(i < treeNumber)
	{
		if(j++ > 1024 * 1024 * 8) break;

		int x = rand() % 1024;
		int y = rand() % 1024;

		if(material[y][x] != GRASS) continue;

		double val = scaled_octave_noise_2d(treeOctaves, treeOctavePersistence, treeOctaveScale, 0.0, 1.0, (x - 512) * treeScale / 1024, (y - 512) * treeScale / 1024);
		if(treeFalloff) val *= falloff(x, y);
		if(treeValueInvert) val = 1.0 - val;
		if(val > treeDensity)
		{
			trees[i++] = ((top[y][x] - 1) << 20) + (y << 10) + x;
			material[y][x] = DIRT;
		}
	}
	if(i < treeNumber)
	{
		printf("\ncould only plant %d trees\n", i);
		treeNumber = i;
	}
	printf(" done.\n");
}
Beispiel #2
0
int
main(int argc, char **argv)
{
    glutInit(&argc, argv);

    if (--argc != 1)
    {
        printf("Usage: %s file.scn\n", argv[0]);
        exit(-1);
    }

    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);

    glutInitWindowSize(framebuffer_width, framebuffer_height);

    glutInitWindowPosition(20, 100);
    glutCreateWindow("Ray tracing");

    glutDisplayFunc(&draw_scene);
    glutIdleFunc(&draw_scene);
    glutReshapeFunc(&resize);
    //glutSpecialFunc(&specialKeyPressed);
    glutKeyboardFunc(&key_pressed);
    glutMouseFunc(&mouse_func);
    glutMotionFunc(&motion_func);

	read_scene(argv[1]);

    init_opengl();
    init_noise();

    glutMainLoop();

    return 1;
}
Beispiel #3
0
int main(int argc, char *argv[])
{
    Py_SetProgramName(argv[0]);
    Py_Initialize();
    init_noise();
    return 0;
}
Beispiel #4
0
scalar_t noise3(scalar_t x, scalar_t y, scalar_t z)
{
	int i, j;
	int bx0, bx1, by0, by1, bz0, bz1;
	int b00, b10, b01, b11;
	scalar_t rx0, rx1, ry0, ry1, rz0, rz1;
	scalar_t sx, sy, sz;
	scalar_t u, v, a, b, c, d;

	if(!tables_valid) {
		init_noise();
		tables_valid = 1;
	}

	setup(x, bx0, bx1, rx0, rx1);
	setup(y, by0, by1, ry0, ry1);
	setup(z, bz0, bz1, rz0, rz1);

	i = perm[bx0];
	j = perm[bx1];

	b00 = perm[i + by0];
	b10 = perm[j + by0];
	b01 = perm[i + by1];
	b11 = perm[j + by1];

	/* calculate hermite interpolating factors */
	sx = s_curve(rx0);
	sy = s_curve(ry0);
	sz = s_curve(rz0);

	/* interpolate along the top slice of the cell */
	u = v3_dot(grad3[b00 + bz0], v3_cons(rx0, ry0, rz0));
	v = v3_dot(grad3[b10 + bz0], v3_cons(rx1, ry0, rz0));
	a = lerp(u, v, sx);

	u = v3_dot(grad3[b01 + bz0], v3_cons(rx0, ry1, rz0));
	v = v3_dot(grad3[b11 + bz0], v3_cons(rx1, ry1, rz0));
	b = lerp(u, v, sx);

	c = lerp(a, b, sy);

	/* interpolate along the bottom slice of the cell */
	u = v3_dot(grad3[b00 + bz0], v3_cons(rx0, ry0, rz1));
	v = v3_dot(grad3[b10 + bz0], v3_cons(rx1, ry0, rz1));
	a = lerp(u, v, sx);

	u = v3_dot(grad3[b01 + bz0], v3_cons(rx0, ry1, rz1));
	v = v3_dot(grad3[b11 + bz0], v3_cons(rx1, ry1, rz1));
	b = lerp(u, v, sx);

	d = lerp(a, b, sy);

	/* interpolate between slices */
	return lerp(c, d, sz);
}
Perlin2D::Perlin2D(int sizeX, int sizeY, float step, short nbOctave, float persistance):
    m_sizeX(sizeX),
    m_sizeY(sizeY),
    m_step(step),
    m_nbOctave(nbOctave),
    m_persistance(persistance)
{
    init_noise();
    init_perlin();
}
Beispiel #6
0
float noise3(float vec[3])
{
	int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
	float rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
    int i;
    int j;
    
	if (start) {
		start = 0;
		init_noise();
	}
    
	setup_noise(0, bx0,bx1, rx0,rx1);
	setup_noise(1, by0,by1, ry0,ry1);
	setup_noise(2, bz0,bz1, rz0,rz1);
    
	i = p[ bx0 ];
	j = p[ bx1 ];
    
	b00 = p[ i + by0 ];
	b10 = p[ j + by0 ];
	b01 = p[ i + by1 ];
	b11 = p[ j + by1 ];
    
	t  = s_curve(rx0);
	sy = s_curve(ry0);
	sz = s_curve(rz0);
    
#define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
    
	q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
	q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
	a = lerp(t, u, v);
    
	q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
	q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
	b = lerp(t, u, v);
    
	c = lerp(sy, a, b);
    
	q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
	q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
	a = lerp(t, u, v);
    
	q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
	q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
	b = lerp(t, u, v);
    
	d = lerp(sy, a, b);
    
	return lerp(sz, c, d);
}
Beispiel #7
0
// --- Methods of Planet ---
Planet::Planet() {
#ifdef SHOW_3DMAPS_WITH_2D
	texHandle = NULL;
#endif
	pblock = NULL;
	xyzGen = NULL;
//	paramDlg = NULL;
	planetCD.MakeAutoParamBlocks(this);	// make and intialize paramblock2
	Init();
	fileVersion = 0;
	// Allocate data structures, compute lookup tables, etc.
	init_noise(seed);
}
Beispiel #8
0
void generateIsland()
{
	printf("generating island outline: ");
	init_noise(islandSeed);
	for(int y = 0; y < 1024; ++y)
	{
		for(int x = 0; x < 1024; ++x)
		{
			double val = scaled_octave_noise_2d(islandOctaves, islandOctavePersistence, islandOctaveScale, 0.0, 1.0, (x - 512) * islandScale / 1024, (y - 512) * islandScale / 1024);
			val *= falloff(x, y);
			if(val > (1.0 - islandDensity)) material[y][x] = GRASS;
		}
	}
	printf(" done.\n");
}
Beispiel #9
0
void tgen_init()
{
    static bool initialized = false;
    if (initialized)
        return;
    initialized = true;
    init_noise();
    rebase_data();
    init_function_map();
    init_static();
    entry_point();

    // save memory state
    mem.save_heap(saved_heap);
}
Beispiel #10
0
scalar_t noise1(scalar_t x)
{
	int bx0, bx1;
	scalar_t rx0, rx1, sx, u, v;

	if(!tables_valid) {
		init_noise();
		tables_valid = 1;
	}

	setup(x, bx0, bx1, rx0, rx1);
	sx = s_curve(rx0);
	u = rx0 * grad1[perm[bx0]];
	v = rx1 * grad1[perm[bx1]];

	return lerp(u, v, sx);
}
Beispiel #11
0
double noise1(double arg)
{
	int bx0, bx1;
	float rx0, rx1, sx, t, u, v, vec[1];
    
	vec[0] = arg;
	if (start) {
		start = 0;
		init_noise();
	}
    
	setup_noise(0, bx0,bx1, rx0,rx1);
    
	sx = s_curve(rx0);
    
	u = rx0 * g1[ p[ bx0 ] ];
	v = rx1 * g1[ p[ bx1 ] ];
    
	return lerp(sx, u, v);
}
Beispiel #12
0
scalar_t noise2(scalar_t x, scalar_t y)
{
	int i, j, b00, b10, b01, b11;
	int bx0, bx1, by0, by1;
	scalar_t rx0, rx1, ry0, ry1;
	scalar_t sx, sy, u, v, a, b;

	if(!tables_valid) {
		init_noise();
		tables_valid = 1;
	}

	setup(x, bx0, bx1, rx0, rx1);
	setup(y, by0, by1, ry0, ry1);

	i = perm[bx0];
	j = perm[bx1];

	b00 = perm[i + by0];
	b10 = perm[j + by0];
	b01 = perm[i + by1];
	b11 = perm[j + by1];

	/* calculate hermite inteprolating factors */
	sx = s_curve(rx0);
	sy = s_curve(ry0);

	/* interpolate along the left edge */
	u = v2_dot(grad2[b00], v2_cons(rx0, ry0));
	v = v2_dot(grad2[b10], v2_cons(rx1, ry0));
	a = lerp(u, v, sx);

	/* interpolate along the right edge */
	u = v2_dot(grad2[b01], v2_cons(rx0, ry1));
	v = v2_dot(grad2[b11], v2_cons(rx1, ry1));
	b = lerp(u, v, sx);

	/* interpolate between them */
	return lerp(a, b, sy);
}
Beispiel #13
0
float noise2(float vec[2])
{
	int bx0, bx1, by0, by1, b00, b10, b01, b11;
	float rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
	int i;
    int j;
    
	if (start) {
		start = 0;
		init_noise();
	}
    
	setup_noise(0, bx0,bx1, rx0,rx1);
	setup_noise(1, by0,by1, ry0,ry1);
    
	i = p[ bx0 ];
	j = p[ bx1 ];
    
	b00 = p[ i + by0 ];
	b10 = p[ j + by0 ];
	b01 = p[ i + by1 ];
	b11 = p[ j + by1 ];
    
	sx = s_curve(rx0);
	sy = s_curve(ry0);
    
#define at2(rx,ry) ( rx * q[0] + ry * q[1] )
    
	q = g2[ b00 ] ; u = at2(rx0,ry0);
	q = g2[ b10 ] ; v = at2(rx1,ry0);
	a = lerp(sx, u, v);
    
	q = g2[ b01 ] ; u = at2(rx0,ry1);
	q = g2[ b11 ] ; v = at2(rx1,ry1);
	b = lerp(sx, u, v);
    
	return lerp(sy, a, b);
}
Beispiel #14
0
void generateTop()
{
	printf("generating island top layer: ");
	init_noise(heightSeed);
	for(int y = 0; y < 1024; ++y)
	{
		for(int x = 0; x < 1024; ++x)
		{
			double val = scaled_octave_noise_2d(heightOctaves, heightOctavePersistence, heightOctaveScale, 0.0, 1.0, (x - 512) * heightScale / 1024, (y - 512) * heightScale / 1024);
			if(heightFalloff) val *= falloff(x, y);
			if(heightValueInvert) val = 1.0f - val;
			double height = pow(val, heightExponent);
			height = heightBase + (heightTop - heightBase) * height;
			if(material[y][x] != 0)
			{
				top[y][x] = height;
				fraction[y][x] = (height - top[y][x]) * 3.0 + 1.0;
				bottom[y][x] = top[y][x] - bottomMinThick;
			}
		}
	}
	printf(" done.\n");
}
Beispiel #15
0
// This method is responsible for responding to the change notification
// messages sent by the texmap dependants.
RefResult Planet::NotifyRefChanged(Interval changeInt, 
	RefTargetHandle hTarget, PartID& partID, RefMessage message ) {
	switch (message) {
		case REFMSG_CHANGE:

			texValidity.SetEmpty();
			if (hTarget == pblock)
				{
				ParamID changing_param = pblock->LastNotifyParamID();
				// MM: 2/99, If the seed changed update the noise table
				if (changing_param == planet_seed) {
					pblock->GetValue(planet_seed, 0, seed, texValidity);
					init_noise(seed);
				}
				planet_param_blk.InvalidateUI(changing_param);
#ifdef SHOW_3DMAPS_WITH_2D
				if (changing_param != -1)
					DiscardTexHandle();
#endif
			}
#ifdef SHOW_3DMAPS_WITH_2D
			else if (hTarget == xyzGen) 
				{
				DiscardTexHandle();
				}
#endif


			// One of the texmap dependants have changed.  We set our
			// validity interval to empty and invalidate the dialog
			// so it gets redrawn.
//			texValidity.SetEmpty();
//			if (hTarget == pblock) {
//				if (paramDlg) 
//					paramDlg->pmap->Invalidate();
//				}
			break;
/*
		case REFMSG_GET_PARAM_DIM: {
			// This returns the 'dimension' of the parameter.  This is 
			// the type and order of magnitude of the parameter.
			GetParamDim *gpd = (GetParamDim *)partID;
			switch (gpd->index) {
				case PB_PERCENT:
					gpd->dim = stdPercentDim; break;
				case PB_SIZE: gpd->dim =  stdWorldDim; 	break;
				case PB_ISLAND:
				case PB_SEED:
					gpd->dim = defaultDim; break;
				case PB_COL1: 
				case PB_COL2: 
				case PB_COL3: 
				case PB_COL4: 
				case PB_COL5: 
				case PB_COL6: 
				case PB_COL7: 
				case PB_COL8: 
					gpd->dim = stdColor255Dim; break;
			}
			return REF_STOP; 
		}

		case REFMSG_GET_PARAM_NAME: {
			// This returns the name that will appear in track view
			// of the parameter.
			GetParamName *gpn = (GetParamName *)partID;
			gpn->name = GetString(nameIDs[gpn->index]);
			return REF_STOP; 
		}
*/
	}
	return(REF_SUCCEED);
}
Beispiel #16
0
int main(int argc,char **argv)
{
  unsigned int outstrlen=0,offset,hdim,wdim=1;
  int i,j;
  unsigned int *future,has_future;
  unsigned long count;
  long li,lj;
  char *outstring,*infile,*fieldfile,*wcol;
  double **series,*sermin,*serinter,**dfuture,max,**cast,sweights;
  double *new,*drift,**diffusion,**gamma;
  struct sfound sf;
  FILE *fout,*ffield;

  if (scan_help(argc,argv))
    show_options(argv[0]);

  for (i=0;i<argc;i++) {
    outstrlen += strlen(argv[i]);
    outstrlen++;
  }
  check_alloc(outstring=(char*)malloc(sizeof(char)*(outstrlen+8)));
  sprintf(outstring,"#Prog: ");
  offset=7;
  for (i=0;i<argc;i++) {
    sprintf(outstring+offset,"%s ",argv[i]);
    offset += (strlen(argv[i])+1);
  }

  scan_options(argc,argv);

  if (pars.MINN < (pars.DIM+1)) {
    fprintf(stderr,"Too few neighbors. System is underdetermined.\n");
    exit(LANGEVIN_MAIN_TOO_FEW_MINN);
  }

  infile=search_datafile(argc,argv,NULL,VERBOSITY);
  if (infile == NULL) {
    fprintf(stderr,"No input datafile found.\n");
    exit(LANGEVIN_MAIN_NO_INPUTFILE);
  }
  
  if (OUTFILE == NULL) {
    check_alloc(OUTFILE=(char*)calloc(strlen(infile)+6,(size_t)1));
    sprintf(OUTFILE,"%s.lang",infile);
    check_alloc(fieldfile=(char*)calloc(strlen(infile)+12,(size_t)1));
    sprintf(fieldfile,"%s.lang.field",infile);
  }
  else {
    check_alloc(fieldfile=(char*)calloc(strlen(OUTFILE)+7,(size_t)1));
    sprintf(fieldfile,"%s.field",OUTFILE);
  }
  OUTFILE=test_outfile(OUTFILE);
  if (!nofields)
    fieldfile=test_outfile(fieldfile);

  if (COLUMN == NULL)
    series=(double**)get_multi_series(infile,&(pars.LENGTH),EXCLUDE,
				      &(pars.DIM),"",dimset,VERBOSITY);
  else
    series=(double**)get_multi_series(infile,&(pars.LENGTH),EXCLUDE,
				      &(pars.DIM),COLUMN,dimset,VERBOSITY);

  init_noise(pars,seed);

  if (INNOISE > 0.0)
    for (li=0;li<pars.LENGTH;li++)
      for (i=0;i<pars.DIM;i++)
	series[i][li] += 2.0*INNOISE*
	  ((double)rnd_long()/(double)ULONG_MAX-0.5);

  check_alloc(sermin=malloc(sizeof(double)*pars.DIM));
  check_alloc(serinter=malloc(sizeof(double)*pars.DIM));
  //  rescale_data(series,pars,sermin,serinter);

  for (i=0;i<pars.DIM;i++) {
    sermin[i]=0.0;
    serinter[i]=1.0;
  }
  max=serinter[0];
  for (i=1;i<pars.DIM;i++)
    if (serinter[i] > max)
      max=serinter[i];

  for (i=0;i<pars.DIM;i++) {
    for (j=0;j<pars.LENGTH;j++)
      series[i][j] /= max;
  }
  if (pars.maxr > 0.0)
    pars.maxr /= max;

  hdim=1;
  pars.hdim=hdim;

  check_alloc(future=(unsigned int*)malloc(sizeof(int)*pars.LENGTH));
  if (WHICHFUTURE>0) {
    check_alloc(wcol=(char*)calloc((size_t)10,(size_t)1));
    sprintf(wcol,"%u",WHICHFUTURE);
    dfuture=(double**)get_multi_series(infile,&(pars.LENGTH),EXCLUDE,
				       &wdim,wcol,1,0L);
    for (li=0;li<hdim;li++)
      future[li]=0;
    for (li=hdim;li<pars.LENGTH-1;li++) {
      has_future= (dfuture[0][li]>0.0);
      for (lj=1;lj<=hdim;lj++)
	has_future &= (dfuture[0][li-lj]>0.0);
      future[li]=has_future;
    }
    future[pars.LENGTH-1]=0;
    free(dfuture);
  }
  else {
    for (li=0;li<pars.LENGTH-1;li++)
      future[li]=1;
    future[pars.LENGTH-1]=0;
    for (li=0;li<hdim;li++)
      future[li]=0;
  }

  check_alloc(sf.found=(unsigned long*)
	      malloc(sizeof(unsigned long)*pars.LENGTH));
  check_alloc(sf.distance=(double*)malloc(sizeof(double)*pars.LENGTH));
  check_alloc(sf.weight=(double*)malloc(sizeof(double)*pars.LENGTH));
  check_alloc(sf.count=(unsigned long*)malloc(sizeof(unsigned long)));
  check_alloc(sf.aveps=(double*)malloc(sizeof(double)));
  sf.count[0]=0;
  sf.aveps[0]=0.0;
  check_alloc(cast=(double**)malloc(sizeof(double*)*pars.DIM));
  for (i=0;i<pars.DIM;i++)
    check_alloc(cast[i]=(double*)malloc(sizeof(double)*(hdim+1)));
  check_alloc(new=(double*)malloc(sizeof(double)*pars.DIM));

  check_alloc(drift=(double*)malloc(sizeof(double)*pars.DIM));
  check_alloc(diffusion=(double**)malloc(sizeof(double*)*pars.DIM));
  check_alloc(gamma=(double**)malloc(sizeof(double*)*pars.DIM));
  for (i=0;i<pars.DIM;i++) {
    check_alloc(diffusion[i]=(double*)malloc(sizeof(double)*pars.DIM));
    check_alloc(gamma[i]=(double*)malloc(sizeof(double)*pars.DIM));
  }

  for (i=0;i<=hdim;i++)
    for (j=0;j<pars.DIM;j++)
      cast[j][hdim-i]=series[j][pars.LENGTH-1-i];

  pars.minminn=(unsigned long)((3.*pars.DIM+3.)/2.0+0.5);
  init_neighbor_search_circ(series,pars,future);

  /* print program call and column labels */
  fout=fopen(OUTFILE,"w");
  fprintf(fout,"%s\n",outstring);
#if defined(MAXNORM)
  fprintf(fout,"#Norm: Maxnorm\n");
#else
  fprintf(fout,"#Norm: L2 Norm\n");
#endif
#if defined(WEIGHTS)
  if (pars.maxr > 0.0)
    fprintf(fout,"#Weights: on WFACT = %lf maxr = %lf\n",WFACT,pars.maxr*max);
  else
    fprintf(fout,"#Weights: on WFACT = %lf maxr not set\n",WFACT);
#else
  fprintf(fout,"#Weights: off\n");
#endif
  fprintf(fout,"#Content: ");
  for (i=0;i<pars.DIM;i++)
    fprintf(fout,"x%d ",i+1);
  fprintf(fout,"\n");
  fflush(fout);

  if (!nofields) {
    ffield=fopen(fieldfile,"w");
    fprintf(ffield,"%s\n",outstring);
#if defined(MAXNORM)
    fprintf(ffield,"#Norm: Maxnorm\n");
#else
    fprintf(ffield,"#Norm: L2 Norm\n");
#endif
#if defined(WEIGHTS)
  if (pars.maxr > 0.0)
    fprintf(ffield,"#Weights: on WFACT = %lf maxr = %lf\n",WFACT,pars.maxr*max);
  else
    fprintf(ffield,"#Weights: on WFACT = %lf maxr not set\n",WFACT);
#else
    fprintf(ffield,"#Weights: off\n");
#endif
    fprintf(ffield,"#Content: ");
    for (i=0;i<pars.DIM;i++)
      for (j=0;j<pars.EMB;j++)
	if (pars.EMB>1) {
	  fprintf(ffield,"x%d_%d ",i+1,j+1);
	}
	else {
	  fprintf(ffield,"x%d ",i+1);
	}
    for (i=0;i<pars.DIM;i++)
      fprintf(ffield,"f%d ",i+1);
    for (i=0;i<pars.DIM;i++)
      for (j=0;j<pars.DIM;j++)
	fprintf(ffield,"g_%d_%d ",i+1,j+1);
    for (i=0;i<pars.DIM;i++)
      for (j=0;j<=i;j++)
	fprintf(ffield,"K_%d_%d ",i+1,j+1);
#if defined(WEIGHTS)
    fprintf(ffield,"distance sweights\n");
#else
    fprintf(ffield,"distance\n");
#endif
    fflush(ffield);
  }

  count=0;
  while (count <FLENGTH) {
    search_neighbors_circ(series,cast,pars,sf);
    get_fields_no_circ(series,pars,sf,drift,gamma,diffusion,cast);
    make_cast_no_circ(cast,new,pars,drift,gamma,diffusion);

    for (i=0;i<pars.DIM;i++)
      fprintf(fout,"%lf ",new[i]*max+sermin[i]);
    fprintf(fout,"\n");
    fflush(fout);

    if (!nofields) {
      for (i=0;i<pars.DIM;i++)
	for (j=0;j<pars.EMB;j++)
	  fprintf(ffield,"%e ",cast[i][hdim-j*pars.DELAY]*max+sermin[i]);
      for (i=0;i<pars.DIM;i++)
	fprintf(ffield,"%e ",drift[i]*max);
      for (i=0;i<pars.DIM;i++)
	for (j=0;j<pars.DIM;j++)
	  fprintf(ffield,"%e ",gamma[i][j]);
      for (i=0;i<pars.DIM;i++)
	for (j=0;j<=i;j++)
	  fprintf(ffield,"%e ",diffusion[i][j]*max);
#if defined(WEIGHTS)
      sweights=sf.weight[0];
      for (i=1;i<pars.MINN;i++)
	sweights += sf.weight[i];
      fprintf(ffield,"%e %lf\n",sf.distance[pars.MINN-1]*max,sweights);
#else
      fprintf(ffield,"%e\n",sf.distance[pars.MINN-1]*max);
#endif
      fflush(ffield);
    }
    for (i=1;i<=hdim;i++)
      for (j=0;j<pars.DIM;j++)
	cast[j][i-1]=cast[j][i];
    for (i=0;i<pars.DIM;i++)
      cast[i][hdim]=new[i];
    count++;
  }
  fclose(fout);
  if (!nofields)
    fclose(ffield);

  return 0;
}