Exemplo n.º 1
0
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;
        }
    }
}
Exemplo n.º 2
0
    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);
    }
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}