| 63 | }; |
| 64 | |
| 65 | ZSparseMatrix Assembler::getBoundaryBlurMatrix(double radius) { |
| 66 | typedef std::priority_queue<Item, std::vector<Item>, ItemComp> Queue; |
| 67 | typedef Eigen::Triplet<double> T; |
| 68 | std::vector<T> triplets; |
| 69 | |
| 70 | size_t num_bd_vertices = m_mesh->getNbrBoundaryNodes(); |
| 71 | double sd = radius / 3.0; |
| 72 | const double A = 2.50662827463; // A = sqrt(2*pi); |
| 73 | |
| 74 | std::vector<int> visited(num_bd_vertices, -1); |
| 75 | |
| 76 | for (size_t i=0; i<num_bd_vertices; i++) { |
| 77 | size_t seed = i; |
| 78 | Queue Q; |
| 79 | Q.push(Item(i, 0.0)); |
| 80 | VectorF seed_n = m_mesh->getBoundaryNodeNormal(seed); |
| 81 | |
| 82 | while (!Q.empty()) { |
| 83 | Item cur_item = Q.top(); |
| 84 | Q.pop(); |
| 85 | |
| 86 | // Check if visited before |
| 87 | if (visited[cur_item.first] == seed) continue; |
| 88 | visited[cur_item.first] = seed; |
| 89 | |
| 90 | size_t curr_glob_idx = m_mesh->getBoundaryNode(cur_item.first); |
| 91 | VectorF curr_n = m_mesh->getBoundaryNodeNormal(cur_item.first); |
| 92 | double normal_factor = fmax(0.0, curr_n.dot(seed_n)); |
| 93 | |
| 94 | // Use gaussian distribution as weights |
| 95 | triplets.push_back(T(seed, cur_item.first, |
| 96 | exp(-0.5 * pow(cur_item.second / sd, 2)) / |
| 97 | (sd*A) * normal_factor)); |
| 98 | |
| 99 | VectorI neighbors = m_mesh->getBoundaryNodeAdjacentBoundaryNodes( |
| 100 | cur_item.first); |
| 101 | for (size_t j=0; j<neighbors.size(); j++) { |
| 102 | size_t next = neighbors[j]; |
| 103 | if (visited[next] == seed) continue; |
| 104 | |
| 105 | size_t next_glob_idx = m_mesh->getBoundaryNode(next); |
| 106 | double next_dist = cur_item.second + |
| 107 | (m_mesh->getNode(curr_glob_idx) - |
| 108 | m_mesh->getNode(next_glob_idx)).norm(); |
| 109 | if (next_dist > 2*sd) continue; |
| 110 | Q.push(Item(next, next_dist)); |
| 111 | } |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | Eigen::SparseMatrix<double> Bd_Blur = Eigen::SparseMatrix<double>(num_bd_vertices, num_bd_vertices); |
| 116 | Bd_Blur.setFromTriplets(triplets.begin(), triplets.end()); |
| 117 | return ZSparseMatrix(Bd_Blur); |
| 118 | } |
| 119 | |
| 120 | VectorF Assembler::getDivergence(double* vector_field, int num_vector_field) { |
| 121 | size_t num_node = m_mesh->getNbrNodes(); |
nothing calls this directly
no test coverage detected