inline Bvert_list reorder(CBedge_list& edges) { Bvert_list ret; Bvert_list verts = edges.get_verts(); for (Bvert_list::size_type i = 0; i < verts.size(); i++) if (Bpoint::find_controller(verts[i]) || Bcurve::find_controller(verts[i])) { ret.push_back(verts[i]); break; } if (ret.empty()) return ret; for (Bvert_list::size_type i = 1; i < verts.size(); i++) { for (Bedge_list::size_type j = 0; j < edges.size(); j++) { Bvert* v = edges[j]->other_vertex(ret.back()); if (v && std::find(ret.begin(), ret.end(), v) == ret.end()) { ret.push_back(v); break; } } } err_adv(debug, " reorder: num of verts: %d", ret.size()); return ret; }
inline double compute_h(Bvert* v) { assert(v); PCell_list cells = Panel::find_cells(v->get_faces()); if (cells.size() == 2) { // common case: vertex in a tube ring (2 neighboring cells) if (Bpoint::find_controller(v) || Bcurve::find_controller(v)) return cells[0]->shared_boundary(cells[1]).avg_len()/2; Bvert_list verts = reorder(cells[0]->shared_boundary(cells[1])); double num = verts.size()-1; assert(num > 1); int index = verts.get_index(v); assert(index != -1); double h = (compute_h(verts.front()) + compute_h(verts.back())) / 2; return h * (1 + min(index/num, 1-index/num)); } else if (cells.size() > 2) { // multiple adjacent cells return PCell::shared_edges(cells).avg_len()/2; } else if (cells.size() == 1) { // just one cell, e.g. tip of a tube, or part of a disk if (cells[0]->num_corners() == 3) { if (cells[0]->nbrs().size() != 1) { return cells[0]->boundary_edges().avg_len()/2; } assert(cells[0]->nbrs().size() == 1); return 0; // it's the tip of the triangle } else if (cells[0]->num_corners() == 4) { if (cells[0]->nbrs().size() == 0) { return cells[0]->boundary_edges().avg_len()/2; } else if (cells[0]->nbrs().size() == 1) { // or maybe should do same rule as next case Bedge_list end_edges = quad_cell_end_edges(cells[0]); err_adv(debug, "found %d end edges", end_edges.size()); return end_edges.avg_len()/2; } return v->strong_edges().avg_len()/2; } if (Bpoint::find_controller(v) || Bcurve::find_controller(v)) return cells[0]->boundary_edges().filter(BorderEdgeFilter()||BcurveFilter()).avg_len()/2; Bvert_list nbrs; v->get_nbrs(nbrs); assert(!nbrs.empty()); return 1.5 * compute_h(nbrs[0]); } err_adv(debug, "compute_h: unexpected number of cells: %d", cells.size()); return -1; }