示例#1
0
文件: quadmodel.cpp 项目: 9gix/cg
static float QuadArea( const float v[4][3] )
{
	float normal1[3], normal2[3];
	VecTriNormal( normal1, v[0], v[1], v[2] );
	VecTriNormal( normal2, v[0], v[2], v[3] );
	return 0.5f * ( VecLen( normal1 ) + VecLen( normal2 ) );
}
示例#2
0
float CosAng ( float *v1, float *v2 )
{
    float ang, a,b ;

    a = VecLen ( v1 ) ;
    b = VecLen ( v2 ) ;

    ang = ((v1[0]*v2[0]) + (v1[1]*v2[1] ) + (v1[2]*v2[2])) / (a*b) ;

    return ( ang ) ;
}
示例#3
0
cvector FFT::fconv(const cvector &a, const cvector &b)
{
	const int neededSize= VecLen(a) + VecLen(b) -1;
	int size = 1;
	while( size <= neededSize) size *= 2;
	
	cvector af = FFT::fft(a, size);
	cvector bf = FFT::fft(b, size);
	cvector cf(Lb(af), Ub(af));
	for(int i = Lb(cf); i<=Ub(cf); ++i)
		cf[i] = af[i] * bf[i];
	cvector result = FFT::ifft(cf);
	cxsc::Resize(result, Lb(result)+1, Lb(result) + neededSize-1);
	return result;
}
示例#4
0
//컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴
//Procedure		Engine
//Author		Andrew McRae
//Date			Mon 27 Jan 1997
//
//Description	Piston Engine Constructor
//
//Inputs		
//
//Returns	
//
//------------------------------------------------------------------------------
Engine::Engine (PMODEL pmodel, ENGINE_TYPE type)
{

	// Initialise

	NullThis ();

	pModel = pmodel;
	Type = type;

	FP ACspeed = VecLen(pModel->Vel);
	if(ACspeed < 10) ACspeed = 10;
	PropVel = ACspeed;				//Speed of airflow through prop			/CSB
	SlipVel = ACspeed;				//Speed of airflow in slipstream		/CSB
	SlipRot = 0;					//Rotation of airflow in slipstream		/CSB
	PropInc = 44;	//CSB 04/06/99	

	Magnetos     = 0;
	Temperature  = 0;
	FuelInPipes  = 0;
	StarterSpeed = 0;
	Priming		 = 0;
	Starting	 = false;

	List.Attach (&pModel->EngineList, this);

}
示例#5
0
cvector FFT::ifft(const cvector &vector)
{
	const int N = VecLen(vector);
	
	fftw_complex *in, *out;
    fftw_plan p;
    
    in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
    out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
    for(int i = Lb(vector); i<=Ub(vector); ++i)
    {
    	in[i-Lb(vector)][0] = _double(Re(vector[i]));
    	in[i-Lb(vector)][1] = _double(Im(vector[i]));
    }
    p = fftw_plan_dft_1d(N, in, out, FFTW_BACKWARD, FFTW_ESTIMATE);
    
    fftw_execute(p); /* repeat as needed */
    
    fftw_destroy_plan(p);
    cvector ret(0, N-1);
    const cxsc::complex n(1.0/N, 0.0);
    for(int i = 0; i<N; ++i)
    {
    	ret[i] = cxsc::complex(out[i][0], out[i][1]) * n;
    }
    fftw_free(in); fftw_free(out);
    return ret;
}
示例#6
0
文件: U_CLOCK.C 项目: CGSG/SUM2016
/* Unit clock inter frame events handle function.
 * ARGUMENTS:
 *   - self-pointer to unit object:
 *       vg4UNIT_CLOCK *Uni;
 *   - animation context:
 *       vg4ANIM *Ani;
 * RETURNS: None.
 */
static VOID VG4_UnitResponse( vg4UNIT_CLOCK *Uni, vg4ANIM *Ani )
{
  DBL r;

  if (Ani->Keys[VK_SPACE])
    VG4_AnimAddUnit(VG4_UnitCreateBall());
  if (Ani->Keys['C'])
    VG4_AnimAddUnit(VG4_UnitCreateCube());
  if (Ani->KeysClick[VK_RETURN] && Ani->Keys[VK_MENU])
    VG4_AnimFlipFullScreen();
  if (Ani->KeysClick[VK_ESCAPE])
    VG4_AnimDoExit();
  if (Ani->KeysClick['P'])
    Ani->IsPause = !Ani->IsPause;


  /* Uni->Pos.Y += Ani->JY * Ani->GlobalDeltaTime; */

  Uni->Pos = VecMulMatr43(Uni->Pos, MatrRotateX(59 * Ani->JY * Ani->GlobalDeltaTime));
  Uni->Pos = VecMulMatr43(Uni->Pos, MatrRotateY(59 * Ani->JX * Ani->GlobalDeltaTime));

  if (Ani->Keys[VK_LBUTTON])
  {
    Uni->Pos = VecMulMatr43(Uni->Pos, MatrRotateY(59 * Ani->Mdx * Ani->GlobalDeltaTime));
    Uni->Pos = VecMulMatr43(Uni->Pos, MatrRotateX(59 * Ani->Mdy * Ani->GlobalDeltaTime));
  }

  Uni->Pos = VecMulMatr43(Uni->Pos, MatrRotateY(59 * Ani->Keys[VK_RIGHT] * Ani->GlobalDeltaTime));
  Uni->Pos = VecMulMatr43(Uni->Pos, MatrRotateY(-59 * Ani->Keys[VK_LEFT] * Ani->GlobalDeltaTime));

  r = VecLen(Uni->Pos);
  Uni->Pos = VecMulNum(Uni->Pos, (r + Ani->Mdz * Ani->DeltaTime * 0.1) / r);

  VG4_RndMatrView = MatrView(Uni->Pos, VecSet(0, 0, 0), VecSet(0, 1, 0));
} /* End of 'VG4_UnitResponse' function */
示例#7
0
文件: sph.C 项目: CoryXie/Graphite
VOID	SphTransform(OBJECT *po, MATRIX xtrans, MATRIX xinvT)
	{
	INT	i;
	INT	numelems;		/* Number of object elements.	  */
	REAL	new_rad;
	SPHERE	*ps;			/* Ptr to sphere data.		     */
	ELEMENT *pe;			/* Ptr to sphere element.	     */
	POINT	surf_point;		/* Point on surface.		     */
	POINT	center_point;		/* Center_point.		     */
	POINT	rad_vector;		/* Radius vector.		     */

	pe	 = po->pelem;
	numelems = po->numelements;

	for (i = 0; i < numelems; i++)
		{
		ps = (SPHERE *)pe->data;

		/* See if radius has changed with a scale. */

		surf_point[0]	= ps->center[0] + ps->rad;
		surf_point[1]	= ps->center[1];
		surf_point[2]	= ps->center[2];
		surf_point[3]	= 1.0;

		center_point[0] = ps->center[0];
		center_point[1] = ps->center[1];
		center_point[2] = ps->center[2];
		center_point[3] = 1.0;

		/* Transform center point. */

		VecMatMult(center_point, xtrans, center_point);
		VecMatMult(surf_point, xtrans, surf_point);

		/* Find radius. */

		VecSub(rad_vector, surf_point, center_point);
		VecCopy(ps->center, center_point);

		new_rad = VecLen(rad_vector);

		if (new_rad != ps->rad)
			{
			ps->rad  = new_rad;
			ps->rad2 = ps->rad * ps->rad;
			}

		pe++;
		}
	}
示例#8
0
文件: sph.C 项目: CoryXie/Graphite
VOID	SphDataNormalize(OBJECT *po, MATRIX normMat)
	{
	INT	i;
	SPHERE	*ps;			/* Ptr to sphere data.		     */
	ELEMENT *pe;			/* Ptr to sphere element.	     */
	POINT	surf_point;		/* Point on surface.		     */
	POINT	center_point;		/* Center point.		     */
	POINT	rad_vector;		/* Radius vector.		     */

	NormalizeBoundBox(&po->bv, normMat);

	pe = po->pelem;

	for (i = 0; i < po->numelements; i++)
		{
		ps = (SPHERE *)pe->data;

		NormalizeBoundBox(&pe->bv, normMat);

		surf_point[0]	= ps->center[0] + ps->rad;
		surf_point[1]	= ps->center[1];
		surf_point[2]	= ps->center[2];
		surf_point[3]	= 1.0;

		center_point[0] = ps->center[0];
		center_point[1] = ps->center[1];
		center_point[2] = ps->center[2];
		center_point[3] = 1.0;


		/* Transform center point. */

		VecMatMult(center_point, normMat, center_point);
		VecMatMult(surf_point, normMat, surf_point);


		/* Find new radius. */

		VecSub(rad_vector, surf_point, center_point);
		VecCopy(ps->center, center_point);

		ps->rad  = VecLen(rad_vector);
		ps->rad2 = ps->rad * ps->rad;

		pe++;
		}
	}
示例#9
0
static VOID MP2_UnitResponse( mp2CONTROL *Uni, mp2ANIM *Ani )
{
  DBL r;
  VEC Dir = VecNormalize(VecSubVec(View, Uni->Pos)),
      Right = VecNormalize(VecCrossVec(Dir, VecSet(0, 1, 0)));
  if (Ani->Keys['T'])
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  if (Ani->Keys['Y'])
    glPolygonMode(GL_FRONT, GL_LINE);
  if (Ani->Keys['U'])
    glPolygonMode(GL_BACK, GL_LINE);
  /*if (Ani->Keys[VK_SPACE])
    MP2_AnimAddUnit(MP2_UnitCreateBall()); */
  if (Ani->KeysClick['C'])
    MP2_AnimAddUnit(MP2_UnitCreateCube(/*Rnd1() * 4, Rnd1() * 4, Rnd1() * 4*/0, 0, 0));
  if (Ani->KeysClick['V'])
    MP2_AnimAddUnit(MP2_UnitCreateSTATICMODEL(/*Rnd1() * 4, Rnd1() * 4, Rnd1() * 4*/0, 0, 0));
  if (Ani->KeysClick[VK_RETURN] && Ani->Keys[VK_MENU])
    MP2_FlipFullScreen(MP2_Anim.hWnd);
  /*if (Ani->KeysClick[VK_ESCAPE])
    MP2_AnimDoExit();*/
  if (Ani->KeysClick['P'])
    Ani->IsPause = !Ani->IsPause;

  /* Uni->Pos.Y += Ani->JY * Ani->GlobalDeltaTime; */
  Uni->Pos = PointTransform(Uni->Pos, MatrRotate((50 * Ani->JY * Ani->GlobalDeltaTime), Right));
  Uni->Pos = PointTransform(Uni->Pos, MatrRotateY(10 * Ani->JX * Ani->GlobalDeltaTime));
   

  if (Ani->Keys[VK_LBUTTON])
  {
    Uni->Pos = PointTransform(Uni->Pos, MatrRotateY(10 * Ani->Mdx * Ani->GlobalDeltaTime));
    Uni->Pos = PointTransform(Uni->Pos, MatrRotateX(10 * Ani->Mdy * Ani->GlobalDeltaTime));
  }
  View.X += Ani->JZ / 10;
  View.Z += Ani->JR / 10;
  Uni->Pos = PointTransform(Uni->Pos, MatrRotateY(10 * Ani->Keys[VK_RIGHT] * Ani->GlobalDeltaTime));
  Uni->Pos = PointTransform(Uni->Pos, MatrRotateY(-10 * Ani->Keys[VK_LEFT] * Ani->GlobalDeltaTime));

  r = VecLen(Uni->Pos);
  Uni->Pos = VecMulNum(Uni->Pos, (r + (-Ani->Mdz) * Ani->DeltaTime * 1.0) / r);
  
  MP2_RndMatrView = MatrView(VecAddVec(Uni->Pos, View), View, VecSet(0, 1, 0));
}
示例#10
0
void VecNormalize(TDA A)
{
  float dist, invdist;

  dist=VecLen(A);
  if(!(dist==0.0))
  {
    invdist=1/dist;
    A[0]*=invdist;
    A[1]*=invdist;
    A[2]*=invdist;
  }
  else
  {
	  assert(dist==0.0);
//    puts("Zero-Length Vectors cannot be Normalized");
//    exit(1);
  }
}
示例#11
0
VOID	PolyRead(OBJECT *po, FILE *pf)
	{
	INT	i, j;			/* Indices.			     */
	INT	instat; 		/* Read status. 		     */
	INT	*vindex;
	INT	totalverts;		/* Total # of vertices in poly mesh. */
	CHAR	normstr[5];		/* Face/vertex normal flag string.   */
	BOOL	pnormals;		/* Face normals present?	     */
	VEC3	pnorm;			/* Polygon normal accumulator.	     */
	VEC3	*vlist, *vptr, *vp;	/* Ptr to vertex list.		     */
	VEC3	*vptmp, *vptmp2;	/* Ptr to vertex list.		     */
	VEC3	tmppnt, tmppnt2, cross;
	POLY	*pp;			/* Ptr to polygon data. 	     */
	ELEMENT *pe;			/* Ptr to polygon element.	     */


	pe = po->pelem;

	/* Allocate space for object data. */

	instat = fscanf(pf, "%ld", &totalverts);

	if (instat != 1)
		{
		printf("Error in PolyRead: totalverts.\n");
		exit(-1);
		}

	pp    = GlobalMalloc(sizeof(POLY)*po->numelements,  "poly.c");
	vlist = GlobalMalloc(sizeof(VEC3)*(totalverts + 1), "poly.c");
	vptr  = vlist;


	/* Are polygon face normals supplied? */

	instat = fscanf(pf, "%s\n", normstr);

	if (instat != 1)
		{
		printf("Error in PolyRead: face normal indicator.\n");
		exit(-1);
		}

	pnormals = (normstr[2] == 'y' ? TRUE : FALSE);


	/* Read vertex list. */

	for (i = 0; i < totalverts; i++)
		{
		instat = fscanf(pf, "%lf %lf %lf", &(*vptr)[0], &(*vptr)[1], &(*vptr)[2]);

		if (instat != 3)
			{
			printf("Error in PolyRead: vertex %ld.\n", i);
			exit(-1);
			}

		vptr++;
		}


	(*vptr)[0] = HUGE_REAL;
	(*vptr)[1] = HUGE_REAL;
	(*vptr)[2] = HUGE_REAL;


	/* Read polygon list. */

	for (i = 0; i < po->numelements; i++)
		{
		instat = fscanf(pf, "%ld", &(pp->nverts));

		if (instat != 1)
			{
			printf("Error in PolyRead: vertex count.\n");
			exit(-1);
			}

		if (pp->nverts > MAX_VERTS)
			{
			printf("Polygon vertex count, %ld, exceeds maximum.\n", pp->nverts);
			exit(-1);
			}

		if (pnormals)
			{
			instat = fscanf(pf, " %lf %lf %lf", &(pp->norm[0]), &(pp->norm[1]), &(pp->norm[2]));

			if (instat != 3)
				{
				printf("Error in PolyRead: face normal %ld.\n", i);
				exit(-1);
				}
			}

		pp->vptr   = vlist;
		pp->vindex = GlobalMalloc(sizeof(INT)*pp->nverts, "poly.c");
		vindex	   = pp->vindex;

		for (j = 0; j < pp->nverts; j++)
			{
			instat = fscanf(pf, "%ld", vindex++);

			if (instat != 1)
				{
				printf("Error in PolyRead: vertex index %ld.\n", i);
				exit(-1);
				}
			}

		/* If not supplied, calculate plane normal. */

		vindex = pp->vindex;
		vptr   = vlist;

		if (!pnormals)
			{
			vp = vptr + (*vindex);
			VecZero(pnorm);

			for (j = 0; j < pp->nverts - 2; j++)
				{
				vptmp  = vptr + (*(vindex + 1));
				vptmp2 = vptr + (*(vindex + 2));

				VecSub(tmppnt,	(*vptmp),  (*vp));
				VecSub(tmppnt2, (*vptmp2), (*vptmp));

				VecCross(cross, tmppnt, tmppnt2);
				VecAdd(pnorm,	pnorm,	cross);

				vp = vptmp;
				vindex += 1;
				}

			VecSub(tmppnt, (*vptmp2), (*vp));
			vindex	= pp->vindex;
			vp	= vptr + (*vindex);

			VecSub(tmppnt2, (*vp), (*vptmp2));
			VecCross(cross, tmppnt, tmppnt2);
			VecAdd(pnorm, pnorm, cross);

			vp	= vptr + (*vindex);
			VecSub(tmppnt, (*vp), (*vptmp2));
			vptmp	= vptr + (*(vindex + 1));

			VecSub(tmppnt2, (*vptmp), (*vp));
			VecCross(cross, tmppnt, tmppnt2);
			VecAdd(pnorm, pnorm, cross);
			VecScale(pp->norm, 1.0/VecLen(pnorm), pnorm);
			}


		/* Calculate plane equation d. */

		vp = pp->vptr + *(pp->vindex);
		pp->d = -(pp->norm[0]*(*vp)[0] + pp->norm[1]*(*vp)[1] + pp->norm[2]*(*vp)[2]);

		pe->data   = (CHAR *)pp;
		pe->parent = po;

		PolyElementBoundBox(pe, pp);

		pp++;
		pe++;
		}
	}
示例#12
0
void
activate_muscle (HEAD *face, float *vt, float *vh, float fstart,  float fin,  float ang,  float val)
{
    float newp[3], va[3], vb[3] ;
    int i,j,k,l ;
    float valen, vblen ;
    float cosa, cosv, dif, tot, percent, thet, newv, the, radf ;

    radf  = 180.0/ M_PI ;
    the   = ang / radf ; ;
    thet  = cos ( the ) ;

    cosa = 0.0 ;

    /* find the length of the muscle */
    for (i=0; i<3; i++)
        va[i] = vt[i] - vh[i] ;
    valen = VecLen ( va ) ;

    /* loop for all polygons */
    for (i=0; i<face->npolygons; i++) {

        /* loop for all vertices */
        for (j=0; j<3; j++) {

            /* find the length of the muscle head to the mesh node */
            for (k=0; k<3; k++)
                vb[k] = face->polygon[i]->vertex[j]->xyz[k] - vh[k] ;
            vblen = VecLen ( vb ) ;

            if ( valen > 0.0 && vblen > 0.0) {
                cosa = CosAng ( va, vb ) ;

                if ( cosa >= thet ) {
                    if ( vblen <= fin ) {
                        cosv = val * ( 1.0 - (cosa/thet) ) ;

                        if ( vblen >= fstart && vblen <= fin) {
                            dif       = vblen - fstart ;
                            tot       = fin - fstart ;
                            percent   = dif/tot ;
                            newv      = cos ( DTOR(percent*90.0) ) ;

                            for ( l=0; l<3; l++)
                                newp[l] = (vb[l] * cosv) * newv ;
                        }
                        else {
                            for ( l=0; l<3; l++)
                                newp[l] = vb[l] * cosv ;

                        }   /* endif vblen>fin */

                        for (l=0; l<3; l++)
                            face->polygon[i]->vertex[j]->xyz[l] += newp[l] ;

                    }  /* endif vblen>fin    */
                }   /* endif cosa>thet    */
            }    /* endif mlen&&tlen   */
        }     /* end for j vertices */
    }      /* end for i polygon  */
}
示例#13
0
SysStatus
__SetupStack(uval stackBottomLocal, uval &__stackTopLocal,
	     uval &__stackTop, ProgExec::XferInfo *info,
	     ProgExec::ArgDesc* args)
{
    EXECTYPE exectype; // To make WORDTYPE work

    SysStatus rc;
    ProgExec::BinInfo &exec = info->exec.prog;
    uval stackTop = __stackTop;
    uval stackTopLocal = __stackTopLocal;
    char **envp;
    char **argv, **argvp;
    // Put argc, argv on top of stack (envp, aux vec to follow)
    envp = args->getEnvp();
    uval envcChild = VecLen(envp);
    WORDTYPE* envpChild = (WORDTYPE*)allocGlobal(sizeof(WORDTYPE)*envcChild);

    rc = PushStrings<EXECTYPE,WORDTYPE>(envp, envpChild, envcChild-1, stackTop,
					stackTopLocal, stackBottomLocal);

    _IF_FAILURE_RET(rc);
    envpChild[envcChild-1] = (WORDTYPE)NULL;

    argv = args->getArgv();
    argvp = args->getArgvPrefix();
    
    uval argcChild = VecLen(argv);
    uval argcpCount = 0;
    if(argvp) {
	argcpCount = VecLen(argvp)-1; // don't include null entry
	argcChild += argcpCount;
    }
    
    WORDTYPE* argvChild = (WORDTYPE*)allocGlobal(sizeof(WORDTYPE)*argcChild);

    rc = PushStrings<EXECTYPE,WORDTYPE>(argv, argvChild + argcpCount,
					argcChild-argcpCount-1, stackTop,
					stackTopLocal, stackBottomLocal);

    _IF_FAILURE_RET(rc);
    argvChild[argcChild -1] = (WORDTYPE)NULL;

    if(argcpCount) {
	/*
	 * A prefix, containing the shell interpreter args, is present
	 * so push it on top of the original parameters
	 */
	rc = PushStrings<EXECTYPE,WORDTYPE>(argvp, argvChild,
					argcpCount, stackTop,
					stackTopLocal, stackBottomLocal);
	_IF_FAILURE_RET(rc);
    }
	
    // Put in architecture specific aux vector
    uval origLocal = stackTopLocal;
    rc = ProgExec::PutAuxVector<EXECTYPE>(stackTopLocal, exec);
    _IF_FAILURE_RET(rc);

    stackTop -= (origLocal - stackTopLocal);
    info->auxv = (ElfW(auxv_t)*)stackTop;


    stackTopLocal -= envcChild * sizeof(WORDTYPE);
    stackTop -= envcChild * sizeof(WORDTYPE);
    memcpy((char*)stackTopLocal,envpChild, envcChild * sizeof(WORDTYPE));

    info->envp = (char**)stackTop;

    stackTopLocal -= argcChild * sizeof(WORDTYPE);
    stackTop -= argcChild * sizeof(WORDTYPE);
    memcpy((char*)stackTopLocal,argvChild, argcChild * sizeof(WORDTYPE));
    info->argv = (char**)stackTop;

    stackTopLocal -= sizeof(WORDTYPE);
    stackTop -= sizeof(WORDTYPE);
    *(WORDTYPE*)stackTopLocal = (WORDTYPE)(argcChild-1); //store argc on stack
    info->argc = argcChild-1;

    __stackTopLocal = stackTopLocal;
    __stackTop = stackTop;
    freeGlobal(envpChild, envcChild*sizeof(WORDTYPE));
    freeGlobal(argvChild, argcChild*sizeof(WORDTYPE));
    return 0;
}
示例#14
0
文件: qedat.c 项目: sencer/cube
int main()
{
  // get list of dat/*.dat, and sort them
  char files[5000][11];
  int nfile = FilesList(files, "dat");
  qsort(&files[0], nfile, sizeof(files[0]), CompStrInt);
  if(nfile < 1) return -1;  // exit if no files

  // read following system information from cube.in
  // number of atoms -> nat
  // number of atomic types -> ntyp
  // number of each atom in system -> num[]
  // proton number of each atom in the same order with num[] -> z[]
  // 3x3 matrix of the cell dimensions -> celldm[3][3]
  int nat = 0, ntyp = 0, num[30], z[30];
  double celldm[3][3];
  ReadInput(&nat, &ntyp, num, z, celldm);

  // we will need
  // the inverse of celldm matrix -> inv[3][3]
  // and lengths of cell vectors -> norm[3]
  double inv[3][3];
  double norm[3] = {
    VecLen(celldm[0]),
    VecLen(celldm[1]),
    VecLen(celldm[2])
  };
  Inv3D(celldm, inv);

  // a string for
  // the name of the dat file to read -> fname[20]
  // the name of the cube file to write -> cname[20]
  // a FILE for the file i/o
  char fname[20], cname[20];
  FILE *f;

  // read the grid information from the files[0]
  int ngrid[3];
  sprintf(fname, "dat/%s", files[0]);
  f = fopen(fname, "r");
  ReadDatHeader(f, ngrid);
  fclose(f);

  // let's calculate ngrid[0] * ngrid[1] once and for all.
  int dim = ngrid[0] * ngrid[1];

  // calculate the voxel sizes
  double vsize[3][3];
  memcpy(vsize, celldm, sizeof(celldm));
  for(int i = 0; i < 3; ++i)
  {
    VecScale(vsize[i], 1.0/ngrid[i]);
  }

  int dummy[3];

#pragma omp parallel for private(f, fname, cname) shared(dummy)
  for(int file = 0; file < nfile; ++file)
  {
    // set cube file name
    sprintf(cname, "cube/%d.cube", atoi(files[file]));
    // if the file exists, skip
    if (access(cname, F_OK) == -1)
    {
      // create a Cube to read dat file into
      Cube *c = CubeInit(nat, ngrid);
      CubeSetVoxels(c, vsize);

      // Read the next dat file (header info is read to skip this part)
      sprintf(fname, "dat/%s", files[file]);
      f = fopen(fname, "r");
      ReadDatHeader(f, dummy);
      ReadDatData(f, ngrid, dim, c);
      fclose(f);

      // get ionic positions for the corresponding frame from cp.pos
      GetAtoms(atoi(files[file]), c, nat, z, num);

      int pos = 0;
      char com[255] = "";
      double rho;

      for (int i = 0; i < c->nat; i++)
      {
        if(Surround(i, c, 0.4, 1) > THR && c->atoms[i].Z == 22)
        {
          rho = Surround(i, c, 2.1, 0) ;
          printf("%d %lf %lf\n", atoi(files[file]), c->atoms[i].coor[2], rho);
          pos += sprintf(com + pos, "%d ", i);
        }
        fflush(stdout);
      }

      CubeBeautify(c, THR);
      CubeTrim(&c, THR);

      sprintf(c->comment[0], "%-10.6f %-10.6f %-10.6f %-10.6f %-10.6f %-10.6f",
          norm[0]*B2A, norm[1]*B2A, norm[2]*B2A,
          DEG*acos(VecDot(celldm[0], celldm[2])/(norm[2]*norm[0])),
          DEG*acos(VecDot(celldm[1], celldm[2])/(norm[1]*norm[2])),
          DEG*acos(VecDot(celldm[0], celldm[1])/(norm[0]*norm[1])));

      strcpy(c->comment[1], com);
      printf("%s %s", files[file], com);
      CubeWrite(c, cname);
      CubeDelete(c);
    }
  }
  return 0;
}