24 #include "BasicShapes.hpp"
25 #include "customOperators.hpp"
27 #include <bitpit_common.hpp>
39 buffer << static_cast<int> (var);
66 buffer << static_cast<int> (var);
115 std::swap(m_shape, x.m_shape);
116 std::swap(m_origin, x.m_origin);
117 std::swap(m_span, x.m_span);
118 std::swap(m_infLimits, x.m_infLimits);
119 std::swap(m_sdr, x.m_sdr);
120 std::swap(m_sdr_inverse, x.m_sdr_inverse);
121 std::swap(m_scaling, x.m_scaling);
122 std::swap(m_typeCoord, x.m_typeCoord);
142 setScaling(s0,s1,s2);
150 checkSpan(span[0],span[1],span[2]);
151 setScaling(span[0],span[1],span[2]);
164 if(dir<0 || dir>2)
return;
167 bool check = checkInfLimits(orig,dir);
170 setSpan(span[0],span[1],span[2]);
183 for (
int dir=0; dir<3; dir++){
198 double a = norm2(axis0);
199 double b = norm2(axis1);
200 double c = norm2(axis2);
202 bool check = ( a>0.0 && b >0.0 && c > 0.0);
204 assert(
false &&
"one or more 0-vector passed as arguments in BasicShape::SetRefSystem method");
212 double tol = 1.0e-3, val;
213 val = std::abs(dotProduct(axis0,axis1)) + std::abs(dotProduct(axis1,axis2)) + std::abs(dotProduct(axis0,axis2));
216 assert(
false &&
"not orthogonal axes passed as arguments in BasicShape::SetRefSystem method");
234 if(label <0 || label >2 ){
235 assert(
false &&
"no correct label passed as argument in BasicShape::setRefSystem");
239 double a = norm2(axis);
241 assert(
false &&
"0-vector passed as axis argument in BasicShape::SetRefSystem method");
245 m_sdr[label] = axis/a;
247 point_mat[0][0] = point_mat[1][1]= point_mat[2][2]=1.0;
249 int next_label = (label + 1)%3;
250 int fin_label = (label + 2)%3;
252 double pj = dotProduct(point_mat[next_label],
m_sdr[label]);
253 m_sdr[next_label] = point_mat[next_label] - pj*
m_sdr[label];
293 for(
int i=0; i<3; ++i){
294 result[i] = scale[i]*result[i];
357 if(!(geo->isSkdTreeSupported()))
return livector1D(0);
363 searchBvTreeMatches(*(geo->getSkdTree()), geo->getPatch(), elements);
380 std::sort(internals.begin(), internals.end());
383 std::sort(originals.begin(), originals.end());
385 livector1D result(originals.size() - internals.size());
387 auto internal_itr = internals.begin();
388 auto original_itr = originals.begin();
389 while (original_itr != originals.end()) {
390 long origval = *original_itr;
391 if (internal_itr == internals.end() || origval != *internal_itr) {
392 result[counter] = origval;
414 for(
auto & cell : tri->getCells()){
417 result[counter] = id;
421 result.resize(counter);
438 for(
auto & cell : tri->getCells()){
441 result[counter] = id;
445 result.resize(counter);
462 for(
const auto & vert : list){
464 result[counter] = real;
469 result.resize(counter);
484 for(
const auto & vert : list){
486 result[counter] = real;
491 result.resize(counter);
508 for(
auto & vert : tri->getVertices()){
511 result[counter] = id;
515 result.resize(counter);
531 for(
auto & vert : tri->getVertices()){
534 result[counter] = id;
538 result.resize(counter);
561 searchKdTreeMatches(*(geo->getKdTree()), elements);
578 std::sort(internals.begin(), internals.end());
581 std::sort(originals.begin(), originals.end());
583 livector1D result(originals.size() - internals.size());
585 auto internal_itr = internals.begin();
586 auto original_itr = originals.begin();
587 while (original_itr != originals.end()) {
588 long origval = *original_itr;
589 if (internal_itr == internals.end() || origval != *internal_itr) {
590 result[counter] = origval;
607 for(
const auto & val : simplexVert){
620 bitpit::Cell & cell = tri->getCell(indexT);
621 bitpit::ConstProxyVector<long> vIds = cell.getVertexIds();
623 for(
const auto & val: vIds){
638 double tol = 1.0E-12;
640 for(
int i=0; i<3; ++i){
641 check = check && ((temp2[i] > -1.0*tol) && (temp2[i]< (1.0+tol)));
670 for (
auto && val: point){
671 result[counter] = std::fmin(bMax[counter], std::fmax(val,bMin[counter]));
685 void BasicShape::searchKdTreeMatches(bitpit::KdTree<3,bitpit::Vertex,long> & tree,
livector1D & result,
bool squeeze ){
688 std::vector<int> candidates;
689 std::vector< std::pair<int, int> > nodeStackLoc;
691 nodeStackLoc.push_back(std::make_pair(0, 0));
692 while(!nodeStackLoc.empty()){
693 std::pair<int, int> toupleId = nodeStackLoc.back();
694 bitpit::KdNode<bitpit::Vertex, long> & target = tree.nodes[toupleId.first];
695 nodeStackLoc.pop_back();
699 if((check%2 == 0) && (target.lchild_ >= 0)){
700 nodeStackLoc.push_back(std::make_pair(target.lchild_, (toupleId.second) + 1));
702 if((check > 0) && (target.rchild_ >= 0)){
703 nodeStackLoc.push_back(std::make_pair(target.rchild_, (toupleId.second) + 1));
707 if (bitpit::CGElem::intersectPointBox(target.object_->getCoords(),
m_bbox[0],
m_bbox[1], 3)){
708 candidates.push_back(toupleId.first);
713 result.reserve(candidates.size());
714 for (
const auto & idCand : candidates){
715 bitpit::KdNode<bitpit::Vertex, long> & target = tree.nodes[idCand];
717 result.push_back(target.label);
721 result.shrink_to_fit();
734 void BasicShape::searchBvTreeMatches(bitpit::PatchSkdTree & tree, bitpit::PatchKernel * geo,
livector1D & result,
bool squeeze){
736 std::size_t rootId = 0;
738 std::vector<std::size_t> toBeCandidates;
739 toBeCandidates.reserve(geo->getCellCount());
741 std::vector<size_t> nodeStack;
742 nodeStack.push_back(rootId);
743 while(!nodeStack.empty()){
744 std::size_t nodeId = nodeStack.back();
745 const bitpit::SkdNode & node = tree.getNode(nodeId);
746 nodeStack.pop_back();
756 for (
int i = bitpit::SkdNode::CHILD_BEGIN; i != bitpit::SkdNode::CHILD_END; ++i) {
757 bitpit::SkdNode::ChildLocation childLocation =
static_cast<bitpit::SkdNode::ChildLocation
>(i);
758 std::size_t childId = node.getChildId(childLocation);
759 if (childId != bitpit::SkdNode::NULL_ID) {
761 nodeStack.push_back(childId);
765 toBeCandidates.push_back(nodeId);
770 result.reserve(toBeCandidates.size());
771 for (
const auto & idCand : toBeCandidates){
772 const bitpit::SkdNode &node = tree.getNode(idCand);
773 std::vector<long> cellids = node.getCells();
774 for(
long id : cellids){
776 result.push_back(
id);
781 result.shrink_to_fit();
800 if(target[level] <
m_bbox[0][level])
return 1;
801 if(target[level] >
m_bbox[1][level])
return 0;
815 for(std::size_t i=0; i<3; ++i){
816 for(std::size_t j=0; j<3; ++j){
817 out[j][i] = mat[i][j];
832 double det = mat[0][0] * (mat[1][1]*mat[2][2] - mat[2][1]*mat[1][2]) -
833 mat[0][1] * (mat[1][0]*mat[2][2] - mat[2][0]*mat[1][2]) +
834 mat[0][2] * (mat[1][0]*mat[2][1] - mat[2][0]*mat[1][1]);
836 out[0][0] = (mat[1][1]*mat[2][2] - mat[2][1]*mat[1][2])/det;
837 out[0][1] = (mat[0][2]*mat[2][1] - mat[2][2]*mat[0][1])/det;
838 out[0][2] = (mat[0][1]*mat[1][2] - mat[1][1]*mat[0][2])/det;
839 out[1][0] = (mat[1][2]*mat[2][0] - mat[2][2]*mat[1][0])/det;
840 out[1][1] = (mat[0][0]*mat[2][2] - mat[2][0]*mat[0][2])/det;
841 out[1][2] = (mat[0][2]*mat[1][0] - mat[1][2]*mat[0][0])/det;
842 out[2][0] = (mat[1][0]*mat[2][1] - mat[2][0]*mat[1][1])/det;
843 out[2][1] = (mat[0][1]*mat[2][0] - mat[2][1]*mat[0][0])/det;
844 out[2][2] = (mat[0][0]*mat[1][1] - mat[1][0]*mat[0][1])/det;
859 for (std::size_t i = 0; i < 3; i++) {
861 for (std::size_t j = 0; j <3; j++) {
862 out[i] += vec[j]*mat[j][i];
878 for (std::size_t i = 0; i < 3; i++) {
880 for (std::size_t j = 0; j <3; j++) {
881 out[i] += vec[j]*mat[i][j];
896 m_span = {{1.0, 1.0, 1.0}};
908 setSpan(span[0], span[1], span[2]);
933 for(
int i =0; i<3; ++i){
941 for(
int i=0; i<3; ++i){
963 for(
int i=0; i<3; ++i){
964 work2[i] = dotProduct(work,
m_sdr[i]);
971 for(
int i =0; i<3; ++i){
1013 void Cube::checkSpan(
double &s0,
double &s1,
double &s2){
1026 bool Cube::checkInfLimits(
double &o0,
int &dir){
1040 void Cube::setScaling(
const double &s0,
const double &s1,
const double &s2){
1051 void Cube::getTempBBox(){
1060 locals[1].fill(1.0);
1061 locals[2][0]= locals[2][1]=1.0;
1064 locals[5][1]= locals[5][2] = 1.0;
1066 locals[7][0] = locals[7][2] = 1.0;
1068 for(
auto &vv : locals){
1070 for(
int i=0; i<3; ++i) {
1088 points[1][0] = points[2][0] = points[5][0]=points[6][0]= bMax[0];
1089 points[2][1] = points[3][1] = points[6][1]=points[7][1]= bMax[1];
1090 points[4][2] = points[5][2] = points[6][2]=points[7][2]= bMax[2];
1092 for(
auto &val:points) val += -1.0*
m_origin;
1094 for(
int j=0; j<3; ++j){
1098 double tmin, tmax, t;
1099 t= dotProduct(points[0],
m_sdr[j]);
1102 for(
int i=1; i<8; ++i){
1103 t= dotProduct(points[i],
m_sdr[j]);
1112 if(tmin>ref2 || tmax<ref1)
return false;
1127 m_span = {{1.0, 2*BITPIT_PI, 1.0}};
1139 setSpan(span[0], span[1], span[2]);
1161 for(
int i =0; i<3; ++i){
1171 for(
int i=0; i<3; ++i){
1192 for(
int i=0; i<3; ++i){
1193 work2[i] = dotProduct(work,
m_sdr[i]);
1197 if(work2[0] ==0.0 && work2[1] ==0.0){work[0] = 0.0; work[1] = 0.0;}
1199 work[0] = pow(work2[0]*work2[0] + work2[1]*work2[1],0.5);
1200 double pdum = std::atan2(work2[1],work2[0]);
1201 work[1] = pdum - (
getSign(pdum)-1.0)*BITPIT_PI;
1204 double param = 2*BITPIT_PI;
1206 if(work[1] < 0) work[1] = param + work[1];
1207 if(work[1] > param) work[1] = work[1] - param;
1214 for(
int i =0; i<3; ++i){
1260 void Cylinder::checkSpan(
double &s0,
double &s1,
double &s2){
1265 double thetalim = 8.0* std::atan(1.0);
1266 s1 = std::min(s1, thetalim);
1278 bool Cylinder::checkInfLimits(
double &orig,
int &dir){
1279 double thetalim = 2.0*BITPIT_PI;
1283 orig = std::max(0.0, orig);
1287 orig = std::min(thetalim, std::max(0.0, orig));
1302 void Cylinder::setScaling(
const double &s0,
const double &s1,
const double &s2){
1315 void Cylinder::getTempBBox(){
1325 for(
int i=0; i<2; ++i){
1326 for(
int j=0; j<5; ++j){
1327 for(
int k=0; k<2; ++k){
1328 locals[counter][0] = double(i)*1.0;
1329 locals[counter][1] = double(j)*0.25;
1330 locals[counter][2] = double(k)*1.0;
1335 for(
auto &vv : locals){
1337 for(
int i=0; i<3; ++i) {
1354 points[1][0] = points[2][0] = points[5][0]=points[6][0]= bMax[0];
1355 points[2][1] = points[3][1] = points[6][1]=points[7][1]= bMax[1];
1356 points[4][2] = points[5][2] = points[6][2]=points[7][2]= bMax[2];
1358 for(
auto &point : points){
1362 for(
int j=0; j<3; ++j){
1363 double tmin = 1.E18, tmax= -1.E18;
1365 for(
int i=0; i<8; ++i){
1366 tmin=std::min(tmin,points[i][j]);
1367 tmax=std::max(tmax,points[i][j]);
1371 if(tmax< 0.0 )
return false;
1373 if(tmin> 1.0 || tmax< 0.0)
return false;
1389 m_span = {{1.0, 2*BITPIT_PI, BITPIT_PI}};
1403 setSpan(span[0], span[1], span[2]);
1425 for(
int i =0; i<3; ++i){
1435 for(
int i=0; i<3; ++i){
1457 for(
int i=0; i<3; ++i){
1458 work2[i] = dotProduct(work,
m_sdr[i]);
1462 work[0] = norm2(work2);
1465 if(work2[0] ==0.0 && work2[1] ==0.0){
1468 double pdum = std::atan2(work2[1],work2[0]);
1469 work[1] = pdum - (
getSign(pdum)-1.0)*BITPIT_PI;
1472 double param = 2.0*BITPIT_PI;
1474 if(work[1] < 0) work[1] = param + work[1];
1475 if(work[1] > param) work[1] = work[1] - param;
1477 work[2] = std::acos(work2[2]/work[0]);
1484 for(
int i =0; i<3; ++i){
1532 void Sphere::checkSpan(
double &s0,
double &s1,
double &s2){
1537 double thetalim = 2.0*BITPIT_PI;
1538 s1 = std::min(s1, thetalim);
1541 s2 = std::min(s2, maxS2);
1556 bool Sphere::checkInfLimits(
double &orig,
int &dir){
1558 double thetalim = 2.0*BITPIT_PI;
1559 double tol = 1.e-12;
1563 orig = std::max(0.0, orig);
1567 orig = std::min(thetalim, std::max(0.0, orig));
1571 orig = std::min((0.5-tol)*thetalim, std::max(0.0, orig));
1586 void Sphere::setScaling(
const double &s0,
const double &s1,
const double &s2){
1599 void Sphere::getTempBBox(){
1609 for(
int i=0; i<2; ++i){
1610 for(
int j=0; j<5; ++j){
1611 for(
int k=0; k<3; ++k){
1612 locals[counter][0] = double(i)*1.0;
1613 locals[counter][1] = double(j)*0.25;
1614 locals[counter][2] = double(k)*0.5;
1620 for(
auto &vv : locals){
1622 for(
int i=0; i<3; ++i) {
1638 points[1][0] = points[2][0] = points[5][0]=points[6][0]= bMax[0];
1639 points[2][1] = points[3][1] = points[6][1]=points[7][1]= bMax[1];
1640 points[4][2] = points[5][2] = points[6][2]=points[7][2]= bMax[2];
1642 for(
auto &point : points){
1646 for(
int j=0; j<3; ++j){
1647 double tmin = 1.E18, tmax= -1.E18;
1649 for(
int i=0; i<8; ++i){
1650 tmin=std::min(tmin,points[i][j]);
1651 tmax=std::max(tmax,points[i][j]);
1655 if(tmax< 0.0 )
return false;
1657 if(tmin> 1.0 || tmax< 0.0)
return false;
1673 m_span = {{1.0, 1.0, 1.0}};
1685 setSpan(span[0], span[1], span[2]);
1711 work2[1] *= (1.0-work2[0]);
1714 for(
int i =0; i<3; ++i){
1722 for(
int i=0; i<3; ++i){
1744 for(
int i=0; i<3; ++i){
1745 work2[i] = dotProduct(work,
m_sdr[i]);
1752 for(
int i =0; i<3; ++i){
1758 if(std::abs(1.0-work2[0]) > 0.0){
1759 work2[1] /= (1.0 - work2[0]);
1761 if(std::abs(work2[1]) > 0.0 ) work2[1] = std::numeric_limits<double>::max();
1762 else work2[1] = 0.0;
1803 void Wedge::checkSpan(
double &s0,
double &s1,
double &s2){
1816 bool Wedge::checkInfLimits(
double &o0,
int &dir){
1830 void Wedge::setScaling(
const double &s0,
const double &s1,
const double &s2){
1841 void Wedge::getTempBBox(){
1850 locals[1].fill(1.0);
1851 locals[2][0]= locals[2][1]=1.0;
1854 locals[5][1]= locals[5][2] = 1.0;
1856 locals[7][0] = locals[7][2] = 1.0;
1858 for(
auto &vv : locals){
1860 for(
int i=0; i<3; ++i) {
1878 points[1][0] = points[2][0] = points[5][0]=points[6][0]= bMax[0];
1879 points[2][1] = points[3][1] = points[6][1]=points[7][1]= bMax[1];
1880 points[4][2] = points[5][2] = points[6][2]=points[7][2]= bMax[2];
1882 for(
auto &val:points) val += -1.0*
m_origin;
1888 double tmin, tmax, t;
1889 t= dotProduct(points[0],
m_sdr[2]);
1891 points[0] += -1.0*t*
m_sdr[2];
1893 for(
int i=1; i<8; ++i){
1894 t= dotProduct(points[i],
m_sdr[2]);
1895 points[i] += -1.0*t*
m_sdr[2];
1906 if(tmin>ref2 || tmax<ref1)
return false;
1908 bMin2 = points[0]; bMax2=points[0];
1909 for(
int i=1; i<8; ++i){
1910 for(
int j=0; j<3; ++j){
1911 bMin2[j] = std::fmin(bMin2[j], points[i][j]);
1912 bMax2[j] = std::fmax(bMax2[j], points[i][j]);