void SessionServer::readFolder()
{
	unsigned short pathLen;
	if(!readSBuf((char*) &pathLen, sizeof(pathLen)))
		return;
	std::unique_ptr<char> path(new char[pathLen + 1]);
	if(!readSBuf(path.get(), pathLen))
		return;
	path.get()[pathLen] = '\0';
	SafeInfo sfInfo;
	int rss = pathValidateR(path.get(), 0, &sfInfo);
	if(rss == 0)
	{
		std::unique_ptr<FileNode> fnodes(new FileNode[20]);
		if(!writeSBuf((char*) &rss, sizeof(rss)))
			return;
		int len, start = 0;
		while(true)
		{
			len = manager->readFolder(path.get(), start, 20, fnodes.get());
			if(len == 0)
			{
				char tmp = 0;
				writeSBuf(&tmp, sizeof(tmp));
			}
			else if(len < 0)
				setErr(ERR_SYS_ERROR);
			else
			{
				start += len;
				for(int i = 0; i < len; ++i)
				{
					char nlen = strlen(fnodes.get()[i].name);
					writeSBuf(&nlen, sizeof(nlen));
					writeSBuf(fnodes.get()[i].name, nlen);
				}
				continue;
			}
			break;
		}
	}
	else
		writeSBuf((char*) &rss, sizeof(rss));
}
Esempio n. 2
0
void meshsurf3::buildSurface( std::vector<vec3d> &vertices, std::vector<vec3d> &normals, std::vector<vec3i> &faces, const levelset3 *fluid, const levelset3 *solid, bool enclose, FLOAT64 dpx, uint iteration, bool doFit ) {
	// Save a reference to the mesher
	const mesher3 &g = *this->g;
	
	tick(); dump("Computing levelset for %d nodes...", g.nodes.size());
	values.clear();
	values.resize(g.nodes.size());
	if( values.empty() ) {
		email::print("Mesher Uninitialized !\n");
		email::send();
		exit(0);
	}
	// Compute levelset for each node
	PARALLEL_FOR for( uint n=0; n<g.nodes.size(); n++ ) {
		FLOAT64 phi = fluid->evalLevelset(g.nodes[n]);
		if( enclose ) phi = fmax(phi,-dpx-solid->evalLevelset(g.nodes[n]));
		values[n] = phi;
	}
	dump("Done. Took %s.\n",stock("meshsurf_levelset_sample"));
	
	// Fill holes
	fillHoles(values,solid,g.nodes,g.elements,g.node2node,fluid->dx);
	
	// Calculate intersections on edges
	tick(); dump("Computing cut edges for each tet...");
	std::vector<vec3d> cutpoints(g.edges.size());
	std::vector<int> cutIndices(g.edges.size());
	uint index = 0;
	for( int n=0; n<g.edges.size(); n++ ) {
		FLOAT64 levelsets[2];
		for( uint m=0; m<2; m++ ) levelsets[m] = values[g.edges[n][m]];
		if( copysign(1.0,levelsets[0]) * copysign(1.0,levelsets[1]) <= 0 ) {
			FLOAT64 det = levelsets[0]-levelsets[1];
			if( fabs(det) < 1e-16 ) det = copysign(1e-16,det);
			FLOAT64 a = fmin(0.99,fmax(0.01,levelsets[0]/det));
			vec3d p = (1.0-a)*g.nodes[g.edges[n][0]]+a*g.nodes[g.edges[n][1]];
			cutpoints[n] = p;
			cutIndices[n] = index++;
		} else {
			cutIndices[n] = -1;
		}
	}
	
	// Copy them to packed array
	vertices.clear();
	vertices.resize(index);
	index = 0;
	for( uint n=0; n<cutIndices.size(); n++ ) {
		if( cutIndices[n] >= 0 ) vertices[index++] = cutpoints[n];
	}
	dump("Done. Took %s.\n",stock());
	
	// Stitch faces (marching tet)
	tick(); dump("Stitching edges...");
	std::vector<std::vector<uint> > node_faces;
	node_faces.resize(g.nodes.size());
	faces.clear();
	for( uint n=0; n<g.elements.size(); n++ ) {
		std::vector<uint> nv;
		for( uint m=0; m<g.element_edges[n].size(); m++ ) {
			uint idx = g.element_edges[n][m];
			if( cutIndices[idx] >= 0 ) {
				nv.push_back(cutIndices[idx]);
			}
		}
		if( nv.size() == 4 ) {
			// Triangulate the veritces
			int idx0 = -1;
			int idx1 = -1;
			for( uint m=0; m<g.element_edges[n].size(); m++ ) {
				if( cutIndices[g.element_edges[n][m]] >= 0 ) {
					idx0 = g.element_edges[n][m];
					break;
				}
			}
			// If found one intersection edge
			if( idx0 >= 0 ) {
				for( uint m=0; m<g.element_edges[n].size(); m++ ) {
					uint opID = g.element_edges[n][m];
					if( cutIndices[opID] >= 0 && isOpEdge(idx0,opID)) {
						idx1 = opID;
						break;
					}
				}
				// If found opposite intersection edge
				if( idx1 >= 0 ) {
					vec3i v;
					v[0] = cutIndices[idx0];
					v[1] = cutIndices[idx1];
					for( uint m=0; m<g.element_edges[n].size(); m++ ) {
						uint idx2 = g.element_edges[n][m];
						if( cutIndices[idx2] >= 0 && idx2 != idx0 && idx2 != idx1 ) {
							v[2] = cutIndices[idx2];
							faces.push_back(v);
							for( uint m=0; m<g.elements[n].size(); m++ ) {
								node_faces[g.elements[n][m]].push_back(faces.size()-1);
							}
						}
					}
				} else {
					dump( "Opposite edge was not found !\n");
					exit(0);
				}
			} else {
				dump( "Ground edge was not found !\n");
				exit(0);
			}
		} else if( nv.size() == 3 ) {
			faces.push_back(vec3i(nv[0],nv[1],nv[2]));
			for( uint m=0; m<g.elements[n].size(); m++ ) {
				node_faces[g.elements[n][m]].push_back(faces.size()-1);
			}
		} else if( nv.size() == 0 ) {
			// Empty surface. Do nothing...
		} else {
			dump( "\nBad stitch encounrtered: Element - edge count = %d.\n", g.element_edges[n].size() );
			dump( "Unknown set found N(%e,%e,%e,%e) = %d.\n",
				   values[g.elements[n][0]], values[g.elements[n][1]], values[g.elements[n][2]], values[g.elements[n][3]], nv.size());
			for( uint k=0; k<g.element_edges[n].size(); k++ ) {
				uint vidx[2] = { g.edges[g.element_edges[n][k]][0], g.edges[g.element_edges[n][k]][1] };
				dump( "Edge info[%d] = edge(%d,%d) = (%e,%e) = (%f,%f)\n", k, vidx[0], vidx[1], values[vidx[0]], values[vidx[1]], copysign(1.0,values[vidx[0]]), copysign(1.0,values[vidx[1]]) );
			}
		}
	}
	dump("Done. Took %s.\n",stock("meshsurf_stitch_mesh"));
	
	// Find closest position
	tick(); dump("Finding closest surface position at surface tets...");
	surfacePos.clear();
	surfacePos.resize(g.nodes.size());
	for( uint n=0; n<g.nodes.size(); n++ ) {
		FLOAT64 dist = 1e8;
		vec3d p = g.nodes[n];
		for( uint m=0; m<node_faces[n].size(); m++ ) {
			vec3d p0 = vertices[faces[node_faces[n][m]][0]];
			vec3d p1 = vertices[faces[node_faces[n][m]][1]];
			vec3d p2 = vertices[faces[node_faces[n][m]][2]];
			vec3d out = g.nodes[n];
			vec3d src = out;
			FLOAT64 d = fmax(1e-8,point_triangle_distance(src,p0,p1,p2,out));
			if( d < dist ) {
				p = out;
				dist = d;
			}
		}
		if( dist < 1.0 ) {
			values[n] = (values[n]>=0 ? 1.0 : -1.0) * dist;
			surfacePos[n].push_back(g.nodes[n]);
			surfacePos[n].push_back(p);
		} else {
			values[n] = (values[n]>=0 ? 1.0 : -1.0) * 1e8;
		}
	}
	dump("Done. Took %s.\n",stock("meshsurf_find_close_pos1"));
	
	if( extrapolate_dist ) {
		// Fast march
		tick();
		std::vector<fastmarch3<FLOAT64>::node3 *> fnodes(g.nodes.size());
		for( uint n=0; n<g.nodes.size(); n++ ) fnodes[n] = new fastmarch3<FLOAT64>::node3;
		for( uint n=0; n<g.nodes.size(); n++ ) {
			vec3d p = g.nodes[n];
			bool fixed = fabs(values[n]) < 1.0;
			fnodes[n]->p = p;
			fnodes[n]->fixed = fixed;
			fnodes[n]->levelset = values[n];
			fnodes[n]->value = 0.0;
			fnodes[n]->p2p.resize(g.node2node[n].size());
			for( uint m=0; m<g.node2node[n].size(); m++ ) {
				fnodes[n]->p2p[m] = fnodes[g.node2node[n][m]];
			}
		}
		fastmarch3<FLOAT64>::fastMarch(fnodes,extrapolate_dist,-extrapolate_dist,1);
		
		// Pick up values
		for( uint n=0; n<g.nodes.size(); n++ ) {
			values[n] = fnodes[n]->levelset;
			delete fnodes[n];
		}
		stock("meshsurf_fastmarch");
	}
	
	// Compute normal
	tick(); dump("Computing normals...");
	computeNormals(vertices,normals,faces,cutIndices);
	dump("Done. Took %s.\n",stock("meshsurf_normal"));

	// Flip facet rotation if necessary
	flipFacet(vertices,normals,faces,0.1*fluid->dx);
	
#if 1
	// Fit surface
	if( doFit ) {
		tick(); dump("Fitting %d surface vertices...", vertices.size() );
		for( uint k=0; k<1; k++ ) {
			smoothMesh(vertices,normals,faces,solid,dpx,1);
			PARALLEL_FOR for( uint n=0; n<vertices.size(); n++ ) {
				vec3d out = vertices[n];
				if( solid->evalLevelset(out) > dpx && fluid->getClosestSurfacePos(out) ) {
					vertices[n] = out;
				}				
			}
		}
		dump("Done. Took %s.\n",stock("meshsurf_fit"));
	}
#endif
	
	// Smooth mesh
#if 1
	tick(); dump("Smoothing faces...");
	smoothMesh(vertices,normals,faces,solid,dpx,iteration);
	dump("Done. Took %s.\n",stock("meshsurf_smooth"));
#endif
	
	// Find closest position again
	tick(); dump("Finding closest surface position at surface tets again...");
	surfacePos.clear();
	surfacePos.resize(g.nodes.size());
	for( uint n=0; n<g.nodes.size(); n++ ) {
		FLOAT64 dist = 1e8;
		vec3d p = g.nodes[n];
		for( uint m=0; m<node_faces[n].size(); m++ ) {
			vec3d p0 = vertices[faces[node_faces[n][m]][0]];
			vec3d p1 = vertices[faces[node_faces[n][m]][1]];
			vec3d p2 = vertices[faces[node_faces[n][m]][2]];
			vec3d out = g.nodes[n];
			vec3d src = out;
			FLOAT64 d = fmax(1e-8,point_triangle_distance(src,p0,p1,p2,out));
			if( d < dist ) {
				p = out;
				dist = d;
			}
		}
		if( dist < 1.0 ) {
			values[n] = (values[n]>=0 ? 1.0 : -1.0) * dist;
		}
	}
	dump("Done. Took %s.\n",stock("meshsurf_find_close_pos2"));
	
	// Flip again
	flipFacet(vertices,normals,faces,0.1*fluid->dx);
}