void smoothMesh(SurfaceMesh &mesh, int maxIter, bool preserveRidges, bool verbose){ double maxMinAngle = 15; double minMaxAngle = 165; double minAngle, maxAngle; int nSmall, nLarge; int nIter = 1; if(verbose){ std::tie(minAngle, maxAngle, nSmall, nLarge) = getMinMaxAngles(mesh, maxMinAngle, minMaxAngle); std::cout << "Initial Quality: Min Angle = " << minAngle << ", " << "Max Angle = " << maxAngle << ", " << "# smaller-than-" << maxMinAngle << " = " << nSmall << ", " << "# larger-than-" << minMaxAngle << " = " << nLarge << std::endl; } for (int nIter = 1; nIter <= maxIter; ++nIter){ for(auto vertex : mesh.get_level_id<1>()){ if((*vertex).selected == true){ surfacemesh_detail::weightedVertexSmooth(mesh, vertex, RINGS); } //barycenterVertexSmooth(mesh, vertex); } std::vector<SurfaceMesh::SimplexID<2> > edgesToFlip; // Get set of good, non-interfering edges to flip according to the // Angle based criteria. surfacemesh_detail::selectFlipEdges(mesh, preserveRidges, surfacemesh_detail::checkFlipAngle, std::back_inserter(edgesToFlip)); for(auto edgeID : edgesToFlip){ surfacemesh_detail::edgeFlip(mesh, edgeID); } init_orientation(mesh); check_orientation(mesh); // Mark for flipping by edge valence. // edgesToFlip.clear(); // selectFlipEdges(mesh, preserveRidges, checkFlipValence, // std::back_inserter(edgesToFlip)); // for(auto edgeID : edgesToFlip){ // edgeFlip(mesh, edgeID); // } // init_orientation(mesh); // check_orientation(mesh); if (verbose){ std::tie(minAngle, maxAngle, nSmall, nLarge) = getMinMaxAngles(mesh, maxMinAngle, minMaxAngle); std::cout << "Iteration " << nIter << ":" << std::endl; std::cout << "Min Angle = " << minAngle << ", " << "Max Angle = " << maxAngle << ", " << "# smaller-than-" << maxMinAngle << " = " << nSmall << ", " << "# larger-than-" << minMaxAngle << " = " << nLarge << std::endl; } } }
FOR_EACH_METAPIXEL(pixel, pixel_index) { allowed = -1; if (pixel->anti_x >= 0 && pixel->anti_y >= 0 && (utils_manhattan_distance(x, y, pixel->anti_x, pixel->anti_y) < forbid_reconstruction_radius)) continue; check_orientation(pixel, pixel_index, compare_func_set->compare_no_flip, 0); if (pixel->flip & FLIP_HOR & allowed_flips) { check_orientation(pixel, pixel_index, compare_func_set->compare_hor_flip, FLIP_HOR); if (pixel->flip & FLIP_VER & allowed_flips) check_orientation(pixel, pixel_index, compare_func_set->compare_hor_ver_flip, FLIP_HOR | FLIP_VER); } if (pixel->flip & FLIP_VER & allowed_flips) check_orientation(pixel, pixel_index, compare_func_set->compare_ver_flip, FLIP_VER); }
int FEM_Adapt::vertex_split(int n, int n1, int n2, int e1, int e3) { int n_e1 = find_local_node_index(e1, n); int n1_e1 = find_local_node_index(e1, n1); int e2 = theMesh->e2e_getNbr(e1, get_edge_index(n_e1, n1_e1)); int n_e3 = find_local_node_index(e3, n); int n2_e3 = find_local_node_index(e3, n2); int e4 = theMesh->e2e_getNbr(e3, get_edge_index(n_e3, n2_e3)); if (!check_orientation(e1, e3, n, n1, n2)) { int tmp = e3; e3 = e4; e4 = tmp; n_e3 = find_local_node_index(e3, n); n2_e3 = find_local_node_index(e3, n2); } int np = newNode(); int e5 = newElement(); int e6 = newElement(); int nnCount=0, neCount=0; int np_nodes[50], np_elems[50]; // I certainly hope the mesh is not this bad adj_traverse(n, n1, n2, e2, e4, &nnCount, &neCount, np_nodes, np_elems); // Element-to-node updates int nl[3]; if ((n_e1 < n1_e1) || ((n_e1 == 2) && (n1_e1 == 0))) { nl[0] = n1; nl[1] = n; nl[2] = np; theMesh->e2n_setAll(e5, nl); nl[0] = e1; nl[1] = e6; nl[2] = e2; theMesh->e2e_setAll(e5, nl); } else { nl[0] = n; nl[1] = n1; nl[2] = np; theMesh->e2n_setAll(e5, nl); nl[0] = e1; nl[1] = e2; nl[2] = e6; theMesh->e2e_setAll(e5, nl); } if ((n_e3 < n2_e3) || ((n_e3 == 2) && (n2_e3 == 0))) { nl[0] = n2; nl[1] = n; nl[2] = np; theMesh->e2n_setAll(e6, nl); nl[0] = e3; nl[1] = e5; nl[2] = e4; theMesh->e2e_setAll(e6, nl); } else { nl[0] = n; nl[1] = n2; nl[2] = np; theMesh->e2n_setAll(e6, nl); nl[0] = e3; nl[1] = e4; nl[2] = e5; theMesh->e2e_setAll(e6, nl); } theMesh->e2n_replace(e2, n, np); theMesh->e2n_replace(e4, n, np); // Element-to-element updates theMesh->e2e_replace(e1, e2, e5); theMesh->e2e_replace(e2, e1, e5); theMesh->e2e_replace(e3, e4, e6); theMesh->e2e_replace(e4, e3, e6); // Node-to-node updates int i; for (i=0; i<nnCount; i++) { printf("np_nodes[%d] = %d\n", i, np_nodes[i]); theMesh->n2n_remove(n, np_nodes[i]); theMesh->n2n_remove(np_nodes[i], n); theMesh->n2n_add(np, np_nodes[i]); theMesh->n2n_add(np_nodes[i], np); } theMesh->n2n_add(n, np); theMesh->n2n_add(np, n); theMesh->n2n_add(n, n1); theMesh->n2n_add(n1, n); theMesh->n2n_add(n, n2); theMesh->n2n_add(n2, n); // Node-to-element updates for (i=0; i<neCount; i++) { theMesh->n2e_remove(n, np_elems[i]); theMesh->e2n_replace(np_elems[i], n, np); theMesh->n2e_add(np, np_elems[i]); } theMesh->n2e_add(n, e5); theMesh->n2e_add(n, e6); theMesh->n2e_add(n1, e5); theMesh->n2e_add(n2, e6); theMesh->n2e_add(np, e5); theMesh->n2e_add(np, e6); return np; }
int FEM_Adapt::vertex_split_help(int n, int n1, int n2, int e1, int e3) { int e1_n = find_local_node_index(e1, n); int e1_n1 = find_local_node_index(e1, n1); int e2 = theMesh->e2e_getNbr(e1, get_edge_index(e1_n, e1_n1)); int e3_n = find_local_node_index(e3, n); int e3_n2 = find_local_node_index(e3, n2); int e4 = theMesh->e2e_getNbr(e3, get_edge_index(e3_n, e3_n2)); if (!check_orientation(e1, e3, n, n1, n2)) { int tmp = e3; e3 = e4; e4 = tmp; e3_n = find_local_node_index(e3, n); e3_n2 = find_local_node_index(e3, n2); } int locknodes[4]; locknodes[0] = n1; locknodes[1] = n; locknodes[2] = n2; locknodes[3] = -1; int lockelems[6]; lockelems[0] = e1; lockelems[1] = e2; lockelems[2] = e3; lockelems[3] = e4; lockelems[4] = -1; lockelems[5] = -1; int elemConn[3]; //FEM_Modify_Lock(theMesh, locknodes, 4, lockelems, 6); #ifdef DEBUG_1 CkPrintf("Vertex Split, %d-%d-%d on chunk %d\n", n1, n, n2, theMod->getfmUtil()->getIdx()); #endif int adjnodes[2]; adjnodes[0] = n; //looks like it will never be shared, since according to later code, all n1, n & n2 should be local.. appears to be not correct //the new node will be shared to wahtever the old node was shared to, we'll do this later int *chunks = NULL; int numChunks = 0; int np = FEM_add_node(theMesh,adjnodes,1,chunks,numChunks,0); locknodes[3] = np; int current, next, nt, nl, eknp, eknt, eknl; // traverse elements on one side of n starting with e2 current = e2; nt = n1; while ((current != e3) && (current != -1)) { eknp = find_local_node_index(current, n); eknt = find_local_node_index(current, nt); eknl = 3 - eknp - eknt; next = theMesh->e2e_getNbr(current, get_edge_index(eknp, eknl)); nl = theMesh->e2n_getNode(current, eknl); FEM_remove_element(theMesh, current, 0); // add nl, nt, np elemConn[eknp] = np; elemConn[eknt] = nt; elemConn[eknl] = nl; int newelem = FEM_add_element(theMesh, elemConn, 3, 0); nt = nl; current = next; } if (current == -1) { // didn't make it all the way around // traverse elements on one side of n starting with e4 current = e4; nt = n2; while ((current != e1) && (current != -1)) { eknp = find_local_node_index(current, n); eknt = find_local_node_index(current, nt); eknl = 3 - eknp - eknt; next = theMesh->e2e_getNbr(current, get_edge_index(eknp, eknl)); nl = theMesh->e2n_getNode(current, eknl); FEM_remove_element(theMesh, current, 0); // add nl, nt, np elemConn[eknp] = np; elemConn[eknt] = nt; elemConn[eknl] = nl; int newelem = FEM_add_element(theMesh, elemConn, 3, 0); nt = nl; current = next; } } // add n, n1, np elemConn[e1_n] = n; elemConn[e1_n1] = n1; elemConn[3 - e1_n - e1_n1] = np; lockelems[4] = FEM_add_element(theMesh, elemConn, 3, 0); // add n, n2, np elemConn[e3_n] = n; elemConn[e3_n2] = n2; elemConn[3 - e3_n - e3_n2] = np; lockelems[5] = FEM_add_element(theMesh, elemConn, 3, 0); return np; }