143 const double delta = 1. / (n - 1.);
147 T.resize((n - 1) * (n - 1) * (n - 1) * 6, 4);
148 V.resize(n * n * (n - 1) + 1, 3);
149 std::vector<int> map(n * n * n, -1);
153 for (
int i = 0; i < n; ++i)
155 for (
int j = 0; j < n; ++j)
157 for (
int k = 0; k < n; ++k)
159 const int grid_index = (i + j * n) * n + k;
164 apex_index = index++;
165 V.row(apex_index) << 0, 0, 1;
167 map[grid_index] = apex_index;
171 const double z = k * delta;
172 const double scale = 1.0 -
z;
173 map[grid_index] = index;
174 V.row(index) << i * delta * scale, j * delta * scale,
z;
179 V.conservativeResize(index, 3);
180 avoid_pyramid_apex(
V);
182 std::array<int, 8> indices;
183 std::array<int, 4> tmp;
185 for (
int i = 0; i < n - 1; ++i)
187 for (
int j = 0; j < n - 1; ++j)
189 for (
int k = 0; k < n - 1; ++k)
191 indices = {{(i + j * n) * n + k,
192 (i + 1 + j * n) * n + k,
193 (i + 1 + (j + 1) * n) * n + k,
194 (i + (j + 1) * n) * n + k,
196 (i + j * n) * n + k + 1,
197 (i + 1 + j * n) * n + k + 1,
198 (i + 1 + (j + 1) * n) * n + k + 1,
199 (i + (j + 1) * n) * n + k + 1}};
201 tmp = {{map[indices[1 - 1]], map[indices[2 - 1]], map[indices[4 - 1]], map[indices[5 - 1]]}};
202 add_tet(tmp,
V, index, T);
204 tmp = {{map[indices[6 - 1]], map[indices[3 - 1]], map[indices[7 - 1]], map[indices[8 - 1]]}};
205 add_tet(tmp,
V, index, T);
207 tmp = {{map[indices[5 - 1]], map[indices[2 - 1]], map[indices[6 - 1]], map[indices[4 - 1]]}};
208 add_tet(tmp,
V, index, T);
210 tmp = {{map[indices[5 - 1]], map[indices[4 - 1]], map[indices[8 - 1]], map[indices[6 - 1]]}};
211 add_tet(tmp,
V, index, T);
213 tmp = {{map[indices[4 - 1]], map[indices[2 - 1]], map[indices[6 - 1]], map[indices[3 - 1]]}};
214 add_tet(tmp,
V, index, T);
216 tmp = {{map[indices[3 - 1]], map[indices[4 - 1]], map[indices[8 - 1]], map[indices[6 - 1]]}};
217 add_tet(tmp,
V, index, T);
222 T.conservativeResize(index, 4);
224 F.resize(4 * index, 3);
226 F.block(0, 0, index, 1) = T.col(1);
227 F.block(0, 1, index, 1) = T.col(0);
228 F.block(0, 2, index, 1) = T.col(2);
230 F.block(index, 0, index, 1) = T.col(0);
231 F.block(index, 1, index, 1) = T.col(1);
232 F.block(index, 2, index, 1) = T.col(3);
234 F.block(2 * index, 0, index, 1) = T.col(1);
235 F.block(2 * index, 1, index, 1) = T.col(2);
236 F.block(2 * index, 2, index, 1) = T.col(3);
238 F.block(3 * index, 0, index, 1) = T.col(2);
239 F.block(3 * index, 1, index, 1) = T.col(0);
240 F.block(3 * index, 2, index, 1) = T.col(3);
245 T.resize((n - 1) * (n - 1) * (n - 1) * 6, 4);
246 V.resize(n * n * n, 3);
247 std::vector<int> map(n * n * n, -1);
250 for (
int i = 0; i < n; ++i)
252 for (
int j = 0; j < n; ++j)
254 for (
int k = 0; k < n; ++k)
256 if (tet && i + j + k >= n)
258 if (prism && i + j >= n)
261 map[(i + j * n) * n + k] = index;
262 V.row(index) << i * delta, j * delta, k * delta;
267 V.conservativeResize(index, 3);
269 std::array<int, 8> indices;
270 std::array<int, 4> tmp;
272 for (
int i = 0; i < n - 1; ++i)
274 for (
int j = 0; j < n - 1; ++j)
276 for (
int k = 0; k < n - 1; ++k)
278 indices = {{(i + j * n) * n + k,
279 (i + 1 + j * n) * n + k,
280 (i + 1 + (j + 1) * n) * n + k,
281 (i + (j + 1) * n) * n + k,
283 (i + j * n) * n + k + 1,
284 (i + 1 + j * n) * n + k + 1,
285 (i + 1 + (j + 1) * n) * n + k + 1,
286 (i + (j + 1) * n) * n + k + 1}};
288 tmp = {{map[indices[1 - 1]], map[indices[2 - 1]], map[indices[4 - 1]], map[indices[5 - 1]]}};
289 add_tet(tmp,
V, index, T);
291 tmp = {{map[indices[6 - 1]], map[indices[3 - 1]], map[indices[7 - 1]], map[indices[8 - 1]]}};
292 add_tet(tmp,
V, index, T);
294 tmp = {{map[indices[5 - 1]], map[indices[2 - 1]], map[indices[6 - 1]], map[indices[4 - 1]]}};
295 add_tet(tmp,
V, index, T);
297 tmp = {{map[indices[5 - 1]], map[indices[4 - 1]], map[indices[8 - 1]], map[indices[6 - 1]]}};
298 add_tet(tmp,
V, index, T);
300 tmp = {{map[indices[4 - 1]], map[indices[2 - 1]], map[indices[6 - 1]], map[indices[3 - 1]]}};
301 add_tet(tmp,
V, index, T);
303 tmp = {{map[indices[3 - 1]], map[indices[4 - 1]], map[indices[8 - 1]], map[indices[6 - 1]]}};
304 add_tet(tmp,
V, index, T);
309 T.conservativeResize(index, 4);
311 F.resize(4 * index, 3);
313 F.block(0, 0, index, 1) = T.col(1);
314 F.block(0, 1, index, 1) = T.col(0);
315 F.block(0, 2, index, 1) = T.col(2);
317 F.block(index, 0, index, 1) = T.col(0);
318 F.block(index, 1, index, 1) = T.col(1);
319 F.block(index, 2, index, 1) = T.col(3);
321 F.block(2 * index, 0, index, 1) = T.col(1);
322 F.block(2 * index, 1, index, 1) = T.col(2);
323 F.block(2 * index, 2, index, 1) = T.col(3);
325 F.block(3 * index, 0, index, 1) = T.col(2);
326 F.block(3 * index, 1, index, 1) = T.col(0);
327 F.block(3 * index, 2, index, 1) = T.col(3);
579#ifdef POLYFEM_WITH_TRIANGLE
580 Eigen::MatrixXi E(poly.rows(), 2);
581 const Eigen::MatrixXd H(0, 2);
582 const std::string flags =
"Qzqa" + std::to_string(
area_param_ / 10.0);
584 for (
int i = 0; i < poly.rows(); ++i)
585 E.row(i) << i, (i + 1) % poly.rows();
587 igl::triangle::triangulate(poly, E, H, flags, pts,
faces);
590 const Eigen::MatrixXi rt = Eigen::MatrixXi::Zero(poly.rows(), 1);
593 Eigen::MatrixXd area;
594 igl::predicates::ear_clipping(poly, rt,
faces, I);
596 igl::doublearea(poly,
faces, area);
598 const double area_avg = area.array().sum() / poly.rows() / 2;
602 Eigen::MatrixXi new_faces;
604 igl::upsample(poly,
faces, pts, new_faces, n_refs);
608 std::vector<int> loop;
609 igl::default_num_threads(1);
610 igl::boundary_loop(
faces, loop);
611 igl::default_num_threads(0);
612 edges.resize(loop.size(), 2);
613 for (
int i = 0; i < loop.size(); ++i)
614 edges.row(i) << loop[i], loop[(i + 1) % loop.size()];