void initDevID(){
   
   static int iInitOk=0;
   if(iInitOk)return;
   iInitOk=1;
   memset(bufDevID,0,sizeof(bufDevID));
#if 0
   //depricated  6.0
   NSString *n = [[UIDevice currentDevice]uniqueIdentifier];
   
   const char *pn=n.UTF8String;
#else
   int iDevIdLen=0;
   char fn[1024];
   snprintf(fn,sizeof(fn)-1, "%s/devid-hex.txt", getFileStorePath());
   
   char *pn=loadFile(fn, iDevIdLen);
   
   if(!pn || iDevIdLen<=0){
      
      pn=&bufDevID[0];
      
      FILE *f=fopen("/dev/urandom","rb");
      if(f){
         unsigned char buf[T_MAX_DEV_ID_LEN_BIN+1];
         fread(buf,1,T_MAX_DEV_ID_LEN_BIN,f);
         fclose(f);
         void bin2Hex(unsigned char *Bin, char * Hex ,int iBinLen);
         bin2Hex(buf, bufDevID, T_MAX_DEV_ID_LEN_BIN);
         bufDevID[T_MAX_DEV_ID_LEN]=0;
         
         saveFile(fn, bufDevID, T_MAX_DEV_ID_LEN);
         setFileAttributes(fn,0);
      }
      
   }
   
#endif
   void safeStrCpy(char *dst, const char *name, int iMaxSize);
   safeStrCpy(&bufDevID[0],pn,sizeof(bufDevID)-1);
   
   int calcMD5(unsigned char *p, int iLen, char *out);
   calcMD5((unsigned char*)pn,strlen(pn),&bufMD5[0]);
   
   
}
/* ******************************************************************************
*  Function Name : instanceFile()
*
*  Description :  Instance the geometry from a BGEO file
*
*  Input Arguments : GU_Detail *file_gdp, GU_Detail *inst_gdp, GU_Detail *mb_gdp
*
*  Return Value : int
*
***************************************************************************** */
int VRAY_clusterThis::instanceFile(GU_Detail * file_gdp, GU_Detail * inst_gdp, GU_Detail * mb_gdp)
{
#ifdef DEBUG
   std::cout << "VRAY_clusterThis::instanceFile()" << std::endl;
   cout << "VRAY_clusterThis::instanceFile() myPointAttributes.geo_fname: " << myPointAttributes.geo_fname << endl;
#endif

#define USE_POINT_FNAME 1

   GU_Detail null_gdp;
   UT_Matrix4 xform(1.0);
   UT_Matrix3 rot_xform(1.0);
//   UT_XformOrder xformOrder(UT_XformOrder::SRT,  UT_XformOrder::XYZ);

#ifdef USE_POINT_FNAME
   GU_Detail * file_geo_gdp;
   file_geo_gdp = VRAY_Procedural::allocateGeometry();
   if(!file_geo_gdp->load((const char *)myPointAttributes.geo_fname).success())
      throw VRAY_clusterThis_Exception("VRAY_clusterThis::instanceFile() Failed to load geometry file ", 1);
   GU_Detail temp_gdp(file_geo_gdp);
#else
   GU_Detail temp_gdp(file_gdp);
#endif

   UT_Vector3 myDir = myPointAttributes.N;
   UT_Vector3 myUp = UT_Vector3(0, 1, 0);

// Transform the geo to the new position
   rot_xform.orient(myDir, myUp);
   xform = rot_xform;

   xform.scale(mySize[0] * myPointAttributes.pscale, mySize[1] * myPointAttributes.pscale, mySize[2] * myPointAttributes.pscale);
//    xform.rotate(myPointAttributes.N[0], myPointAttributes.N[1], myPointAttributes.N[2], xformOrder);
   xform.translate(myPointAttributes.myNewPos[0], myPointAttributes.myNewPos[1], myPointAttributes.myNewPos[2]);
//   xform.xform(xformOrder, myPointAttributes.myNewPos[0], myPointAttributes.myNewPos[1], myPointAttributes.myNewPos[2],
//               myPointAttributes.N[0], myPointAttributes.N[1], myPointAttributes.N[2],
//               mySize[0], mySize[1], mySize[2]);

   temp_gdp.transform(xform);

//   GU_Detail theFileGDP(theFiles[myPointAttributes.lod][myPointAttributes.anim_frame]);
   addFileAttributeRefs(&temp_gdp);
   setFileAttributes(&temp_gdp);

   // Run CVEX function on this instance
   if(myCVEX_Exec)
      VRAY_clusterThis::runCVEX(&temp_gdp, &null_gdp, myCVEXFname, CLUSTER_CVEX_POINT);
   if(myCVEX_Exec_prim)
      VRAY_clusterThis::runCVEX(&temp_gdp, &null_gdp, myCVEXFname_prim, CLUSTER_CVEX_PRIM);

   inst_gdp->merge(temp_gdp);


   if(myDoMotionBlur == CLUSTER_MB_DEFORMATION) {
#ifdef USE_POINT_FNAME
         GU_Detail temp_gdp(file_geo_gdp);
#else
         GU_Detail temp_gdp(file_gdp);
#endif

         xform.identity();
         rot_xform.identity();
         rot_xform.orient(myDir, myUp);
         xform = rot_xform;

         xform.scale(mySize[0] * myPointAttributes.pscale, mySize[1] * myPointAttributes.pscale, mySize[2] * myPointAttributes.pscale);
//        xform.rotate(myPointAttributes.N[0], myPointAttributes.N[1], myPointAttributes.N[2], xformOrder);
         xform.translate(myPointAttributes.myMBPos[0], myPointAttributes.myMBPos[1], myPointAttributes.myMBPos[2]);
         //   xform.xform(xformOrder, myPointAttributes.myMBPos[0], myPointAttributes.myMBPos[1], myPointAttributes.myMBPos[2],
         //               myPointAttributes.N[0], myPointAttributes.N[1], myPointAttributes.N[2],
         //               mySize[0], mySize[1], mySize[2]);

         // Run CVEX function on this instance
         if(myCVEX_Exec)
            VRAY_clusterThis::runCVEX(&temp_gdp, &null_gdp, myCVEXFname, CLUSTER_CVEX_POINT);
         if(myCVEX_Exec_prim)
            VRAY_clusterThis::runCVEX(&temp_gdp, &null_gdp, myCVEXFname_prim, CLUSTER_CVEX_PRIM);

         temp_gdp.transform(xform);
         mb_gdp->merge(temp_gdp);
      }


#ifdef USE_POINT_FNAME
   VRAY_Procedural::freeGeometry(file_geo_gdp);
#endif

   return 0;
}
/* ******************************************************************************
*  Function Name : instanceFile()
*
*  Description :  Instance the geometry from a BGEO file
*
*  Input Arguments : GU_Detail *file_gdp, GU_Detail *inst_gdp, GU_Detail *mb_gdp
*
*  Return Value : int
*
***************************************************************************** */
int VRAY_clusterThis::instanceFile(GU_Detail * file_gdp, GU_Detail * inst_gdp, GU_Detail * mb_gdp)
{
#ifdef DEBUG
   std::cout << "VRAY_clusterThis::instanceFile()" << std::endl;
#endif

   GU_Detail temp_gdp(file_gdp), null_gdp;
   UT_Matrix4 xform(1.0);
   UT_Matrix3 rot_xform(1.0);
//   UT_XformOrder xformOrder(UT_XformOrder::SRT,  UT_XformOrder::XYZ);

   UT_Vector3 myDir = myPointAttributes.N;
//   myDir.normalize();
   UT_Vector3 myUp = UT_Vector3(0,1,0);

// Transform the geo to the new position
   rot_xform.orient(myDir, myUp);
   xform = rot_xform;

   xform.scale(mySize[0] * myPointAttributes.pscale, mySize[1] * myPointAttributes.pscale, mySize[2] * myPointAttributes.pscale);
//    xform.rotate(myPointAttributes.N[0], myPointAttributes.N[1], myPointAttributes.N[2], xformOrder);
   xform.translate(myPointAttributes.myNewPos[0], myPointAttributes.myNewPos[1], myPointAttributes.myNewPos[2]);
//   xform.xform(xformOrder, myPointAttributes.myNewPos[0], myPointAttributes.myNewPos[1], myPointAttributes.myNewPos[2],
//               myPointAttributes.N[0], myPointAttributes.N[1], myPointAttributes.N[2],
//               mySize[0], mySize[1], mySize[2]);

   temp_gdp.transform(xform);

//   GU_Detail theFileGDP(theFiles[myPointAttributes.lod][myPointAttributes.anim_frame]);
   addFileAttributeOffsets(&temp_gdp);
   setFileAttributes(&temp_gdp);

   // Run CVEX function on this instance
   if(myCVEX_Exec)
      VRAY_clusterThis::runCVEX(&temp_gdp, &null_gdp, myCVEXFname, CLUSTER_CVEX_POINT);

   if(myCVEX_Exec_prim)
      VRAY_clusterThis::runCVEX(&temp_gdp, &null_gdp, myCVEXFname_prim, CLUSTER_CVEX_PRIM);

   inst_gdp->merge(temp_gdp);


   if(myDoMotionBlur == CLUSTER_MB_DEFORMATION) {
         GU_Detail temp_gdp(file_gdp);

         xform.identity();
         rot_xform.identity();
         rot_xform.orient(myDir, myUp);
         xform = rot_xform;

         xform.scale(mySize[0] * myPointAttributes.pscale, mySize[1] * myPointAttributes.pscale, mySize[2] * myPointAttributes.pscale);
//        xform.rotate(myPointAttributes.N[0], myPointAttributes.N[1], myPointAttributes.N[2], xformOrder);
         xform.translate(myPointAttributes.myMBPos[0], myPointAttributes.myMBPos[1], myPointAttributes.myMBPos[2]);
         //   xform.xform(xformOrder, myPointAttributes.myMBPos[0], myPointAttributes.myMBPos[1], myPointAttributes.myMBPos[2],
         //               myPointAttributes.N[0], myPointAttributes.N[1], myPointAttributes.N[2],
         //               mySize[0], mySize[1], mySize[2]);

         // Run CVEX function on this instance
         if(myCVEX_Exec)
            VRAY_clusterThis::runCVEX(&temp_gdp, &null_gdp, myCVEXFname, CLUSTER_CVEX_POINT);

         if(myCVEX_Exec_prim)
            VRAY_clusterThis::runCVEX(&temp_gdp, &null_gdp, myCVEXFname_prim, CLUSTER_CVEX_PRIM);

         temp_gdp.transform(xform);
         mb_gdp->merge(temp_gdp);

      }

   return 0;
}