From 94d3e79a8617f88dc0219cfdeedfa3147833719d Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Mon, 24 Jun 2019 14:43:36 +0200 Subject: Initialize at openlb-1-3 --- src/io/octree.hh | 756 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 756 insertions(+) create mode 100644 src/io/octree.hh (limited to 'src/io/octree.hh') diff --git a/src/io/octree.hh b/src/io/octree.hh new file mode 100644 index 0000000..2efb083 --- /dev/null +++ b/src/io/octree.hh @@ -0,0 +1,756 @@ +/* This file is part of the OpenLB library + * + * Copyright (C) 2015 Thomas Henn + * E-mail contact: info@openlb.net + * The most recent release of OpenLB can be downloaded at + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** \file + * Octree - adapted from http://www.flipcode.com/archives/Octree_Implementation.shtml + */ + +#ifndef OCTREE_HH +#define OCTREE_HH + +#include + +#include "core/singleton.h" + +using namespace olb::util; +/// All OpenLB code is contained in this namespace. +namespace olb { + +template +class STLmesh; + +template +struct STLtriangle; + +template +class Octree; + +template +Octree::Octree(Vector center, T rad, STLmesh* mesh, short maxDepth, T overlap, Octree* parent) + : _center(center), _radius(rad), _mesh(mesh), _maxDepth(maxDepth),_isLeaf(false), _boundaryNode(false), _inside(false), _parent(parent), _child(nullptr) +{ + + + findTriangles(overlap); + // cout << _triangles.size() << std::endl; + if (_triangles.size() > 0 && 0 < _maxDepth) { + + _child = new Octree*[8]; + + Vector tmpCenter = _center; + T tmpRad = _radius/2.; + tmpCenter[0] = _center[0] - tmpRad; + tmpCenter[1] = _center[1] - tmpRad; + tmpCenter[2] = _center[2] + tmpRad; + _child[0] = new Octree(tmpCenter, tmpRad, _mesh, _maxDepth-1, overlap, this); + + tmpCenter[0] = _center[0] + tmpRad; + tmpCenter[1] = _center[1] - tmpRad; + tmpCenter[2] = _center[2] + tmpRad; + _child[1] = new Octree(tmpCenter, tmpRad, _mesh, _maxDepth-1, overlap, this); + + tmpCenter[0] = _center[0] - tmpRad; + tmpCenter[1] = _center[1] - tmpRad; + tmpCenter[2] = _center[2] - tmpRad; + _child[2] = new Octree(tmpCenter, tmpRad, _mesh, _maxDepth-1, overlap, this); + + tmpCenter[0] = _center[0] + tmpRad; + tmpCenter[1] = _center[1] - tmpRad; + tmpCenter[2] = _center[2] - tmpRad; + _child[3] = new Octree(tmpCenter, tmpRad, _mesh, _maxDepth-1, overlap, this); + + tmpCenter[0] = _center[0] - tmpRad; + tmpCenter[1] = _center[1] + tmpRad; + tmpCenter[2] = _center[2] + tmpRad; + _child[4] = new Octree(tmpCenter, tmpRad, _mesh, _maxDepth-1, overlap, this); + + tmpCenter[0] = _center[0] + tmpRad; + tmpCenter[1] = _center[1] + tmpRad; + tmpCenter[2] = _center[2] + tmpRad; + _child[5] = new Octree(tmpCenter, tmpRad, _mesh, _maxDepth-1, overlap, this); + + tmpCenter[0] = _center[0] - tmpRad; + tmpCenter[1] = _center[1] + tmpRad; + tmpCenter[2] = _center[2] - tmpRad; + _child[6] = new Octree(tmpCenter, tmpRad, _mesh, _maxDepth-1, overlap, this); + + tmpCenter[0] = _center[0] + tmpRad; + tmpCenter[1] = _center[1] + tmpRad; + tmpCenter[2] = _center[2] - tmpRad; + _child[7] = new Octree(tmpCenter, tmpRad, _mesh, _maxDepth-1, overlap, this); + + } else { + _isLeaf = true; + if (_triangles.size() > 0 ) { + _boundaryNode = true; + } + } +} + +template +Octree::~Octree() +{ + if (_maxDepth!=0 && !_isLeaf) { + for (int i=0; i<8; i++) { + delete _child[i]; + } + delete[] _child; + } +} + +template +void Octree::findTriangles(T overlap) +{ + if (_parent == nullptr) { + _triangles.reserve(_mesh->triangleSize()); + for (unsigned int i=0; i<_mesh->triangleSize(); ++i) { + if (AABBTri(_mesh->getTri(i))) { + _triangles.push_back(i); + } + } + } else { + std::vector::iterator it; + for (it = _parent->_triangles.begin(); it!=_parent->_triangles.end(); ++it) { + if (AABBTri(_mesh->getTri(*it), overlap)) { + _triangles.push_back(*it); + } + } + } +} + +template +bool Octree::AABBTri(const STLtriangle& tri, T overlap) +{ + std::vector v0(3,T()), v1(3,T()), v2(3,T()), f0(3,T()), f1(3,T()), f2(3,T()), e(3, T()); + + /* Test intersection cuboids - triangle + * Intersection test after Christer Ericson - Real time Collision Detection p. + * TestTriangleAABB p.171 */ + Vector c(_center); + T eps = 2e-16; + + for (int j=0; j<3; j++) { + v0[j] = tri.point[0].r[j]-_center[j]; + v1[j] = tri.point[1].r[j]-_center[j]; + v2[j] = tri.point[2].r[j]-_center[j]; + e[j] = _radius*1.01 + overlap; // + std::numeric_limits::epsilon(); // *1.01; + } + for (int j=0; j<3; j++) { + f0[j] = v1[j] - v0[j]; + f1[j] = v2[j] - v1[j]; + f2[j] = v0[j] - v2[j]; + } + T p0=T(), p1=T(), r=T(); + //test a00 + p0 = v0[2]*v1[1]-v0[1]*v1[2]; + p1 = v2[2]*v1[1]-v2[2]*v0[1]+v0[2]*v2[1]-v1[2]*v2[1]; + r = e[1] * std::fabs(f0[2]) + e[2]*std::fabs(f0[1]); + T mmm = std::max(-std::max(p0, p1), std::min(p0, p1)); + if (mmm > r+eps) { + return false; + } + + // test a01 + p0 = v0[1]*v1[2]-v0[1]*v2[2]-v0[2]*v1[1]+v0[2]*v2[1]; + p1 = -v1[1]*v2[2]+v1[2]*v2[1]; + r = e[1] * std::fabs(f1[2]) + e[2]*std::fabs(f1[1]); + mmm = std::max(-std::max(p0, p1), std::min(p0, p1)); + if (mmm > r+eps) { + return false; + } + + // test a02 + p0 = v0[1]*v2[2]-v0[2]*v2[1]; + p1 = v0[1]*v1[2]-v0[2]*v1[1]+v1[1]*v2[2]-v1[2]*v2[1]; + r = e[1]*std::fabs(f2[2]) + e[2]*std::fabs(f2[1]); + mmm = std::max(-std::max(p0, p1), std::min(p0, p1)); + if (mmm > r+eps) { + return false; + } + + // test a10 + p0 = v0[0]*v1[2]-v0[2]*v1[0]; + p1 = v0[0]*v2[2]-v0[2]*v2[0]-v1[0]*v2[2]+v1[2]*v2[0]; + r = e[0]*std::fabs(f0[2]) + e[2]*std::fabs(f0[0]); + mmm = std::max(-std::max(p0, p1), std::min(p0, p1)); + if (mmm > r+eps) { + return false; + } + + // test a11 + p0 = -v0[0]*v1[2]+v0[0]*v2[2]+v0[2]*v1[0]-v0[2]*v2[0]; + p1 = v1[0]*v2[2]-v1[2]*v2[0]; + r = (T)(e[0]*std::fabs(f1[2])+e[2]*std::fabs(f1[0])); + mmm = std::max(-std::max(p0, p1), std::min(p0, p1)); + if (mmm > r+eps) { + return false; + } + + // test a12 + p0 = -v0[0]*v2[2]+v0[2]*v2[0]; + p1 = -v0[0]*v1[2]+v0[2]*v1[0]-v1[0]*v2[2]+v1[2]*v2[0]; + r = e[0]*std::fabs(f2[2])+e[2]*std::fabs(f2[0]); + mmm = std::max(-std::max(p0, p1), std::min(p0, p1)); + if (mmm > r+eps) { + return false; + } + + // test a20 + p0 = -v0[0]*v1[1]+v0[1]*v1[0]; + p1 = -v0[0]*v2[1]+v0[1]*v2[0]+v1[0]*v2[1]-v1[1]*v2[0]; + r = e[0]*std::fabs(f0[1])+e[1]*std::fabs(f0[0]); + mmm = std::max(-std::max(p0, p1), std::min(p0, p1)); + if (mmm > r+eps) { + return false; + } + + // test a21 + p0 = v0[0]*v1[1]-v0[0]*v2[1]-v0[1]*v1[0]+v0[1]*v2[0]; + p1 = -v1[0]*v2[1]+v1[1]*v2[0]; + r = e[0]*std::fabs(f1[1])+e[1]*std::fabs(f1[0]); + mmm = std::max(-std::max(p0, p1), std::min(p0, p1)); + if (mmm > r+eps) { + return false; + } + + // test a22 + p0 = v0[0]*v2[1]-v0[1]*v2[0]; + p1 = v0[0]*v1[1]-v0[1]*v1[0]+v1[0]*v2[1]-v1[1]*v2[0]; + r = e[0]*std::fabs(f2[1])+e[1]*std::fabs(f2[0]); + mmm = std::max(-std::max(p0, p1), std::min(p0, p1)); + if (mmm > r+eps) { + return false; + } + + if (std::max(std::max(v0[0], v1[0]), v2[0]) < -e[0] || std::min(std::min(v0[0], v1[0]), v2[0]) > e[0]) { + return false; + } + if (std::max(std::max(v0[1], v1[1]), v2[1]) < -e[1] || std::min(std::min(v0[1], v1[1]), v2[1]) > e[1]) { + return false; + } + if (std::max(std::max(v0[2], v1[2]), v2[2]) < -e[2] || std::min(std::min(v0[2], v1[2]), v2[2]) > e[2]) { + return false; + } + + /* Test intersection cuboids - triangle plane*/ + r = e[0]*std::fabs(tri.normal[0]) + e[1]*std::fabs(tri.normal[1]) + e[2]*std::fabs(tri.normal[2]); + T s = tri.normal[0]*c[0] + tri.normal[1]*c[1] + tri.normal[2]*c[2] - tri.d; + return (fabs(s) <= r); +} + +template +Octree* Octree::find(const Vector& pt,const int& maxDepth) +{ + // clout << pt[0] << " " << pt[1] << " " << pt[2] << std::endl; + + if (_isLeaf || maxDepth == _maxDepth) { + if (std::abs(_center[0] - pt[0]) < _radius + std::numeric_limits::epsilon() && + std::abs(_center[1] - pt[1]) < _radius + std::numeric_limits::epsilon() && + std::abs(_center[2] - pt[2]) < _radius + std::numeric_limits::epsilon()) { + // clout << pt[0] << " " << pt[1] << " " << pt[2] << std::endl; + return this; + } else { + OstreamManager clout(std::cout, "Octree"); + clout << "Point: " << std::setprecision(10) << pt[0]<< " " <find] Point outside of geometry."); + return nullptr; + } + } else { + if (pt[0] < _center[0]) { + if (pt[1] < _center[1]) { + if (pt[2] < _center[2]) { + return _child[2]->find(pt, maxDepth); + } else { + return _child[0]->find(pt, maxDepth); + } + } else { + if (pt[2] < _center[2]) { + return _child[6]->find(pt, maxDepth); + } else { + return _child[4]->find(pt, maxDepth); + } + } + } else { + if (pt[1] < _center[1]) { + if (pt[2] < _center[2]) { + return _child[3]->find(pt, maxDepth); + } else { + return _child[1]->find(pt, maxDepth); + } + } else { + if (pt[2] < _center[2]) { + return _child[7]->find(pt, maxDepth); + } else { + return _child[5]->find(pt, maxDepth); + } + } + } + } +} + +template +int Octree::testIntersection(const Vector& pt,const Vector& dir, bool print) +{ + int intersections = 0; + Vector q; + std::vector > qs; + T a; +#ifdef OLB_DEBUG + if (print) { + OstreamManager clout(std::cout, "Octree"); + clout << "Center: " << _center[0] << " " << _center[1] << " "<< _center[2] << " Dir: " << dir[0] << " " << dir[1] << " "<< dir[2] << std::endl; + clout << "Tris: "; + for (unsigned k=0; k<_triangles.size(); ++k) { + clout << _triangles[k] << " "; + } + clout << std::endl; + } +#endif + for (unsigned k=0; k<_triangles.size(); ++k) { + if (_mesh->getTri(_triangles[k]).testRayIntersect(pt, dir, q, a)) { + if (std::fabs(_center[0]-q[0]) <= _radius + std::numeric_limits::epsilon() + 1/1000. * _radius && std::fabs(_center[1]-q[1]) <= _radius + std::numeric_limits::epsilon() + 1/1000. * _radius && std::fabs(_center[2]-q[2]) <= _radius + std::numeric_limits::epsilon() + 1/1000. * _radius) { + bool newpoint=true; + for (unsigned i=0; i +void Octree::checkRay(const Vector& pt,const Vector& dir, unsigned short& rayInside) +{ + unsigned short left=0, right=0; + Vector dirNormed(dir); + dirNormed.normalize(); + dirNormed*= _radius * 2.; + Vector q; + std::vector > qs; + T a = 1.; + + for (unsigned int k=0; k<_triangles.size(); ++k) { + if (_mesh->getTri(_triangles[k]).testRayIntersect(pt, dirNormed, q, a, 0.) && a<1.) { + bool newpoint=true; + for (unsigned int i=0; i +void Octree::getCenterpoints(std::vector >& pts) +{ + if (_isLeaf) { + pts.push_back(_center); + } else { + for (int i=0; i<8; i++) { + _child[i]->getCenterpoints(pts); + } + } +} + +template +void Octree::getLeafs(std::vector* >& pts) +{ + if (_isLeaf) { + pts.push_back(this); + } else { + for (int i=0; i<8; i++) { + _child[i]->getLeafs(pts); + } + } +} + +template +bool Octree::isLeaf() +{ + return _isLeaf; +} + +template +void Octree::write(const Vector& pt,const std::string no) +{ + if (_triangles.size()>0 && (std::fabs(pt[0]-_center[0]) < _radius && std::fabs(pt[1]-_center[1]) < _radius && std::fabs(pt[2]-_center[2]) < _radius)) { + std::string fullName = singleton::directories().getVtkOutDir() + "Octree_" + no + ".stl"; + std::ofstream f(fullName.c_str()); + if (!f) { + std::cerr << "[Octree] could not open file: " << fullName << std::endl; + } + f << "solid ascii" << std::endl << std::flush; + std::vector::iterator it = _triangles.begin(); + for (; it != _triangles.end(); ++it) { + f << "facet normal" << _mesh->getTri(*it).normal[0] << " " << _mesh->getTri(*it).normal[1] << " " << _mesh->getTri(*it).normal[2] << " " <getTri(*it).point[0].r[0] << " " << _mesh->getTri(*it).point[0].r[1] << " " << _mesh->getTri(*it).point[0].r[2] << "\n"; + f << " vertex " << _mesh->getTri(*it).point[1].r[0] << " " << _mesh->getTri(*it).point[1].r[1] << " " << _mesh->getTri(*it).point[1].r[2] << "\n"; + f << " vertex " << _mesh->getTri(*it).point[2].r[0] << " " << _mesh->getTri(*it).point[2].r[1] << " " << _mesh->getTri(*it).point[2].r[2] << "\n"; + f << " endloop\n"; + f << "endfacet\n"; + } + f.close(); + } + if (!_isLeaf) { + for (int i=0; i<8; i++) { + std::stringstream istr; + istr << i; + _child[i]->write(pt, no+istr.str()); + } + } +} + +template +void Octree::write(const int depth,const std::string no) +{ + if (_triangles.size()>0 && _maxDepth == depth) { + std::string fullName = singleton::directories().getVtkOutDir() + "Octree_" + no + ".stl"; + std::ofstream f(fullName.c_str()); + if (!f) { + std::cerr << "[Octree] could not open file: " << fullName << std::endl; + } + f << "solid ascii" << std::endl << std::flush; + std::vector::iterator it = _triangles.begin(); + for (; it != _triangles.end(); ++it) { + f << "facet normal" << _mesh->getTri(*it).normal[0] << " " << _mesh->getTri(*it).normal[1] << " " << _mesh->getTri(*it).normal[2] << " " <getTri(*it).point[0].r[0] << " " << _mesh->getTri(*it).point[0].r[1] << " " << _mesh->getTri(*it).point[0].r[2] << "\n"; + f << " vertex " << _mesh->getTri(*it).point[1].r[0] << " " << _mesh->getTri(*it).point[1].r[1] << " " << _mesh->getTri(*it).point[1].r[2] << "\n"; + f << " vertex " << _mesh->getTri(*it).point[2].r[0] << " " << _mesh->getTri(*it).point[2].r[1] << " " << _mesh->getTri(*it).point[2].r[2] << "\n"; + f << " endloop\n"; + f << "endfacet\n"; + } + f.close(); + } + if (!_isLeaf) { + for (int i=0; i<8; i++) { + std::stringstream istr; + istr << i; + _child[i]->write(depth, no+istr.str()); + } + } +} + + +template +void Octree::write(const std::string fName) +{ + int rank = 0; +#ifdef PARALLEL_MODE_MPI + rank = singleton::mpi().getRank(); +#endif + if (rank==0) { + std::vector* > leafs; + getLeafs(leafs); + typename std::vector* >::iterator it = leafs.begin(); + + std::string fullName = singleton::directories().getVtkOutDir() + fName + ".vtk"; + std::ofstream f(fullName.c_str()); + if (!f) { + std::cerr << "[Particles3D] could not open file: " << fullName << std::endl; + } + f << "# vtk DataFile Version 2.0" << std::endl << std::flush; + f << "Octree"<< std::endl << std::flush; + f << "ASCII"<< std::endl << std::flush; + f << "DATASET UNSTRUCTURED_GRID"<< std::endl << std::flush; + std::stringstream points; + std::stringstream cells; + std::stringstream cell_types; + // std::stringstream point_data; + std::stringstream cell_data; + std::stringstream cell_leaf; + std::stringstream cell_boundary; + + points << "POINTS " << leafs.size()*8 << " float" << std::endl; + cells << "CELLS " << leafs.size() << " " << leafs.size()*9 << std::endl; + cell_types << "CELL_TYPES " << leafs.size() << std::endl; + cell_data << "CELL_DATA " << leafs.size() << std::endl; + cell_data << "SCALARS insideout int" << std::endl; + cell_data << "LOOKUP_TABLE default" << std::endl; + cell_leaf << "SCALARS leaf int" << std::endl; + cell_leaf << "LOOKUP_TABLE default" << std::endl; + cell_boundary << "SCALARS boundary int" << std::endl; + cell_boundary << "LOOKUP_TABLE default" << std::endl; + + Vector center; + Vector pt; + + T rad; + int i=0; + for (; it != leafs.end(); ++it) { + center = (*it)->getCenter(); + rad = (*it)->getRadius(); + + pt[0] = center[0] - rad; + pt[1] = center[1] - rad; + pt[2] = center[2] - rad; + points << pt[0]<< " " << pt[1]<< " " << pt[2] << " "; + + pt[0] = center[0] + rad; + pt[1] = center[1] - rad; + pt[2] = center[2] - rad; + points << pt[0]<< " " << pt[1]<< " " << pt[2] << " "; + + pt[0] = center[0] - rad; + pt[1] = center[1] + rad; + pt[2] = center[2] - rad; + points << pt[0]<< " " << pt[1]<< " " << pt[2] << " "; + + pt[0] = center[0] + rad; + pt[1] = center[1] + rad; + pt[2] = center[2] - rad; + points << pt[0]<< " " << pt[1]<< " " << pt[2] << " "; + + pt[0] = center[0] - rad; + pt[1] = center[1] - rad; + pt[2] = center[2] + rad; + points << pt[0]<< " " << pt[1]<< " " << pt[2] << " "; + + pt[0] = center[0] + rad; + pt[1] = center[1] - rad; + pt[2] = center[2] + rad; + points << pt[0]<< " " << pt[1]<< " " << pt[2] << " "; + + pt[0] = center[0] - rad; + pt[1] = center[1] + rad; + pt[2] = center[2] + rad; + points << pt[0]<< " " << pt[1]<< " " << pt[2] << " "; + + pt[0] = center[0] + rad; + pt[1] = center[1] + rad; + pt[2] = center[2] + rad; + points << pt[0]<< " " << pt[1]<< " " << pt[2] << " " << std::endl; + + cells << "8 "; + for (int j=0; j<8; j++) { + cells << i+j << " "; + } + i+=8; + cells << std::endl; + + cell_types << 11 << std::endl; + + cell_data << (*it)->getInside() << " "<< std::endl; + cell_leaf << (*it)->getMaxdepth() << " "<< std::endl; + cell_boundary << (*it)->getBoundaryNode() << " " << std::endl; + } + + f << points.str() << cells.str() << cell_types.str() << cell_data.str() << cell_leaf.str() << cell_boundary.str(); + + // f << "POINT_DATA 0\nCELL_DATA 0\n" << std::endl; + f.close(); + } + OstreamManager clout(std::cout, "Octree"); + /*if (_verbose)*/ clout << "Write ... OK" << std::endl; +} + +template +bool Octree::closestIntersectionSphere(const Vector& pt, const T& rad, const Vector& direction, Vector& q, T& a, STLtriangle& tri) +{ + a = std::numeric_limits::infinity(); + T alpha = T(); + std::vector qtmp(3, T()); + bool found = false; + for (unsigned int k=0; k<_triangles.size(); ++k) { + if (_mesh->getTri(_triangles[k]).testMovingSphereIntersect(pt, rad, direction, qtmp, alpha)) { + if (alpha < a) { + a = alpha; + q = qtmp; + found = true; + tri = _mesh->getTri(_triangles[k]); + } + } + } + return found; +} + +template +bool Octree::closestIntersection(const Vector& pt, const Vector& direction, Vector& q, T& a, STLtriangle& tri, const T& rad, bool print) +{ + a = std::numeric_limits::infinity(); + T alpha = T(); + Vector qtmp; + bool found = false; +#ifdef OLB_DEBUG + if (print) { + std::cout << "Tri Size: " << _triangles.size() << std::endl; + } +#endif + + for (unsigned int k=0; k<_triangles.size(); ++k) { + if (_mesh->getTri(_triangles[k]).testRayIntersect(pt, direction, qtmp, alpha, rad)) { + if (print) { + std::cout << "Found intersection!" << std::endl; + } + if (alpha < a) { + a = alpha; + q = qtmp; + found = true; + tri = _mesh->getTri(_triangles[k]); + } + } + } + // std::cout << a << std::endl; + return found; +} + +template +bool Octree::closestIntersection(const Vector& pt, const Vector& direction, Vector& q, T& a) +{ + STLtriangle tri; + return closestIntersection(pt, direction, q, a, tri, 0.); +} + +template +void Octree::intersectRayNode(const Vector& pt, const Vector& dir, Vector& s) +{ + T t,d; + s*=T(); + //Plane Normals outside + + if (dir[0] > 0.) { + // n = {1, 0, 0} + d = _center[0] + _radius; + t = (d - pt[0])/dir[0]; + s = pt + t*dir; + if (std::fabs(s[1]-_center[1]) < _radius && std::fabs(s[2]-_center[2]) < _radius) { + return; + } + } else if (dir[0] < 0.) { + // n = {-1, 0, 0} + d = _center[0] - _radius; + t = (d - pt[0])/dir[0]; + s = pt + t*dir; + if (std::fabs(s[1]-_center[1]) < _radius && std::fabs(s[2]-_center[2]) < _radius) { + return; + } + } + + if (dir[1] > 0.) { + d = _center[1] + _radius; + t = (d - pt[1])/dir[1]; + s = pt + t*dir; + if (std::fabs(s[0]-_center[0]) < _radius && std::fabs(s[2]-_center[2]) < _radius) { + return; + } + } else if (dir[1] < 0.) { + // n = {0, 0, -1} + d = _center[1] - _radius; + t = (d - pt[1])/dir[1]; + s = pt + t*dir; + if (std::fabs(s[0]-_center[0]) < _radius && std::fabs(s[2]-_center[2]) < _radius) { + return; + } + } + + if (dir[2] > 0.) { + // n = {0, 0, 1} + d = _center[2] + _radius; + t = (d - pt[2])/dir[2]; + s = pt + t*dir; + if (std::fabs(s[0]-_center[0]) < _radius && std::fabs(s[1]-_center[1]) < _radius) { + return; + } + } else if (dir[2] < 0.) { + // n = {0, 0, -1} + d = _center[2] - _radius; + t = (d - pt[2])/dir[2]; + s = pt + t*dir; + if (std::fabs(s[0]-_center[0]) < _radius && std::fabs(s[1]-_center[1]) < _radius) { + return; + } + } +} + +template +void Octree::print() +{ + OstreamManager clout(std::cout, "Octree"); + clout << "radius=" << _radius << "; center=(" << _center[0] << "," << _center[1] << "," << _center[2] << ")" << std::endl; +} + +template +void Octree::trianglesOnLine(const Vector& pt1, const Vector& pt2, std::set& tris) +{ + tris.clear(); + std::vector line = pt2-pt1; + std::vector s = pt1; + T lineNorm2 = line[0] * line[0] + line[1] * line[1] + line[2] * line[2]; + T dist2 = T(); + Octree* node = NULL; + int it = 0; + while (dist2 < lineNorm2 && it < 50) { + node = find(s); + tris.insert(node->_triangles.begin(), node->_triangles.end()); + node->intersectRayNode(s, line, s); + for (int i=0; i<3; i++) { + s[i] = s[i] + line[i]*_radius*0.001 /* *node->getRadius()*/; + } + it++; + dist2 = (pt1[0]-s[0])*(pt1[0]-s[0]) + (pt1[1]-s[1])*(pt1[1]-s[1]) + (pt1[2]-s[2])*(pt1[2]-s[2]); + } + + +} + +} + +#endif -- cgit v1.2.3