////////////////////////////////////////////////////////////////////////// // get value of node id at time step t // input // id: node Id // t: time step in check // output // nodeData: vector value at this node // return // 1: operation successful // -1: invalid id ////////////////////////////////////////////////////////////////////////// int Solution::GetValue(int id, float t, VECTOR3& nodeData) { float adjusted_t = t - m_MinT; if((id < 0) || (id >= m_nNodeNum) || (adjusted_t < 0.0) || (adjusted_t > (float)(m_nTimeSteps-1))) return -1; if(!isTimeVarying()) nodeData = m_pDataArray[(int)adjusted_t][id]; else { int lowT, highT; float ratio; lowT = (int)floor(adjusted_t); ratio = adjusted_t - (float)floor(adjusted_t); highT = lowT + 1; if(lowT >= (m_nTimeSteps-1)) { highT = lowT; ratio = 0.0; } nodeData.Set(Lerp(m_pDataArray[lowT][id][0], m_pDataArray[highT][id][0], ratio), Lerp(m_pDataArray[lowT][id][1], m_pDataArray[highT][id][1], ratio), Lerp(m_pDataArray[lowT][id][2], m_pDataArray[highT][id][2], ratio)); } return 1; }
int vtCStreamLine::AdvectOneStep(TIME_DIR time_dir, INTEG_ORD integ_ord, TIME_DEP time_dep, PointInfo& seedInfo, VECTOR3& finalP) { int istat; PointInfo thisParticle; VECTOR3 vel; float curTime = m_fCurrentTime; float dt = m_fInitialStepSize; finalP.Set(-1, -1, -1); thisParticle = seedInfo; // the first point istat = m_pField->at_phys(seedInfo.fromCell, seedInfo.phyCoord, seedInfo, m_fCurrentTime, vel); if(istat == OUT_OF_BOUND) return OUT_OF_BOUND; if((fabs(vel[0]) < m_fStationaryCutoff) && (fabs(vel[1]) < m_fStationaryCutoff) && (fabs(vel[2]) < m_fStationaryCutoff)) return CRITICAL_POINT; float error; if(integ_ord == SECOND) istat = runge_kutta2(time_dir, time_dep, thisParticle, &curTime, dt); else if(integ_ord == FOURTH) istat = runge_kutta4(time_dir, time_dep, thisParticle, &curTime, dt); else if(integ_ord == RK45) istat = runge_kutta45(time_dir, time_dep, thisParticle, &curTime, dt, &error); else return OUT_OF_BOUND; if(istat == OUT_OF_BOUND) // out of boundary return OUT_OF_BOUND; m_pField->at_phys(thisParticle.fromCell, thisParticle.phyCoord, thisParticle, m_fCurrentTime, vel); if((fabs(vel[0]) < m_fStationaryCutoff) && (fabs(vel[1]) < m_fStationaryCutoff) && (fabs(vel[2]) < m_fStationaryCutoff)) return CRITICAL_POINT; else finalP = thisParticle.phyCoord; return OKAY; }
// streamline advects as far as possible till the boundary or terminates at // critical points. only two cases will happen: OUT_OF_BOUND & CRITICAL_POINT int vtCStreamLine::executeInfiniteAdvection(TIME_DIR time_dir, TIME_DEP time_dep, vtListSeedTrace& seedTrace, float& totalStepsize, vector<float>* vStepsize) { int istat; vtParticleInfo* thisSeed; PointInfo thisParticle, prevParticle, second_prevParticle, seedInfo; vtListParticleIter sIter; float dt, dt_estimate, cell_volume, mag, curTime; VECTOR3 vel; INTEG_ORD integ_ord; // initialize integ_ord = m_integrationOrder; sIter = m_lSeeds.begin(); thisSeed = *sIter; seedInfo = thisSeed->m_pointInfo; seedTrace.clear(); totalStepsize = 0.0; // the first point seedTrace.push_back(new VECTOR3(seedInfo.phyCoord)); istat = m_pField->at_phys(seedInfo.fromCell, seedInfo.phyCoord, seedInfo, m_fCurrentTime, vel); if((fabs(vel[0]) < m_fStationaryCutoff) && (fabs(vel[1]) < m_fStationaryCutoff) && (fabs(vel[2]) < m_fStationaryCutoff)) return CRITICAL_POINT; thisParticle = seedInfo; curTime = m_fCurrentTime; // get the initial stepsize cell_volume = m_pField->volume_of_cell(seedInfo.inCell); mag = vel.GetMag(); if(fabs(mag) < 1.0e-6f) dt_estimate = 1.0e-5f; else dt_estimate = pow(cell_volume, (float)0.3333333f) / mag; dt = m_fInitialStepSize * dt_estimate; #ifdef DEBUG fprintf(fDebugOut, "****************new particle*****************\n"); fprintf(fDebugOut, "seed: %f, %f, %f with step size %f\n", seedInfo.phyCoord[0],seedInfo.phyCoord[1],seedInfo.phyCoord[2],dt); #endif // start to advect while(true) { second_prevParticle = prevParticle; prevParticle = thisParticle; // take a proper step, also calculates a new step size for the next step if(integ_ord == SECOND || integ_ord == FOURTH) istat = oneStepGeometric(integ_ord, time_dir, time_dep, thisParticle, prevParticle, second_prevParticle, &curTime, &dt, seedTrace.size()); else if(integ_ord == RK45) istat = oneStepEmbedded(integ_ord, time_dir, time_dep, thisParticle, &curTime, &dt); else return OUT_OF_BOUND; if(istat == OUT_OF_BOUND) // out of boundary { // find the boundary intersection point VECTOR3 intersectP, startP, endP; float oldStepsize, stepSize; oldStepsize = stepSize = dt; startP = prevParticle.phyCoord; endP = thisParticle.phyCoord; m_pField->BoundaryIntersection(intersectP, startP, endP, &stepSize, oldStepsize); totalStepsize += stepSize; seedTrace.push_back(new VECTOR3(intersectP)); if(vStepsize != NULL) vStepsize->push_back(stepSize); return OUT_OF_BOUND; } // find the loop list<VECTOR3*>::iterator searchIter; searchIter = seedTrace.end(); searchIter--; for(; searchIter != seedTrace.begin(); searchIter--) { if(thisParticle.phyCoord == **searchIter) // loop return CRITICAL_POINT; } m_pField->at_phys(thisParticle.fromCell, thisParticle.phyCoord, thisParticle, m_fCurrentTime, vel); seedTrace.push_back(new VECTOR3(thisParticle.phyCoord)); if(vStepsize != NULL) vStepsize->push_back(dt); totalStepsize += dt; #ifdef DEBUG fprintf(fDebugOut, "***************advected particle***************\n"); fprintf(fDebugOut, "pos = (%f, %f, %f), vel = (%f, %f, %f) with step size %f, total step size %f\n", thisParticle.phyCoord[0], thisParticle.phyCoord[1], thisParticle.phyCoord[2], vel[0], vel[1], vel[2], dt, totalStepsize); #endif if(totalStepsize > 4000.0) { printf("curl\n"); vel.Set(0.0, 0.0, 0.0); } if((fabs(vel[0]) < m_fStationaryCutoff) && (fabs(vel[1]) < m_fStationaryCutoff) && (fabs(vel[2]) < m_fStationaryCutoff)) return CRITICAL_POINT; if((int)seedTrace.size() > 2) adapt_step(second_prevParticle.phyCoord, prevParticle.phyCoord, thisParticle.phyCoord, &dt); } return OUT_OF_BOUND; }
void compute_streamlines() { printf("generating seeds...\n"); int num=0; int grid_res[3]; float* vectors=get_grid_vec_data(grid_res);//get vec data at each grid point //load seeds from file int* donot_change=new int[grid_res[0]*grid_res[1]*grid_res[2]]; memset(donot_change,0,sizeof(int)*grid_res[0]*grid_res[1]*grid_res[2]); float* new_vectors=new float[grid_res[0]*grid_res[1]*grid_res[2]*3]; memset(new_vectors,0,sizeof(float)*grid_res[0]*grid_res[1]*grid_res[2]*3); int nSeeds; //set first seed as domain center sl_list.clear(); seed_list.clear(); //set boundary condition for(int z=0;z<grid_res[2];z++) for(int y=0;y<grid_res[1];y++) for(int x=0;x<grid_res[0];x++) { if( x==0||x==grid_res[0]-1|| y==0||y==grid_res[1]-1|| z==0||z==grid_res[2]-1) { int idx=x+y*grid_res[0]+z*grid_res[0]*grid_res[1]; new_vectors[idx*3+0]=vectors[idx*3+0]; new_vectors[idx*3+1]=vectors[idx*3+1]; new_vectors[idx*3+2]=vectors[idx*3+2]; donot_change[idx]=1; } } int* old_bin, *new_bin; old_bin=new int [grid_res[0]*grid_res[1]*grid_res[2]]; new_bin=new int [grid_res[0]*grid_res[1]*grid_res[2]]; for(int i=0;i<grid_res[0]*grid_res[1]*grid_res[2];i++) { VECTOR3 orif; orif.Set(vectors[i*3+0],vectors[i*3+1],vectors[i*3+2]); old_bin[i]=get_bin_number_3D(orif,theta, phi,binnum); new_bin[i]=0.0; } if(!entropies) { printf("calculating every point entropies\n"); entropies=new float[grid_res[0]*grid_res[1]*grid_res[2]]; calc_entropy( old_bin,grid_res, binnum, entropies); dumpEntropyField("entropies.bin",entropies, grid_res); printf("entropy calculation done\n"); } int selected_line_num=0; float entropy=8888; std::vector<VECTOR3> seedlist,selected_list; srand((unsigned)time(NULL)); // initialize random number generator std::vector<float> entropies; int x_min=0,x_max=0,y_min=0,y_max=0; int* occupied=new int[grid_res[0]*grid_res[1]*grid_res[2]]; memset(occupied,0,sizeof(int)*grid_res[0]*grid_res[1]*grid_res[2]); float* kx=new float[grid_res[0]*grid_res[1]*grid_res[2]]; float* ky=new float[grid_res[0]*grid_res[1]*grid_res[2]]; float* kz=new float[grid_res[0]*grid_res[1]*grid_res[2]]; float* b=new float[grid_res[0]*grid_res[1]*grid_res[2]]; float* c1=new float[grid_res[0]*grid_res[1]*grid_res[2]]; float* c2=new float[grid_res[0]*grid_res[1]*grid_res[2]]; float* c3=new float[grid_res[0]*grid_res[1]*grid_res[2]]; // ADD-BY-LEETEN 2009/11/10-BEGIN _FlowDiffusionInit(grid_res[0], grid_res[1], grid_res[2]); int get_bin_by_angle(float mytheta, float myphi, int binnum, float* theta, float* phi); static const int iNrOfThetas = 720; static const int iNrOfPhis = 360; static const double dNrOfThetas = double(iNrOfThetas); static const double dNrOfPhis = double(iNrOfPhis); static int ppiAngleMap[iNrOfThetas][iNrOfPhis]; for(int t = 0; t < iNrOfThetas; t++) for(int p = 0; p < iNrOfPhis; p++) { float fTheta = M_PI * 2.0f * float(t) / float(iNrOfThetas); float fPhi = M_PI * float(p) / float(iNrOfPhis); int iBin = get_bin_by_angle(fTheta, fPhi, binnum, theta, phi); if( iBin >= 0 ) ppiAngleMap[t][p] = iBin; } _FlowDiffusionSetAngleMap(&ppiAngleMap[0][0], iNrOfPhis, iNrOfThetas); // ADD-BY-LEETEN 2009/11/10-END //initial entropy float error=0.05; float target_entropy=-error*log2(error)-(1-error)*log2(1-error)+error*log2(359); printf("entropy_target=%f\n",target_entropy); std::vector<int> line_color; int *histo_puv=new int[binnum*binnum]; int *histo_pv=new int[binnum]; float* entropy_tmp=new float[binnum]; float* pv=new float[binnum]; int line_num_thres=NR_OF_STREAMLINES;//27; //want to select top line_num_thres lines memset(kx,0,sizeof(float)*grid_res[0]*grid_res[1]*grid_res[2]); memset(ky,0,sizeof(float)*grid_res[0]*grid_res[1]*grid_res[2]); memset(kz,0,sizeof(float)*grid_res[0]*grid_res[1]*grid_res[2]); memset(b,0,sizeof(float)*grid_res[0]*grid_res[1]*grid_res[2]); memset(c1,0,sizeof(float)*grid_res[0]*grid_res[1]*grid_res[2]); memset(c2,0,sizeof(float)*grid_res[0]*grid_res[1]*grid_res[2]); memset(c3,0,sizeof(float)*grid_res[0]*grid_res[1]*grid_res[2]); int round=0; std::vector<float> line_importance,entropy_list; // while(selected_line_num<line_num_thres )//&& entropy>.5) while(entropy>target_entropy) { VECTOR3 next_seed; std::vector<VECTOR3> seeds; printf("%d seeds selected,round=%d entropy=%f\n",seed_list.size(), round, entropy); selectStreamlines_by_distribution(vectors,new_vectors, grid_res, occupied,seeds, theta, phi,old_bin,new_bin,0,0,round++,line_importance,entropy); //select new seed for(int i=0;i<seeds.size();i++) line_color.push_back(selected_line_num+i); selected_line_num+=seeds.size(); //printf("calculate the bin number\r"); for(int i=0;i<grid_res[0]*grid_res[1]*grid_res[2];i++) { VECTOR3 newf,orif; orif.Set(vectors[i*3+0],vectors[i*3+1],vectors[i*3+2]); newf.Set(new_vectors[i*3+0],new_vectors[i*3+1],new_vectors[i*3+2]); //if within error range, let it be teh same bin as the ori, otherwise select the bin num newf.Normalize(); float dotv=dot(newf,orif); new_bin[i]=get_bin_number_3D(newf,theta, phi,binnum); } entropy=calcRelativeEntropy6_new( vectors, new_vectors, grid_res, VECTOR3(2,2,2),//do not count boundaries VECTOR3(grid_res[0]-2,grid_res[1]-2,grid_res[2]-2),theta,phi,old_bin,new_bin,0,binnum,histo_puv,histo_pv, pv,entropy_tmp); // entropy_list.push_back(entropy); for(int i=0;i<seeds.size();i++) { selected_list.push_back(seeds[i]); //seedlist.push_back(seeds[i]); seed_list.push_back(seeds[i]); } //dumpEntropy(entropies,"entropy.bin"); dumpSeeds(seed_list,"myseeds.seed");//crtical points excluded double dwStart= GetTickCount(); //printf("streamline size=%d\n",sl_list.size()); reconstruct_field_GVF_3D(new_vectors,vectors,grid_res,sl_list,donot_change, kx,ky,kz,b,c1,c2,c3);//,importance); double elapsedTime= GetTickCount() - dwStart; printf("\n\n reconstruction time is %.3f milli-seconds.\n",elapsedTime); //clear the memory of sl_list;save memory for larger dataset /*std::list<vtListSeedTrace*>::iterator pIter; pIter = sl_list.begin(); for (; pIter!=sl_list.end(); pIter++) { vtListSeedTrace *trace = *pIter; std::list<VECTOR3*>::iterator pnIter,pnIter2; pnIter = trace->begin(); for (; pnIter!= trace->end(); pnIter++) delete *pnIter; delete trace; } sl_list.clear();*/ //dumpReconstruedField("r.vec", new_vectors, grid_res); unsigned char* dat=new unsigned char[grid_res[0]*grid_res[1]*grid_res[2]]; for(int i=0;i<grid_res[0]*grid_res[1]*grid_res[2];i++) dat[i]=occupied[i]*255; /*FILE* test=fopen("impor.bin","wb"); fwrite(grid_res,sizeof(int),3,test); fwrite(occupied,sizeof(unsigned char),grid_res[0]*grid_res[1]*grid_res[2],test); fclose(test); */ delete [] dat; for(int i=0;i<sl_list.size();i++) line_color.push_back(i); char filename[255]; memset(filename,0,255); sprintf(filename,"streamlines%d.dat",round); save_streamlines_to_file_hand_tuning(filename,line_color,nSeeds); dumpEntropies(line_importance); // getchar(); // printf("halted, save files now\n"); } //dumpReconstruedField("r.vec", new_vectors, grid_res); dumpSeeds(seed_list,"myseeds.seed");//crtical points excluded delete [] histo_puv; delete [] histo_pv; delete [] pv; delete [] entropy_tmp; delete [] occupied; delete [] old_bin; delete [] new_bin; delete [] kx; delete [] ky; delete [] kz; delete [] b; delete [] c1; delete [] c2; delete [] c3; delete [] donot_change; delete [] vectors; delete [] new_vectors; #if USE_CUDA _FlowDiffusionFree(); #endif }
//speed up by reusing histograms void selectStreamlines_by_distribution(float* vectors,float* new_vectors, int* grid_res, int* occupied, std::vector<VECTOR3>& seeds, float* theta, float* phi, int* bin_vector, int* bin_newvectors, int* g_histo,int* g_histo_puv,int round, std::vector<float>& line_importance, float in_entropy) { int sample_number_allowed=50; int kernel_size[3]; kernel_size[0]=kernel_size[1]= 8;//this is radium, actuall kernel is 2 x kernel_size+1 kernel_size[2]=8; float* img_entropies=new float[grid_res[0]*grid_res[1]*grid_res[2]]; float sum=0; float maximum=0; int* bin_my_vector,*bin_new_vector; bin_my_vector=new int[grid_res[0]*grid_res[1]*grid_res[2]]; bin_new_vector=new int[grid_res[0]*grid_res[1]*grid_res[2]]; memcpy(bin_my_vector,bin_vector,sizeof(int)*grid_res[0]*grid_res[1]*grid_res[2]); memcpy(bin_new_vector,bin_newvectors,sizeof(int)*grid_res[0]*grid_res[1]*grid_res[2]); // memcpy(img_entropies,entropies,sizeof(float)*grid_res[0]*grid_res[1]*grid_res[2]); // for(int i=0;i<grid_res[0]*grid_res[1]*grid_res[2];i++) // { // if(maximum<img_entropies[i]) // maximum=img_entropies[i]; // sum=sum+img_entropies[i]; // } int radius=1;//for update_occupied, not using printf("calculate entropy...\n"); int *histo_puv=new int[binnum*binnum]; int *histo_pv=new int[binnum]; //float* puv=new float[binnum*binnum]; float* pv=new float[binnum]; float* entropy_tmp=new float[binnum]; int z=0; double dwStart = GetTickCount(); for(int y=0;y<grid_res[1];y++) { //double dwStart = GetTickCount(); for(int x=0;x<grid_res[0];x++) { memset(histo_puv,0,sizeof(int)*binnum*binnum); memset(histo_pv,0,sizeof(int)*binnum); for(int z=0;z<grid_res[2];z++) { VECTOR3 startpt,endpt; startpt.Set(max(0,x-kernel_size[0]),max(0,y-kernel_size[1]),max(0,z-kernel_size[2])); endpt.Set(min(x+kernel_size[0],grid_res[0]-1),min(y+kernel_size[1],grid_res[1]-1), min(z+kernel_size[2],grid_res[2]-1)); if(z==0)//calculate the first histogram { for(int tz=(int)startpt.z(); tz<=(int)endpt.z();tz++) { for(int ty=(int)startpt.y(); ty<=(int)endpt.y();ty++) { for(int tx=(int)startpt.x(); tx<=(int)endpt.x();tx++) { int idx=tx+ty*grid_res[0]+tz*grid_res[0]*grid_res[1]; int bin_no_ori=bin_vector[idx]; int bin_no_new=bin_newvectors[idx]; if(bin_no_ori<0 || bin_no_ori>=binnum|| bin_no_new<0 || bin_no_new>=binnum) { printf("sth wrong, bin id=%d %d\n", bin_no_ori,bin_no_new); } idx=bin_no_ori+binnum*bin_no_new; histo_puv[idx]++;//p(x,y) histo_pv[bin_no_new]++; } } } } else//update the histogram { //most the oldest for(int ty=(int)startpt.y(); ty<=(int)endpt.y();ty++) { for(int tx=(int)startpt.x(); tx<=(int)endpt.x();tx++) { if(z-kernel_size[2]>=0) { int tz=z-kernel_size[2]; int idx=tx+ty*grid_res[0]+tz*grid_res[0]*grid_res[1]; int bin_no_ori=bin_vector[idx]; int bin_no_new=bin_newvectors[idx]; if(bin_no_ori<0 || bin_no_ori>=binnum|| bin_no_new<0 || bin_no_new>=binnum) { printf("sth wrong, bin id=%d %d\n", bin_no_ori,bin_no_new); } idx=bin_no_ori+binnum*bin_no_new; if(histo_puv[idx]<=0 ||histo_pv[bin_no_new]<=0 ) printf("something wrong x=%d y=%d z=%d\n",tx,ty,tz); histo_puv[idx]--;//p(x,y) histo_pv[bin_no_new]--; } if(z+kernel_size[2]<grid_res[2]) { int tz=z+kernel_size[2]; int idx=tx+ty*grid_res[0]+tz*grid_res[0]*grid_res[1]; int bin_no_ori=bin_vector[idx]; int bin_no_new=bin_newvectors[idx]; if(bin_no_ori<0 || bin_no_ori>=binnum|| bin_no_new<0 || bin_no_new>=binnum) { printf("sth wrong, bin id=%d %d\n", bin_no_ori,bin_no_new); } idx=bin_no_ori+binnum*bin_no_new; histo_puv[idx]++;//p(x,y) //p(y) histo_pv[bin_no_new]++; } } } } float entropy=calcRelativeEntropy6_by_known_histograms( vectors,new_vectors, grid_res, startpt, endpt, theta, phi, bin_vector, bin_newvectors,occupied,binnum, histo_puv, histo_pv, pv, entropy_tmp, g_histo,g_histo_puv); //if(round<=0 || round>=3) entropy=entropy*entropy;//*entropy*entropy*entropy;//enhance int idx=x+y*grid_res[0]+z*grid_res[0]*grid_res[1]; img_entropies[idx]=entropy; if(entropy>maximum) maximum=entropy; sum=sum+entropy; } } // double elapsedTime= GetTickCount() - dwStart; // printf("\n\n entorpy for each point time is %.3f milli-seconds.\n",elapsedTime); printf("y=%d/%d\r",y,grid_res[1]); } double elapsedTime= GetTickCount() - dwStart; printf("\n\n time for entorpy calculation is %.3f milli-seconds.\n",elapsedTime); // printf("halted\n"); // getchar(); //save result to file unsigned char* data; float* importance=new float[grid_res[0]*grid_res[1]*grid_res[2]]; data = new unsigned char[grid_res[0]*grid_res[1]*grid_res[2]]; for(int i=0;i<grid_res[0]*grid_res[1]*grid_res[2];i++) { if(maximum>0) { data[i]=(unsigned char)((img_entropies[i]/maximum)*255); importance[i]=img_entropies[i]/maximum; } } char szname[255]; memset(szname,0,255); sprintf(szname,"importance%d.bin",round); dumpImportanceField(szname,importance, grid_res); //normalized it to (0~1) for(int i=0;i<grid_res[0]*grid_res[1]*grid_res[2];i++) { //if(round<=1) img_entropies[i]=img_entropies[i]/sum; //else // img_entropies[i]=1-img_entropies[i]/sum; } //start the importance sampling, acceptance-rejection method // dwStart= GetTickCount(); // int* selX, *selY,*selZ; // selX=new int[sample_number_allowed]; // selY=new int[sample_number_allowed]; // selZ=new int[sample_number_allowed]; // float M=(maximum/sum)*1.1; // int i=0; // srand((unsigned)time(NULL)); // while(i<sample_number_allowed) // { // float randx = ((float)rand()/(float)RAND_MAX); // float randy = ((float)rand()/(float)RAND_MAX); // float randz = ((float)rand()/(float)RAND_MAX); // float randu = ((float)rand()/(float)RAND_MAX); // int x=(int)(floor(randx*(grid_res[0]-1))); // int y=(int)(floor(randy*(grid_res[1]-1))); // int z=(int)(floor(randz*(grid_res[2]-1))); // float u=randu; // if(u<(img_entropies[x+y*grid_res[0]+z*grid_res[0]*grid_res[1]] /M)) // { // selX[i]=x; // selY[i]=y; // selZ[i]=z; // i++; // } // } // elapsedTime= GetTickCount() - dwStart; // printf("\n\n sampling time is %.3f milli-seconds.\n",elapsedTime); dwStart= GetTickCount(); srand((unsigned)time(NULL)); int* selX, *selY,*selZ; selX=new int[sample_number_allowed]; selY=new int[sample_number_allowed]; selZ=new int[sample_number_allowed]; float* qz=new float[grid_res[2]]; //get z marginal for(int k=0;k<grid_res[2];k++) { float sum=0; for(int j=0;j<grid_res[1];j++) { for(int i=0;i<grid_res[0];i++) sum=sum+img_entropies[i+j*grid_res[0]+k*grid_res[0]*grid_res[1]]; } qz[k]=sum; } //get y,z joint probs float *qy=new float[grid_res[1]*grid_res[2]]; for(int z=0;z<grid_res[2];z++) { if(qz[z]<=0) { for(int y=0;y<grid_res[1];y++) { qy[z*grid_res[1]+y] = 0.0; } continue; } for(int y=0;y<grid_res[1];y++) { float sumy = 0; for(int x=0;x<grid_res[0];x++) { int idx=x+y*grid_res[0]+z*grid_res[0]*grid_res[1]; sumy = sumy + img_entropies[idx]; } qy[z*grid_res[1]+y]=sumy/qz[z]; } } //get x,y,z joint probs float *qx=new float[grid_res[1]*grid_res[2]*grid_res[0]]; for(int z=0;z<grid_res[2];z++) { for(int y=0;y<grid_res[1];y++) { int idy = z*grid_res[1]+y; if(qy[idy]<=0.0) { for(int x=0;x<grid_res[0];x++) { int idx=x+y*grid_res[0]+z*grid_res[0]*grid_res[1]; qx[idx] = 0.0; } continue; } for(int x=0;x<grid_res[0];x++) { int idx=x+y*grid_res[0]+z*grid_res[0]*grid_res[1]; qx[idx] = img_entropies[idx]/(qy[idy] * qz[z]); } } } int i=0; while(i<sample_number_allowed) { selZ[i] = sample_from(qz,grid_res[2]); i++; } i=0; while(i<sample_number_allowed) { selY[i] = sample_from(qy+selZ[i]*grid_res[1],grid_res[1]); i++; } i=0; while(i<sample_number_allowed) { selX[i] = sample_from(qx+selZ[i]*grid_res[0]*grid_res[1]+selY[i]*grid_res[0],grid_res[0]); i++; } elapsedTime= GetTickCount() - dwStart; printf("\n\n sampling time is %.3f milli-seconds.\n",elapsedTime); float cur_entropy=in_entropy; //scan and get the distributions out list<vtListSeedTrace*> lines,new_lines; for(i=0;i<sample_number_allowed;i++)//start pruning { lines.clear(); new_lines.clear(); VECTOR3 newseed; newseed.Set(selX[i],selY[i],selZ[i]); //if(occupied[(int)newseed.x()+((int)newseed.y())*grid_res[0]+((int)newseed.z())*grid_res[0]*grid_res[1]]==1) // continue;//do not select this one osuflow->SetEntropySeedPoints( &newseed,1); osuflow->SetIntegrationParams(minstepsize, maxstepsize); //small and large step size //adjust streamline length by its entropy value int idx=selX[i]+selY[i]*grid_res[0]+selZ[i]*grid_res[0]*grid_res[1]; float length=entropies[idx]*maxi_stepnum; osuflow->GenStreamLines(lines , BACKWARD_AND_FORWARD,length, 0); //maxi steps // combinehalflines(lines, new_lines);//for display only, the streamline stops when gets too near to an existing combinehalflines_check_stop_entropy(lines, new_lines,grid_res,entropies);//for display only, the streamline stops when gets too near to an existing /* if(new_lines.size()) { sl_list.push_back(*(new_lines.begin())); seeds.push_back(VECTOR3(selX[i],selY[i],selZ[i])); UpdateOccupied(new_lines,occupied,grid_res,radius); //float max_entropy=getImportance(new_lines, grid_res, importance); //line_importance.push_back(max_entropy); } */ list<vtListSeedTrace*> tmp_whole_set_lines; if(new_lines.size()) { float epsilon=0.01; tmp_whole_set_lines=sl_list; tmp_whole_set_lines.push_back(*new_lines.begin()); bool discard=discardredundantstreamlines(cur_entropy,epsilon,tmp_whole_set_lines, vectors,new_vectors,grid_res, bin_my_vector,bin_new_vector,binnum, theta, phi, histo_puv, histo_pv, pv, entropy_tmp); if(discard==false) { sl_list.push_back(*(new_lines.begin())); seeds.push_back(VECTOR3(selX[i],selY[i],selZ[i])); UpdateOccupied(new_lines,occupied,grid_res,0); line_importance.push_back(cur_entropy); } tmp_whole_set_lines.clear(); //density control should depend on the information content too. } } //std::vector<int> line_color; //for(int i=0;i<sl_list.size();i++) // line_color.push_back(i); //save_streamlines_to_file_alpha_by_importance(line_color,line_importance,sl_list.size(), importance, grid_res); delete [] pv; delete [] histo_puv; delete [] histo_pv; delete [] entropy_tmp; delete [] selX; delete [] selY; delete [] selZ; //save2PPM_3("cand_seeds_image.ppm", data, grid_res[0],grid_res[1]); delete [] data; delete [] img_entropies; delete [] importance; delete [] bin_my_vector; delete [] bin_new_vector; return; }