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)); }
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); }