Пример #1
0
//////////////////////////////////////////////////////////////////////////
// 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;
}
Пример #2
0
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;
}
Пример #3
0
// 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;
}
Пример #4
0
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
}
Пример #5
0
//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;
}