8#define CASE_EDGE_POSITION_L_3D \
9 case EdgePosition::L_xnn_3D: \
10 case EdgePosition::L_xn0_3D: \
11 case EdgePosition::L_xnN_3D: \
12 case EdgePosition::L_x0n_3D: \
13 case EdgePosition::L_x00_3D: \
14 case EdgePosition::L_x0N_3D: \
15 case EdgePosition::L_xNn_3D: \
16 case EdgePosition::L_xN0_3D: \
17 case EdgePosition::L_xNN_3D
18#define CASE_EDGE_POSITION_H_3D \
19 case EdgePosition::H_nyn_3D: \
20 case EdgePosition::H_ny0_3D: \
21 case EdgePosition::H_nyN_3D: \
22 case EdgePosition::H_0yn_3D: \
23 case EdgePosition::H_0y0_3D: \
24 case EdgePosition::H_0yN_3D: \
25 case EdgePosition::H_Nyn_3D: \
26 case EdgePosition::H_Ny0_3D: \
27 case EdgePosition::H_NyN_3D
28#define CASE_EDGE_POSITION_P_3D \
29 case EdgePosition::P_nnz_3D: \
30 case EdgePosition::P_n0z_3D: \
31 case EdgePosition::P_nNz_3D: \
32 case EdgePosition::P_0nz_3D: \
33 case EdgePosition::P_00z_3D: \
34 case EdgePosition::P_0Nz_3D: \
35 case EdgePosition::P_Nnz_3D: \
36 case EdgePosition::P_N0z_3D: \
37 case EdgePosition::P_NNz_3D
38#define CASE_EDGE_POSITION_D1_3D \
39 case EdgePosition::D1_xyn_3D: \
40 case EdgePosition::D1_xy0_3D: \
41 case EdgePosition::D1_xyN_3D
42#define CASE_EDGE_POSITION_D2_3D \
43 case EdgePosition::D2_nyz_3D: \
44 case EdgePosition::D2_0yz_3D: \
45 case EdgePosition::D2_Nyz_3D
46#define CASE_EDGE_POSITION_D3_3D \
47 case EdgePosition::D3_xnz_3D: \
48 case EdgePosition::D3_x0z_3D: \
49 case EdgePosition::D3_xNz_3D
50#define CASE_EDGE_POSITION_L_2D \
51 case EdgePosition::L_xn_2D: \
52 case EdgePosition::L_x0_2D: \
53 case EdgePosition::L_xN_2D
54#define CASE_EDGE_POSITION_H_2D \
55 case EdgePosition::H_ny_2D: \
56 case EdgePosition::H_0y_2D: \
57 case EdgePosition::H_Ny_2D
60 : cellNumber_{}, vertexNumber_{}, edgeNumber_{}, triangleNumber_{},
61 tetrahedronNumber_{}, isAccelerated_{} {
64 this->hasPreconditionedDistributedEdges_ =
true;
65 this->hasPreconditionedDistributedTriangles_ =
true;
74 const float &xSpacing,
75 const float &ySpacing,
76 const float &zSpacing,
82 if(xDim < 1 or yDim < 1 or zDim < 1)
84 else if(xDim > 1 and yDim > 1 and zDim > 1)
86 else if((xDim > 1 and yDim > 1) or (yDim > 1 and zDim > 1)
87 or (xDim > 1 and zDim > 1))
89 else if(xDim > 1 or yDim > 1 or zDim > 1)
116 esetdims_[3] = (xDim - 1) * (yDim - 1) * zDim;
117 esetdims_[4] = xDim * (yDim - 1) * (zDim - 1);
118 esetdims_[5] = (xDim - 1) * yDim * (zDim - 1);
119 esetdims_[6] = (xDim - 1) * (yDim - 1) * (zDim - 1);
122 for(
int k = 1; k < 7; ++k)
126 eshift_[1] = (xDim - 1) * yDim;
128 eshift_[3] = xDim * (yDim - 1);
132 eshift_[7] = (xDim - 1) * (yDim - 1);
134 eshift_[9] = xDim * (yDim - 1);
136 eshift_[11] = (xDim - 1) * yDim;
138 eshift_[13] = (xDim - 1) * (yDim - 1);
140 tsetdims_[0] = (xDim - 1) * (yDim - 1) * zDim * 2;
141 tsetdims_[1] = (xDim - 1) * yDim * (zDim - 1) * 2;
142 tsetdims_[2] = xDim * (yDim - 1) * (zDim - 1) * 2;
143 tsetdims_[3] = (xDim - 1) * (yDim - 1) * (zDim - 1) * 2;
144 tsetdims_[4] = (xDim - 1) * (yDim - 1) * (zDim - 1) * 2;
145 tsetdims_[5] = (xDim - 1) * (yDim - 1) * (zDim - 1) * 2;
148 for(
int k = 1; k < 6; ++k)
152 tshift_[1] = (xDim - 1) * (yDim - 1) * 2;
154 tshift_[3] = (xDim - 1) * yDim * 2;
156 tshift_[5] = xDim * (yDim - 1) * 2;
158 tshift_[7] = (xDim - 1) * (yDim - 1) * 2;
160 tshift_[9] = (xDim - 1) * (yDim - 1) * 2;
162 tshift_[11] = (xDim - 1) * (yDim - 1) * 2;
165 tetshift_[1] = (xDim - 1) * (yDim - 1) * 6;
170 for(
int k = 0; k < 7; ++k)
173 for(
int k = 0; k < 6; ++k)
184 }
else if(yDim == 1) {
199 for(
int k = 1; k < 3; ++k)
211 for(
int k = 0; k < 3; ++k)
219 for(
int k = 0; k < 3; ++k) {
238 unsigned long long int msb[3];
240 bool allDimensionsArePowerOfTwo =
true;
241 for(
int k = 0; k < 3; ++k)
243 allDimensionsArePowerOfTwo =
false;
245 if(allDimensionsArePowerOfTwo) {
249 div_[1] = msb[0] + msb[1];
255 bool allDimensionsArePowerOfTwo = (isDi and isDj);
257 if(allDimensionsArePowerOfTwo) {
272 unsigned long long int &r) {
273 if(v && !(v & (v - 1))) {
282template <
typename Derived>
287 if(this->metaGrid_ !=
nullptr) {
288 return this->isVertexOnGlobalBoundaryInternal(vertexId);
292#ifndef TTK_ENABLE_KAMIKAZE
293 if(vertexId < 0 or vertexId >= vertexNumber_)
297 switch(this->underlying().getVertexPosition(vertexId)) {
298 case VertexPosition::CENTER_3D:
299 case VertexPosition::CENTER_2D:
300 case VertexPosition::CENTER_1D:
307template <
typename Derived>
312 if(this->metaGrid_ !=
nullptr) {
313 return this->isEdgeOnGlobalBoundaryInternal(edgeId);
317#ifndef TTK_ENABLE_KAMIKAZE
318 if(edgeId < 0 or edgeId >= edgeNumber_)
322 switch(this->underlying().getEdgePosition(edgeId)) {
323 case EdgePosition::L_xnn_3D:
324 case EdgePosition::H_nyn_3D:
325 case EdgePosition::P_nnz_3D:
326 case EdgePosition::D1_xyn_3D:
327 case EdgePosition::D2_nyz_3D:
328 case EdgePosition::D3_xnz_3D:
329 case EdgePosition::D4_3D:
330 case EdgePosition::L_xn_2D:
331 case EdgePosition::H_ny_2D:
332 case EdgePosition::D1_2D:
344 if(this->metaGrid_ !=
nullptr) {
345 return this->isTriangleOnGlobalBoundaryInternal(triangleId);
349#ifndef TTK_ENABLE_KAMIKAZE
350 if(triangleId < 0 or triangleId >= triangleNumber_)
354 if(dimensionality_ == 3)
360template <
typename Derived>
363 const int &localNeighborId,
366#ifndef TTK_ENABLE_KAMIKAZE
367 if(localNeighborId < 0
372 switch(this->underlying().getVertexPosition(vertexId)) {
373 case VertexPosition::CENTER_3D:
374 neighborId = vertexId + this->vertexNeighborABCDEFGH_[localNeighborId];
376 case VertexPosition::FRONT_FACE_3D:
377 neighborId = vertexId + this->vertexNeighborABCD_[localNeighborId];
379 case VertexPosition::BACK_FACE_3D:
380 neighborId = vertexId + this->vertexNeighborEFGH_[localNeighborId];
382 case VertexPosition::TOP_FACE_3D:
383 neighborId = vertexId + this->vertexNeighborAEFB_[localNeighborId];
385 case VertexPosition::BOTTOM_FACE_3D:
386 neighborId = vertexId + this->vertexNeighborGHDC_[localNeighborId];
388 case VertexPosition::LEFT_FACE_3D:
389 neighborId = vertexId + this->vertexNeighborAEGC_[localNeighborId];
391 case VertexPosition::RIGHT_FACE_3D:
392 neighborId = vertexId + this->vertexNeighborBFHD_[localNeighborId];
394 case VertexPosition::TOP_FRONT_EDGE_3D:
395 neighborId = vertexId + this->vertexNeighborAB_[localNeighborId];
397 case VertexPosition::BOTTOM_FRONT_EDGE_3D:
398 neighborId = vertexId + this->vertexNeighborCD_[localNeighborId];
400 case VertexPosition::LEFT_FRONT_EDGE_3D:
401 neighborId = vertexId + this->vertexNeighborAC_[localNeighborId];
403 case VertexPosition::RIGHT_FRONT_EDGE_3D:
404 neighborId = vertexId + this->vertexNeighborBD_[localNeighborId];
406 case VertexPosition::TOP_BACK_EDGE_3D:
407 neighborId = vertexId + this->vertexNeighborEF_[localNeighborId];
409 case VertexPosition::BOTTOM_BACK_EDGE_3D:
410 neighborId = vertexId + this->vertexNeighborGH_[localNeighborId];
412 case VertexPosition::LEFT_BACK_EDGE_3D:
413 neighborId = vertexId + this->vertexNeighborEG_[localNeighborId];
415 case VertexPosition::RIGHT_BACK_EDGE_3D:
416 neighborId = vertexId + this->vertexNeighborFH_[localNeighborId];
418 case VertexPosition::TOP_LEFT_EDGE_3D:
419 neighborId = vertexId + this->vertexNeighborAE_[localNeighborId];
421 case VertexPosition::TOP_RIGHT_EDGE_3D:
422 neighborId = vertexId + this->vertexNeighborBF_[localNeighborId];
424 case VertexPosition::BOTTOM_LEFT_EDGE_3D:
425 neighborId = vertexId + this->vertexNeighborCG_[localNeighborId];
427 case VertexPosition::BOTTOM_RIGHT_EDGE_3D:
428 neighborId = vertexId + this->vertexNeighborDH_[localNeighborId];
430 case VertexPosition::TOP_LEFT_FRONT_CORNER_3D:
431 neighborId = vertexId + this->vertexNeighborA_[localNeighborId];
433 case VertexPosition::TOP_RIGHT_FRONT_CORNER_3D:
434 neighborId = vertexId + this->vertexNeighborB_[localNeighborId];
436 case VertexPosition::BOTTOM_LEFT_FRONT_CORNER_3D:
437 neighborId = vertexId + this->vertexNeighborC_[localNeighborId];
439 case VertexPosition::BOTTOM_RIGHT_FRONT_CORNER_3D:
440 neighborId = vertexId + this->vertexNeighborD_[localNeighborId];
442 case VertexPosition::TOP_LEFT_BACK_CORNER_3D:
443 neighborId = vertexId + this->vertexNeighborE_[localNeighborId];
445 case VertexPosition::TOP_RIGHT_BACK_CORNER_3D:
446 neighborId = vertexId + this->vertexNeighborF_[localNeighborId];
448 case VertexPosition::BOTTOM_LEFT_BACK_CORNER_3D:
449 neighborId = vertexId + this->vertexNeighborG_[localNeighborId];
451 case VertexPosition::BOTTOM_RIGHT_BACK_CORNER_3D:
452 neighborId = vertexId + this->vertexNeighborH_[localNeighborId];
454 case VertexPosition::CENTER_2D:
455 neighborId = vertexId + this->vertexNeighbor2dABCD_[localNeighborId];
457 case VertexPosition::TOP_EDGE_2D:
458 neighborId = vertexId + this->vertexNeighbor2dAB_[localNeighborId];
460 case VertexPosition::BOTTOM_EDGE_2D:
461 neighborId = vertexId + this->vertexNeighbor2dCD_[localNeighborId];
463 case VertexPosition::LEFT_EDGE_2D:
464 neighborId = vertexId + this->vertexNeighbor2dAC_[localNeighborId];
466 case VertexPosition::RIGHT_EDGE_2D:
467 neighborId = vertexId + this->vertexNeighbor2dBD_[localNeighborId];
469 case VertexPosition::TOP_LEFT_CORNER_2D:
470 neighborId = vertexId + this->vertexNeighbor2dA_[localNeighborId];
472 case VertexPosition::TOP_RIGHT_CORNER_2D:
473 neighborId = vertexId + this->vertexNeighbor2dB_[localNeighborId];
475 case VertexPosition::BOTTOM_LEFT_CORNER_2D:
476 neighborId = vertexId + this->vertexNeighbor2dC_[localNeighborId];
478 case VertexPosition::BOTTOM_RIGHT_CORNER_2D:
479 neighborId = vertexId + this->vertexNeighbor2dD_[localNeighborId];
481 case VertexPosition::CENTER_1D:
482 neighborId = (localNeighborId == 0 ? vertexId + 1 : vertexId - 1);
484 case VertexPosition::LEFT_CORNER_1D:
485 neighborId = vertexId + 1;
487 case VertexPosition::RIGHT_CORNER_1D:
488 neighborId = vertexId - 1;
498const vector<vector<SimplexId>> *
500 if(vertexNeighborList_.empty()) {
502 vertexNeighborList_.resize(vertexNumber_);
503 for(
SimplexId i = 0; i < vertexNumber_; ++i) {
509 printMsg(
"Built " + to_string(vertexNumber_) +
" vertex neighbors.", 1,
513 return &vertexNeighborList_;
521template <
typename Derived>
524#ifndef TTK_ENABLE_KAMIKAZE
525 if(localEdgeId < 0 or localEdgeId >= getVertexEdgeNumberInternal(vertexId))
545 const auto &p = this->underlying().getVertexCoords(vertexId);
547 switch(this->underlying().getVertexPosition(vertexId)) {
548 case VertexPosition::CENTER_3D:
549 edgeId = getVertexEdgeABCDEFGH(p.data(), localEdgeId);
551 case VertexPosition::FRONT_FACE_3D:
552 edgeId = getVertexEdgeABDC(p.data(), localEdgeId);
554 case VertexPosition::BACK_FACE_3D:
555 edgeId = getVertexEdgeEFHG(p.data(), localEdgeId);
557 case VertexPosition::TOP_FACE_3D:
558 edgeId = getVertexEdgeAEFB(p.data(), localEdgeId);
560 case VertexPosition::BOTTOM_FACE_3D:
561 edgeId = getVertexEdgeGHDC(p.data(), localEdgeId);
563 case VertexPosition::LEFT_FACE_3D:
564 edgeId = getVertexEdgeAEGC(p.data(), localEdgeId);
566 case VertexPosition::RIGHT_FACE_3D:
567 edgeId = getVertexEdgeBFHD(p.data(), localEdgeId);
569 case VertexPosition::TOP_FRONT_EDGE_3D:
570 edgeId = getVertexEdgeAB(p.data(), localEdgeId);
572 case VertexPosition::BOTTOM_FRONT_EDGE_3D:
573 edgeId = getVertexEdgeCD(p.data(), localEdgeId);
575 case VertexPosition::LEFT_FRONT_EDGE_3D:
576 edgeId = getVertexEdgeAC(p.data(), localEdgeId);
578 case VertexPosition::RIGHT_FRONT_EDGE_3D:
579 edgeId = getVertexEdgeBD(p.data(), localEdgeId);
581 case VertexPosition::TOP_BACK_EDGE_3D:
582 edgeId = getVertexEdgeEF(p.data(), localEdgeId);
584 case VertexPosition::BOTTOM_BACK_EDGE_3D:
585 edgeId = getVertexEdgeGH(p.data(), localEdgeId);
587 case VertexPosition::LEFT_BACK_EDGE_3D:
588 edgeId = getVertexEdgeEG(p.data(), localEdgeId);
590 case VertexPosition::RIGHT_BACK_EDGE_3D:
591 edgeId = getVertexEdgeFH(p.data(), localEdgeId);
593 case VertexPosition::TOP_LEFT_EDGE_3D:
594 edgeId = getVertexEdgeAE(p.data(), localEdgeId);
596 case VertexPosition::TOP_RIGHT_EDGE_3D:
597 edgeId = getVertexEdgeBF(p.data(), localEdgeId);
599 case VertexPosition::BOTTOM_LEFT_EDGE_3D:
600 edgeId = getVertexEdgeCG(p.data(), localEdgeId);
602 case VertexPosition::BOTTOM_RIGHT_EDGE_3D:
603 edgeId = getVertexEdgeDH(p.data(), localEdgeId);
605 case VertexPosition::TOP_LEFT_FRONT_CORNER_3D:
606 edgeId = getVertexEdgeA(p.data(), localEdgeId);
608 case VertexPosition::TOP_RIGHT_FRONT_CORNER_3D:
609 edgeId = getVertexEdgeB(p.data(), localEdgeId);
611 case VertexPosition::BOTTOM_LEFT_FRONT_CORNER_3D:
612 edgeId = getVertexEdgeC(p.data(), localEdgeId);
614 case VertexPosition::BOTTOM_RIGHT_FRONT_CORNER_3D:
615 edgeId = getVertexEdgeD(p.data(), localEdgeId);
617 case VertexPosition::TOP_LEFT_BACK_CORNER_3D:
618 edgeId = getVertexEdgeE(p.data(), localEdgeId);
620 case VertexPosition::TOP_RIGHT_BACK_CORNER_3D:
621 edgeId = getVertexEdgeF(p.data(), localEdgeId);
623 case VertexPosition::BOTTOM_LEFT_BACK_CORNER_3D:
624 edgeId = getVertexEdgeG(p.data(), localEdgeId);
626 case VertexPosition::BOTTOM_RIGHT_BACK_CORNER_3D:
627 edgeId = getVertexEdgeH(p.data(), localEdgeId);
629 case VertexPosition::CENTER_2D:
630 edgeId = getVertexEdge2dABCD(p.data(), localEdgeId);
632 case VertexPosition::TOP_EDGE_2D:
633 edgeId = getVertexEdge2dAB(p.data(), localEdgeId);
635 case VertexPosition::BOTTOM_EDGE_2D:
636 edgeId = getVertexEdge2dCD(p.data(), localEdgeId);
638 case VertexPosition::LEFT_EDGE_2D:
639 edgeId = getVertexEdge2dAC(p.data(), localEdgeId);
641 case VertexPosition::RIGHT_EDGE_2D:
642 edgeId = getVertexEdge2dBD(p.data(), localEdgeId);
644 case VertexPosition::TOP_LEFT_CORNER_2D:
645 edgeId = getVertexEdge2dA(p.data(), localEdgeId);
647 case VertexPosition::TOP_RIGHT_CORNER_2D:
648 edgeId = getVertexEdge2dB(p.data(), localEdgeId);
650 case VertexPosition::BOTTOM_LEFT_CORNER_2D:
651 edgeId = getVertexEdge2dC(p.data(), localEdgeId);
653 case VertexPosition::BOTTOM_RIGHT_CORNER_2D:
654 edgeId = getVertexEdge2dD(p.data(), localEdgeId);
656 case VertexPosition::CENTER_1D:
657 edgeId = (localEdgeId == 0 ? vertexId : vertexId - 1);
659 case VertexPosition::LEFT_CORNER_1D:
662 case VertexPosition::RIGHT_CORNER_1D:
663 edgeId = vertexId - 1;
672const vector<vector<SimplexId>> *
691template <
typename Derived>
694#ifndef TTK_ENABLE_KAMIKAZE
695 if(vertexId < 0 or vertexId >= vertexNumber_)
699 switch(this->underlying().getVertexPosition(vertexId)) {
700 case VertexPosition::CENTER_3D:
702 case VertexPosition::FRONT_FACE_3D:
703 case VertexPosition::BACK_FACE_3D:
704 case VertexPosition::TOP_FACE_3D:
705 case VertexPosition::BOTTOM_FACE_3D:
706 case VertexPosition::LEFT_FACE_3D:
707 case VertexPosition::RIGHT_FACE_3D:
709 case VertexPosition::TOP_FRONT_EDGE_3D:
710 case VertexPosition::RIGHT_FRONT_EDGE_3D:
711 case VertexPosition::BOTTOM_BACK_EDGE_3D:
712 case VertexPosition::LEFT_BACK_EDGE_3D:
713 case VertexPosition::BOTTOM_LEFT_EDGE_3D:
714 case VertexPosition::TOP_RIGHT_EDGE_3D:
716 case VertexPosition::TOP_RIGHT_FRONT_CORNER_3D:
717 case VertexPosition::BOTTOM_LEFT_BACK_CORNER_3D:
719 case VertexPosition::TOP_BACK_EDGE_3D:
720 case VertexPosition::BOTTOM_FRONT_EDGE_3D:
721 case VertexPosition::LEFT_FRONT_EDGE_3D:
722 case VertexPosition::TOP_LEFT_EDGE_3D:
723 case VertexPosition::RIGHT_BACK_EDGE_3D:
724 case VertexPosition::BOTTOM_RIGHT_EDGE_3D:
726 case VertexPosition::TOP_LEFT_FRONT_CORNER_3D:
727 case VertexPosition::BOTTOM_LEFT_FRONT_CORNER_3D:
728 case VertexPosition::BOTTOM_RIGHT_FRONT_CORNER_3D:
729 case VertexPosition::TOP_LEFT_BACK_CORNER_3D:
730 case VertexPosition::TOP_RIGHT_BACK_CORNER_3D:
731 case VertexPosition::BOTTOM_RIGHT_BACK_CORNER_3D:
740template <
typename Derived>
743 const int &localTriangleId,
745#ifndef TTK_ENABLE_KAMIKAZE
746 if(localTriangleId < 0
747 or localTriangleId >= getVertexTriangleNumberInternal(vertexId))
751 const auto &p = this->underlying().getVertexCoords(vertexId);
753 switch(this->underlying().getVertexPosition(vertexId)) {
754 case VertexPosition::CENTER_3D:
755 triangleId = getVertexTriangleABCDEFGH(p.data(), localTriangleId);
757 case VertexPosition::FRONT_FACE_3D:
758 triangleId = getVertexTriangleABDC(p.data(), localTriangleId);
760 case VertexPosition::BACK_FACE_3D:
761 triangleId = getVertexTriangleEFHG(p.data(), localTriangleId);
763 case VertexPosition::TOP_FACE_3D:
764 triangleId = getVertexTriangleAEFB(p.data(), localTriangleId);
766 case VertexPosition::BOTTOM_FACE_3D:
767 triangleId = getVertexTriangleGHDC(p.data(), localTriangleId);
769 case VertexPosition::LEFT_FACE_3D:
770 triangleId = getVertexTriangleAEGC(p.data(), localTriangleId);
772 case VertexPosition::RIGHT_FACE_3D:
773 triangleId = getVertexTriangleBFHD(p.data(), localTriangleId);
775 case VertexPosition::TOP_FRONT_EDGE_3D:
776 triangleId = getVertexTriangleAB(p.data(), localTriangleId);
778 case VertexPosition::BOTTOM_FRONT_EDGE_3D:
779 triangleId = getVertexTriangleCD(p.data(), localTriangleId);
781 case VertexPosition::LEFT_FRONT_EDGE_3D:
782 triangleId = getVertexTriangleAC(p.data(), localTriangleId);
784 case VertexPosition::RIGHT_FRONT_EDGE_3D:
785 triangleId = getVertexTriangleBD(p.data(), localTriangleId);
787 case VertexPosition::TOP_BACK_EDGE_3D:
788 triangleId = getVertexTriangleEF(p.data(), localTriangleId);
790 case VertexPosition::BOTTOM_BACK_EDGE_3D:
791 triangleId = getVertexTriangleGH(p.data(), localTriangleId);
793 case VertexPosition::LEFT_BACK_EDGE_3D:
794 triangleId = getVertexTriangleEG(p.data(), localTriangleId);
796 case VertexPosition::RIGHT_BACK_EDGE_3D:
797 triangleId = getVertexTriangleFH(p.data(), localTriangleId);
799 case VertexPosition::TOP_LEFT_EDGE_3D:
800 triangleId = getVertexTriangleAE(p.data(), localTriangleId);
802 case VertexPosition::TOP_RIGHT_EDGE_3D:
803 triangleId = getVertexTriangleBF(p.data(), localTriangleId);
805 case VertexPosition::BOTTOM_LEFT_EDGE_3D:
806 triangleId = getVertexTriangleCG(p.data(), localTriangleId);
808 case VertexPosition::BOTTOM_RIGHT_EDGE_3D:
809 triangleId = getVertexTriangleDH(p.data(), localTriangleId);
811 case VertexPosition::TOP_LEFT_FRONT_CORNER_3D:
812 triangleId = getVertexTriangleA(p.data(), localTriangleId);
814 case VertexPosition::TOP_RIGHT_FRONT_CORNER_3D:
815 triangleId = getVertexTriangleB(p.data(), localTriangleId);
817 case VertexPosition::BOTTOM_LEFT_FRONT_CORNER_3D:
818 triangleId = getVertexTriangleC(p.data(), localTriangleId);
820 case VertexPosition::BOTTOM_RIGHT_FRONT_CORNER_3D:
821 triangleId = getVertexTriangleD(p.data(), localTriangleId);
823 case VertexPosition::TOP_LEFT_BACK_CORNER_3D:
824 triangleId = getVertexTriangleE(p.data(), localTriangleId);
826 case VertexPosition::TOP_RIGHT_BACK_CORNER_3D:
827 triangleId = getVertexTriangleF(p.data(), localTriangleId);
829 case VertexPosition::BOTTOM_LEFT_BACK_CORNER_3D:
830 triangleId = getVertexTriangleG(p.data(), localTriangleId);
832 case VertexPosition::BOTTOM_RIGHT_BACK_CORNER_3D:
833 triangleId = getVertexTriangleH(p.data(), localTriangleId);
843const vector<vector<SimplexId>> *
862SimplexId ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(
867template <
typename Derived>
870 const int &localLinkId,
873#ifndef TTK_ENABLE_KAMIKAZE
878 const auto &p = this->underlying().getVertexCoords(vertexId);
880 switch(this->underlying().getVertexPosition(vertexId)) {
881 case VertexPosition::CENTER_3D:
882 linkId = getVertexLinkABCDEFGH(p.data(), localLinkId);
884 case VertexPosition::FRONT_FACE_3D:
885 linkId = getVertexLinkABDC(p.data(), localLinkId);
887 case VertexPosition::BACK_FACE_3D:
888 linkId = getVertexLinkEFHG(p.data(), localLinkId);
890 case VertexPosition::TOP_FACE_3D:
891 linkId = getVertexLinkAEFB(p.data(), localLinkId);
893 case VertexPosition::BOTTOM_FACE_3D:
894 linkId = getVertexLinkGHDC(p.data(), localLinkId);
896 case VertexPosition::LEFT_FACE_3D:
897 linkId = getVertexLinkAEGC(p.data(), localLinkId);
899 case VertexPosition::RIGHT_FACE_3D:
900 linkId = getVertexLinkBFHD(p.data(), localLinkId);
902 case VertexPosition::TOP_FRONT_EDGE_3D:
903 linkId = getVertexLinkAB(p.data(), localLinkId);
905 case VertexPosition::BOTTOM_FRONT_EDGE_3D:
906 linkId = getVertexLinkCD(p.data(), localLinkId);
908 case VertexPosition::LEFT_FRONT_EDGE_3D:
909 linkId = getVertexLinkAC(p.data(), localLinkId);
911 case VertexPosition::RIGHT_FRONT_EDGE_3D:
912 linkId = getVertexLinkBD(p.data(), localLinkId);
914 case VertexPosition::TOP_BACK_EDGE_3D:
915 linkId = getVertexLinkEF(p.data(), localLinkId);
917 case VertexPosition::BOTTOM_BACK_EDGE_3D:
918 linkId = getVertexLinkGH(p.data(), localLinkId);
920 case VertexPosition::LEFT_BACK_EDGE_3D:
921 linkId = getVertexLinkEG(p.data(), localLinkId);
923 case VertexPosition::RIGHT_BACK_EDGE_3D:
924 linkId = getVertexLinkFH(p.data(), localLinkId);
926 case VertexPosition::TOP_LEFT_EDGE_3D:
927 linkId = getVertexLinkAE(p.data(), localLinkId);
929 case VertexPosition::TOP_RIGHT_EDGE_3D:
930 linkId = getVertexLinkBF(p.data(), localLinkId);
932 case VertexPosition::BOTTOM_LEFT_EDGE_3D:
933 linkId = getVertexLinkCG(p.data(), localLinkId);
935 case VertexPosition::BOTTOM_RIGHT_EDGE_3D:
936 linkId = getVertexLinkDH(p.data(), localLinkId);
938 case VertexPosition::TOP_LEFT_FRONT_CORNER_3D:
939 linkId = getVertexLinkA(p.data(), localLinkId);
941 case VertexPosition::TOP_RIGHT_FRONT_CORNER_3D:
942 linkId = getVertexLinkB(p.data(), localLinkId);
944 case VertexPosition::BOTTOM_LEFT_FRONT_CORNER_3D:
945 linkId = getVertexLinkC(p.data(), localLinkId);
947 case VertexPosition::BOTTOM_RIGHT_FRONT_CORNER_3D:
948 linkId = getVertexLinkD(p.data(), localLinkId);
950 case VertexPosition::TOP_LEFT_BACK_CORNER_3D:
951 linkId = getVertexLinkE(p.data(), localLinkId);
953 case VertexPosition::TOP_RIGHT_BACK_CORNER_3D:
954 linkId = getVertexLinkF(p.data(), localLinkId);
956 case VertexPosition::BOTTOM_LEFT_BACK_CORNER_3D:
957 linkId = getVertexLinkG(p.data(), localLinkId);
959 case VertexPosition::BOTTOM_RIGHT_BACK_CORNER_3D:
960 linkId = getVertexLinkH(p.data(), localLinkId);
962 case VertexPosition::CENTER_2D:
963 linkId = getVertexLink2dABCD(p.data(), localLinkId);
965 case VertexPosition::TOP_EDGE_2D:
966 linkId = getVertexLink2dAB(p.data(), localLinkId);
968 case VertexPosition::BOTTOM_EDGE_2D:
969 linkId = getVertexLink2dCD(p.data(), localLinkId);
971 case VertexPosition::LEFT_EDGE_2D:
972 linkId = getVertexLink2dAC(p.data(), localLinkId);
974 case VertexPosition::RIGHT_EDGE_2D:
975 linkId = getVertexLink2dBD(p.data(), localLinkId);
977 case VertexPosition::TOP_LEFT_CORNER_2D:
978 linkId = getVertexLink2dA(p.data(), localLinkId);
980 case VertexPosition::TOP_RIGHT_CORNER_2D:
981 linkId = getVertexLink2dB(p.data(), localLinkId);
983 case VertexPosition::BOTTOM_LEFT_CORNER_2D:
984 linkId = getVertexLink2dC(p.data(), localLinkId);
986 case VertexPosition::BOTTOM_RIGHT_CORNER_2D:
987 linkId = getVertexLink2dD(p.data(), localLinkId);
997const vector<vector<SimplexId>> *
999 if(vertexLinkList_.empty()) {
1002 vertexLinkList_.resize(vertexNumber_);
1003 for(
SimplexId i = 0; i < vertexNumber_; ++i) {
1009 printMsg(
"Built " + to_string(vertexNumber_) +
" vertex links.", 1,
1013 return &vertexLinkList_;
1016template <
typename Derived>
1020#ifndef TTK_ENABLE_KAMIKAZE
1021 if(vertexId < 0 or vertexId >= vertexNumber_)
1025 switch(this->underlying().getVertexPosition(vertexId)) {
1026 case VertexPosition::CENTER_3D:
1028 case VertexPosition::FRONT_FACE_3D:
1029 case VertexPosition::BACK_FACE_3D:
1030 case VertexPosition::TOP_FACE_3D:
1031 case VertexPosition::BOTTOM_FACE_3D:
1032 case VertexPosition::LEFT_FACE_3D:
1033 case VertexPosition::RIGHT_FACE_3D:
1035 case VertexPosition::TOP_FRONT_EDGE_3D:
1036 case VertexPosition::RIGHT_FRONT_EDGE_3D:
1037 case VertexPosition::BOTTOM_BACK_EDGE_3D:
1038 case VertexPosition::LEFT_BACK_EDGE_3D:
1039 case VertexPosition::BOTTOM_LEFT_EDGE_3D:
1040 case VertexPosition::TOP_RIGHT_EDGE_3D:
1042 case VertexPosition::TOP_RIGHT_FRONT_CORNER_3D:
1043 case VertexPosition::BOTTOM_LEFT_BACK_CORNER_3D:
1044 case VertexPosition::CENTER_2D:
1046 case VertexPosition::TOP_BACK_EDGE_3D:
1047 case VertexPosition::BOTTOM_FRONT_EDGE_3D:
1048 case VertexPosition::LEFT_FRONT_EDGE_3D:
1049 case VertexPosition::TOP_LEFT_EDGE_3D:
1050 case VertexPosition::RIGHT_BACK_EDGE_3D:
1051 case VertexPosition::BOTTOM_RIGHT_EDGE_3D:
1053 case VertexPosition::TOP_EDGE_2D:
1054 case VertexPosition::BOTTOM_EDGE_2D:
1055 case VertexPosition::LEFT_EDGE_2D:
1056 case VertexPosition::RIGHT_EDGE_2D:
1058 case VertexPosition::TOP_LEFT_FRONT_CORNER_3D:
1059 case VertexPosition::BOTTOM_LEFT_FRONT_CORNER_3D:
1060 case VertexPosition::BOTTOM_RIGHT_FRONT_CORNER_3D:
1061 case VertexPosition::TOP_LEFT_BACK_CORNER_3D:
1062 case VertexPosition::TOP_RIGHT_BACK_CORNER_3D:
1063 case VertexPosition::BOTTOM_RIGHT_BACK_CORNER_3D:
1064 case VertexPosition::TOP_RIGHT_CORNER_2D:
1065 case VertexPosition::BOTTOM_LEFT_CORNER_2D:
1067 case VertexPosition::TOP_LEFT_CORNER_2D:
1068 case VertexPosition::BOTTOM_RIGHT_CORNER_2D:
1077template <
typename Derived>
1080 const int &localStarId,
1083#ifndef TTK_ENABLE_KAMIKAZE
1088 const auto &p = this->underlying().getVertexCoords(vertexId);
1090 switch(this->underlying().getVertexPosition(vertexId)) {
1091 case VertexPosition::CENTER_3D:
1092 starId = getVertexStarABCDEFGH(p.data(), localStarId);
1094 case VertexPosition::FRONT_FACE_3D:
1095 starId = getVertexStarABDC(p.data(), localStarId);
1097 case VertexPosition::BACK_FACE_3D:
1098 starId = getVertexStarEFHG(p.data(), localStarId);
1100 case VertexPosition::TOP_FACE_3D:
1101 starId = getVertexStarAEFB(p.data(), localStarId);
1103 case VertexPosition::BOTTOM_FACE_3D:
1104 starId = getVertexStarGHDC(p.data(), localStarId);
1106 case VertexPosition::LEFT_FACE_3D:
1107 starId = getVertexStarAEGC(p.data(), localStarId);
1109 case VertexPosition::RIGHT_FACE_3D:
1110 starId = getVertexStarBFHD(p.data(), localStarId);
1112 case VertexPosition::TOP_FRONT_EDGE_3D:
1113 starId = getVertexStarAB(p.data(), localStarId);
1115 case VertexPosition::BOTTOM_FRONT_EDGE_3D:
1116 starId = getVertexStarCD(p.data(), localStarId);
1118 case VertexPosition::LEFT_FRONT_EDGE_3D:
1119 starId = getVertexStarAC(p.data(), localStarId);
1121 case VertexPosition::RIGHT_FRONT_EDGE_3D:
1122 starId = getVertexStarBD(p.data(), localStarId);
1124 case VertexPosition::TOP_BACK_EDGE_3D:
1125 starId = getVertexStarEF(p.data(), localStarId);
1127 case VertexPosition::BOTTOM_BACK_EDGE_3D:
1128 starId = getVertexStarGH(p.data(), localStarId);
1130 case VertexPosition::LEFT_BACK_EDGE_3D:
1131 starId = getVertexStarEG(p.data(), localStarId);
1133 case VertexPosition::RIGHT_BACK_EDGE_3D:
1134 starId = getVertexStarFH(p.data(), localStarId);
1136 case VertexPosition::TOP_LEFT_EDGE_3D:
1137 starId = getVertexStarAE(p.data(), localStarId);
1139 case VertexPosition::TOP_RIGHT_EDGE_3D:
1140 starId = getVertexStarBF(p.data(), localStarId);
1142 case VertexPosition::BOTTOM_LEFT_EDGE_3D:
1143 starId = getVertexStarCG(p.data(), localStarId);
1145 case VertexPosition::BOTTOM_RIGHT_EDGE_3D:
1146 starId = getVertexStarDH(p.data(), localStarId);
1148 case VertexPosition::TOP_LEFT_FRONT_CORNER_3D:
1149 starId = getVertexStarA(p.data(), localStarId);
1151 case VertexPosition::TOP_RIGHT_FRONT_CORNER_3D:
1152 starId = getVertexStarB(p.data(), localStarId);
1154 case VertexPosition::BOTTOM_LEFT_FRONT_CORNER_3D:
1155 starId = getVertexStarC(p.data(), localStarId);
1157 case VertexPosition::BOTTOM_RIGHT_FRONT_CORNER_3D:
1158 starId = getVertexStarD(p.data(), localStarId);
1160 case VertexPosition::TOP_LEFT_BACK_CORNER_3D:
1161 starId = getVertexStarE(p.data(), localStarId);
1163 case VertexPosition::TOP_RIGHT_BACK_CORNER_3D:
1164 starId = getVertexStarF(p.data(), localStarId);
1166 case VertexPosition::BOTTOM_LEFT_BACK_CORNER_3D:
1167 starId = getVertexStarG(p.data(), localStarId);
1169 case VertexPosition::BOTTOM_RIGHT_BACK_CORNER_3D:
1170 starId = getVertexStarH(p.data(), localStarId);
1172 case VertexPosition::CENTER_2D:
1173 starId = getVertexStar2dABCD(p.data(), localStarId);
1175 case VertexPosition::TOP_EDGE_2D:
1176 starId = getVertexStar2dAB(p.data(), localStarId);
1178 case VertexPosition::BOTTOM_EDGE_2D:
1179 starId = getVertexStar2dCD(p.data(), localStarId);
1181 case VertexPosition::LEFT_EDGE_2D:
1182 starId = getVertexStar2dAC(p.data(), localStarId);
1184 case VertexPosition::RIGHT_EDGE_2D:
1185 starId = getVertexStar2dBD(p.data(), localStarId);
1187 case VertexPosition::TOP_LEFT_CORNER_2D:
1188 starId = getVertexStar2dA(p.data(), localStarId);
1190 case VertexPosition::TOP_RIGHT_CORNER_2D:
1191 starId = getVertexStar2dB(p.data(), localStarId);
1193 case VertexPosition::BOTTOM_LEFT_CORNER_2D:
1194 starId = getVertexStar2dC(p.data(), localStarId);
1196 case VertexPosition::BOTTOM_RIGHT_CORNER_2D:
1197 starId = getVertexStar2dD(p.data(), localStarId);
1207const vector<vector<SimplexId>> *
1210 if(vertexStarList_.empty()) {
1212 vertexStarList_.resize(vertexNumber_);
1213 for(
SimplexId i = 0; i < vertexNumber_; ++i) {
1219 printMsg(
"Built " + to_string(vertexNumber_) +
" vertex stars.", 1,
1223 return &vertexStarList_;
1226template <
typename Derived>
1233 if(dimensionality_ == 3) {
1234 const auto &p = this->underlying().getVertexCoords(vertexId);
1236 x = origin_[0] + spacing_[0] * p[0];
1237 y = origin_[1] + spacing_[1] * p[1];
1238 z = origin_[2] + spacing_[2] * p[2];
1239 }
else if(dimensionality_ == 2) {
1240 const auto &p = this->underlying().getVertexCoords(vertexId);
1242 if(dimensions_[0] > 1 and dimensions_[1] > 1) {
1243 x = origin_[0] + spacing_[0] * p[0];
1244 y = origin_[1] + spacing_[1] * p[1];
1246 }
else if(dimensions_[1] > 1 and dimensions_[2] > 1) {
1248 y = origin_[1] + spacing_[1] * p[0];
1249 z = origin_[2] + spacing_[2] * p[1];
1250 }
else if(dimensions_[0] > 1 and dimensions_[2] > 1) {
1251 x = origin_[0] + spacing_[0] * p[0];
1253 z = origin_[2] + spacing_[2] * p[1];
1255 }
else if(dimensionality_ == 1) {
1256 if(dimensions_[0] > 1) {
1257 x = origin_[0] + spacing_[0] * vertexId;
1260 }
else if(dimensions_[1] > 1) {
1262 y = origin_[1] + spacing_[1] * vertexId;
1264 }
else if(dimensions_[2] > 1) {
1267 z = origin_[2] + spacing_[2] * vertexId;
1274template <
typename Derived>
1277 const int &localVertexId,
1279#ifndef TTK_ENABLE_KAMIKAZE
1280 if(edgeId < 0 or edgeId >= edgeNumber_)
1282 if(localVertexId < 0 or localVertexId >= 2)
1286 const auto &p = this->underlying().getEdgeCoords(edgeId);
1289 if(isAccelerated_) {
1290 const auto tmp = p[0] + (p[1] << div_[0]) + (p[2] << div_[1]);
1291 return (localVertexId == 0) ? tmp + a : tmp + b;
1293 const auto tmp = p[0] + (p[1] * vshift_[0]) + (p[2] * vshift_[1]);
1294 return (localVertexId == 0) ? tmp + a : tmp + b;
1299 if(isAccelerated_) {
1300 const auto tmp = p[0] + (p[1] << div_[0]);
1301 return localVertexId == 0 ? tmp + a : tmp + b;
1303 const auto tmp = p[0] + (p[1] * vshift_[0]);
1304 return localVertexId == 0 ? tmp + a : tmp + b;
1308 switch(this->underlying().getEdgePosition(edgeId)) {
1310 vertexId = helper3d(0, 1);
1313 vertexId = helper3d(0, vshift_[0]);
1316 vertexId = helper3d(0, vshift_[1]);
1319 vertexId = helper3d(1, vshift_[0]);
1322 vertexId = helper3d(0, vshift_[0] + vshift_[1]);
1325 vertexId = helper3d(1, vshift_[1]);
1327 case EdgePosition::D4_3D:
1328 vertexId = helper3d(1, vshift_[0] + vshift_[1]);
1332 vertexId = helper2d(0, 1);
1335 vertexId = helper2d(0, vshift_[0]);
1337 case EdgePosition::D1_2D:
1338 vertexId = helper2d(1, vshift_[0]);
1341 case EdgePosition::FIRST_EDGE_1D:
1342 vertexId = localVertexId == 0 ? 0 : 1;
1344 case EdgePosition::LAST_EDGE_1D:
1345 vertexId = localVertexId == 0 ? edgeNumber_ - 1 : edgeNumber_;
1347 case EdgePosition::CENTER_1D:
1348 vertexId = localVertexId == 0 ? edgeId : edgeId + 1;
1355const vector<std::array<SimplexId, 2>> *
1356 ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(
getEdges)() {
1358 if(edgeList_.empty()) {
1361 edgeList_.resize(edgeNumber_);
1362 for(
SimplexId i = 0; i < edgeNumber_; ++i) {
1364 getEdgeVertexInternal(i, 0, id0);
1365 getEdgeVertexInternal(i, 1, id1);
1366 edgeList_[i] = {id0, id1};
1370 "Built " + to_string(edgeNumber_) +
" edges.", 1, t.
getElapsedTime(), 1);
1376template <
typename Derived>
1379#ifndef TTK_ENABLE_KAMIKAZE
1380 if(edgeId < 0 or edgeId >= edgeNumber_)
1384 switch(this->underlying().getEdgePosition(edgeId)) {
1385 case EdgePosition::L_xnn_3D:
1386 case EdgePosition::H_nyn_3D:
1387 case EdgePosition::P_nnz_3D:
1388 case EdgePosition::D4_3D:
1390 case EdgePosition::L_x0n_3D:
1391 case EdgePosition::L_xNn_3D:
1392 case EdgePosition::L_xn0_3D:
1393 case EdgePosition::L_xnN_3D:
1394 case EdgePosition::H_ny0_3D:
1395 case EdgePosition::H_nyN_3D:
1396 case EdgePosition::H_0yn_3D:
1397 case EdgePosition::H_Nyn_3D:
1398 case EdgePosition::P_n0z_3D:
1399 case EdgePosition::P_nNz_3D:
1400 case EdgePosition::P_0nz_3D:
1401 case EdgePosition::P_Nnz_3D:
1402 case EdgePosition::D1_xyn_3D:
1403 case EdgePosition::D2_nyz_3D:
1404 case EdgePosition::D3_xnz_3D:
1406 case EdgePosition::L_x00_3D:
1407 case EdgePosition::L_xNN_3D:
1408 case EdgePosition::H_0yN_3D:
1409 case EdgePosition::H_Ny0_3D:
1410 case EdgePosition::P_0Nz_3D:
1411 case EdgePosition::P_N0z_3D:
1412 case EdgePosition::D1_xy0_3D:
1413 case EdgePosition::D1_xyN_3D:
1414 case EdgePosition::D2_0yz_3D:
1415 case EdgePosition::D2_Nyz_3D:
1416 case EdgePosition::D3_x0z_3D:
1417 case EdgePosition::D3_xNz_3D:
1419 case EdgePosition::L_xN0_3D:
1420 case EdgePosition::L_x0N_3D:
1421 case EdgePosition::H_0y0_3D:
1422 case EdgePosition::H_NyN_3D:
1423 case EdgePosition::P_00z_3D:
1424 case EdgePosition::P_NNz_3D:
1425 case EdgePosition::L_xn_2D:
1426 case EdgePosition::H_ny_2D:
1427 case EdgePosition::D1_2D:
1429 case EdgePosition::L_x0_2D:
1430 case EdgePosition::L_xN_2D:
1431 case EdgePosition::H_0y_2D:
1432 case EdgePosition::H_Ny_2D:
1442template <
typename Derived>
1445 const int &localTriangleId,
1447#ifndef TTK_ENABLE_KAMIKAZE
1448 if(localTriangleId < 0
1449 or localTriangleId >= getEdgeTriangleNumberInternal(edgeId))
1453 const auto &p = this->underlying().getEdgeCoords(edgeId);
1455 switch(this->underlying().getEdgePosition(edgeId)) {
1456 case EdgePosition::L_xnn_3D:
1457 triangleId = getEdgeTriangleL_xnn(p.data(), localTriangleId);
1459 case EdgePosition::L_xn0_3D:
1460 triangleId = getEdgeTriangleL_xn0(p.data(), localTriangleId);
1462 case EdgePosition::L_xnN_3D:
1463 triangleId = getEdgeTriangleL_xnN(p.data(), localTriangleId);
1465 case EdgePosition::L_x0n_3D:
1466 triangleId = getEdgeTriangleL_x0n(p.data(), localTriangleId);
1468 case EdgePosition::L_x00_3D:
1469 triangleId = getEdgeTriangleL_x00(p.data(), localTriangleId);
1471 case EdgePosition::L_x0N_3D:
1472 triangleId = getEdgeTriangleL_x0N(p.data(), localTriangleId);
1474 case EdgePosition::L_xNn_3D:
1475 triangleId = getEdgeTriangleL_xNn(p.data(), localTriangleId);
1477 case EdgePosition::L_xN0_3D:
1478 triangleId = getEdgeTriangleL_xN0(p.data(), localTriangleId);
1480 case EdgePosition::L_xNN_3D:
1481 triangleId = getEdgeTriangleL_xNN(p.data(), localTriangleId);
1483 case EdgePosition::H_nyn_3D:
1484 triangleId = getEdgeTriangleH_nyn(p.data(), localTriangleId);
1486 case EdgePosition::H_ny0_3D:
1487 triangleId = getEdgeTriangleH_ny0(p.data(), localTriangleId);
1489 case EdgePosition::H_nyN_3D:
1490 triangleId = getEdgeTriangleH_nyN(p.data(), localTriangleId);
1492 case EdgePosition::H_0yn_3D:
1493 triangleId = getEdgeTriangleH_0yn(p.data(), localTriangleId);
1495 case EdgePosition::H_0y0_3D:
1496 triangleId = getEdgeTriangleH_0y0(p.data(), localTriangleId);
1498 case EdgePosition::H_0yN_3D:
1499 triangleId = getEdgeTriangleH_0yN(p.data(), localTriangleId);
1501 case EdgePosition::H_Nyn_3D:
1502 triangleId = getEdgeTriangleH_Nyn(p.data(), localTriangleId);
1504 case EdgePosition::H_Ny0_3D:
1505 triangleId = getEdgeTriangleH_Ny0(p.data(), localTriangleId);
1507 case EdgePosition::H_NyN_3D:
1508 triangleId = getEdgeTriangleH_NyN(p.data(), localTriangleId);
1510 case EdgePosition::P_nnz_3D:
1511 triangleId = getEdgeTriangleP_nnz(p.data(), localTriangleId);
1513 case EdgePosition::P_n0z_3D:
1514 triangleId = getEdgeTriangleP_n0z(p.data(), localTriangleId);
1516 case EdgePosition::P_nNz_3D:
1517 triangleId = getEdgeTriangleP_nNz(p.data(), localTriangleId);
1519 case EdgePosition::P_0nz_3D:
1520 triangleId = getEdgeTriangleP_0nz(p.data(), localTriangleId);
1522 case EdgePosition::P_00z_3D:
1523 triangleId = getEdgeTriangleP_00z(p.data(), localTriangleId);
1525 case EdgePosition::P_0Nz_3D:
1526 triangleId = getEdgeTriangleP_0Nz(p.data(), localTriangleId);
1528 case EdgePosition::P_Nnz_3D:
1529 triangleId = getEdgeTriangleP_Nnz(p.data(), localTriangleId);
1531 case EdgePosition::P_N0z_3D:
1532 triangleId = getEdgeTriangleP_N0z(p.data(), localTriangleId);
1534 case EdgePosition::P_NNz_3D:
1535 triangleId = getEdgeTriangleP_NNz(p.data(), localTriangleId);
1537 case EdgePosition::D1_xyn_3D:
1538 triangleId = getEdgeTriangleD1_xyn(p.data(), localTriangleId);
1540 case EdgePosition::D1_xy0_3D:
1541 triangleId = getEdgeTriangleD1_xy0(p.data(), localTriangleId);
1543 case EdgePosition::D1_xyN_3D:
1544 triangleId = getEdgeTriangleD1_xyN(p.data(), localTriangleId);
1546 case EdgePosition::D2_nyz_3D:
1547 triangleId = getEdgeTriangleD2_nyz(p.data(), localTriangleId);
1549 case EdgePosition::D2_0yz_3D:
1550 triangleId = getEdgeTriangleD2_0yz(p.data(), localTriangleId);
1552 case EdgePosition::D2_Nyz_3D:
1553 triangleId = getEdgeTriangleD2_Nyz(p.data(), localTriangleId);
1555 case EdgePosition::D3_xnz_3D:
1556 triangleId = getEdgeTriangleD3_xnz(p.data(), localTriangleId);
1558 case EdgePosition::D3_x0z_3D:
1559 triangleId = getEdgeTriangleD3_x0z(p.data(), localTriangleId);
1561 case EdgePosition::D3_xNz_3D:
1562 triangleId = getEdgeTriangleD3_xNz(p.data(), localTriangleId);
1564 case EdgePosition::D4_3D:
1565 triangleId = getEdgeTriangleD4_xyz(p.data(), localTriangleId);
1568 case EdgePosition::L_xn_2D:
1569 triangleId = getEdgeTriangleL_xn(p.data(), localTriangleId);
1571 case EdgePosition::L_x0_2D:
1572 triangleId = getEdgeTriangleL_x0(p.data(), localTriangleId);
1574 case EdgePosition::L_xN_2D:
1575 triangleId = getEdgeTriangleL_xN(p.data(), localTriangleId);
1577 case EdgePosition::H_ny_2D:
1578 triangleId = getEdgeTriangleH_ny(p.data(), localTriangleId);
1580 case EdgePosition::H_0y_2D:
1581 triangleId = getEdgeTriangleH_0y(p.data(), localTriangleId);
1583 case EdgePosition::H_Ny_2D:
1584 triangleId = getEdgeTriangleH_Ny(p.data(), localTriangleId);
1586 case EdgePosition::D1_2D:
1587 triangleId = getEdgeTriangleD1_xy(p.data(), localTriangleId);
1598const vector<vector<SimplexId>> *
1622template <
typename Derived>
1626#ifndef TTK_ENABLE_KAMIKAZE
1631 const auto &p = this->underlying().getEdgeCoords(edgeId);
1633 switch(this->underlying().getEdgePosition(edgeId)) {
1635 linkId = getEdgeLinkL(p.data(), localLinkId);
1638 linkId = getEdgeLinkH(p.data(), localLinkId);
1641 linkId = getEdgeLinkP(p.data(), localLinkId);
1644 linkId = getEdgeLinkD1(p.data(), localLinkId);
1647 linkId = getEdgeLinkD2(p.data(), localLinkId);
1650 linkId = getEdgeLinkD3(p.data(), localLinkId);
1652 case EdgePosition::D4_3D:
1653 linkId = getEdgeLinkD4(p.data(), localLinkId);
1657 linkId = getEdgeLink2dL(p.data(), localLinkId);
1660 linkId = getEdgeLink2dH(p.data(), localLinkId);
1662 case EdgePosition::D1_2D:
1663 linkId = getEdgeLink2dD1(p.data(), localLinkId);
1674const vector<vector<SimplexId>> *
1677 if(edgeLinkList_.empty()) {
1680 edgeLinkList_.resize(edgeNumber_);
1681 for(
SimplexId i = 0; i < edgeNumber_; ++i) {
1687 printMsg(
"Built " + to_string(edgeNumber_) +
" edge links.", 1,
1691 return &edgeLinkList_;
1694template <
typename Derived>
1698#ifndef TTK_ENABLE_KAMIKAZE
1699 if(edgeId < 0 or edgeId >= edgeNumber_)
1703 switch(this->underlying().getEdgePosition(edgeId)) {
1704 case EdgePosition::L_xnn_3D:
1705 case EdgePosition::H_nyn_3D:
1706 case EdgePosition::P_nnz_3D:
1707 case EdgePosition::D4_3D:
1709 case EdgePosition::D1_xyn_3D:
1710 case EdgePosition::D2_nyz_3D:
1711 case EdgePosition::D3_xnz_3D:
1713 case EdgePosition::L_x0n_3D:
1714 case EdgePosition::L_xNn_3D:
1715 case EdgePosition::L_xn0_3D:
1716 case EdgePosition::L_xnN_3D:
1717 case EdgePosition::H_ny0_3D:
1718 case EdgePosition::H_nyN_3D:
1719 case EdgePosition::H_0yn_3D:
1720 case EdgePosition::H_Nyn_3D:
1721 case EdgePosition::P_n0z_3D:
1722 case EdgePosition::P_nNz_3D:
1723 case EdgePosition::P_0nz_3D:
1724 case EdgePosition::P_Nnz_3D:
1726 case EdgePosition::L_x00_3D:
1727 case EdgePosition::L_xNN_3D:
1728 case EdgePosition::H_0yN_3D:
1729 case EdgePosition::H_Ny0_3D:
1730 case EdgePosition::P_0Nz_3D:
1731 case EdgePosition::P_N0z_3D:
1732 case EdgePosition::D1_xy0_3D:
1733 case EdgePosition::D1_xyN_3D:
1734 case EdgePosition::D2_0yz_3D:
1735 case EdgePosition::D2_Nyz_3D:
1736 case EdgePosition::D3_x0z_3D:
1737 case EdgePosition::D3_xNz_3D:
1738 case EdgePosition::L_xn_2D:
1739 case EdgePosition::H_ny_2D:
1740 case EdgePosition::D1_2D:
1742 case EdgePosition::L_xN0_3D:
1743 case EdgePosition::L_x0N_3D:
1744 case EdgePosition::H_0y0_3D:
1745 case EdgePosition::H_NyN_3D:
1746 case EdgePosition::P_00z_3D:
1747 case EdgePosition::P_NNz_3D:
1748 case EdgePosition::L_x0_2D:
1749 case EdgePosition::L_xN_2D:
1750 case EdgePosition::H_0y_2D:
1751 case EdgePosition::H_Ny_2D:
1761template <
typename Derived>
1765#ifndef TTK_ENABLE_KAMIKAZE
1770 const auto &p = this->underlying().getEdgeCoords(edgeId);
1772 switch(this->underlying().getEdgePosition(edgeId)) {
1774 starId = getEdgeStarL(p.data(), localStarId);
1777 starId = getEdgeStarH(p.data(), localStarId);
1780 starId = getEdgeStarP(p.data(), localStarId);
1783 starId = getEdgeStarD1(p.data(), localStarId);
1786 starId = getEdgeStarD2(p.data(), localStarId);
1789 starId = getEdgeStarD3(p.data(), localStarId);
1791 case EdgePosition::D4_3D:
1793 = p[2] * tetshift_[1] + p[1] * tetshift_[0] + p[0] * 6 + localStarId;
1797 starId = getEdgeStar2dL(p.data(), localStarId);
1800 starId = getEdgeStar2dH(p.data(), localStarId);
1802 case EdgePosition::D1_2D:
1803 starId = p[0] * 2 + p[1] * tshift_[0] + localStarId;
1814const vector<vector<SimplexId>> *
1817 if(edgeStarList_.empty()) {
1820 edgeStarList_.resize(edgeNumber_);
1821 for(
SimplexId i = 0; i < edgeNumber_; ++i) {
1827 printMsg(
"Built " + to_string(edgeNumber_) +
" edge stars.", 1,
1831 return &edgeStarList_;
1834template <
typename Derived>
1837 const int &localVertexId,
1839#ifndef TTK_ENABLE_KAMIKAZE
1840 if(triangleId < 0 or triangleId >= triangleNumber_)
1842 if(localVertexId < 0 or localVertexId >= 3)
1862 const auto &p = this->underlying().getTriangleCoords(triangleId);
1865 switch(this->underlying().getTrianglePosition(triangleId)) {
1866 case TrianglePosition::F_3D:
1867 vertexId = getTriangleVertexF(p.data(), localVertexId);
1869 case TrianglePosition::H_3D:
1870 vertexId = getTriangleVertexH(p.data(), localVertexId);
1872 case TrianglePosition::C_3D:
1873 vertexId = getTriangleVertexC(p.data(), localVertexId);
1875 case TrianglePosition::D1_3D:
1876 vertexId = getTriangleVertexD1(p.data(), localVertexId);
1878 case TrianglePosition::D2_3D:
1879 vertexId = getTriangleVertexD2(p.data(), localVertexId);
1881 case TrianglePosition::D3_3D:
1882 vertexId = getTriangleVertexD3(p.data(), localVertexId);
1884 case TrianglePosition::TOP_2D:
1885 switch(localVertexId) {
1888 vertexId = p[0] / 2 + p[1] * vshift_[0];
1891 vertexId = p[0] / 2 + p[1] * vshift_[0] + 1;
1894 vertexId = p[0] / 2 + p[1] * vshift_[0] + vshift_[0];
1898 case TrianglePosition::BOTTOM_2D:
1899 switch(localVertexId) {
1902 vertexId = p[0] / 2 + p[1] * vshift_[0] + 1;
1905 vertexId = p[0] / 2 + p[1] * vshift_[0] + vshift_[0] + 1;
1908 vertexId = p[0] / 2 + p[1] * vshift_[0] + vshift_[0];
1916template <
typename Derived>
1919 const int &localEdgeId,
1921#ifndef TTK_ENABLE_KAMIKAZE
1922 if(triangleId < 0 or triangleId >= triangleNumber_)
1924 if(localEdgeId < 0 or localEdgeId >= 3)
1928 const auto &p = this->underlying().getTriangleCoords(triangleId);
1929 const auto par = triangleId % 2;
1932 switch(this->underlying().getTrianglePosition(triangleId)) {
1933 case TrianglePosition::F_3D:
1934 edgeId = (par == 1) ? getTriangleEdgeF_1(p.data(), localEdgeId)
1935 : getTriangleEdgeF_0(p.data(), localEdgeId);
1937 case TrianglePosition::H_3D:
1938 edgeId = (par == 1) ? getTriangleEdgeH_1(p.data(), localEdgeId)
1939 : getTriangleEdgeH_0(p.data(), localEdgeId);
1941 case TrianglePosition::C_3D:
1942 edgeId = (par == 1) ? getTriangleEdgeC_1(p.data(), localEdgeId)
1943 : getTriangleEdgeC_0(p.data(), localEdgeId);
1945 case TrianglePosition::D1_3D:
1946 edgeId = (par == 1) ? getTriangleEdgeD1_1(p.data(), localEdgeId)
1947 : getTriangleEdgeD1_0(p.data(), localEdgeId);
1949 case TrianglePosition::D2_3D:
1950 edgeId = (par == 1) ? getTriangleEdgeD2_1(p.data(), localEdgeId)
1951 : getTriangleEdgeD2_0(p.data(), localEdgeId);
1953 case TrianglePosition::D3_3D:
1954 edgeId = (par == 1) ? getTriangleEdgeD3_1(p.data(), localEdgeId)
1955 : getTriangleEdgeD3_0(p.data(), localEdgeId);
1957 case TrianglePosition::TOP_2D:
1958 switch(localEdgeId) {
1961 edgeId = p[0] / 2 + p[1] * eshift_[0];
1964 edgeId = esetshift_[0] + p[0] / 2 + p[1] * eshift_[2];
1967 edgeId = esetshift_[1] + p[0] / 2 + p[1] * eshift_[4];
1971 case TrianglePosition::BOTTOM_2D:
1972 switch(localEdgeId) {
1975 edgeId = p[0] / 2 + (p[1] + 1) * eshift_[0];
1978 edgeId = esetshift_[0] + (p[0] + 1) / 2 + p[1] * eshift_[2];
1981 edgeId = esetshift_[1] + p[0] / 2 + p[1] * eshift_[4];
1990 vector<vector<SimplexId>> &edges)
const {
1994 for(
int j = 0; j < 3; ++j)
2000const vector<vector<SimplexId>> *
2014const vector<std::array<SimplexId, 3>> *
2017 if(triangleList_.empty()) {
2020 triangleList_.resize(triangleNumber_);
2021 for(
SimplexId i = 0; i < triangleNumber_; ++i) {
2022 for(
int j = 0; j < 3; ++j)
2023 getTriangleVertexInternal(i, j, triangleList_[i][j]);
2026 printMsg(
"Built " + to_string(triangleNumber_) +
" triangles.", 1,
2030 return &triangleList_;
2033template <
typename Derived>
2036 const int &localLinkId,
2039#ifndef TTK_ENABLE_KAMIKAZE
2044 const auto &p = this->underlying().getTriangleCoords(triangleId);
2046 switch(this->underlying().getTrianglePosition(triangleId)) {
2047 case TrianglePosition::F_3D:
2048 linkId = getTriangleLinkF(p.data(), localLinkId);
2050 case TrianglePosition::H_3D:
2051 linkId = getTriangleLinkH(p.data(), localLinkId);
2053 case TrianglePosition::C_3D:
2054 linkId = getTriangleLinkC(p.data(), localLinkId);
2056 case TrianglePosition::D1_3D:
2057 linkId = getTriangleLinkD1(p.data(), localLinkId);
2059 case TrianglePosition::D2_3D:
2060 linkId = getTriangleLinkD2(p.data(), localLinkId);
2062 case TrianglePosition::D3_3D:
2063 linkId = getTriangleLinkD3(p.data(), localLinkId);
2078const vector<vector<SimplexId>> *
2080 if(triangleLinkList_.empty()) {
2083 triangleLinkList_.resize(triangleNumber_);
2084 for(
SimplexId i = 0; i < triangleNumber_; ++i) {
2090 printMsg(
"Built " + to_string(triangleNumber_) +
" triangle links.", 1,
2093 return &triangleLinkList_;
2096template <
typename Derived>
2100#ifndef TTK_ENABLE_KAMIKAZE
2101 if(triangleId < 0 or triangleId >= triangleNumber_)
2105 const auto &p = this->underlying().getTriangleCoords(triangleId);
2107 switch(this->underlying().getTrianglePosition(triangleId)) {
2108 case TrianglePosition::F_3D:
2109 return (p[2] > 0 and p[2] < nbvoxels_[2]) ? 2 : 1;
2110 case TrianglePosition::H_3D:
2111 return (p[1] > 0 and p[1] < nbvoxels_[1]) ? 2 : 1;
2112 case TrianglePosition::C_3D:
2113 return (p[0] < 2 or p[0] >= (dimensions_[0] * 2 - 2)) ? 1 : 2;
2115 case TrianglePosition::D1_3D:
2116 case TrianglePosition::D2_3D:
2117 case TrianglePosition::D3_3D:
2125template <
typename Derived>
2128 const int &localStarId,
2131#ifndef TTK_ENABLE_KAMIKAZE
2136 const auto &p = this->underlying().getTriangleCoords(triangleId);
2138 switch(this->underlying().getTrianglePosition(triangleId)) {
2139 case TrianglePosition::F_3D:
2140 starId = getTriangleStarF(p.data(), localStarId);
2142 case TrianglePosition::H_3D:
2143 starId = getTriangleStarH(p.data(), localStarId);
2145 case TrianglePosition::C_3D:
2146 starId = getTriangleStarC(p.data(), localStarId);
2148 case TrianglePosition::D1_3D:
2149 starId = getTriangleStarD1(p.data(), localStarId);
2151 case TrianglePosition::D2_3D:
2152 starId = getTriangleStarD2(p.data(), localStarId);
2154 case TrianglePosition::D3_3D:
2155 starId = getTriangleStarD3(p.data(), localStarId);
2165const vector<vector<SimplexId>> *
2168 if(triangleStarList_.empty()) {
2171 triangleStarList_.resize(triangleNumber_);
2172 for(
SimplexId i = 0; i < triangleNumber_; ++i) {
2178 printMsg(
"Built " + to_string(triangleNumber_) +
" triangle stars.", 1,
2181 return &triangleStarList_;
2184template <
typename Derived>
2187#ifndef TTK_ENABLE_KAMIKAZE
2188 if(triangleId < 0 or triangleId >= triangleNumber_)
2192 if(dimensionality_ == 2) {
2193 const auto &p = this->underlying().getTriangleCoords(triangleId);
2197 if(p[0] / 2 == nbvoxels_[Di_] - 1 and p[1] == nbvoxels_[Dj_] - 1)
2199 else if(p[0] / 2 == nbvoxels_[Di_] - 1 or p[1] == nbvoxels_[Dj_] - 1)
2204 if(p[0] == 0 and p[1] == 0)
2206 else if(p[0] == 0 or p[1] == 0)
2216template <
typename Derived>
2219 const int &localNeighborId,
2221#ifndef TTK_ENABLE_KAMIKAZE
2222 if(localNeighborId < 0
2223 or localNeighborId >= getTriangleNeighborNumber(triangleId))
2229 if(dimensionality_ == 2) {
2230 const auto &p = this->underlying().getTriangleCoords(triangleId);
2234 if(p[0] / 2 == nbvoxels_[Di_] - 1 and p[1] == nbvoxels_[Dj_] - 1)
2235 neighborId = triangleId - 1;
2236 else if(p[0] / 2 == nbvoxels_[Di_] - 1) {
2237 switch(localNeighborId) {
2239 neighborId = triangleId - 1;
2242 neighborId = triangleId + tshift_[0] - 1;
2245 }
else if(p[1] == nbvoxels_[Dj_] - 1) {
2246 switch(localNeighborId) {
2248 neighborId = triangleId - 1;
2251 neighborId = triangleId + 1;
2255 switch(localNeighborId) {
2257 neighborId = triangleId - 1;
2260 neighborId = triangleId + 1;
2263 neighborId = triangleId + tshift_[0] - 1;
2268 if(p[0] == 0 and p[1] == 0)
2269 neighborId = triangleId + 1;
2270 else if(p[0] == 0) {
2271 switch(localNeighborId) {
2273 neighborId = triangleId + 1;
2276 neighborId = triangleId - tshift_[0] + 1;
2279 }
else if(p[1] == 0) {
2280 switch(localNeighborId) {
2282 neighborId = triangleId + 1;
2285 neighborId = triangleId - 1;
2289 switch(localNeighborId) {
2291 neighborId = triangleId + 1;
2294 neighborId = triangleId - 1;
2297 neighborId = triangleId - tshift_[0] + 1;
2308 vector<vector<SimplexId>> &neighbors) {
2318template <
typename Derived>
2321#ifndef TTK_ENABLE_KAMIKAZE
2322 if(tetId < 0 or tetId >= tetrahedronNumber_)
2324 if(localVertexId < 0 or localVertexId >= 4)
2330 if(dimensionality_ == 3) {
2332 const auto &c = this->underlying().getTetrahedronCoords(tetId);
2333 const auto p{c.data()};
2337 vertexId = getTetrahedronVertexABCG(p, localVertexId);
2340 vertexId = getTetrahedronVertexBCDG(p, localVertexId);
2343 vertexId = getTetrahedronVertexABEG(p, localVertexId);
2346 vertexId = getTetrahedronVertexBEFG(p, localVertexId);
2349 vertexId = getTetrahedronVertexBFGH(p, localVertexId);
2352 vertexId = getTetrahedronVertexBDGH(p, localVertexId);
2359template <
typename Derived>
2362#ifndef TTK_ENABLE_KAMIKAZE
2363 if(tetId < 0 or tetId >= tetrahedronNumber_)
2365 if(localEdgeId < 0 or localEdgeId >= 6)
2371 if(dimensionality_ == 3) {
2373 const auto &c = this->underlying().getTetrahedronCoords(tetId);
2374 const auto p{c.data()};
2378 edgeId = getTetrahedronEdgeABCG(p, localEdgeId);
2381 edgeId = getTetrahedronEdgeBCDG(p, localEdgeId);
2384 edgeId = getTetrahedronEdgeABEG(p, localEdgeId);
2387 edgeId = getTetrahedronEdgeBEFG(p, localEdgeId);
2390 edgeId = getTetrahedronEdgeBFGH(p, localEdgeId);
2393 edgeId = getTetrahedronEdgeBDGH(p, localEdgeId);
2402 vector<vector<SimplexId>> &edges)
const {
2406 for(
int j = 0; j < 6; ++j)
2413template <
typename Derived>
2416 const int &localTriangleId,
2418#ifndef TTK_ENABLE_KAMIKAZE
2419 if(tetId < 0 or tetId >= tetrahedronNumber_)
2421 if(localTriangleId < 0 or localTriangleId >= 4)
2427 if(dimensionality_ == 3) {
2429 const auto &c = this->underlying().getTetrahedronCoords(tetId);
2430 const auto p{c.data()};
2434 triangleId = getTetrahedronTriangleABCG(p, localTriangleId);
2437 triangleId = getTetrahedronTriangleBCDG(p, localTriangleId);
2440 triangleId = getTetrahedronTriangleABEG(p, localTriangleId);
2443 triangleId = getTetrahedronTriangleBEFG(p, localTriangleId);
2446 triangleId = getTetrahedronTriangleBFGH(p, localTriangleId);
2449 triangleId = getTetrahedronTriangleBDGH(p, localTriangleId);
2458 vector<vector<SimplexId>> &triangles)
const {
2461 triangles[i].resize(4);
2462 for(
int j = 0; j < 4; ++j)
2469template <
typename Derived>
2472#ifndef TTK_ENABLE_KAMIKAZE
2473 if(tetId < 0 or tetId >= tetrahedronNumber_)
2477 if(dimensionality_ == 3) {
2479 const auto &c = this->underlying().getTetrahedronCoords(tetId);
2480 const auto p{c.data()};
2484 if(p[0] == 0 and p[2] == 0)
2486 else if(p[0] == 0 or p[2] == 0)
2492 if(p[1] == nbvoxels_[1] - 1 and p[2] == 0)
2494 else if(p[1] == nbvoxels_[1] - 1 or p[2] == 0)
2500 if(p[0] == 0 and p[1] == 0)
2502 else if(p[0] == 0 or p[1] == 0)
2508 if(p[1] == 0 and p[2] == nbvoxels_[2] - 1)
2510 else if(p[1] == 0 or p[2] == nbvoxels_[2] - 1)
2516 if(p[0] == nbvoxels_[0] - 1 and p[2] == nbvoxels_[2] - 1)
2518 else if(p[0] == nbvoxels_[0] - 1 or p[2] == nbvoxels_[2] - 1)
2524 if(p[0] == nbvoxels_[0] - 1 and p[1] == nbvoxels_[1] - 1)
2526 else if(p[0] == nbvoxels_[0] - 1 or p[1] == nbvoxels_[1] - 1)
2537template <
typename Derived>
2540 const int &localNeighborId,
2542#ifndef TTK_ENABLE_KAMIKAZE
2543 if(localNeighborId < 0
2544 or localNeighborId >= getTetrahedronNeighborNumber(tetId))
2550 if(dimensionality_ == 3) {
2552 const auto &c = this->underlying().getTetrahedronCoords(tetId);
2553 const auto p{c.data()};
2557 neighborId = getTetrahedronNeighborABCG(tetId, p, localNeighborId);
2560 neighborId = getTetrahedronNeighborBCDG(tetId, p, localNeighborId);
2563 neighborId = getTetrahedronNeighborABEG(tetId, p, localNeighborId);
2566 neighborId = getTetrahedronNeighborBEFG(tetId, p, localNeighborId);
2569 neighborId = getTetrahedronNeighborBFGH(tetId, p, localNeighborId);
2572 neighborId = getTetrahedronNeighborBDGH(tetId, p, localNeighborId);
2581 vector<vector<SimplexId>> &neighbors) {
2594 return dimensionality_ + 1;
2599 const int &localVertexId,
2602 if(dimensionality_ == 3)
2603 getTetrahedronVertex(cellId, localVertexId, vertexId);
2604 else if(dimensionality_ == 2)
2605 getTriangleVertexInternal(cellId, localVertexId, vertexId);
2606 else if(dimensionality_ == 1)
2607 getEdgeVertexInternal(cellId, localVertexId, vertexId);
2623 const int &localEdgeId,
2653 const int &localTriangleId,
2661const vector<vector<SimplexId>> *
2678 if(dimensionality_ == 3)
2679 return getTetrahedronNeighborNumber(cellId);
2680 else if(dimensionality_ == 2)
2681 return getTriangleNeighborNumber(cellId);
2682 else if(dimensionality_ == 1) {
2683 printErr(
"getCellNeighborNumber() not implemented in 1D! (TODO)");
2692 const int &localNeighborId,
2694 if(dimensionality_ == 3)
2695 getTetrahedronNeighbor(cellId, localNeighborId, neighborId);
2696 else if(dimensionality_ == 2)
2697 getTriangleNeighbor(cellId, localNeighborId, neighborId);
2698 else if(dimensionality_ == 1) {
2699 printErr(
"getCellNeighbor() not implemented in 1D! (TODO)");
2706const vector<vector<SimplexId>> *
2708 if(cellNeighborList_.empty()) {
2711 if(dimensionality_ == 3)
2712 getTetrahedronNeighbors(cellNeighborList_);
2713 else if(dimensionality_ == 2)
2714 getTriangleNeighbors(cellNeighborList_);
2715 else if(dimensionality_ == 1) {
2716 printErr(
"getCellNeighbors() not implemented in 1D! (TODO)");
2720 printMsg(
"Built " + to_string(cellNumber_) +
" cell neighbors.", 1,
2724 return &cellNeighborList_;
3071#ifdef TTK_ENABLE_MPI
3073int ttk::ImplicitTriangulation::preconditionDistributedCells() {
3074 if(this->hasPreconditionedDistributedCells_) {
3077 if(!ttk::hasInitializedMPI()) {
3080 if(this->cellGhost_ ==
nullptr) {
3081 if(ttk::isRunningWithMPI()) {
3082 this->printErr(
"Missing cell ghost array!");
3090 const auto nLocCells{this->getNumberOfCells()};
3093 const int nTetraPerCube{this->dimensionality_ == 3 ? 6 : 2};
3094 std::vector<unsigned char> fillCells(nLocCells / nTetraPerCube);
3102 this->localGridOffset_[0] + this->dimensions_[0], this->localGridOffset_[0],
3103 this->localGridOffset_[1] + this->dimensions_[1], this->localGridOffset_[1],
3104 this->localGridOffset_[2] + this->dimensions_[2], this->localGridOffset_[2],
3107 for(
SimplexId lcid = 0; lcid < nLocCells; ++lcid) {
3109 if(this->cellGhost_[lcid / nTetraPerCube] == 1) {
3113 std::array<SimplexId, 3> p{};
3114 if(this->dimensionality_ == 3) {
3115 this->tetrahedronToPosition(lcid, p.data());
3116 }
else if(this->dimensionality_ == 2) {
3117 this->triangleToPosition2d(lcid, p.data());
3124 p[0] += this->localGridOffset_[0];
3125 p[1] += this->localGridOffset_[1];
3126 p[2] += this->localGridOffset_[2];
3128 if(p[0] < localBBox[0]) {
3129 localBBox[0] = p[0];
3131 if(p[0] > localBBox[1]) {
3132 localBBox[1] = p[0];
3134 if(p[1] < localBBox[2]) {
3135 localBBox[2] = p[1];
3137 if(p[1] > localBBox[3]) {
3138 localBBox[3] = p[1];
3140 if(p[2] < localBBox[4]) {
3141 localBBox[4] = p[2];
3143 if(p[2] > localBBox[5]) {
3144 localBBox[5] = p[2];
3151 for(
size_t i = 0; i < this->neighborRanks_.size(); ++i) {
3152 const auto neigh{this->neighborRanks_[i]};
3153 MPI_Sendrecv(this->neighborCellBBoxes_[
ttk::MPIrank_].data(), 6,
3155 this->neighborCellBBoxes_[neigh].data(), 6,
3156 ttk::getMPIType(
SimplexId{}), neigh, neigh, ttk::MPIcomm_,
3160 this->hasPreconditionedDistributedCells_ =
true;
3165void ttk::ImplicitTriangulation::createMetaGrid(
const double *
const bounds) {
3168 if(!ttk::isRunningWithMPI()) {
3173 if(this->metaGrid_ !=
nullptr) {
3178 std::array<double, 6> tempBounds = {
3179 bounds[0], bounds[2], bounds[4], bounds[1], bounds[3], bounds[5],
3181 std::array<double, 6> tempGlobalBounds{};
3184 MPI_Allreduce(tempBounds.data(), tempGlobalBounds.data(), 3, MPI_DOUBLE,
3185 MPI_MIN, ttk::MPIcomm_);
3187 MPI_Allreduce(&tempBounds[3], &tempGlobalBounds[3], 3, MPI_DOUBLE, MPI_MAX,
3191 std::array<double, 6> globalBounds{
3192 tempGlobalBounds[0], tempGlobalBounds[3], tempGlobalBounds[1],
3193 tempGlobalBounds[4], tempGlobalBounds[2], tempGlobalBounds[5],
3196 const std::array<int, 3> dimensions = {
3198 std::round((globalBounds[1] - globalBounds[0]) / this->spacing_[0]))
3201 std::round((globalBounds[3] - globalBounds[2]) / this->spacing_[1]))
3204 std::round((globalBounds[5] - globalBounds[4]) / this->spacing_[2]))
3208 this->localGridOffset_ = {
3210 std::round((this->origin_[0] - globalBounds[0]) / this->spacing_[0])),
3212 std::round((this->origin_[1] - globalBounds[2]) / this->spacing_[1])),
3214 std::round((this->origin_[2] - globalBounds[4]) / this->spacing_[2])),
3217 this->metaGrid_ = std::make_shared<ImplicitNoPreconditions>();
3218 this->metaGrid_->setInputGrid(globalBounds[0], globalBounds[1],
3219 globalBounds[2], this->spacing_[0],
3220 this->spacing_[1], this->spacing_[2],
3221 dimensions[0], dimensions[1], dimensions[2]);
3222 this->metaGrid_->preconditionBoundaryVertices();
3223 this->metaGrid_->preconditionBoundaryEdges();
3224 this->metaGrid_->preconditionBoundaryTriangles();
3227std::array<SimplexId, 3>
3228 ttk::ImplicitTriangulation::getVertGlobalCoords(
const SimplexId lvid)
const {
3231 std::array<SimplexId, 3> p{};
3232 if(this->dimensionality_ == 3) {
3233 this->vertexToPosition(lvid, p.data());
3234 }
else if(this->dimensionality_ == 2) {
3235 this->vertexToPosition2d(lvid, p.data());
3239 p[0] += this->localGridOffset_[0];
3240 p[1] += this->localGridOffset_[1];
3241 p[2] += this->localGridOffset_[2];
3246std::array<SimplexId, 3>
3247 ttk::ImplicitTriangulation::getVertLocalCoords(
const SimplexId gvid)
const {
3250 std::array<SimplexId, 3> p{};
3251 if(this->dimensionality_ == 3) {
3252 this->metaGrid_->vertexToPosition(gvid, p.data());
3253 }
else if(this->dimensionality_ == 2) {
3254 this->metaGrid_->vertexToPosition2d(gvid, p.data());
3258 p[0] -= this->localGridOffset_[0];
3259 p[1] -= this->localGridOffset_[1];
3260 p[2] -= this->localGridOffset_[2];
3265bool ImplicitTriangulation::isVertexOnGlobalBoundaryInternal(
3268 if(!ttk::isRunningWithMPI()) {
3272#ifndef TTK_ENABLE_KAMIKAZE
3277 if(this->metaGrid_ ==
nullptr) {
3282 const auto gvid{this->getVertexGlobalIdInternal(lvid)};
3286 return this->metaGrid_->isVertexOnBoundary(gvid);
3289bool ImplicitTriangulation::isEdgeOnGlobalBoundaryInternal(
3292 if(!ttk::isRunningWithMPI()) {
3296#ifndef TTK_ENABLE_KAMIKAZE
3300 if(this->metaGrid_ ==
nullptr) {
3305 const auto geid{this->getEdgeGlobalIdInternal(leid)};
3309 return this->metaGrid_->isEdgeOnBoundary(geid);
3312bool ImplicitTriangulation::isTriangleOnGlobalBoundaryInternal(
3315 if(!ttk::isRunningWithMPI()) {
3319#ifndef TTK_ENABLE_KAMIKAZE
3323 if(this->metaGrid_ ==
nullptr) {
3328 const auto gtid{this->getTriangleGlobalIdInternal(ltid)};
3332 return this->metaGrid_->isTriangleOnBoundary(gtid);
3335int ttk::ImplicitTriangulation::getCellRankInternal(
3338 const int nTetraPerCube{this->dimensionality_ == 3 ? 6 : 2};
3339 const auto locCubeId{lcid / nTetraPerCube};
3341 if(this->cellGhost_[locCubeId] == 0) {
3345#ifndef TTK_ENABLE_KAMIKAZE
3347 this->printErr(
"Empty neighborsRanks_!");
3353 std::vector<bool> inRank(nVertsCell);
3354 for(
const auto neigh : this->neighborRanks_) {
3355 std::fill(inRank.begin(), inRank.end(),
false);
3356 const auto &bbox{this->neighborCellBBoxes_[neigh]};
3357 for(
SimplexId i = 0; i < nVertsCell; ++i) {
3360 if(this->vertexGhost_[v] == 0) {
3363 const auto p{this->getVertGlobalCoords(v)};
3364 if(p[0] >= bbox[0] && p[0] <= bbox[1] && p[1] >= bbox[2]
3365 && p[1] <= bbox[3] && p[2] >= bbox[4] && p[2] <= bbox[5]) {
3371 inRank.begin(), inRank.end(), [](
const bool v) { return v; })) {
#define TTK_TRIANGULATION_INTERNAL(NAME)
bool ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() isTriangleOnBoundary(const SimplexId &triangleId) const
#define CASE_EDGE_POSITION_P_3D
int ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL() getEdgeStar(const SimplexId &edgeId, const int &localStarId, SimplexId &starId) const
const vector< vector< SimplexId > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getCellNeighbors()
SimplexId ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL() getTriangleStarNumber(const SimplexId &triangleId) const
int ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getCellNeighbor(const SimplexId &cellId, const int &localNeighborId, SimplexId &neighborId) const
int ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL() getVertexStar(const SimplexId &vertexId, const int &localStarId, SimplexId &starId) const
SimplexId ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getTriangleLinkNumber(const SimplexId &triangleId) const
int ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL() getEdgeLink(const SimplexId &edgeId, const int &localLinkId, SimplexId &linkId) const
#define CASE_EDGE_POSITION_D2_3D
#define CASE_EDGE_POSITION_D1_3D
int ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL() getTriangleLink(const SimplexId &triangleId, const int &localLinkId, SimplexId &linkId) const
SimplexId ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getCellVertexNumber(const SimplexId &) const
SimplexId ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL() getEdgeStarNumber(const SimplexId &edgeId) const
#define CASE_EDGE_POSITION_L_2D
#define CASE_EDGE_POSITION_H_2D
int ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL() getVertexNeighbor(const SimplexId &vertexId, const int &localNeighborId, SimplexId &neighborId) const
#define CASE_EDGE_POSITION_H_3D
const vector< vector< SimplexId > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getTriangleLinks()
#define CASE_EDGE_POSITION_L_3D
const vector< vector< SimplexId > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getTriangleStars()
SimplexId ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getVertexLinkNumber(const SimplexId &vertexId) const
SimplexId ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getCellNeighborNumber(const SimplexId &cellId) const
SimplexId ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL() getVertexStarNumber(const SimplexId &vertexId) const
const vector< vector< SimplexId > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getVertexLinks()
const vector< vector< SimplexId > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getEdgeStars()
#define CASE_EDGE_POSITION_D3_3D
bool ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL() isEdgeOnBoundary(const SimplexId &edgeId) const
int ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getCellVertex(const SimplexId &cellId, const int &localVertexId, SimplexId &vertexId) const
SimplexId ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getEdgeLinkNumber(const SimplexId &edgeId) const
const vector< vector< SimplexId > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getVertexNeighbors()
int ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL() getTriangleStar(const SimplexId &triangleId, const int &localStarId, SimplexId &starId) const
const vector< std::array< SimplexId, 3 > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getTriangles()
const vector< vector< SimplexId > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getVertexStars()
int ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL() getVertexPoint(const SimplexId &vertexId, float &x, float &y, float &z) const
const vector< std::array< SimplexId, 2 > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getEdges()
bool ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL() isVertexOnBoundary(const SimplexId &vertexId) const
int ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL() getVertexLink(const SimplexId &vertexId, const int &localLinkId, SimplexId &linkId) const
const vector< vector< SimplexId > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getEdgeLinks()
SimplexId PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL() getVertexNeighborNumber(const SimplexId &vertexId) const
virtual SimplexId getVertexTriangleNumberInternal(const SimplexId &ttkNotUsed(vertexId)) const
virtual SimplexId getVertexNeighborNumber(const SimplexId &vertexId) const
virtual bool isVertexOnBoundary(const SimplexId &vertexId) const
virtual int getVertexTriangleInternal(const SimplexId &ttkNotUsed(vertexId), const int &ttkNotUsed(localTriangleId), SimplexId &ttkNotUsed(triangleId)) const
virtual bool isEdgeOnBoundary(const SimplexId &edgeId) const
std::vector< std::vector< SimplexId > > vertexEdgeList_
std::vector< std::vector< SimplexId > > triangleEdgeVector_
virtual int getTriangleEdgeInternal(const SimplexId &ttkNotUsed(triangleId), const int &ttkNotUsed(localEdgeId), SimplexId &ttkNotUsed(edgeId)) const
virtual SimplexId getEdgeTriangleNumberInternal(const SimplexId &ttkNotUsed(edgeId)) const
virtual int getEdgeTriangleInternal(const SimplexId &ttkNotUsed(edgeId), const int &ttkNotUsed(localTriangleId), SimplexId &ttkNotUsed(triangleId)) const
virtual int getVertexEdgeInternal(const SimplexId &ttkNotUsed(vertexId), const int &ttkNotUsed(localEdgeId), SimplexId &ttkNotUsed(edgeId)) const
std::vector< std::vector< SimplexId > > vertexTriangleList_
std::vector< std::vector< SimplexId > > cellEdgeVector_
std::vector< std::vector< SimplexId > > cellTriangleVector_
std::vector< std::vector< SimplexId > > edgeTriangleList_
void setDebugMsgPrefix(const std::string &prefix)
int printMsg(const std::string &msg, const debug::Priority &priority=debug::Priority::INFO, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cout) const
int getTriangleVertexInternal(const SimplexId &triangleId, const int &localVertexId, SimplexId &vertexId) const override
int getTetrahedronVertex(const SimplexId &tetId, const int &localVertexId, SimplexId &vertexId) const override
int getTetrahedronTriangle(const SimplexId &tetId, const int &id, SimplexId &triangleId) const override
SimplexId getEdgeTriangleNumberInternal(const SimplexId &edgeId) const override
int getVertexEdgeInternal(const SimplexId &vertexId, const int &id, SimplexId &edgeId) const override
int getEdgeVertexInternal(const SimplexId &edgeId, const int &localVertexId, SimplexId &vertexId) const override
SimplexId getVertexTriangleNumberInternal(const SimplexId &vertexId) const override
SimplexId getTriangleNeighborNumber(const SimplexId &triangleId) const override
int getEdgeTriangleInternal(const SimplexId &edgeId, const int &id, SimplexId &triangleId) const override
int getTetrahedronNeighbor(const SimplexId &tetId, const int &localNeighborId, SimplexId &neighborId) const override
int getVertexTriangleInternal(const SimplexId &vertexId, const int &id, SimplexId &triangleId) const override
SimplexId getTetrahedronNeighborNumber(const SimplexId &tetId) const override
int getTriangleNeighbor(const SimplexId &triangleId, const int &localNeighborId, SimplexId &neighborId) const override
int getTriangleEdgeInternal(const SimplexId &triangleId, const int &id, SimplexId &edgeId) const override
int getTetrahedronEdge(const SimplexId &tetId, const int &id, SimplexId &edgeId) const override
std::array< SimplexId, 8 > vertexNeighborGH_
std::array< SimplexId, 4 > vertexNeighbor2dAC_
std::array< SimplexId, 8 > vertexNeighborBF_
std::array< SimplexId, 8 > vertexNeighborBD_
std::array< SimplexId, 3 > vertexNeighbor2dB_
std::array< SimplexId, 7 > vertexNeighborB_
std::array< SimplexId, 6 > vertexNeighborEF_
SimplexId tetrahedronNumber_
std::array< SimplexId, 14 > vertexNeighborABCDEFGH_
const std::vector< std::vector< SimplexId > > * getTriangleEdgesInternal() override
SimplexId getCellEdgeNumberInternal(const SimplexId &cellId) const override
std::array< SimplexId, 8 > vertexNeighborEG_
int getCellTriangleInternal(const SimplexId &cellId, const int &id, SimplexId &triangleId) const override
std::array< SimplexId, 4 > vertexNeighborH_
std::array< SimplexId, 4 > vertexNeighborE_
std::array< SimplexId, 2 > vertexNeighbor2dD_
bool TTK_TRIANGULATION_INTERNAL() isTriangleOnBoundary(const SimplexId &triangleId) const override
const std::vector< std::vector< SimplexId > > * getVertexEdgesInternal() override
std::array< SimplexId, 10 > vertexNeighborAEFB_
virtual int getTriangleNeighbor(const SimplexId &triangleId, const int &localNeighborId, SimplexId &neighborId) const =0
std::array< SimplexId, 6 > vertexNeighbor2dABCD_
std::array< SimplexId, 6 > vertexNeighborFH_
std::array< SimplexId, 6 > vertexNeighborDH_
std::array< SimplexId, 6 > vertexNeighborCD_
const std::vector< std::vector< SimplexId > > * getCellEdgesInternal() override
std::array< SimplexId, 7 > vertexNeighborG_
int setInputGrid(const float &xOrigin, const float &yOrigin, const float &zOrigin, const float &xSpacing, const float &ySpacing, const float &zSpacing, const SimplexId &xDim, const SimplexId &yDim, const SimplexId &zDim) override
int getTetrahedronNeighbors(std::vector< std::vector< SimplexId > > &neighbors)
int TTK_TRIANGULATION_INTERNAL() getCellNeighbor(const SimplexId &cellId, const int &localNeighborId, SimplexId &neighborId) const override
const std::vector< std::vector< SimplexId > > * getVertexTrianglesInternal() override
virtual SimplexId getTetrahedronNeighborNumber(const SimplexId &tetId) const =0
virtual int getTetrahedronNeighbor(const SimplexId &tetId, const int &localNeighborId, SimplexId &neighborId) const =0
std::array< SimplexId, 10 > vertexNeighborAEGC_
virtual int getTetrahedronTriangle(const SimplexId &tetId, const int &id, SimplexId &triangleId) const =0
std::array< SimplexId, 10 > vertexNeighborEFGH_
std::array< SimplexId, 2 > vertexNeighbor2dA_
bool isPowerOfTwo(unsigned long long int v, unsigned long long int &r)
SimplexId TTK_TRIANGULATION_INTERNAL() getNumberOfVertices() const override
SimplexId getVertexEdgeNumberInternal(const SimplexId &vertexId) const override
std::array< SimplexId, 4 > vertexNeighbor2dBD_
std::array< SimplexId, 10 > vertexNeighborBFHD_
int getTriangleNeighbors(std::vector< std::vector< SimplexId > > &neighbors)
std::array< SimplexId, 4 > vertexNeighborD_
SimplexId getNumberOfEdgesInternal() const override
std::array< SimplexId, 4 > vertexNeighborC_
virtual int getTetrahedronEdge(const SimplexId &tetId, const int &id, SimplexId &edgeId) const =0
virtual SimplexId getTriangleNeighborNumber(const SimplexId &triangleId) const =0
int getTetrahedronEdges(std::vector< std::vector< SimplexId > > &edges) const
std::array< SimplexId, 4 > vertexNeighbor2dCD_
std::array< SimplexId, 8 > vertexNeighborCG_
std::array< SimplexId, 3 > vertexNeighbor2dC_
std::array< SimplexId, 6 > vertexNeighborAC_
const std::vector< std::vector< SimplexId > > * getEdgeTrianglesInternal() override
std::array< SimplexId, 10 > vertexNeighborABCD_
std::array< SimplexId, 10 > vertexNeighborGHDC_
std::array< SimplexId, 8 > vertexNeighborAB_
std::array< SimplexId, 6 > vertexNeighborAE_
int getCellEdgeInternal(const SimplexId &cellId, const int &id, SimplexId &edgeId) const override
std::array< SimplexId, 4 > vertexNeighborA_
SimplexId getNumberOfTrianglesInternal() const override
std::array< SimplexId, 4 > vertexNeighborF_
const std::vector< std::vector< SimplexId > > * getCellTrianglesInternal() override
std::array< SimplexId, 4 > vertexNeighbor2dAB_
int preconditionVertexNeighborsInternal() override
~ImplicitTriangulation() override
SimplexId triangleNumber_
int getTetrahedronTriangles(std::vector< std::vector< SimplexId > > &triangles) const
std::array< SimplexId, 3 > dimensions_
COMMON_EXPORTS int MPIsize_
COMMON_EXPORTS int MPIrank_
int SimplexId
Identifier type for simplices of any dimension.
printMsg(debug::output::GREEN+" "+debug::output::ENDCOLOR+debug::output::GREEN+"▒"+debug::output::ENDCOLOR+debug::output::GREEN+"▒▒▒▒▒▒▒▒▒▒▒▒▒░"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)