PolygonalMesh* Polygonizer::computeSurfaceNerLinear(float epsilon, float tau)
{
	bool ***isIn = new bool**[dimZ+1];
	float ***value = new float**[dimZ+1];
	for(int i=0; i<dimZ+1; i++){
		isIn[i] = new bool*[dimY+1];
		value[i] = new float*[dimY+1];

		for(int j=0; j<dimY+1; j++){
			isIn[i][j] = new bool[dimX+1];
			value[i][j] = new float[dimX+1];

			for(int k=0; k<dimX+1; k++){
				isIn[i][j][k] = false;
				value[i][j][k] = 0;
			}
		}
	}

	float o[3];
	o[0] = originX;
	o[1] = originY;
	o[2] = originZ;
	float space[3];
	space[0] = spaceX;
	space[1] = spaceY;
	space[2] = spaceZ;
	int dim[3];
	dim[0] = dimX;
	dim[1] = dimY;
	dim[2] = dimZ;

	func->asignValueToVoxels(value, isIn, o, space, dim);

	int ***index = new int**[dimZ+1];
	for(int i=0; i<dimZ+1; i++){
		index[i] = new int*[dimY+1];
		for(int j=0; j<dimY+1; j++){
			index[i][j] = new int[dimX+1];
			for(int k=0; k<dimX+1; k++)
				index[i][j][k] = -1;
		}
	}

	int current = 0;
	int face_N = 0;
	for(int i=0; i<dimZ; i++)
		for(int j=0; j<dimY; j++)
			for(int k=0; k<dimX-1; k++){
				if(!isIn[i][j][k] || !isIn[i][j][k+1])
					continue;
				if((value[i][j][k] > 0 && value[i][j][k+1] <= 0) || 
				    (value[i][j][k] <= 0 && value[i][j][k+1] > 0)){
					face_N++;
					if(index[i][j][k+1] < 0){
						index[i][j][k+1] = current;
						current++;
					}
					if(index[i][j+1][k+1] < 0){
						index[i][j+1][k+1] = current;
						current++;
					}
					if(index[i+1][j][k+1] < 0){
						index[i+1][j][k+1] = current;
						current++;
					}
					if(index[i+1][j+1][k+1] < 0){
						index[i+1][j+1][k+1] = current;
						current++;
					}
				}
			}

	for(int i=0; i<dimX; i++)
		for(int j=0; j<dimZ; j++)
			for(int k=0; k<dimY-1; k++){
				if(!isIn[j][k][i] || !isIn[j][k+1][i])
					continue;
				if((value[j][k][i] > 0 && value[j][k+1][i] <= 0) || 
				    (value[j][k][i] <= 0&& value[j][k+1][i] > 0)){
					face_N++;
					if(index[j][k+1][i] < 0){
						index[j][k+1][i] = current;
						current++;
					}
					if(index[j+1][k+1][i] < 0){
						index[j+1][k+1][i] = current;
						current++;
					}
					if(index[j][k+1][i+1] < 0){
						index[j][k+1][i+1] = current;
						current++;
					}
					if(index[j+1][k+1][i+1] < 0){
						index[j+1][k+1][i+1] = current;
						current++;
					}
				}
			}

	for(int i=0; i<dimY; i++)
		for(int j=0; j<dimX; j++)
			for(int k=0; k<dimZ-1; k++){
				if(!isIn[k][i][j] || !isIn[k+1][i][j])
					continue;
				if((value[k][i][j] > 0  && value[k+1][i][j] <= 0) || 
				    (value[k][i][j] <= 0 && value[k+1][i][j] > 0)){
					face_N++;
					if(index[k+1][i][j] < 0){
						index[k+1][i][j] = current;
						current++;
					}
					if(index[k+1][i+1][j] < 0){
						index[k+1][i+1][j] = current;
						current++;
					}
					if(index[k+1][i][j+1] < 0){
						index[k+1][i][j+1] = current;
						current++;
					}
					if(index[k+1][i+1][j+1] < 0){
						index[k+1][i+1][j+1] = current;
						current++;
					}
				}
			}

	PolygonalMesh* mesh = new PolygonalMesh;
	int vertex_N = current;
	mesh->setVertexCount(vertex_N);
	float (*vertex)[3] = mesh->vertex;
	int* degree = mesh->degree_f = new int[vertex_N];
	current = 0;
	for(int i=0; i<vertex_N; i++){
		vertex[i][0] = vertex[i][1] = vertex[i][2] = 0;
		degree[i] = 0;
	}

	mesh->setFaceCount(face_N);
	double (*Q)[10] = new double[vertex_N][10];
	for(int i=0; i<vertex_N; i++)
		MAT_INIT(Q[i]);
	for(int i=0; i<face_N; i++)
		mesh->setPolygonCount(i, 4);
	face_N = 0;
	int **face = mesh->face;
	bool flag = false;
	for(int i=0; i<dimZ; i++)
		for(int j=0; j<dimY; j++)
			for(int k=0; k<dimX-1; k++){
				if(!isIn[i][j][k] || !isIn[i][j][k+1])
					continue;
				if(value[i][j][k] > 0 && value[i][j][k+1] <= 0){
					face[face_N][0] = index[i][j][k+1];
					face[face_N][1] = index[i][j+1][k+1];
					face[face_N][2] = index[i+1][j+1][k+1];
					face[face_N][3] = index[i+1][j][k+1];
					face_N++;
					flag = true;
				}
				else if(value[i][j][k] <= 0 && value[i][j][k+1] > 0){
					face[face_N][0] = index[i][j][k+1];
					face[face_N][1] = index[i+1][j][k+1];
					face[face_N][2] = index[i+1][j+1][k+1];
					face[face_N][3] = index[i][j+1][k+1];
					face_N++;
					flag = true;
				}
				if(!flag)
					continue;
				flag = false;
				float p[3], s[3], e[3];
				s[0] = originX + k*spaceX;
				e[0] = originX + (k+1)*spaceX;
				s[1] = e[1] = originY + j*spaceY;
				s[2] = e[2] = originZ + i*spaceZ;
				float f1 = value[i][j][k];
				float f2 = value[i][j][k+1];
				searchZero(p, s, e, f1, f2, epsilon);
				
				float g[3];
				//func->gradient(g, p[0], p[1], p[2]);
				double len = PolygonalMesh::LENGTH(g);
			
				double nor[3];
				nor[0] = g[0]/len;
				nor[1] = g[1]/len;
				nor[2] = g[2]/len;

				double d = -PolygonalMesh::DOT(nor, p);
				double Q_tmp[10];
				MATRIX(Q_tmp, nor, d);

				int i0 = index[i][j][k+1];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[i][j+1][k+1];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[i+1][j+1][k+1];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[i+1][j][k+1];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;
			}

	for(int i=0; i<dimX; i++)
		for(int j=0; j<dimZ; j++)
			for(int k=0; k<dimY-1; k++){
				if(!isIn[j][k][i] || !isIn[j][k+1][i])
					continue;
				if(value[j][k][i] > 0 && value[j][k+1][i] <= 0){
					face[face_N][0] = index[j][k+1][i];
					face[face_N][1] = index[j+1][k+1][i];
					face[face_N][2] = index[j+1][k+1][i+1];
					face[face_N][3] = index[j][k+1][i+1];
					face_N++;
					flag = true;
				}
				else if(value[j][k][i] <= 0 && value[j][k+1][i] > 0){
					face[face_N][0] = index[j][k+1][i];
					face[face_N][1] = index[j][k+1][i+1];
					face[face_N][2] = index[j+1][k+1][i+1];
					face[face_N][3] = index[j+1][k+1][i];
					face_N++;
					flag = true;
				}
				if(!flag)
					continue;
				flag = false;
				float p[3], s[3], e[3];
				s[1] = originY + k*spaceY;
				e[1] = originY + (k+1)*spaceY;
				s[2] = e[2] = originZ + j*spaceZ;
				s[0] = e[0] = originX + i*spaceX;
				float f1 = value[j][k][i];
				float f2 = value[j][k+1][i];
				searchZero(p, s, e, f1, f2, epsilon);
				
				float g[3];
				//func->gradient(g, p[0], p[1], p[2]);
				double len = PolygonalMesh::LENGTH(g);
			
				double nor[3];
				nor[0] = g[0]/len;
				nor[1] = g[1]/len;
				nor[2] = g[2]/len;

				double d = -PolygonalMesh::DOT(nor, p);
				double Q_tmp[10];
				MATRIX(Q_tmp, nor, d);
				
				int i0 = index[j][k+1][i];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[j+1][k+1][i];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[j+1][k+1][i+1];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[j][k+1][i+1];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;
			}

	for(int i=0; i<dimY; i++)
		for(int j=0; j<dimX; j++)
			for(int k=0; k<dimZ-1; k++){
				if(!isIn[k][i][j] || !isIn[k+1][i][j])
					continue;
				if(value[k][i][j] > 0 && value[k+1][i][j] <= 0){
					face[face_N][0] = index[k+1][i][j];
					face[face_N][1] = index[k+1][i][j+1];
					face[face_N][2] = index[k+1][i+1][j+1];
					face[face_N][3] = index[k+1][i+1][j];
					face_N++;
					flag = true;
				}
				else if(value[k][i][j] <= 0 && value[k+1][i][j] > 0){
					face[face_N][0] = index[k+1][i][j];
					face[face_N][1] = index[k+1][i+1][j];
					face[face_N][2] = index[k+1][i+1][j+1];
					face[face_N][3] = index[k+1][i][j+1];
					face_N++;
					flag = true;
				}
				if(!flag)
					continue;
				flag = false;
				float p[3], s[3], e[3];
				s[2] = originZ + k*spaceZ;
				e[2] = originZ + (k+1)*spaceZ;
				s[0] = e[0] = originX + j*spaceX;
				s[1] = e[1] = originY + i*spaceY;
				float f1 = value[k][i][j];
				float f2 = value[k+1][i][j];
				searchZero(p, s, e, f1, f2, epsilon);
				
				float g[3];
				//func->gradient(g, p[0], p[1], p[2]);
				double len = PolygonalMesh::LENGTH(g);
				
				double nor[3];
				nor[0] = g[0]/len;
				nor[1] = g[1]/len;
				nor[2] = g[2]/len;

				double d = -PolygonalMesh::DOT(nor, p);
				double Q_tmp[10];
				MATRIX(Q_tmp, nor, d);

				int i0 = index[k+1][i][j];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[k+1][i][j+1];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[k+1][i+1][j+1];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[k+1][i+1][j];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;
			}
	
	//FOR SVD
			
  vnl_matrix< float > A( 3, 3, 0. ); 
  vnl_vector<float> b( 3, 0. );

	for(int i=0; i<vertex_N; i++){
		if(degree[i] == 0)
			continue;
		vertex[i][0] /= degree[i];
		vertex[i][1] /= degree[i];
		vertex[i][2] /= degree[i];
continue;
		A[0][0] = (float)Q[i][0];
		A[1][0] = A[0][1] = (float)Q[i][1];
		A[2][0] = A[0][2] = (float)Q[i][2];
		A[1][1] = (float)Q[i][3];
		A[1][2] = A[2][1] = (float)Q[i][4];
		A[2][2] = (float)Q[i][5];

		float Av[3];
		MAT_BY_VEC(Av, Q[i], vertex[i]);
		b[1] = -(float)Q[i][6] - Av[0];
		b[2] = -(float)Q[i][7] - Av[1];
		b[3] = -(float)Q[i][8] - Av[2];

    vnl_svd<float> svd( A );
    svd.zero_out_absolute( tau );

    vnl_vector< float > x = svd.solve( b );

		if(fabs(x[1]) > spaceX || fabs(x[2]) > spaceY || fabs(x[3]) > spaceZ)
			continue;

		mesh->vertex[i][0] += x[1];
		mesh->vertex[i][1] += x[2];
		mesh->vertex[i][2] += x[3];
	}

	for(int i=0; i<dimZ+1; i++){
		for(int j=0; j<dimY+1; j++){
			delete[] isIn[i][j];
			delete[] index[i][j];
			delete[] value[i][j];
		}
		delete[] isIn[i];
		delete[] index[i];
		delete[] value[i];
	}
	delete[] isIn;
	delete[] index;
	delete[] Q;
	delete[] value;

	return mesh;
}
PolygonalMesh* Polygonizer::computeSurfaceNet()
{
	float p[3];
	bool ***isIn = new bool**[dimZ+1];
	bool ***isValid = new bool**[dimZ+1];
	for(int i=0; i<dimZ+1; i++){
		isIn[i] = new bool*[dimY+1];
		isValid[i] = new bool*[dimY+1];
		p[2] = originZ + i*spaceZ;
		for(int j=0; j<dimY+1; j++){
			isIn[i][j] = new bool[dimX+1];
			isValid[i][j] = new bool[dimX+1];
			p[1] = originY + j*spaceY;
			for(int k=0; k<dimX+1; k++){
				p[0] = originX + k*spaceX;
				isIn[i][j][k] 
					= (func->value(p[0], p[1], p[2], isValid[i][j][k]) > 0);
			}
		}
	}

	int ***index = new int**[dimZ+1];
	for(int i=0; i<dimZ+1; i++){
		index[i] = new int*[dimY+1];
		for(int j=0; j<dimY+1; j++){
			index[i][j] = new int[dimX+1];
			for(int k=0; k<dimX+1; k++)
				index[i][j][k] = -1;
		}
	}

	int current = 0;
	int face_N = 0;
	for(int i=0; i<dimZ; i++)
		for(int j=0; j<dimY; j++)
			for(int k=0; k<dimX-1; k++){
				if(!isValid[i][j][k] || !isValid[i][j][k+1])
					continue;
				if((!isIn[i][j][k] && isIn[i][j][k+1]) || 
				    (isIn[i][j][k] && !isIn[i][j][k+1])){
					face_N++;
					if(index[i][j][k+1] < 0){
						index[i][j][k+1] = current;
						current++;
					}
					if(index[i][j+1][k+1] < 0){
						index[i][j+1][k+1] = current;
						current++;
					}
					if(index[i+1][j][k+1] < 0){
						index[i+1][j][k+1] = current;
						current++;
					}
					if(index[i+1][j+1][k+1] < 0){
						index[i+1][j+1][k+1] = current;
						current++;
					}
				}
			}

	for(int i=0; i<dimX; i++)
		for(int j=0; j<dimZ; j++)
			for(int k=0; k<dimY-1; k++){
				if(!isValid[j][k][i] || !isValid[j][k+1][i])
					continue;
				if((!isIn[j][k][i] && isIn[j][k+1][i]) || 
				    (isIn[j][k][i] && !isIn[j][k+1][i])){
					face_N++;
					if(index[j][k+1][i] < 0){
						index[j][k+1][i] = current;
						current++;
					}
					if(index[j+1][k+1][i] < 0){
						index[j+1][k+1][i] = current;
						current++;
					}
					if(index[j][k+1][i+1] < 0){
						index[j][k+1][i+1] = current;
						current++;
					}
					if(index[j+1][k+1][i+1] < 0){
						index[j+1][k+1][i+1] = current;
						current++;
					}
				}
			}

	for(int i=0; i<dimY; i++)
		for(int j=0; j<dimX; j++)
			for(int k=0; k<dimZ-1; k++){
				if(!isValid[k][i][j] || !isValid[k+1][i][j])
					continue;
				if((!isIn[k][i][j] && isIn[k+1][i][j]) || 
				    (isIn[k][i][j] && !isIn[k+1][i][j])){
					face_N++;
					if(index[k+1][i][j] < 0){
						index[k+1][i][j] = current;
						current++;
					}
					if(index[k+1][i+1][j] < 0){
						index[k+1][i+1][j] = current;
						current++;
					}
					if(index[k+1][i][j+1] < 0){
						index[k+1][i][j+1] = current;
						current++;
					}
					if(index[k+1][i+1][j+1] < 0){
						index[k+1][i+1][j+1] = current;
						current++;
					}
				}
			}
	
	PolygonalMesh* mesh = new PolygonalMesh;
	int vertex_N = current;
	mesh->setVertexCount(vertex_N);
	float (*vertex)[3] = mesh->vertex;
	current = 0;
	for(int i=0; i<dimZ+1; i++)
		for(int j=0; j<dimY+1; j++)
			for(int k=0; k<dimX+1; k++)
				if(index[i][j][k] >= 0){
					index[i][j][k] = current;
					vertex[current][0] = spaceX*((float)k-0.5f) + originX;
					vertex[current][1] = spaceY*((float)j-0.5f) + originY;
					vertex[current][2] = spaceZ*((float)i-0.5f) + originZ;
					current++;
				}


	mesh->setFaceCount(face_N);
	for(int i=0; i<face_N; i++)
		mesh->setPolygonCount(i, 4);
	face_N = 0;
	int **face = mesh->face;
	for(int i=0; i<dimZ; i++)
		for(int j=0; j<dimY; j++)
			for(int k=0; k<dimX-1; k++){
				if(!isValid[i][j][k] || !isValid[i][j][k+1])
					continue;
				if(isIn[i][j][k] && !isIn[i][j][k+1]){
					face[face_N][0] = index[i][j][k+1];
					face[face_N][1] = index[i][j+1][k+1];
					face[face_N][2] = index[i+1][j+1][k+1];
					face[face_N][3] = index[i+1][j][k+1];
					face_N++;
				}
				else if(!isIn[i][j][k] && isIn[i][j][k+1]){
					face[face_N][0] = index[i][j][k+1];
					face[face_N][1] = index[i+1][j][k+1];
					face[face_N][2] = index[i+1][j+1][k+1];
					face[face_N][3] = index[i][j+1][k+1];
					face_N++;
				}
			}

	for(int i=0; i<dimX; i++)
		for(int j=0; j<dimZ; j++)
			for(int k=0; k<dimY-1; k++){
				if(!isValid[j][k][i] || !isValid[j][k+1][i])
					continue;
				if(isIn[j][k][i] && !isIn[j][k+1][i]){
					face[face_N][0] = index[j][k+1][i];
					face[face_N][1] = index[j+1][k+1][i];
					face[face_N][2] = index[j+1][k+1][i+1];
					face[face_N][3] = index[j][k+1][i+1];
					face_N++;
				}
				else if(!isIn[j][k][i] && isIn[j][k+1][i]){
					face[face_N][0] = index[j][k+1][i];
					face[face_N][1] = index[j][k+1][i+1];
					face[face_N][2] = index[j+1][k+1][i+1];
					face[face_N][3] = index[j+1][k+1][i];
					face_N++;
				}
			}

	for(int i=0; i<dimY; i++)
		for(int j=0; j<dimX; j++)
			for(int k=0; k<dimZ-1; k++){
				if(!isValid[k][i][j] || !isValid[k+1][i][j])
					continue;
				if(isIn[k][i][j] && !isIn[k+1][i][j]){
					face[face_N][0] = index[k+1][i][j];
					face[face_N][1] = index[k+1][i][j+1];
					face[face_N][2] = index[k+1][i+1][j+1];
					face[face_N][3] = index[k+1][i+1][j];
					face_N++;
				}
				else if(!isIn[k][i][j] && isIn[k+1][i][j]){
					face[face_N][0] = index[k+1][i][j];
					face[face_N][1] = index[k+1][i+1][j];
					face[face_N][2] = index[k+1][i+1][j+1];
					face[face_N][3] = index[k+1][i][j+1];
					face_N++;
				}
			}
	
	for(int i=0; i<dimZ+1; i++){
		for(int j=0; j<dimY+1; j++){
			delete[] isIn[i][j];
			delete[] index[i][j];
		}
		delete[] isIn[i];
		delete[] index[i];
	}
	delete[] isIn;
	delete[] index;

	return mesh;
}
PolygonalMesh* Polygonizer::computeSurfaceNetOctTree(float tol, int min, int max)
{
	OctTreeP oct;
	oct.func = func;
	oct.originX = originX;
	oct.originY = originY;
	oct.originZ = originZ;
	oct.sizeX = dimX*spaceX;
	oct.sizeY = dimY*spaceY;
	oct.sizeZ = dimZ*spaceZ;
	oct.constructStandard(min, max);

	int vertex_N, face_N;
	oct.countVertexAndFace(vertex_N, face_N);
	PolygonalMesh* mesh = new PolygonalMesh;
	mesh->setVertexCount(vertex_N);
	mesh->setFaceCount(face_N);
	for(int i=0; i<face_N; i++)
		mesh->setPolygonCount(i, 4);
	
	double (*Q)[10] = new double[vertex_N][10];
	for(int i=0; i<vertex_N; i++)
		MAT_INIT(Q[i]);

	oct.simplify(Q, tol);
	oct.polygonize2(mesh->vertex, mesh->face);
	//return mesh;

	//oct.simplify(Q, tol);
	//oct.polygonize2(mesh->vertex, mesh->face);

	//FOR SVD
			
  vnl_matrix< float > A( 3, 3, 0. );
  
  vnl_vector<float> b( 3, 0. ), x( 3, 0. );
	for(int i=0; i<vertex_N; i++){
		A[0][0] = Q[i][0];
		A[1][0] = A[0][1] = Q[i][1];
		A[2][0] = A[0][2] = Q[i][2];
		A[1][1] = Q[i][3];
		A[1][2] = A[2][1] = Q[i][4];
		A[2][2] = Q[i][5];

		float tmp[3];
		MAT_BY_VEC(tmp, Q[i], mesh->vertex[i]);
		
		b[1] = -Q[i][6] - tmp[0];
		b[2] = -Q[i][7] - tmp[1];
		b[3] = -Q[i][8] - tmp[2];
		
        vnl_svd< float > svd( A );
        svd.zero_out_relative( 0.025 );
		x = svd.solve( b );

		mesh->vertex[i][0] += x[1];
		mesh->vertex[i][1] += x[2];
		mesh->vertex[i][2] += x[3];
	}

	delete[] Q;
	return mesh;
}
PolygonalMesh* Polygonizer::computeSurfaceNetSIG02(float epsilon, float tau)
{
	float p[3];
	bool ***isIn = new bool**[dimZ+1];
	bool ***isValid = new bool**[dimZ+1];
	for(int i=0; i<dimZ+1; i++){
		isIn[i] = new bool*[dimY+1];
		isValid[i] = new bool*[dimY+1];
		p[2] = originZ + i*spaceZ;
		for(int j=0; j<dimY+1; j++){
			isIn[i][j] = new bool[dimX+1];
			isValid[i][j] = new bool[dimX+1];
			p[1] = originY + j*spaceY;
			for(int k=0; k<dimX+1; k++){
				p[0] = originX + k*spaceX;
				isIn[i][j][k] 
					= (func->value(p[0], p[1], p[2], isValid[i][j][k]) > 0);
			}
		}
	}

	int ***index = new int**[dimZ+1];
	for(int i=0; i<dimZ+1; i++){
		index[i] = new int*[dimY+1];
		for(int j=0; j<dimY+1; j++){
			index[i][j] = new int[dimX+1];
			for(int k=0; k<dimX+1; k++)
				index[i][j][k] = -1;
		}
	}

	int current = 0;
	int face_N = 0;
	for(int i=0; i<dimZ; i++)
		for(int j=0; j<dimY; j++)
			for(int k=0; k<dimX-1; k++){
				if(!isValid[i][j][k] || !isValid[i][j][k+1])
					continue;
				if((!isIn[i][j][k] && isIn[i][j][k+1]) || 
				    (isIn[i][j][k] && !isIn[i][j][k+1])){
					face_N++;
					if(index[i][j][k+1] < 0){
						index[i][j][k+1] = current;
						current++;
					}
					if(index[i][j+1][k+1] < 0){
						index[i][j+1][k+1] = current;
						current++;
					}
					if(index[i+1][j][k+1] < 0){
						index[i+1][j][k+1] = current;
						current++;
					}
					if(index[i+1][j+1][k+1] < 0){
						index[i+1][j+1][k+1] = current;
						current++;
					}
				}
			}

	for(int i=0; i<dimX; i++)
		for(int j=0; j<dimZ; j++)
			for(int k=0; k<dimY-1; k++){
				if(!isValid[j][k][i] || !isValid[j][k+1][i])
					continue;
				if((!isIn[j][k][i] && isIn[j][k+1][i]) || 
				    (isIn[j][k][i] && !isIn[j][k+1][i])){
					face_N++;
					if(index[j][k+1][i] < 0){
						index[j][k+1][i] = current;
						current++;
					}
					if(index[j+1][k+1][i] < 0){
						index[j+1][k+1][i] = current;
						current++;
					}
					if(index[j][k+1][i+1] < 0){
						index[j][k+1][i+1] = current;
						current++;
					}
					if(index[j+1][k+1][i+1] < 0){
						index[j+1][k+1][i+1] = current;
						current++;
					}
				}
			}

	for(int i=0; i<dimY; i++)
		for(int j=0; j<dimX; j++)
			for(int k=0; k<dimZ-1; k++){
				if(!isValid[k][i][j] || !isValid[k+1][i][j])
					continue;
				if((!isIn[k][i][j] && isIn[k+1][i][j]) || 
				    (isIn[k][i][j] && !isIn[k+1][i][j])){
					face_N++;
					if(index[k+1][i][j] < 0){
						index[k+1][i][j] = current;
						current++;
					}
					if(index[k+1][i+1][j] < 0){
						index[k+1][i+1][j] = current;
						current++;
					}
					if(index[k+1][i][j+1] < 0){
						index[k+1][i][j+1] = current;
						current++;
					}
					if(index[k+1][i+1][j+1] < 0){
						index[k+1][i+1][j+1] = current;
						current++;
					}
				}
			}
	
	PolygonalMesh* mesh = new PolygonalMesh;
	int vertex_N = current;
	mesh->setVertexCount(vertex_N);
	float (*vertex)[3] = mesh->vertex;
	int* degree = mesh->degree_f = new int[vertex_N];
	current = 0;
	for(int i=0; i<vertex_N; i++){
		vertex[i][0] = vertex[i][1] = vertex[i][2] = 0;
		degree[i] = 0;
	}
	/*
	for(i=0; i<dimZ+1; i++)
		for(int j=0; j<dimY+1; j++)
			for(int k=0; k<dimX+1; k++)
				if(index[i][j][k] >= 0){
					index[i][j][k] = current;
					vertex[current][0] = spaceX*((float)k-0.5f) + originX;
					vertex[current][1] = spaceY*((float)j-0.5f) + originY;
					vertex[current][2] = spaceZ*((float)i-0.5f) + originZ;
					current++;
				}
				*/


	mesh->setFaceCount(face_N);
	double (*Q)[10] = new double[vertex_N][10];
	for(int i=0; i<vertex_N; i++)
		MAT_INIT(Q[i]);
	for(int i=0; i<face_N; i++)
		mesh->setPolygonCount(i, 4);
	face_N = 0;
	int **face = mesh->face;
	bool flag = false;
	for(int i=0; i<dimZ; i++)
		for(int j=0; j<dimY; j++)
			for(int k=0; k<dimX-1; k++){
				if(!isValid[i][j][k] || !isValid[i][j][k+1])
					continue;
				if(isIn[i][j][k] && !isIn[i][j][k+1]){
					face[face_N][0] = index[i][j][k+1];
					face[face_N][1] = index[i][j+1][k+1];
					face[face_N][2] = index[i+1][j+1][k+1];
					face[face_N][3] = index[i+1][j][k+1];
					face_N++;
					flag = true;
				}
				else if(!isIn[i][j][k] && isIn[i][j][k+1]){
					face[face_N][0] = index[i][j][k+1];
					face[face_N][1] = index[i+1][j][k+1];
					face[face_N][2] = index[i+1][j+1][k+1];
					face[face_N][3] = index[i][j+1][k+1];
					face_N++;
					flag = true;
				}
				if(!flag)
					continue;
				flag = false;
				float p[3], s[3], e[3];
				s[0] = originX + k*spaceX;
				e[0] = originX + (k+1)*spaceX;
				s[1] = e[1] = originY + j*spaceY;
				s[2] = e[2] = originZ + i*spaceZ;
				bisection(p, s, e, epsilon);
				
				float g[3];
				func->gradient(g, p[0], p[1], p[2]);
				double len = PolygonalMesh::LENGTH(g);
				//if((float)len == 0)
					//continue;
				double nor[3];
				nor[0] = g[0]/len;
				nor[1] = g[1]/len;
				nor[2] = g[2]/len;

				double d = -PolygonalMesh::DOT(nor, p);
				double Q_tmp[10];
				MATRIX(Q_tmp, nor, d);

				int i0 = index[i][j][k+1];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[i][j+1][k+1];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[i+1][j+1][k+1];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[i+1][j][k+1];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;
			}

	for(int i=0; i<dimX; i++)
		for(int j=0; j<dimZ; j++)
			for(int k=0; k<dimY-1; k++){
				if(!isValid[j][k][i] || !isValid[j][k+1][i])
					continue;
				if(isIn[j][k][i] && !isIn[j][k+1][i]){
					face[face_N][0] = index[j][k+1][i];
					face[face_N][1] = index[j+1][k+1][i];
					face[face_N][2] = index[j+1][k+1][i+1];
					face[face_N][3] = index[j][k+1][i+1];
					face_N++;
					flag = true;
				}
				else if(!isIn[j][k][i] && isIn[j][k+1][i]){
					face[face_N][0] = index[j][k+1][i];
					face[face_N][1] = index[j][k+1][i+1];
					face[face_N][2] = index[j+1][k+1][i+1];
					face[face_N][3] = index[j+1][k+1][i];
					face_N++;
					flag = true;
				}
				if(!flag)
					continue;
				flag = false;
				float p[3], s[3], e[3];
				s[1] = originY + k*spaceY;
				e[1] = originY + (k+1)*spaceY;
				s[2] = e[2] = originZ + j*spaceZ;
				s[0] = e[0] = originX + i*spaceX;
				bisection(p, s, e, epsilon);
				
				float g[3];
				func->gradient(g, p[0], p[1], p[2]);
				double len = PolygonalMesh::LENGTH(g);
				//if((float)len == 0)
					//continue;
				double nor[3];
				nor[0] = g[0]/len;
				nor[1] = g[1]/len;
				nor[2] = g[2]/len;

				double d = -PolygonalMesh::DOT(nor, p);
				double Q_tmp[10];
				MATRIX(Q_tmp, nor, d);
				
				int i0 = index[j][k+1][i];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[j+1][k+1][i];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[j+1][k+1][i+1];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[j][k+1][i+1];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;
			}

	for(int i=0; i<dimY; i++)
		for(int j=0; j<dimX; j++)
			for(int k=0; k<dimZ-1; k++){
				if(!isValid[k][i][j] || !isValid[k+1][i][j])
					continue;
				if(isIn[k][i][j] && !isIn[k+1][i][j]){
					face[face_N][0] = index[k+1][i][j];
					face[face_N][1] = index[k+1][i][j+1];
					face[face_N][2] = index[k+1][i+1][j+1];
					face[face_N][3] = index[k+1][i+1][j];
					face_N++;
					flag = true;
				}
				else if(!isIn[k][i][j] && isIn[k+1][i][j]){
					face[face_N][0] = index[k+1][i][j];
					face[face_N][1] = index[k+1][i+1][j];
					face[face_N][2] = index[k+1][i+1][j+1];
					face[face_N][3] = index[k+1][i][j+1];
					face_N++;
					flag = true;
				}
				if(!flag)
					continue;
				flag = false;
				float p[3], s[3], e[3];
				s[2] = originZ + k*spaceZ;
				e[2] = originZ + (k+1)*spaceZ;
				s[0] = e[0] = originX + j*spaceX;
				s[1] = e[1] = originY + i*spaceY;
				bisection(p, s, e, epsilon);
				
				float g[3];
				func->gradient(g, p[0], p[1], p[2]);
				double len = PolygonalMesh::LENGTH(g);
				//if((float)len == 0)
					//continue;
				double nor[3];
				nor[0] = g[0]/len;
				nor[1] = g[1]/len;
				nor[2] = g[2]/len;

				double d = -PolygonalMesh::DOT(nor, p);
				double Q_tmp[10];
				MATRIX(Q_tmp, nor, d);

				int i0 = index[k+1][i][j];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[k+1][i][j+1];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[k+1][i+1][j+1];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;

				i0 = index[k+1][i+1][j];
				MAT_SUM(Q[i0], Q_tmp);
				vertex[i0][0] += p[0];
				vertex[i0][1] += p[1];
				vertex[i0][2] += p[2];
				degree[i0]++;
			}
	
	//FOR SVD
			
	vnl_matrix< float > A( 3, 3, 0. ); 
	vnl_vector< float > b(3, 0.), x(3, 0.);

	for(int i=0; i<vertex_N; i++){
		if(degree[i] == 0)
			continue;
		vertex[i][0] /= degree[i];
		vertex[i][1] /= degree[i];
		vertex[i][2] /= degree[i];
continue;
		A[0][0] = (float)Q[i][0];
		A[1][0] = A[0][1] = (float)Q[i][1];
		A[2][0] = A[0][2] = (float)Q[i][2];
		A[1][1] = (float)Q[i][3];
		A[1][2] = A[2][1] = (float)Q[i][4];
		A[2][2] = (float)Q[i][5];

		float Av[3];
		MAT_BY_VEC(Av, Q[i], vertex[i]);
		b[0] = -(float)Q[i][6] - Av[0];
		b[1] = -(float)Q[i][7] - Av[1];
		b[2] = -(float)Q[i][8] - Av[2];

    vnl_svd<float> svd( A );
    svd.zero_out_absolute( 0.0000001 );

    x = svd.solve( b );

    if(fabs(x[1]) > spaceX || fabs(x[2]) > spaceY || fabs(x[3]) > spaceZ)
			continue;

		mesh->vertex[i][0] += x[1];
		mesh->vertex[i][1] += x[2];
		mesh->vertex[i][2] += x[3];
	}

	for(int i=0; i<dimZ+1; i++){
		for(int j=0; j<dimY+1; j++){
			delete[] isIn[i][j];
			delete[] index[i][j];
		}
		delete[] isIn[i];
		delete[] index[i];
	}
	delete[] isIn;
	delete[] index;
	delete[] Q;
	delete[] isValid;

	return mesh;
}
Example #5
0
//2D mesh for cross sections. (for the paper)
PolygonalMesh* HRBF::generateCrossSection(float o[], float t1[], float t2[], int n, int m)
{
	PolygonalMesh *mesh = new PolygonalMesh;
	mesh->setVertexCount(n*m);
	mesh->setFaceCount((n-1)*(m-1));
	int **face = mesh->face;
	float (*vertex)[3] = mesh->vertex;
	float *v = mesh->value = new float[mesh->vertex_N];
	mesh->isValid = new bool[mesh->vertex_N];
	mesh->isCovered = new bool[mesh->vertex_N];

	double t3[3];
	PolygonalMesh::CROSS(t3, t1, t2);
	double len = PolygonalMesh::LENGTH(t3);
	//0.3 for kernal
	t3[0] /= -0.4*len;
	t3[1] /= -0.4*len;
	t3[2] /= -0.4*len;

	int i;
	for(i = 0; i< mesh->vertex_N; i++)
		mesh->isValid[i] = true;

	for(i=0; i<n; i++){
		float p1[3];
		p1[0] = o[0] + t1[0]*i;
		p1[1] = o[1] + t1[1]*i;
		p1[2] = o[2] + t1[2]*i;
		for(int j=0; j<m; j++){
			float p2[3];
			p2[0] = t2[0]*j;
			p2[1] = t2[1]*j;
			p2[2] = t2[2]*j;

			int index = i*m+j;
			vertex[index][0] = p1[0] + p2[0];
			vertex[index][1] = p1[1] + p2[1];
			vertex[index][2] = p1[2] + p2[2];

			bool flag;
			float f = value(vertex[index][0], vertex[index][1], vertex[index][2], flag);//);//
			

			if(_isnan(f)){
				v[index] = 0;
				continue;
			}

			/*
			vertex[index][0] += f*(float)t3[0];
			vertex[index][1] += f*(float)t3[1];
			vertex[index][2] += f*(float)t3[2];
			*/
			
			v[index] = f;
			mesh->isCovered[index] = flag;
			//if(!flag)
				//v[index] = 1000000;
			//else
				//v[index] = -10000000;
		}
	}

	for(i=0; i<n-1; i++){
		for(int j=0; j<m-1; j++){
			int index = i*(m-1)+j;
			mesh->setPolygonCount(index, 4);
			face[index][3] = i*m+j;
			face[index][2] = (i+1)*m+j;
			face[index][1] = (i+1)*m+j+1;
			face[index][0] = i*m+j+1;
			//bool flag = (v[face[index][0]] > 0);
			
			/*
			if(PolygonalMesh::LENGTH(vertex[face[index][0]]) > 5 ||
				PolygonalMesh::LENGTH(vertex[face[index][1]]) > 5 ||
				PolygonalMesh::LENGTH(vertex[face[index][2]]) > 5 ||
				PolygonalMesh::LENGTH(vertex[face[index][3]]) > 5)
				face[index][0] = -1;
				*/
			/*
			for(int k=1; k<4; k++){ 
				if(flag != (v[face[index][k]] > 0)){
					v[i*n+j] = -100;
				}
			}*/
			/*
			if(v[face[index][0]] == v[face[index][1]] 
				== v[face[index][2]] == v[face[index][3]] == 0)
				v[i*n+j] = 1000000;*/
		}
	}
	mesh->computeFaceNormal();
	return mesh;
}