28#ifndef BLOCK_LATTICE_STL_READER_HH
29#define BLOCK_LATTICE_STL_READER_HH
52 int method,
bool verbose, T overlap, T max)
53 : _cuboidDecomposition (cbg3d),
55 _voxelSize(voxelSize),
59 _mesh(fName, stlSize),
61 clout(std::cout,
"BlockLatticeSTLreader")
63 this->
getName() =
"BlockLatticeSTLreader";
66 clout <<
"Voxelizing ..." << std::endl;
69 Vector<T,3> extension = _mesh.getMax() - _mesh.getMin();
77 T radius = _voxelSize *
util::pow(2, j - 1);
80 for (
unsigned i = 0; i < 3; i++) {
81 center[i] = (_mesh.getMin()[i] + _mesh.getMax()[i]) / 2. - _voxelSize / 4.;
85 _tree =
new Octree<T>(center, radius, &_mesh, j, _overlap);
88 for (
int i = 0; i < 3; i++) {
89 this->
_myMin[i] = center[i] + _voxelSize / 2.;
90 this->
_myMax[i] = center[i] - _voxelSize / 2.;
92 for (
int i = 0; i < 3; i++) {
93 while (this->
_myMin[i] > _mesh.getMin()[i]) {
94 this->
_myMin[i] -= _voxelSize;
96 while (this->
_myMax[i] < _mesh.getMax()[i]) {
97 this->
_myMax[i] += _voxelSize;
99 this->
_myMax[i] -= _voxelSize;
100 this->
_myMin[i] += _voxelSize;
126 clout <<
"creating of the lists for signed distance function"<< std::endl;
127 _trianglesInCuboidList.resize(_loadBalancer.size());
129 for(
int iC=0; iC < _loadBalancer.size();iC++)
132 int globC = _loadBalancer.glob(iC);
133 auto& cuboid = _cuboidDecomposition.get(globC);
141 if (cuboid.isInside(center, 6))
144 _trianglesInCuboidList[iC].push_back(triangle);
151 clout <<
'\n' <<
'\n' <<
"WARNING! The sensitivity in signed distance function could be insufficient for your case!!!" <<
'\n' << std::endl;
155 clout <<
"Voxelizing ... OK" << std::endl;
162 T sensitivity = 1.e-30;
163 _neighbouringTriangleInCuboidList.resize(_loadBalancer.size());
164 clout <<
"createNeighbouringTriangleInCuboidVector called" << std::endl;
165 for(
int iC=0; iC < _loadBalancer.size();iC++)
167 _neighbouringTriangleInCuboidList[iC].resize(_trianglesInCuboidList[iC].size());
171 for (
int ii=0;ii<_neighbouringTriangleInCuboidList[iC].size(); ii++)
173 std::vector<STLtriangle<T>> vec;
175 for(
int jj=ii+1;jj<_trianglesInCuboidList[iC].size();jj++)
178 auto& i = (_trianglesInCuboidList[iC])[ii];
179 auto& j = (_trianglesInCuboidList[iC])[jj];
182 if(
norm(i.point[0]-j.point[0]) < sensitivity ||
norm(i.point[1]-j.point[1]) < sensitivity ||
norm(i.point[2]-j.point[2]) < sensitivity ||
183 norm(i.point[0]-j.point[1]) < sensitivity ||
norm(i.point[1]-j.point[2]) < sensitivity ||
norm(i.point[2]-j.point[0]) < sensitivity ||
184 norm(i.point[0]-j.point[2]) < sensitivity ||
norm(i.point[1]-j.point[0]) < sensitivity ||
norm(i.point[2]-j.point[1]) < sensitivity )
187 (_neighbouringTriangleInCuboidList[iC][ii]).push_back(pj);
188 (_neighbouringTriangleInCuboidList[iC][jj]).push_back(pi);
193 clout <<
"createneighbouringTriangleInCuboidVector finished" << std::endl;
201 int method,
bool verbose, T overlap, T max)
202 : _voxelSize(voxelSize),
205 _fName(
"meshPoints.stl"),
206 _mesh(meshPoints, stlSize),
208 clout(std::cout,
"BlockLatticeSTLreader")
210 this->
getName() =
"BlockLatticeSTLreader";
213 clout <<
"Voxelizing ..." << std::endl;
216 Vector<T,3> extension = _mesh.getMax() - _mesh.getMin();
224 T radius = _voxelSize *
util::pow(2, j - 1);
227 for (
unsigned i = 0; i < 3; i++) {
228 center[i] = (_mesh.getMin()[i] + _mesh.getMax()[i]) / 2. - _voxelSize / 4.;
233 _tree =
new Octree<T>(center, radius, &_mesh, j, _overlap);
236 for (
int i = 0; i < 3; i++) {
237 this->
_myMin[i] = center[i] + _voxelSize / 2.;
238 this->
_myMax[i] = center[i] - _voxelSize / 2.;
240 for (
int i = 0; i < 3; i++) {
241 while (this->
_myMin[i] > _mesh.getMin()[i]) {
242 this->
_myMin[i] -= _voxelSize;
244 while (this->
_myMax[i] < _mesh.getMax()[i]) {
245 this->
_myMax[i] += _voxelSize;
247 this->
_myMax[i] -= _voxelSize;
248 this->
_myMin[i] += _voxelSize;
287 clout <<
"Voxelizing ... OK" << std::endl;
306 std::vector<Octree<T>*> leafs;
307 _tree->getLeafs(leafs);
308 typename std::vector<Octree<T>*>::iterator it = leafs.begin();
311 int intersections = 0;
314 T step = 1. / 1000. * _voxelSize;
315 for (; it != leafs.end(); ++it) {
318 pt = (*it)->getCenter();
326 while (s[0] < _mesh.getMax()[0] + std::numeric_limits<T>::epsilon()) {
327 node = _tree->
find(s, (*it)->getMaxdepth());
332 inside += (intersections % 2);
340 while (s[1] < _mesh.getMax()[1] + std::numeric_limits<T>::epsilon()) {
341 node = _tree->
find(s, (*it)->getMaxdepth());
346 inside += (intersections % 2);
354 while (s[2] < _mesh.getMax()[2] + std::numeric_limits<T>::epsilon()) {
355 node = _tree->
find(s, (*it)->getMaxdepth());
360 inside += (intersections % 2);
361 (*it)->setInside(inside > 1);
370void BlockLatticeSTLreader<T>::indicate2()
373 Vector<T,3> rayPt = _tree->getCenter() - rad + .5 * _voxelSize;
374 Vector<T,3> pt = rayPt;
381 T step = 1. / 1000. * _voxelSize;
383 Octree<T>* node =
nullptr;
384 unsigned short rayInside = 0;
385 Vector<T,3> nodeInters;
386 while (pt[0] < _mesh.getMax()[0] + std::numeric_limits<T>::epsilon()) {
387 node = _tree->find(pt);
389 nodeInters[2] = node->getCenter()[2] - node->getRadius();
391 while (pt[1] < _mesh.getMax()[1] + std::numeric_limits<T>::epsilon()) {
392 node = _tree->find(pt);
394 nodeInters[2] = node->getCenter()[2] - node->getRadius();
396 while (pt[2] < _mesh.getMax()[2] + std::numeric_limits<T>::epsilon()) {
397 node = _tree->find(pt);
398 node->checkRay(nodeInters, rayDir, rayInside);
399 node->intersectRayNode(pt, rayDir, nodeInters);
400 pt = nodeInters + step * rayDir;
418void BlockLatticeSTLreader<T>::indicate2_Xray()
421 Vector<T,3> rayPt = _tree->getCenter() - rad + .5 * _voxelSize;
422 Vector<T,3> pt = rayPt;
429 T step = 1. / 1000. * _voxelSize;
431 Octree<T>* node =
nullptr;
432 unsigned short rayInside = 0;
433 Vector<T,3> nodeInters;
434 while (pt[2] < _mesh.getMax()[2] + std::numeric_limits<T>::epsilon()) {
435 node = _tree->find(pt);
437 nodeInters[0] = node->getCenter()[0] - node->getRadius();
439 while (pt[1] < _mesh.getMax()[1] + std::numeric_limits<T>::epsilon()) {
440 node = _tree->find(pt);
442 nodeInters[0] = node->getCenter()[0] - node->getRadius();
444 while (pt[0] < _mesh.getMax()[0] + std::numeric_limits<T>::epsilon()) {
445 node = _tree->find(pt);
446 node->checkRay(nodeInters, rayDir, rayInside);
447 node->intersectRayNode(pt, rayDir, nodeInters);
448 pt = nodeInters + step * rayDir;
464void BlockLatticeSTLreader<T>::indicate2_Yray()
466 T rad = _tree->getRadius();
467 Vector<T,3> rayPt = _tree->getCenter() - rad + .5 * _voxelSize;
468 Vector<T,3> pt = rayPt;
475 T step = 1. / 1000. * _voxelSize;
477 Octree<T>* node =
nullptr;
478 unsigned short rayInside = 0;
479 Vector<T,3> nodeInters;
480 while (pt[2] < _mesh.getMax()[2] + std::numeric_limits<T>::epsilon()) {
481 node = _tree->find(pt);
483 nodeInters[1] = node->getCenter()[1] - node->getRadius();
485 while (pt[0] < _mesh.getMax()[0] + std::numeric_limits<T>::epsilon()) {
486 node = _tree->find(pt);
488 nodeInters[1] = node->getCenter()[1] - node->getRadius();
490 while (pt[1] < _mesh.getMax()[1] + std::numeric_limits<T>::epsilon()) {
491 node = _tree->find(pt);
492 node->checkRay(nodeInters, rayDir, rayInside);
493 node->intersectRayNode(pt, rayDir, nodeInters);
494 pt = nodeInters + step * rayDir;
509void BlockLatticeSTLreader<T>::indicate3()
511 std::vector<Octree<T>*> leafs;
512 _tree->getLeafs(leafs);
513 typename std::vector<Octree<T>*>::iterator it = leafs.begin();
515 Vector<T,3> dir, pt,
s;
516 Octree<T>* node =
nullptr;
517 T step = 1. / 1000. * _voxelSize;
519 int sum_intersections;
521 for (; it != leafs.end(); ++it) {
522 pt = (*it)->getCenter();
524 sum_intersections = 0;
531 while (s[0] < _mesh.getMax()[0] + std::numeric_limits<T>::epsilon()) {
532 node = _tree->find(s, (*it)->getMaxdepth());
533 intersections = node->testIntersection(pt, dir);
534 node->intersectRayNode(pt, dir, s);
536 if (intersections > 0) {
548 while (s[1] < _mesh.getMax()[1] + std::numeric_limits<T>::epsilon()) {
549 node = _tree->find(s, (*it)->getMaxdepth());
550 intersections = node->testIntersection(pt, dir);
551 node->intersectRayNode(pt, dir, s);
553 if (intersections > 0) {
565 while (s[2] < _mesh.getMax()[2] + std::numeric_limits<T>::epsilon()) {
566 node = _tree->find(s, (*it)->getMaxdepth());
567 intersections = node->testIntersection(pt, dir);
568 node->intersectRayNode(pt, dir, s);
570 if (intersections > 0) {
582 while (s[0] > _mesh.getMin()[0] - std::numeric_limits<T>::epsilon()) {
583 node = _tree->find(s, (*it)->getMaxdepth());
584 intersections = node->testIntersection(pt, dir);
585 node->intersectRayNode(pt, dir, s);
587 if (intersections > 0) {
599 while (s[1] > _mesh.getMin()[1] - std::numeric_limits<T>::epsilon()) {
600 node = _tree->find(s, (*it)->getMaxdepth());
601 intersections = node->testIntersection(pt, dir);
602 node->intersectRayNode(pt, dir, s);
604 if (intersections > 0) {
616 while (s[2] > _mesh.getMin()[2] - std::numeric_limits<T>::epsilon()) {
617 node = _tree->find(s, (*it)->getMaxdepth());
618 intersections = node->testIntersection(pt, dir);
619 node->intersectRayNode(pt, dir, s);
621 if (intersections > 0) {
626 (*it)->setInside(sum_intersections > 5);
634 T coords = _tree->getRadius();
636 if (c[0] - coords < input[0] && input[0] < c[0] + coords && c[1] - coords < input[1]
637 && input[1] < c[1] + coords && c[2] - coords < input[2] && input[2] < c[2] + coords) {
638 std::vector<T> tmp(input, input + 3);
639 output[0] = _tree->find(tmp)->getInside();
651 Vector<T,3> extends = _mesh.getMax() - _mesh.getMin();
655 Vector<T,3> center = _mesh.getMin() + 1 / 2. * extends;
656 T step = _voxelSize / 1000., a = 0;
658 for (
int i = 0; i < 3; i++) {
662 if (!(_mesh.getMin()[0] < origin[0] && origin[0] < _mesh.getMax()[0]
663 && _mesh.getMin()[1] < origin[1] && origin[1] < _mesh.getMax()[1]
664 && _mesh.getMin()[2] < origin[2] && origin[2] < _mesh.getMax()[2])) {
669 d = _mesh.getMin()[0];
670 t = (d - origin[0]) / dir[0];
671 pt[0] = origin[0] + (t + step) * dir[0];
672 pt[1] = origin[1] + (t + step) * dir[1];
673 pt[2] = origin[2] + (t + step) * dir[2];
675 if (_mesh.getMin()[1] < pt[1] && pt[1] < _mesh.getMax()[1]
676 && _mesh.getMin()[2] < pt[2] && pt[2] < _mesh.getMax()[2]) {
680 else if (dir[0] < 0) {
681 d = _mesh.getMax()[0];
682 t = (d - origin[0]) / dir[0];
683 pt[0] = origin[0] + (t + step) * dir[0];
684 pt[1] = origin[1] + (t + step) * dir[1];
685 pt[2] = origin[2] + (t + step) * dir[2];
686 if (_mesh.getMin()[1] < pt[1] && pt[1] < _mesh.getMax()[1]
687 && _mesh.getMin()[2] < pt[2] && pt[2] < _mesh.getMax()[2]) {
692 if (dir[1] > 0 && !foundQ) {
693 d = _mesh.getMin()[1];
694 t = (d - origin[1]) / dir[1];
695 pt[0] = origin[0] + (t + step) * dir[0];
696 pt[1] = origin[1] + (t + step) * dir[1];
697 pt[2] = origin[2] + (t + step) * dir[2];
698 if (_mesh.getMin()[0] < pt[0] && pt[0] < _mesh.getMax()[0]
699 && _mesh.getMin()[2] < pt[2] && pt[2] < _mesh.getMax()[2]) {
703 else if (dir[1] < 0 && !foundQ) {
704 d = _mesh.getMax()[1];
705 t = (d - origin[1]) / dir[1];
706 pt[0] = origin[0] + (t + step) * dir[0];
707 pt[1] = origin[1] + (t + step) * dir[1];
708 pt[2] = origin[2] + (t + step) * dir[2];
709 if (_mesh.getMin()[0] < pt[0] && pt[0] < _mesh.getMax()[0]
710 && _mesh.getMin()[2] < pt[2] && pt[2] < _mesh.getMax()[2]) {
715 if (dir[2] > 0 && !foundQ) {
716 d = _mesh.getMin()[2];
717 t = (d - origin[2]) / dir[2];
718 pt[0] = origin[0] + (t + step) * dir[0];
719 pt[1] = origin[1] + (t + step) * dir[1];
720 pt[2] = origin[2] + (t + step) * dir[2];
721 if (_mesh.getMin()[0] < pt[0] && pt[0] < _mesh.getMax()[0]
722 && _mesh.getMin()[1] < pt[1] && pt[1] < _mesh.getMax()[1]) {
726 else if (dir[2] < 0 && !foundQ) {
727 d = _mesh.getMax()[2];
728 t = (d - origin[2]) / dir[2];
729 pt[0] = origin[0] + (t + step) * dir[0];
730 pt[1] = origin[1] + (t + step) * dir[1];
731 pt[2] = origin[2] + (t + step) * dir[2];
732 if (_mesh.getMin()[0] < pt[0] && pt[0] < _mesh.getMax()[0]
733 && _mesh.getMin()[1] < pt[1] && pt[1] < _mesh.getMax()[1]) {
743 while ((
util::fabs(pt[0] - center[0]) < extends[0])
744 && (
util::fabs(pt[1] - center[1]) < extends[1])
745 && (
util::fabs(pt[2] - center[2]) < extends[2])) {
746 node = _tree->
find(pt);
749 distance =
norm(vek);
755 for (
int i = 0; i < 3; i++) {
756 pt[i] = s[i] + step * dir[i];
762 clout <<
"Returning false" << std::endl;
771 unsigned countTriangles = 0;
775 if (triangle.isPointInside(pt)) {
777 normal+=triangle.getNormal();
780 if (countTriangles > 0) {
781 return normal / countTriangles;
789Vector<T,3> BlockLatticeSTLreader<T>::evalSurfaceNormal(
const Vector<T,3>& origin)
793 T
distance = std::numeric_limits<T>::max();
795 for (
const STLtriangle<T>& triangle : _mesh.getTriangles()) {
798 if (
triangle.isPointInside(pointOnTriangle))
800 PhysR<T,3> const currDistance = pointOnTriangle - origin;
801 T currDistanceNorm =
norm(currDistance);
803 std::cout <<
"util near zero" << std::endl;
804 return findNormalOnSurface(origin);
806 else if (distance > currDistanceNorm) {
809 closestPoint = pointOnTriangle;
905 using namespace util;
906 T distance = std::numeric_limits<T>::max();
907 auto& triangles = _trianglesInCuboidList[iC];
909 int triangle_index=-1;
912 for (
int i=0;i<triangles.size();i++)
914 auto& triangle = triangles[i];
915 PhysR<T,3> pointOnTriangle = triangle.closestPtPointTriangle(input);
916 T distance2 =
util::min(distance,
norm(pointOnTriangle - input));
917 if(distance2 < distance && triangle.isPointInside(pointOnTriangle) )
920 _triangle = triangle;
922 normal =
normalize(pointOnTriangle - input);
925 Vector<T,3> distancesToEdges = {}, VortexPoint = {}, EdgePoint1 = {}, EdgePoint2 = {};
929 if(_triangle.
isEdgePoint(distancesToEdges, EdgePoint1, EdgePoint2))
931 for(
auto& i: _neighbouringTriangleInCuboidList[iC][triangle_index])
933 if( (EdgePoint1 == i.point[0] || EdgePoint1 == i.point[1] || EdgePoint1 == i.point[2]) && (EdgePoint2 == i.point[0] || EdgePoint2 == i.point[1] || EdgePoint2 == i.point[2]))
953 else if(_triangle.
isVortexPoint(distancesToEdges, VortexPoint))
955 int triangle_counter = 0;
958 if(VortexPoint == _triangle.
point[0])
960 vortex1 = _triangle.
point[1];
961 vortex2 = _triangle.
point[2];
965 if(VortexPoint == _triangle.
point[1])
967 vortex1 = _triangle.
point[0];
968 vortex2 = _triangle.
point[2];
972 if(VortexPoint == _triangle.
point[2])
974 vortex1 = _triangle.
point[0];
975 vortex2 = _triangle.
point[1];
979 edge1 =
normalize(vortex1 - VortexPoint);
980 edge2 =
normalize(vortex2 - VortexPoint);
981 dotP = dotProduct3D(edge1, edge2);
986 else if(dotP > 0.999999)
990 pseudoNormal = acos(dotP)*_triangle.
getNormal();
994 for(
auto& i: _neighbouringTriangleInCuboidList[iC][triangle_index])
996 if( VortexPoint == i.point[0] || VortexPoint == i.point[1] || VortexPoint == i.point[2])
1000 if(VortexPoint == i.point[0])
1002 vortex1 = i.point[1];
1003 vortex2 = i.point[2];
1007 if(VortexPoint == i.point[1])
1009 vortex1 = i.point[0];
1010 vortex2 = i.point[2];
1014 if(VortexPoint == i.point[2])
1016 vortex1 = i.point[0];
1017 vortex2 = i.point[1];
1020 std::cout <<
"something went wrong" << std::endl;
1023 edge1 =
normalize(vortex1 - VortexPoint);
1024 edge2 =
normalize(vortex2 - VortexPoint);
1025 dotP = dotProduct3D(edge1, edge2);
1028 if(dotP < -0.999999)
1029 { pseudoNormal +=
M_PI*i.getNormal();}
1030 else if(dotP > 0.999999)
1034 pseudoNormal += acos(dotP)*i.getNormal();
1075 auto globC = _cuboidDecomposition.getC(input, 0);
1076 if (_loadBalancer.isLocal(*globC)) {
1077 iC = _loadBalancer.loc(*globC);
1079 globC = _cuboidDecomposition.getC(input, 3);
1080 if (_loadBalancer.isLocal(*globC)) {
1081 iC = _loadBalancer.loc(*globC);
1083 throw std::runtime_error(
"Distance origin must be located within local cuboid (overlap)");
1086 return signedDistance(iC, input);
1090template <
typename T>
1093 return evalSurfaceNormal(pos);
1101 clout <<
"voxelSize=" << _voxelSize <<
"; stlSize=" << _stlSize << std::endl;
1102 clout <<
"minPhysR(VoxelMesh)=(" << this->_myMin[0] <<
"," << this->_myMin[1]
1103 <<
"," << this->_myMin[2] <<
")";
1104 clout <<
"; maxPhysR(VoxelMesh)=(" << this->_myMax[0] <<
","
1105 << this->_myMax[1] <<
"," << this->_myMax[2] <<
")" << std::endl;
1111 _tree->write(_fName);
1117 if (stlName ==
"") {
1118 _mesh.write(_fName);
1121 _mesh.write(stlName);
1128 unsigned int noTris = _mesh.triangleSize();
1131 for (
unsigned int i = 0; i < noTris; i++) {
1132 center = _mesh.getTri(i).getCenter();
1134 center + _mesh.getTri(i).normal *
util::sqrt(3.) * _voxelSize)->getInside()) {
1137 _mesh.getTri(i).point[0] = _mesh.getTri(i).point[2];
1138 _mesh.getTri(i).point[2] = pt;
1139 _mesh.getTri(i).init();
1150 std::vector<Octree<T>*> leafs;
1151 _tree->getLeafs(leafs);
1152 for (
auto it = leafs.begin(); it != leafs.end(); ++it) {
1153 if ((*it)->getBoundaryNode()) {
1154 (*it)->setInside(
true);
Input in STL format – header file.
void writeSTL(std::string stlName="")
Writes STL mesh in Si units.
~BlockLatticeSTLreader() override
T signedDistance(int locC, const Vector< T, 3 > &input)
Computes signed distance to closest triangle in direction of the surface normal in local cuboid locC.
void print()
Prints console output.
void writeOctree()
Writes Octree.
bool operator()(bool output[], const T input[]) override
Returns whether node is inside or not.
void setBoundaryInsideNodes()
Every octree leaf intersected by the STL will be part of the inside nodes.
BlockLatticeSTLreader(CuboidDecomposition3D< T > &cbg3d, LoadBalancer< T > &hlb, const std::string fName, T voxelSize, T stlSize=1, int method=2, bool verbose=false, T overlap=0., T max=0.)
Constructs a new BlockLatticeSTLreader from a file.
Vector< T, 3 > surfaceNormal(const Vector< T, 3 > &pos, const T meshSize=0) override
Finds and returns normal of the closest surface (triangle)
void createNeighbouringTriangleInCuboidVector()
Needed for the signed Distance function: Creates a list of neighbouring triangles for each triangle.
void setNormalsOutside()
Rearranges normals of triangles to point outside of geometry.
bool distance(T &distance, const Vector< T, 3 > &origin, const Vector< T, 3 > &direction, int iC=-1) override
Computes distance to closest triangle intersection.
Base class for all LoadBalancer.
bool closestIntersection(const Vector< T, 3 > &pt, const Vector< T, 3 > &direction, Vector< T, 3 > &q, T &a)
Test intersection of ray with all triangles in Octree q contains point of closest intersection to pt ...
void intersectRayNode(const Vector< T, 3 > &pt, const Vector< T, 3 > &dir, Vector< T, 3 > &s)
Computes intersection of ray with Octree boundaries.
int testIntersection(const Vector< T, 3 > &pt, const Vector< T, 3 > &dir, bool print=false)
Test intersection of ray with all triangles in Octree returns number of intersections.
Octree< T > * find(const Vector< T, 3 > &, const int &maxDepth=0)
Find the node containing the first param with remaining maxDepth.
const T getRadius() const
Gets radius.
Wrapper functions that simplify the use of MPI.
platform_constant Fraction s[Q]
platform_constant Fraction t[Q]
T triangle(Vector< T, 2 > p, Vector< T, 2 > a, Vector< T, 2 > b, Vector< T, 2 > c) any_platform
Exact signed distance to the surface of two-dimensional triangle.
Distribution< T > normal(T mean, T stddev)
bool distance(S &distance, const Vector< S, D > &origin, const Vector< S, D > &direction, S precision, S pitch, F1 isInside, F2 isInsideBoundingBox)
Expr pow(Expr base, Expr exp)
T dotProduct3D(const Vector< T, 3 > &a, const Vector< T, 3 > &b)
dot product, only valid in 3d
bool nearZero(T a) any_platform
return true if a is close to zero
Top level namespace for all of OpenLB.
constexpr T max(const ScalarVector< T, D, IMPL > &v)
Vector< T, D > PhysR
Type for spatial (physical) coordinates.
constexpr T norm(const ScalarVector< T, D, IMPL > &a) any_platform
Euclidean vector norm.
constexpr Vector< T, D > normalize(const ScalarVector< T, D, IMPL > &a, T scale=T{1})
Octree - adapted from http://www.flipcode.com/archives/Octree_Implementation.shtml.
Definition of singletons: global, publicly available information.
bool getPointToEdgeDistances(const Vector< T, 3 > &input, Vector< T, 3 > &output, T sensitivity=1.e-15)
Returns true if the point is on a edge (smaller than sensitivity) and gives the perpendicular distanc...
bool isVortexPoint(const Vector< T, 3 > &input, Vector< T, 3 > &P, T sensitivity=1.e-15)
Returns true if is near vortex (smaller than sensitivity) and saves in P the vortex points.
Vector< T, 3 > & getNormal()
Return write access to normal.
bool isEdgePoint(const Vector< T, 3 > &input, Vector< T, 3 > &P1, Vector< T, 3 > &P2, T sensitivity=1.e-15)
Returns true if is near edge (smaller than sensitivity) and not near vortex and saves in P1 and P2 th...
Vector< T, 3 > closestPtPointTriangle(const Vector< T, 3 > &pt) const
computes closest Point in a triangle to another point.
std::vector< Vector< T, 3 > > point
A triangle contains 3 Points.