| 103 | } |
| 104 | |
| 105 | bool PeriodicExploration::run_tetgen(Float max_tet_vol) { |
| 106 | #ifdef WITH_TETGEN |
| 107 | const size_t dim = m_vertices.cols(); |
| 108 | const size_t num_vertices = m_vertices.rows(); |
| 109 | TetgenWrapper tetgen; |
| 110 | tetgen.set_points(m_vertices); |
| 111 | tetgen.set_triangles(m_faces); |
| 112 | if (max_tet_vol == 0.0) { |
| 113 | max_tet_vol = |
| 114 | pow(m_default_thickness * pow(0.5, m_refine_order), dim); |
| 115 | } |
| 116 | tetgen.set_split_boundary(false); |
| 117 | tetgen.set_max_tet_volume(max_tet_vol); |
| 118 | tetgen.set_verbosity(0); |
| 119 | try { |
| 120 | tetgen.run(); |
| 121 | } catch (TetgenException& e) { |
| 122 | save_mesh("tetgen_debug.msh"); |
| 123 | std::cerr << e.what() << std::endl; |
| 124 | std::cerr << "Data saved in tetgen_debug.msh" << std::endl; |
| 125 | return false; |
| 126 | } |
| 127 | |
| 128 | // Important note: |
| 129 | // |
| 130 | // The following code is based on rather shaky the observation that tetgen |
| 131 | // will only append to the existing list of vertices. Therefore, the face |
| 132 | // arrays are still valid given the "Y" flag is used. |
| 133 | MatrixFr vertices = tetgen.get_vertices(); |
| 134 | assert(vertices.rows() > 0); |
| 135 | assert((vertices.block(0, 0, num_vertices, dim).array()==m_vertices.array()).all()); |
| 136 | m_vertices = vertices; |
| 137 | m_voxels = tetgen.get_voxels(); |
| 138 | |
| 139 | const size_t num_vol_vertices = m_vertices.rows(); |
| 140 | for (auto& velocity : m_shape_velocities) { |
| 141 | velocity.conservativeResize(num_vol_vertices, dim); |
| 142 | velocity.block(num_vertices, 0, |
| 143 | num_vol_vertices-num_vertices, dim).setZero(); |
| 144 | } |
| 145 | update_mesh(); |
| 146 | |
| 147 | return true; |
| 148 | #else |
| 149 | return false; |
| 150 | #endif |
| 151 | } |
| 152 | |
| 153 | bool PeriodicExploration::is_printable() { |
| 154 | ParameterCommon::Variables vars; |