268 int output_dimension,
272 create_dataset_to_point_mapping(rtree, ccplx, point_src);
273 if (rtree.domain_dimension == 1) {
274 for(
auto& cell: cells) {
282 cc_node_idx_t np = nan_edge_solver(ccplx, rtree, cn0_pnti, corners[0], cell, func);
283 ccplx.add_cell(cc_t::cell_kind_t::SEGMENT, {cn0_pnti, np}, output_dimension);
286 cc_node_idx_t np = nan_edge_solver(ccplx, rtree, cn1_pnti, corners[1], cell, func);
287 ccplx.add_cell(cc_t::cell_kind_t::SEGMENT, {np, cn1_pnti}, output_dimension);
291 cc_node_idx_t np = nan_edge_solver(ccplx, rtree, ctr_pnti, cell, corners[0], func);
292 ccplx.add_cell(cc_t::cell_kind_t::SEGMENT, {np, ctr_pnti}, output_dimension);
294 ccplx.add_cell(cc_t::cell_kind_t::SEGMENT, {cn0_pnti, ctr_pnti}, output_dimension);
297 cc_node_idx_t np = nan_edge_solver(ccplx, rtree, ctr_pnti, cell, corners[1], func);
298 ccplx.add_cell(cc_t::cell_kind_t::SEGMENT, {ctr_pnti, np}, output_dimension);
300 ccplx.add_cell(cc_t::cell_kind_t::SEGMENT, {ctr_pnti, cn1_pnti}, output_dimension);
304 ccplx.add_cell(cc_t::cell_kind_t::SEGMENT, {cn0_pnti, ctr_pnti}, output_dimension);
305 ccplx.add_cell(cc_t::cell_kind_t::SEGMENT, {ctr_pnti, cn1_pnti}, output_dimension);
308 }
else if (rtree.domain_dimension == 2) {
309 for(
auto& cell: cells) {
311 for(
int i=0; i<2; i++) {
312 for(
int j=-1; j<2; j+=2) {
313 std::vector<rt_diti_list_t> triangles;
315 if (nbrs.size() > 1) {
318 if( ((i == 0) && (j == -1)) || ((i == 1) && (j == 1)) )
319 triangles.push_back({corners[1], corners[0], cell});
321 triangles.push_back({corners[0], corners[1], cell});
325 if( ((i == 0) && (j == -1)) || ((i == 1) && (j == 1)) )
326 triangles.push_back({corners[1], corners[0], cell});
328 triangles.push_back({corners[0], corners[1], cell});
330 for(
auto triangle: triangles) {
331 std::array<cc_node_idx_t, 3> tpnts {add_node(ccplx, rtree, triangle[0]),
332 add_node(ccplx, rtree, triangle[1]),
333 add_node(ccplx, rtree, triangle[2])};
334 int num_bad =
static_cast<int>(std::count_if(tpnts.begin(), tpnts.end(), [](
cc_node_idx_t i) { return i<0; }));
336 ccplx.add_cell(cc_t::cell_kind_t::TRIANGLE, {tpnts[0], tpnts[1], tpnts[2]}, output_dimension);
337 }
else if ((num_bad == 1) || (num_bad == 2)) {
339 std::array<int, 3> p {0, 1, 2};
340 if ( ((tpnts[1] < 0) && (num_bad == 1)) || ((tpnts[1] >= 0) && (num_bad == 2)) )
342 else if ( ((tpnts[2] < 0) && (num_bad == 1)) || ((tpnts[2] >= 0) && (num_bad == 2)) )
346 cc_node_idx_t np1 = nan_edge_solver(ccplx, rtree, tpnts[p[1]], triangle[p[1]], triangle[p[0]], func);
347 cc_node_idx_t np2 = nan_edge_solver(ccplx, rtree, tpnts[p[2]], triangle[p[2]], triangle[p[0]], func);
348 ccplx.add_cell(cc_t::cell_kind_t::TRIANGLE, {np1, tpnts[p[1]], tpnts[p[2]]}, output_dimension);
349 ccplx.add_cell(cc_t::cell_kind_t::TRIANGLE, {tpnts[p[2]], np2, np1}, output_dimension);
351 cc_node_idx_t np1 = nan_edge_solver(ccplx, rtree, tpnts[p[0]], triangle[p[0]], triangle[p[1]], func);
352 cc_node_idx_t np2 = nan_edge_solver(ccplx, rtree, tpnts[p[0]], triangle[p[0]], triangle[p[2]], func);
353 ccplx.add_cell(cc_t::cell_kind_t::TRIANGLE, {tpnts[p[0]], np1, np2}, output_dimension);
362 for(
int i=0; i<2; i++) {
363 for(
int j=-1; j<2; j+=2) {
365 if (nbrs.size() > 1) {
370 if( ((i == 0) && (j == -1)) || ((i == 1) && (j == 1)) )
371 std::swap(cn0_pnti, cn1_pnti);
372 ccplx.add_cell(cc_t::cell_kind_t::TRIANGLE, {cn0_pnti, cn1_pnti, ctr_pnti}, output_dimension);
378 if( ((i == 0) && (j == -1)) || ((i == 1) && (j == 1)) )
379 std::swap(cn0_pnti, cn1_pnti);
380 ccplx.add_cell(cc_t::cell_kind_t::TRIANGLE, {cn0_pnti, cn1_pnti, ctr_pnti}, output_dimension);
387 }
else if (rtree.domain_dimension == 3) {
388 for(
auto& cell: cells) {
390 new_cell[4] = add_node(ccplx, rtree, cell);
391 std::array<int, 5> p {0, 1, 3, 2, 4};
392 if (new_cell[4] >= 0) {
393 for(
int dim=0; dim<3; dim++) {
394 for(
int dir=-1; dir<2; dir+=2) {
395 rt_diti_list_t nbrs = rtree.get_existing_neighbor(cell, dim, dir);
396 if (nbrs.size() > 1) {
399 for(
int k=0; k<4; ++k)
400 new_cell[p[k]] = add_node(ccplx, rtree, corners[k]);
401 ccplx.add_cell(cc_t::cell_kind_t::PYRAMID, new_cell, output_dimension);
405 for(
int k=0; k<4; ++k)
406 new_cell[p[k]] = add_node(ccplx, rtree, corners[k]);
407 ccplx.add_cell(cc_t::cell_kind_t::PYRAMID, new_cell, output_dimension);
414 std::cout <<
"ERROR: construct_geometry_fans: output_dimension>3 not supported for output_dimension>0!" << std::endl;
510 int output_dimension,
512 bool degenerate_fallback =
true
514 create_dataset_to_point_mapping(rtree, ccplx, point_src);
515 for(
auto& cell: cells) {
516 std::vector<cc_node_idx_t> cnr_pti;
518 for(
auto& corner: corners) {
520 cnr_pti.push_back(pnti);
522 if (rtree.domain_dimension == 1) {
523 ccplx.add_cell(cc_t::cell_kind_t::SEGMENT, {cnr_pti[0], cnr_pti[1]}, output_dimension);
524 }
else if (rtree.domain_dimension == 2) {
525 const std::array<int, 4> p = {0, 1, 3, 2};
526 bool try_harder = !(ccplx.add_cell(cc_t::cell_kind_t::QUAD, {cnr_pti[0], cnr_pti[1], cnr_pti[3], cnr_pti[2]}, output_dimension));
527 if ( degenerate_fallback && try_harder) {
528 for(
int i=0; i<4; i++) {
529 if ((cnr_pti[p[i]] < 0) || (cnr_pti[p[(i+0)%4]] == cnr_pti[p[(i+1)%4]])) {
530 ccplx.add_cell(cc_t::cell_kind_t::TRIANGLE, {cnr_pti[p[(i+1)%4]], cnr_pti[p[(i+2)%4]], cnr_pti[p[(i+3)%4]]}, output_dimension);
536 ccplx.add_cell(cc_t::cell_kind_t::HEXAHEDRON,
537 {cnr_pti[0], cnr_pti[1], cnr_pti[3], cnr_pti[2],
538 cnr_pti[4], cnr_pti[5], cnr_pti[7], cnr_pti[6]},