Nori

include/nori/kdtree.h

Go to the documentation of this file.
00001 /*
00002     This class contains a implementation of a KD-Tree to compute ray-triangle
00003         intersections in three dimensions. It was originally part of Mitsuba and 
00004         slightly adapted for
00005 
00006     Copyright (c) 2007-2012 by Wenzel Jakob
00007 
00008     Mitsuba is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License Version 3
00010     as published by the Free Software Foundation.
00011 
00012     Mitsuba is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program. If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 #if !defined(__KDTREE_H)
00022 #define __KDTREE_H
00023 
00024 #include <nori/gkdtree.h>
00025 #include <nori/mesh.h>
00026 
00027 NORI_NAMESPACE_BEGIN
00028 
00029 /**
00030  * \brief Specializes \ref GenericKDTree to a three-dimensional
00031  * tree that can be used to intersect rays against triangles meshes.
00032  *
00033  * The internal tree construction algorithm generates a surface area
00034  * heuristic (SAH) kd-tree using the "perfect splits" optimization.
00035  *
00036  * This class also implements an robust adapted version of the optimized 
00037  * ray traversal algorithm (TA^B_{rec}), which is explained in Vlastimil 
00038  * Havran's PhD thesis "Heuristic Ray Shooting Algorithms". 
00039  *
00040  * \author Wenzel Jakob
00041  */
00042 class KDTree : public GenericKDTree<BoundingBox3f, SurfaceAreaHeuristic3, KDTree> {
00043 protected:
00044         typedef GenericKDTree<BoundingBox3f, SurfaceAreaHeuristic3, KDTree>  Parent;
00045         typedef Parent::SizeType                                             SizeType;
00046         typedef Parent::IndexType                                            IndexType;
00047         typedef Parent::KDNode                                               KDNode;
00048 
00049         using Parent::m_nodes;
00050         using Parent::m_bbox;
00051         using Parent::m_indices;
00052 
00053 public:
00054         /// Create a new and empty kd-tree
00055         KDTree();
00056 
00057         /// Release all memory
00058         virtual ~KDTree();
00059 
00060         /**
00061          * \brief Register a triangle mesh for inclusion in the kd-tree.
00062          *
00063          * This function can only be used before \ref build() is called
00064          */
00065         void addMesh(Mesh *mesh);
00066 
00067         /// Build the kd-tree
00068         void build();
00069 
00070         /**
00071          * \brief Intersect a ray against all triangle meshes registered
00072          * with the kd-tree
00073          *
00074          * Detailed information about the intersection, if any, will be
00075          * stored in the provided \ref Intersection data record. 
00076          *
00077          * The <tt>shadowRay</tt> parameter specifies whether this detailed
00078          * information is really needed. When set to \c true, the 
00079          * function just checks whether or not there is occlusion, but without
00080          * providing any more detail (i.e. \c its will not be filled with
00081          * contents). This is usually much faster.
00082          *
00083          * \return \c true If an intersection was found
00084          */
00085         bool rayIntersect(const Ray3f &ray, Intersection &its, 
00086                 bool shadowRay = false) const;
00087 
00088         /// Return the total number of internally represented triangles 
00089         inline SizeType getPrimitiveCount() const { return m_primitiveCount; }
00090 
00091         /// Return the total number of meshes registered with the kd-tree
00092         inline SizeType getMeshCount() const { return (SizeType) m_meshes.size(); }
00093 
00094         /// Return one of the registered meshes
00095         inline Mesh *getMesh(IndexType idx) { return m_meshes[idx]; }
00096         
00097         /// Return one of the registered meshes (const version)
00098         inline const Mesh *getMesh(IndexType idx) const { return m_meshes[idx]; }
00099 
00100         //// Return an axis-aligned bounding box containing the entire tree
00101         inline const BoundingBox3f &getBoundingBox() const {
00102                 return m_bbox;
00103         }
00104 
00105         //// Return an axis-aligned bounding box containing the given triangle
00106         inline BoundingBox3f getBoundingBox(IndexType index) const {
00107                 IndexType meshIdx = findMesh(index);
00108                 return m_meshes[meshIdx]->getBoundingBox(index);
00109         }
00110 
00111         /**
00112          * \brief Returns the axis-aligned bounding box of a triangle after it has 
00113          * clipped to the extents of another given bounding box.
00114          *
00115          * See \ref Mesh::getClippedBoundingBox() for details
00116          */
00117         inline BoundingBox3f getClippedBoundingBox(IndexType index, const BoundingBox3f &clip) const {
00118                 IndexType meshIdx = findMesh(index);
00119                 return m_meshes[meshIdx]->getClippedBoundingBox(index, clip);
00120         }
00121 protected:
00122         /**
00123          * \brief Compute the mesh and triangle indices corresponding to 
00124          * a primitive index used by the underlying generic kd-tree implementation. 
00125          */
00126         IndexType findMesh(IndexType &idx) const {
00127                 std::vector<IndexType>::const_iterator it = std::lower_bound(
00128                                 m_sizeMap.begin(), m_sizeMap.end(), idx+1) - 1;
00129                 idx -= *it;
00130                 return (IndexType) (it - m_sizeMap.begin());
00131         }
00132 private:
00133         std::vector<Mesh *> m_meshes;
00134         std::vector<SizeType> m_sizeMap;
00135         SizeType m_primitiveCount;
00136 };
00137 
00138 NORI_NAMESPACE_END
00139 
00140 #endif /* __KDTREE_H */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines