From 3c4e78f24f6e0f275808832ac7d828cb978ef2e6 Mon Sep 17 00:00:00 2001 From: dbp Date: Wed, 15 Jan 2014 17:21:18 +0400 Subject: [PATCH] 0024473: TKMath, BVH - introduce template-based package for Bounding volume hierarchy structures and tools --- adm/UDLIST | 1 + src/BVH/BVH.cxx | 121 ++++++++++++ src/BVH/BVH_BinnedBuilder.hxx | 69 +++++++ src/BVH/BVH_BinnedBuilder.lxx | 256 ++++++++++++++++++++++++++ src/BVH/BVH_Box.hxx | 98 ++++++++++ src/BVH/BVH_Box.lxx | 263 +++++++++++++++++++++++++++ src/BVH/BVH_Builder.hxx | 67 +++++++ src/BVH/BVH_Builder.lxx | 84 +++++++++ src/BVH/BVH_Geometry.hxx | 68 +++++++ src/BVH/BVH_Geometry.lxx | 123 +++++++++++++ src/BVH/BVH_Object.hxx | 59 ++++++ src/BVH/BVH_Object.lxx | 65 +++++++ src/BVH/BVH_ObjectSet.hxx | 74 ++++++++ src/BVH/BVH_ObjectSet.lxx | 115 ++++++++++++ src/BVH/BVH_PrimitiveSet.hxx | 66 +++++++ src/BVH/BVH_PrimitiveSet.lxx | 106 +++++++++++ src/BVH/BVH_Properties.cxx | 22 +++ src/BVH/BVH_Properties.hxx | 74 ++++++++ src/BVH/BVH_Properties.lxx | 223 +++++++++++++++++++++++ src/BVH/BVH_Set.hxx | 60 ++++++ src/BVH/BVH_Set.lxx | 49 +++++ src/BVH/BVH_Sorter.hxx | 41 +++++ src/BVH/BVH_Sorter.lxx | 75 ++++++++ src/BVH/BVH_SpatialMedianBuilder.hxx | 38 ++++ src/BVH/BVH_SpatialMedianBuilder.lxx | 39 ++++ src/BVH/BVH_SweepPlaneBuilder.hxx | 45 +++++ src/BVH/BVH_SweepPlaneBuilder.lxx | 183 +++++++++++++++++++ src/BVH/BVH_Tree.hxx | 239 ++++++++++++++++++++++++ src/BVH/BVH_Tree.lxx | 139 ++++++++++++++ src/BVH/BVH_Triangulation.hxx | 65 +++++++ src/BVH/BVH_Triangulation.lxx | 97 ++++++++++ src/BVH/BVH_Types.hxx | 130 +++++++++++++ src/BVH/BVH_Types.lxx | 112 ++++++++++++ src/BVH/FILES | 32 ++++ src/NCollection/NCollection_Vec2.hxx | 14 ++ src/NCollection/NCollection_Vec3.hxx | 16 ++ src/NCollection/NCollection_Vec4.hxx | 18 ++ src/TKMath/PACKAGES | 1 + 38 files changed, 3347 insertions(+) create mode 100644 src/BVH/BVH.cxx create mode 100644 src/BVH/BVH_BinnedBuilder.hxx create mode 100644 src/BVH/BVH_BinnedBuilder.lxx create mode 100644 src/BVH/BVH_Box.hxx create mode 100644 src/BVH/BVH_Box.lxx create mode 100644 src/BVH/BVH_Builder.hxx create mode 100644 src/BVH/BVH_Builder.lxx create mode 100644 src/BVH/BVH_Geometry.hxx create mode 100644 src/BVH/BVH_Geometry.lxx create mode 100644 src/BVH/BVH_Object.hxx create mode 100644 src/BVH/BVH_Object.lxx create mode 100644 src/BVH/BVH_ObjectSet.hxx create mode 100644 src/BVH/BVH_ObjectSet.lxx create mode 100644 src/BVH/BVH_PrimitiveSet.hxx create mode 100644 src/BVH/BVH_PrimitiveSet.lxx create mode 100644 src/BVH/BVH_Properties.cxx create mode 100644 src/BVH/BVH_Properties.hxx create mode 100644 src/BVH/BVH_Properties.lxx create mode 100644 src/BVH/BVH_Set.hxx create mode 100644 src/BVH/BVH_Set.lxx create mode 100644 src/BVH/BVH_Sorter.hxx create mode 100644 src/BVH/BVH_Sorter.lxx create mode 100644 src/BVH/BVH_SpatialMedianBuilder.hxx create mode 100644 src/BVH/BVH_SpatialMedianBuilder.lxx create mode 100644 src/BVH/BVH_SweepPlaneBuilder.hxx create mode 100644 src/BVH/BVH_SweepPlaneBuilder.lxx create mode 100644 src/BVH/BVH_Tree.hxx create mode 100644 src/BVH/BVH_Tree.lxx create mode 100644 src/BVH/BVH_Triangulation.hxx create mode 100644 src/BVH/BVH_Triangulation.lxx create mode 100644 src/BVH/BVH_Types.hxx create mode 100644 src/BVH/BVH_Types.lxx create mode 100644 src/BVH/FILES diff --git a/adm/UDLIST b/adm/UDLIST index b150602ca6..8568959596 100644 --- a/adm/UDLIST +++ b/adm/UDLIST @@ -3,6 +3,7 @@ n NCollection p BSplCLib p BSplSLib p Bnd +p BVH p CSLib p Convert p Dico diff --git a/src/BVH/BVH.cxx b/src/BVH/BVH.cxx new file mode 100644 index 0000000000..9f92ebade4 --- /dev/null +++ b/src/BVH/BVH.cxx @@ -0,0 +1,121 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include + +// Specific instantiations of struct templates to avoid compilation warnings + +template class BVH_Box; +template class BVH_Box; +template class BVH_Box; + +template class BVH_Box; +template class BVH_Box; +template class BVH_Box; + +template class BVH_Set; +template class BVH_Set; +template class BVH_Set; + +template class BVH_Set; +template class BVH_Set; +template class BVH_Set; + +template class BVH_Object; +template class BVH_Object; +template class BVH_Object; + +template class BVH_Object; +template class BVH_Object; +template class BVH_Object; + +template class BVH_ObjectSet; +template class BVH_ObjectSet; +template class BVH_ObjectSet; + +template class BVH_ObjectSet; +template class BVH_ObjectSet; +template class BVH_ObjectSet; + +template class BVH_Geometry; +template class BVH_Geometry; +template class BVH_Geometry; + +template class BVH_Geometry; +template class BVH_Geometry; +template class BVH_Geometry; + +template class BVH_Tree; +template class BVH_Tree; +template class BVH_Tree; + +template class BVH_Tree; +template class BVH_Tree; +template class BVH_Tree; + +template class BVH_Builder; +template class BVH_Builder; +template class BVH_Builder; + +template class BVH_Builder; +template class BVH_Builder; +template class BVH_Builder; + +template class BVH_BinnedBuilder; +template class BVH_BinnedBuilder; +template class BVH_BinnedBuilder; + +template class BVH_BinnedBuilder; +template class BVH_BinnedBuilder; +template class BVH_BinnedBuilder; + +template class BVH_SweepPlaneBuilder; +template class BVH_SweepPlaneBuilder; +template class BVH_SweepPlaneBuilder; + +template class BVH_SweepPlaneBuilder; +template class BVH_SweepPlaneBuilder; +template class BVH_SweepPlaneBuilder; + +template class BVH_SpatialMedianBuilder; +template class BVH_SpatialMedianBuilder; +template class BVH_SpatialMedianBuilder; + +template class BVH_SpatialMedianBuilder; +template class BVH_SpatialMedianBuilder; +template class BVH_SpatialMedianBuilder; + +template class BVH_PrimitiveSet; +template class BVH_PrimitiveSet; +template class BVH_PrimitiveSet; + +template class BVH_PrimitiveSet; +template class BVH_PrimitiveSet; +template class BVH_PrimitiveSet; + +template class BVH_Triangulation; +template class BVH_Triangulation; +template class BVH_Triangulation; + +template class BVH_Triangulation; +template class BVH_Triangulation; +template class BVH_Triangulation; + +template class BVH_Transform; +template class BVH_Transform; diff --git a/src/BVH/BVH_BinnedBuilder.hxx b/src/BVH/BVH_BinnedBuilder.hxx new file mode 100644 index 0000000000..d472640790 --- /dev/null +++ b/src/BVH/BVH_BinnedBuilder.hxx @@ -0,0 +1,69 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BVH_BinnedBuilder_Header +#define _BVH_BinnedBuilder_Header + +#include + +//! Stores parameters of single node bin (slice of AABB). +template +struct BVH_Bin +{ + //! Creates new node bin. + BVH_Bin() : Count (0) {} + + Standard_Integer Count; //!< Number of primitives in the bin + BVH_Box Box; //!< AABB of the bin +}; + +//! Performs building of BVH tree using binned SAH algorithm. +//! Number of Bins controls tree's quality (greater - better) in cost of construction time. +template +class BVH_BinnedBuilder : public BVH_Builder +{ +public: + + //! Type for the array of bins of BVH tree node. + typedef BVH_Bin BVH_BinVector[Bins]; + +public: + + //! Creates binned SAH BVH builder. + BVH_BinnedBuilder (const Standard_Integer theLeafNodeSize = 5, + const Standard_Integer theMaxTreeDepth = 32); + + //! Releases resources of binned SAH BVH builder. + virtual ~BVH_BinnedBuilder(); + +protected: + + //! Builds BVH node for specified task info. + virtual void BuildNode (BVH_Set* theSet, + BVH_Tree* theBVH, + const Standard_Integer theNode); + + //! Arranges node primitives into bins. + virtual void GetSubVolumes (BVH_Set* theSet, + BVH_Tree* theBVH, + const Standard_Integer theNode, + BVH_BinVector& theBins, + const Standard_Integer theAxis); + +}; + +#include + +#endif // _BVH_BinnedBuilder_Header diff --git a/src/BVH/BVH_BinnedBuilder.lxx b/src/BVH/BVH_BinnedBuilder.lxx new file mode 100644 index 0000000000..0cf105d335 --- /dev/null +++ b/src/BVH/BVH_BinnedBuilder.lxx @@ -0,0 +1,256 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +// ======================================================================= +// function : BVH_BinnedBuilder +// purpose : +// ======================================================================= +template +BVH_BinnedBuilder::BVH_BinnedBuilder (const Standard_Integer theLeafNodeSize, + const Standard_Integer theMaxTreeDepth) +: BVH_Builder (theLeafNodeSize, + theMaxTreeDepth) +{ + // +} + +// ======================================================================= +// function : ~BVH_BinnedBuilder +// purpose : +// ======================================================================= +template +BVH_BinnedBuilder::~BVH_BinnedBuilder() +{ + // +} + +// ======================================================================= +// function : GetSubVolumes +// purpose : +// ======================================================================= +template +void BVH_BinnedBuilder::GetSubVolumes (BVH_Set* theSet, + BVH_Tree* theBVH, + const Standard_Integer theNode, + BVH_BinVector& theBins, + const Standard_Integer theAxis) +{ + const T aMin = BVHTools::VecComp::Get (theBVH->MinPoint (theNode), theAxis); + const T aMax = BVHTools::VecComp::Get (theBVH->MaxPoint (theNode), theAxis); + + const T anInvStep = static_cast (Bins) / (aMax - aMin); + + for (Standard_Integer anIdx = theBVH->BegPrimitive (theNode); anIdx <= theBVH->EndPrimitive (theNode); ++anIdx) + { + typename BVH_Set::BVH_BoxNt aBox = theSet->Box (anIdx); + + Standard_Integer aBinIndex = static_cast (std::floor ((theSet->Center (anIdx, theAxis) - aMin) * anInvStep)); + if (aBinIndex < 0) + { + aBinIndex = 0; + } + else if (aBinIndex >= Bins) + { + aBinIndex = Bins - 1; + } + + theBins[aBinIndex].Count++; + theBins[aBinIndex].Box.Combine (aBox); + } +} + +namespace BVHTools +{ + // ======================================================================= + // function : SplitPrimitives + // purpose : + // ======================================================================= + template + Standard_Integer SplitPrimitives (BVH_Set* theSet, + const BVH_Box& theBox, + const Standard_Integer theBeg, + const Standard_Integer theEnd, + const Standard_Integer theBin, + const Standard_Integer theAxis, + const Standard_Integer theBins) + { + const T aMin = BVHTools::VecComp::Get (theBox.CornerMin(), theAxis); + const T aMax = BVHTools::VecComp::Get (theBox.CornerMax(), theAxis); + + const T anInvStep = static_cast (theBins) / (aMax - aMin); + + Standard_Integer aLftIdx (theBeg); + Standard_Integer aRghIdx (theEnd); + + do + { + while ((Standard_Integer) std::floor ((theSet->Center (aLftIdx, theAxis) - aMin) * anInvStep) <= theBin && aLftIdx < theEnd) + { + ++aLftIdx; + } + while ((Standard_Integer) std::floor ((theSet->Center (aRghIdx, theAxis) - aMin) * anInvStep) > theBin && aRghIdx > theBeg) + { + --aRghIdx; + } + + if (aLftIdx <= aRghIdx) + { + if (aLftIdx != aRghIdx) + { + theSet->Swap (aLftIdx, aRghIdx); + } + + ++aLftIdx; + --aRghIdx; + } + } while (aLftIdx <= aRghIdx); + + return aLftIdx; + } +} + +#if defined (_WIN32) && defined (max) + #undef max +#endif + +#include + +// ======================================================================= +// function : BuildNode +// purpose : +// ======================================================================= +template +void BVH_BinnedBuilder::BuildNode (BVH_Set* theSet, + BVH_Tree* theBVH, + const Standard_Integer theNode) +{ + const BVH_Box aBox (theBVH->MinPoint (theNode), + theBVH->MaxPoint (theNode)); + + const typename BVH_Box::BVH_VecNt aSize = aBox.Size(); + + // Parameters for storing best split + Standard_Integer aMinSplitAxis = -1; + Standard_Integer aMinSplitIndex = 0; + Standard_Integer aMinSplitNumLft = 0; + Standard_Integer aMinSplitNumRgh = 0; + + BVH_Box aMinSplitBoxLft; + BVH_Box aMinSplitBoxRgh; + + Standard_Real aMinSplitCost = std::numeric_limits::max(); + + // Find best split + for (Standard_Integer anAxis = 0; anAxis < (N < 4 ? N : 3); ++anAxis) + { + if (BVHTools::VecComp::Get (aSize, anAxis) <= THE_NODE_MIN_SIZE) + continue; + + BVH_BinVector aBins; + GetSubVolumes (theSet, theBVH, theNode, aBins, anAxis); + + // Choose the best split (with minimum SAH cost) + for (Standard_Integer aSplit = 1; aSplit < Bins; ++aSplit) + { + Standard_Integer aLftCount = 0; + Standard_Integer aRghCount = 0; + + BVH_Box aLftAABB; + BVH_Box aRghAABB; + + for (Standard_Integer anIndex = 0; anIndex < aSplit; ++anIndex) + { + aLftCount += aBins[anIndex].Count; + aLftAABB.Combine (aBins[anIndex].Box); + } + + for (Standard_Integer anIndex = aSplit; anIndex < Bins; ++anIndex) + { + aRghCount += aBins[anIndex].Count; + aRghAABB.Combine (aBins[anIndex].Box); + } + + // Simple SAH evaluation + Standard_Real aCost = (static_cast (aLftAABB.Area()) /* / aNodeArea */) * aLftCount + + (static_cast (aRghAABB.Area()) /* / aNodeArea */) * aRghCount; + + if (aCost <= aMinSplitCost) + { + aMinSplitCost = aCost; + aMinSplitAxis = anAxis; + aMinSplitIndex = aSplit; + aMinSplitBoxLft = aLftAABB; + aMinSplitBoxRgh = aRghAABB; + aMinSplitNumLft = aLftCount; + aMinSplitNumRgh = aRghCount; + } + } + } + + if (aMinSplitAxis == -1) + { + return; + } + + theBVH->SetInner (theNode); + + const Standard_Integer aMiddle = BVHTools::SplitPrimitives (theSet, aBox, + theBVH->BegPrimitive (theNode), + theBVH->EndPrimitive (theNode), + aMinSplitIndex - 1, + aMinSplitAxis, + Bins); + + static const Standard_Integer aLftNode = 1; + static const Standard_Integer aRghNode = 2; + + // Setting up tasks for child nodes + for (Standard_Integer aSide = aLftNode; aSide <= aRghNode; ++aSide) + { + typename BVH_Box::BVH_VecNt aMinPoint = (aSide == aLftNode) + ? aMinSplitBoxLft.CornerMin() + : aMinSplitBoxRgh.CornerMin(); + typename BVH_Box::BVH_VecNt aMaxPoint = (aSide == aLftNode) + ? aMinSplitBoxLft.CornerMax() + : aMinSplitBoxRgh.CornerMax(); + + Standard_Integer aBegPrimitive = (aSide == aLftNode) + ? theBVH->BegPrimitive (theNode) + : aMiddle; + Standard_Integer aEndPrimitive = (aSide == aLftNode) + ? aMiddle - 1 + : theBVH->EndPrimitive (theNode); + + Standard_Integer aChildIndex = theBVH->AddLeafNode (aMinPoint, aMaxPoint, aBegPrimitive, aEndPrimitive); + + theBVH->Level (aChildIndex) = theBVH->Level (theNode) + 1; + + // Check to see if child node must be split + const Standard_Integer aNbPimitives = (aSide == aLftNode) + ? aMinSplitNumLft + : aMinSplitNumRgh; + + if (aSide == aLftNode) + theBVH->LeftChild (theNode) = aChildIndex; + else + theBVH->RightChild (theNode) = aChildIndex; + + const Standard_Boolean isLeaf = aNbPimitives <= BVH_Builder::myLeafNodeSize + || theBVH->Level (aChildIndex) >= BVH_Builder::myMaxTreeDepth; + + if (!isLeaf) + BVH_Builder::myTasksQueue.Append (aChildIndex); + } +} diff --git a/src/BVH/BVH_Box.hxx b/src/BVH/BVH_Box.hxx new file mode 100644 index 0000000000..f62bbbe0c9 --- /dev/null +++ b/src/BVH/BVH_Box.hxx @@ -0,0 +1,98 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BVH_Box_Header +#define _BVH_Box_Header + +#include + +//! Axis aligned bounding box (AABB). +template +class BVH_Box +{ +public: + + typedef typename BVHTools::VectorType::Type BVH_VecNt; + +public: + + //! Creates uninitialized bounding box. + BVH_Box() : myInitialized (Standard_False) {} + + //! Creates bounding box of given point. + BVH_Box (const BVH_VecNt& thePoint) + : myMinPoint (thePoint), + myMaxPoint (thePoint), + myInitialized (Standard_True) {} + + //! Creates copy of another bounding box. + BVH_Box (const BVH_Box& theBox) + : myMinPoint (theBox.myMinPoint), + myMaxPoint (theBox.myMaxPoint), + myInitialized (theBox.myInitialized) {} + + //! Creates bounding box from corner points. + BVH_Box (const BVH_VecNt& theMinPoint, + const BVH_VecNt& theMaxPoint) + : myMinPoint (theMinPoint), + myMaxPoint (theMaxPoint), + myInitialized (Standard_True) {} + +public: + + //! Clears bounding box. + void Clear(); + + //! Is bounding box valid? + Standard_Boolean IsValid() const; + + //! Appends new point to the bounding box. + void Add (const BVH_VecNt& thePoint); + + //! Combines bounding box with another one. + void Combine (const BVH_Box& theVolume); + + //! Returns minimum point of bounding box. + const BVH_VecNt& CornerMin() const; + + //! Returns maximum point of bounding box. + const BVH_VecNt& CornerMax() const; + + //! Returns minimum point of bounding box. + BVH_VecNt& CornerMin(); + + //! Returns maximum point of bounding box. + BVH_VecNt& CornerMax(); + + //! Returns surface area of bounding box. + T Area() const; + + //! Returns diagonal of bounding box. + BVH_VecNt Size() const; + + //! Returns center of bounding box. + BVH_VecNt Center() const; + +protected: + + BVH_VecNt myMinPoint; //!< Minimum point of bounding box + BVH_VecNt myMaxPoint; //!< Maximum point of bounding box + Standard_Boolean myInitialized; //!< Is bounding box valid? + +}; + +#include + +#endif // _BVH_Box_Header diff --git a/src/BVH/BVH_Box.lxx b/src/BVH/BVH_Box.lxx new file mode 100644 index 0000000000..572fcd8c52 --- /dev/null +++ b/src/BVH/BVH_Box.lxx @@ -0,0 +1,263 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +namespace BVHTools +{ + template + struct CenterAxis { + // Not implemented + }; + + template + struct CenterAxis + { + static T Center (const BVH_Box& theBox, + const Standard_Integer theAxis) + { + if (theAxis == 0) + { + return (theBox.CornerMin().x() + theBox.CornerMax().x()) * static_cast (0.5); + } + else if (theAxis == 1) + { + return (theBox.CornerMin().y() + theBox.CornerMax().y()) * static_cast (0.5); + } + return static_cast (0.0); + } + }; + + template + struct CenterAxis + { + static T Center (const BVH_Box& theBox, + const Standard_Integer theAxis) + { + if (theAxis == 0) + { + return (theBox.CornerMin().x() + theBox.CornerMax().x()) * static_cast (0.5); + } + else if (theAxis == 1) + { + return (theBox.CornerMin().y() + theBox.CornerMax().y()) * static_cast (0.5); + } + else if (theAxis == 2) + { + return (theBox.CornerMin().z() + theBox.CornerMax().z()) * static_cast (0.5); + } + return static_cast (0.0); + } + }; + + template + struct CenterAxis + { + static T Center (const BVH_Box& theBox, + const Standard_Integer theAxis) + { + if (theAxis == 0) + { + return (theBox.CornerMin().x() + theBox.CornerMax().x()) * static_cast (0.5); + } + else if (theAxis == 1) + { + return (theBox.CornerMin().y() + theBox.CornerMax().y()) * static_cast (0.5); + } + else if (theAxis == 2) + { + return (theBox.CornerMin().z() + theBox.CornerMax().z()) * static_cast (0.5); + } + return static_cast (0.0); + } + }; +} + +// ======================================================================= +// function : Clear +// purpose : +// ======================================================================= +template +void BVH_Box::Clear() +{ + myInitialized = Standard_False; +} + +// ======================================================================= +// function : Clear +// purpose : +// ======================================================================= +template +Standard_Boolean BVH_Box::IsValid() const +{ + return myInitialized; +} + +// ======================================================================= +// function : Add +// purpose : +// ======================================================================= +template +void BVH_Box::Add (const BVH_VecNt& thePoint) +{ + if (!myInitialized) + { + myMinPoint = thePoint; + myMaxPoint = thePoint; + + myInitialized = Standard_True; + } + else + { + myMinPoint = myMinPoint.cwiseMin (thePoint); + myMaxPoint = myMaxPoint.cwiseMax (thePoint); + } +} + +// ======================================================================= +// function : Combine +// purpose : +// ======================================================================= +template +void BVH_Box::Combine (const BVH_Box& theBox) +{ + if (!theBox.myInitialized) + { + return; + } + + if (!myInitialized) + { + myMinPoint = theBox.myMinPoint; + myMaxPoint = theBox.myMaxPoint; + + myInitialized = Standard_True; + } + else + { + myMinPoint = myMinPoint.cwiseMin (theBox.myMinPoint); + myMaxPoint = myMaxPoint.cwiseMax (theBox.myMaxPoint); + } +} + +namespace BVHTools +{ + template + struct SurfaceCalculator + { + // Not implemented + }; + + template + struct SurfaceCalculator + { + static T Area (const typename BVH_Box::BVH_VecNt& theSize) + { + return theSize.x() * theSize.y(); + } + }; + + template + struct SurfaceCalculator + { + static T Area (const typename BVH_Box::BVH_VecNt& theSize) + { + return ( theSize.x() * theSize.y() + + theSize.x() * theSize.z() + + theSize.z() * theSize.y() ) * static_cast (2.0); + } + }; + + template + struct SurfaceCalculator + { + static T Area (const typename BVH_Box::BVH_VecNt& theSize) + { + return ( theSize.x() * theSize.y() + + theSize.x() * theSize.z() + + theSize.z() * theSize.y() ) * static_cast (2.0); + } + }; +} + +// ======================================================================= +// function : Area +// purpose : +// ======================================================================= +template +T BVH_Box::Area() const +{ + return BVHTools::SurfaceCalculator::Area (myMaxPoint - myMinPoint); +} + +// ======================================================================= +// function : CornerMin +// purpose : +// ======================================================================= +template +const typename BVH_Box::BVH_VecNt& BVH_Box::CornerMin() const +{ + return myMinPoint; +} + +// ======================================================================= +// function : CornerMax +// purpose : +// ======================================================================= +template +const typename BVH_Box::BVH_VecNt& BVH_Box::CornerMax() const +{ + return myMaxPoint; +} + +// ======================================================================= +// function : CornerMin +// purpose : +// ======================================================================= +template +typename BVH_Box::BVH_VecNt& BVH_Box::CornerMin() +{ + return myMinPoint; +} + +// ======================================================================= +// function : CornerMax +// purpose : +// ======================================================================= +template +typename BVH_Box::BVH_VecNt& BVH_Box::CornerMax() +{ + return myMaxPoint; +} + +// ======================================================================= +// function : Size +// purpose : +// ======================================================================= +template +typename BVH_Box::BVH_VecNt BVH_Box::Size() const +{ + return myMaxPoint - myMinPoint; +} + +// ======================================================================= +// function : Center +// purpose : +// ======================================================================= +template +typename BVH_Box::BVH_VecNt BVH_Box::Center() const +{ + return (myMinPoint + myMaxPoint) * static_cast (0.5); +} diff --git a/src/BVH/BVH_Builder.hxx b/src/BVH/BVH_Builder.hxx new file mode 100644 index 0000000000..e8165a7d4d --- /dev/null +++ b/src/BVH/BVH_Builder.hxx @@ -0,0 +1,67 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BVH_Builder_Header +#define _BVH_Builder_Header + +#include +#include + +#include + +namespace +{ + //! Minimum node size to split. + const Standard_Real THE_NODE_MIN_SIZE = 1e-5; +} + +//! Performs building of BVH tree. +template +class BVH_Builder +{ +public: + + //! Creates abstract BVH builder. + BVH_Builder (const Standard_Integer theLeafNodeSize, + const Standard_Integer theMaxTreeDepth); + + //! Releases resources of BVH builder. + virtual ~BVH_Builder() = 0; + +public: + + //! Builds BVH using specified algorithm. + void Build (BVH_Set* theSet, + BVH_Tree* theBVH, + const BVH_Box& theBox); + +protected: + + //! Builds BVH node for specified task info. + virtual void BuildNode (BVH_Set* theSet, + BVH_Tree* theBVH, + const Standard_Integer theTask); + +protected: + + Standard_Integer myMaxTreeDepth; //!< Maximum depth of constructed BVH + Standard_Integer myLeafNodeSize; //!< Maximum number of primitives per leaf + NCollection_Vector myTasksQueue; //!< Queue to manage BVH node building tasks + +}; + +#include + +#endif // _BVH_Builder_Header diff --git a/src/BVH/BVH_Builder.lxx b/src/BVH/BVH_Builder.lxx new file mode 100644 index 0000000000..11662cddcd --- /dev/null +++ b/src/BVH/BVH_Builder.lxx @@ -0,0 +1,84 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +// ======================================================================= +// function : BVH_Builder +// purpose : +// ======================================================================= +template +BVH_Builder::BVH_Builder (const Standard_Integer theLeafNodeSize, + const Standard_Integer theMaxTreeDepth) +: myMaxTreeDepth (theMaxTreeDepth), + myLeafNodeSize (theLeafNodeSize) +{ + // +} + +// ======================================================================= +// function : ~BVH_Builder +// purpose : +// ======================================================================= +template +BVH_Builder::~BVH_Builder() +{ + // +} + +// ======================================================================= +// function : Build +// purpose : +// ======================================================================= +template +void BVH_Builder::Build (BVH_Set* theSet, + BVH_Tree* theBVH, + const BVH_Box& theBox) +{ + if (theBVH == NULL) + { + return; + } + + theBVH->Clear(); + if (theSet->Size() == 0) + { + return; + } + + const Standard_Integer aRoot = theBVH->AddLeafNode (theBox, 0, theSet->Size() - 1); + if (theSet->Size() == 1) + { + return; + } + + myTasksQueue.Append (aRoot); + for (Standard_Integer aTask = 0; aTask < myTasksQueue.Size(); ++aTask) + { + BuildNode (theSet, theBVH, myTasksQueue.Value (aTask)); + } + + myTasksQueue.Clear(); +} + +// ======================================================================= +// function : BuildNode +// purpose : +// ======================================================================= +template +void BVH_Builder::BuildNode (BVH_Set* , + BVH_Tree* , + const Standard_Integer ) +{ + // need to disable compile warnings +} diff --git a/src/BVH/BVH_Geometry.hxx b/src/BVH/BVH_Geometry.hxx new file mode 100644 index 0000000000..1bb856edda --- /dev/null +++ b/src/BVH/BVH_Geometry.hxx @@ -0,0 +1,68 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BVH_Geometry_Header +#define _BVH_Geometry_Header + +#include +#include + +//! BVH geometry as a set of abstract geometric objects. +template +class BVH_Geometry : public BVH_ObjectSet +{ +public: + + //! Creates uninitialized BVH geometry. + BVH_Geometry(); + + //! Releases resources of BVH geometry. + virtual ~BVH_Geometry(); + +public: + + //! Marks geometry as outdated. + virtual void MarkDirty(); + + //! Returns AABB of whole geometry. + virtual BVH_Box Box() const; + + //! Returns constructed BVH tree. + virtual const NCollection_Handle >& BVH(); + + //! Returns the method (builder) to construct BVH. + virtual const NCollection_Handle >& Builder() const; + + //! Sets the method (builder) to construct BVH. + virtual void SetBuilder (NCollection_Handle >& theBuilder); + +protected: + + //! Updates internal geometry state. + virtual void Update(); + +protected: + + Standard_Boolean myIsDirty; //!< Is geometry state outdated? + NCollection_Handle > myBVH; //!< Constructed hight-level BVH + NCollection_Handle > myBuilder; //!< Builder for hight-level BVH + + mutable BVH_Box myBox; //!< Cached bounding box of geometric objects + +}; + +#include + +#endif // _BVH_Geometry_Header diff --git a/src/BVH/BVH_Geometry.lxx b/src/BVH/BVH_Geometry.lxx new file mode 100644 index 0000000000..beaf2d79d9 --- /dev/null +++ b/src/BVH/BVH_Geometry.lxx @@ -0,0 +1,123 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +// ======================================================================= +// function : BVH_Geometry +// purpose : +// ======================================================================= +template +BVH_Geometry::BVH_Geometry() +: myIsDirty (Standard_False), + myBVH (new BVH_Tree()) +{ + // Set default builder - binned SAH split + myBuilder = new BVH_BinnedBuilder (1 /* primitive per leaf */); +} + +// ======================================================================= +// function : ~BVH_Geometry +// purpose : +// ======================================================================= +template +BVH_Geometry::~BVH_Geometry() +{ + myBVH.Nullify(); + myBuilder.Nullify(); +} + +// ======================================================================= +// function : MarkDirty +// purpose : +// ======================================================================= +template +void BVH_Geometry::MarkDirty() +{ + myIsDirty = Standard_True; +} + +// ======================================================================= +// function : Box +// purpose : +// ======================================================================= +template +BVH_Box BVH_Geometry::Box() const +{ + if (!myIsDirty) + { + return myBox; + } + + myBox = BVH_Set::Box(); + return myBox; +} + +// ======================================================================= +// function : BVH +// purpose : +// ======================================================================= +template +const NCollection_Handle >& BVH_Geometry::BVH() +{ + if (myIsDirty) + { + Update(); + } + + return myBVH; +} + +// ======================================================================= +// function : Update +// purpose : +// ======================================================================= +template +void BVH_Geometry::Update() +{ + if (!myIsDirty) + { + return; + } + + BVH_Box aBox; + for (Standard_Integer anIndex = 0; anIndex < BVH_ObjectSet::myObjects.Size(); ++anIndex) + { + aBox.Combine (BVH_ObjectSet::myObjects.Value (anIndex)->Box()); + } + + myBuilder->Build (this, myBVH.operator->(), aBox); + myIsDirty = Standard_False; +} + +// ======================================================================= +// function : Builder +// purpose : +// ======================================================================= +template +const NCollection_Handle >& BVH_Geometry::Builder() const +{ + return myBuilder; +} + +// ======================================================================= +// function : SetBuilder +// purpose : +// ======================================================================= +template +void BVH_Geometry::SetBuilder (NCollection_Handle >& theBuilder) +{ + myBuilder = theBuilder; +} diff --git a/src/BVH/BVH_Object.hxx b/src/BVH/BVH_Object.hxx new file mode 100644 index 0000000000..c097c59490 --- /dev/null +++ b/src/BVH/BVH_Object.hxx @@ -0,0 +1,59 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BVH_Object_Header +#define _BVH_Object_Header + +#include +#include + +#include + +//! Abstract geometric object. +template +class BVH_Object +{ +public: + + //! Creates new abstract geometric object. + BVH_Object(); + + //! Releases resources of geometric object. + virtual ~BVH_Object() = 0; + +public: + + //! Returns AABB of geometric object. + virtual BVH_Box Box() const = 0; + + //! Returns properties of geometric object. + virtual const NCollection_Handle& Properties() const; + + //! Sets properties of geometric object. + virtual void SetProperties (const NCollection_Handle& theProperties); + + //! Marks object state as outdated. + virtual void MarkDirty(); + +protected: + + Standard_Boolean myIsDirty; //!< Marks that internal object state need to be updated + NCollection_Handle myProperties; //!< Generic properties assigned to the object + +}; + +#include + +#endif // _BVH_Object_Header diff --git a/src/BVH/BVH_Object.lxx b/src/BVH/BVH_Object.lxx new file mode 100644 index 0000000000..b8aacdde84 --- /dev/null +++ b/src/BVH/BVH_Object.lxx @@ -0,0 +1,65 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +// ======================================================================= +// function : BVH_Object +// purpose : +// ======================================================================= +template +BVH_Object::BVH_Object() +: myIsDirty (Standard_False) +{ + // +} + +// ======================================================================= +// function : ~BVH_Object +// purpose : +// ======================================================================= +template +BVH_Object::~BVH_Object() +{ + // +} + +// ======================================================================= +// function : Properties +// purpose : +// ======================================================================= +template +const NCollection_Handle& BVH_Object::Properties() const +{ + return myProperties; +} + +// ======================================================================= +// function : SetProperties +// purpose : +// ======================================================================= +template +void BVH_Object::SetProperties (const NCollection_Handle& theProperties) +{ + myProperties = theProperties; +} + +// ======================================================================= +// function : MarkDirty +// purpose : +// ======================================================================= +template +void BVH_Object::MarkDirty() +{ + myIsDirty = Standard_True; +} diff --git a/src/BVH/BVH_ObjectSet.hxx b/src/BVH/BVH_ObjectSet.hxx new file mode 100644 index 0000000000..1b4a7fced9 --- /dev/null +++ b/src/BVH/BVH_ObjectSet.hxx @@ -0,0 +1,74 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BVH_ObjectSet_Header +#define _BVH_ObjectSet_Header + +#include +#include + +#include + +//! Set of abstract geometric objects to build BVH. +template +class BVH_ObjectSet : public BVH_Set +{ +public: + + //! Type for array of geometric objects. + typedef NCollection_Vector > > BVH_ObjectList; + +public: + + //! Creates set of geometric objects. + BVH_ObjectSet(); + + //! Releases resources of set of geometric objects. + virtual ~BVH_ObjectSet(); + +public: + + //! Clears all geometric objects. + virtual void Clear(); + + //! Returns array of geometric objects. + BVH_ObjectList& Objects(); + + //! Returns array of geometric objects. + const BVH_ObjectList& Objects() const; + +public: + + //! Return total number of objects. + virtual Standard_Integer Size() const; + + //! Returns AABB of specified object. + virtual BVH_Box Box (const Standard_Integer theIndex) const; + + //! Returns centroid position in specified axis. + virtual T Center (const Standard_Integer theIndex, const Standard_Integer theAxis) const; + + //! Swaps indices of two specified objects in the set. + virtual void Swap (const Standard_Integer theIndex1, const Standard_Integer theIndex2); + +protected: + + BVH_ObjectList myObjects; //!< Array of geometric objects + +}; + +#include + +#endif // _BVH_ObjectSet_Header diff --git a/src/BVH/BVH_ObjectSet.lxx b/src/BVH/BVH_ObjectSet.lxx new file mode 100644 index 0000000000..9ca6994889 --- /dev/null +++ b/src/BVH/BVH_ObjectSet.lxx @@ -0,0 +1,115 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +// ======================================================================= +// function : BVH_ObjectSet +// purpose : +// ======================================================================= +template +BVH_ObjectSet::BVH_ObjectSet() +{ + // +} + +// ======================================================================= +// function : ~BVH_ObjectSet +// purpose : +// ======================================================================= +template +BVH_ObjectSet::~BVH_ObjectSet() +{ + // +} + +// ======================================================================= +// function : Clears all geometric objects +// purpose : +// ======================================================================= +template +void BVH_ObjectSet::Clear() +{ + for (Standard_Integer anObjectIdx = 0; anObjectIdx < myObjects.Size(); ++anObjectIdx) + { + myObjects.ChangeValue (anObjectIdx).Nullify(); + } + myObjects.Clear(); +} + +// ======================================================================= +// function : Objects +// purpose : +// ======================================================================= +template +typename BVH_ObjectSet::BVH_ObjectList& BVH_ObjectSet::Objects() +{ + return myObjects; +} + +// ======================================================================= +// function : Objects +// purpose : +// ======================================================================= +template +const typename BVH_ObjectSet::BVH_ObjectList& BVH_ObjectSet::Objects() const +{ + return myObjects; +} + +// ======================================================================= +// function : Size +// purpose : +// ======================================================================= +template +Standard_Integer BVH_ObjectSet::Size() const +{ + return myObjects.Size(); +} + +// ======================================================================= +// function : Box +// purpose : +// ======================================================================= +template +BVH_Box BVH_ObjectSet::Box (const Standard_Integer theIndex) const +{ + return myObjects.Value (theIndex)->Box(); +} + +// ======================================================================= +// function : Center +// purpose : +// ======================================================================= +template +T BVH_ObjectSet::Center (const Standard_Integer theIndex, + const Standard_Integer theAxis) const +{ + typename BVH_Set::BVH_BoxNt aBox = myObjects.Value (theIndex)->Box(); + return BVHTools::CenterAxis::Center (aBox, theAxis); +} + +// ======================================================================= +// function : Swap +// purpose : +// ======================================================================= +template +void BVH_ObjectSet::Swap (const Standard_Integer theIndex1, + const Standard_Integer theIndex2) +{ + NCollection_Handle > anObject1 = myObjects.Value (theIndex1); + NCollection_Handle > anObject2 = myObjects.Value (theIndex2); + + myObjects.ChangeValue (theIndex1) = anObject2; + myObjects.ChangeValue (theIndex2) = anObject1; +} diff --git a/src/BVH/BVH_PrimitiveSet.hxx b/src/BVH/BVH_PrimitiveSet.hxx new file mode 100644 index 0000000000..ed2a520124 --- /dev/null +++ b/src/BVH/BVH_PrimitiveSet.hxx @@ -0,0 +1,66 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BVH_PrimitiveSet_Header +#define _BVH_PrimitiveSet_Header + +#include +#include + +//! Set of abstract geometric primitives. +template +class BVH_PrimitiveSet : public BVH_Object, public BVH_Set +{ + using BVH_Set::Box; + +public: + + //! Creates set of abstract primitives. + BVH_PrimitiveSet(); + + //! Releases resources of set of abstract primitives. + virtual ~BVH_PrimitiveSet(); + +public: + + //! Returns AABB of primitive set. + virtual BVH_Box Box() const; + + //! Returns constructed BVH tree. + virtual const NCollection_Handle >& BVH(); + + //! Returns the method (builder) to construct BVH. + virtual const NCollection_Handle >& Builder() const; + + //! Sets the method (builder) to construct BVH. + virtual void SetBuilder (NCollection_Handle >& theBuilder); + +protected: + + //! Updates BVH of primitive set. + virtual void Update(); + +protected: + + NCollection_Handle > myBVH; //!< Constructed bottom-level BVH + NCollection_Handle > myBuilder; //!< Builder for bottom-level BVH + + mutable BVH_Box myBox; //!< Cached bounding box of geometric primitives + +}; + +#include + +#endif // _BVH_PrimitiveSet_Header diff --git a/src/BVH/BVH_PrimitiveSet.lxx b/src/BVH/BVH_PrimitiveSet.lxx new file mode 100644 index 0000000000..6ad57b403f --- /dev/null +++ b/src/BVH/BVH_PrimitiveSet.lxx @@ -0,0 +1,106 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +// ======================================================================= +// function : BVH_PrimitiveSet +// purpose : +// ======================================================================= +template +BVH_PrimitiveSet::BVH_PrimitiveSet() +: myBVH (new BVH_Tree()) +{ + // Set default builder - binned SAH split + myBuilder = new BVH_BinnedBuilder (5, 32); +} + +// ======================================================================= +// function : ~BVH_PrimitiveSet +// purpose : +// ======================================================================= +template +BVH_PrimitiveSet::~BVH_PrimitiveSet() +{ + myBVH.Nullify(); + myBuilder.Nullify(); +} + +// ======================================================================= +// function : BVH +// purpose : +// ======================================================================= +template +const NCollection_Handle >& BVH_PrimitiveSet::BVH() +{ + if (BVH_Object::myIsDirty) + { + Update(); + } + + return myBVH; +} + +// ======================================================================= +// function : Box +// purpose : +// ======================================================================= +template +BVH_Box BVH_PrimitiveSet::Box() const +{ + if (!BVH_Object::myIsDirty) + { + return myBox; + } + + myBox = BVH_Set::Box(); + return myBox; +} + +// ======================================================================= +// function : Update +// purpose : +// ======================================================================= +template +void BVH_PrimitiveSet::Update() +{ + if (!BVH_Object::myIsDirty) + { + return; + } + + myBuilder->Build (this, myBVH.operator->(), Box()); + BVH_Object::myIsDirty = Standard_False; +} + +// ======================================================================= +// function : Builder +// purpose : +// ======================================================================= +template +const NCollection_Handle >& BVH_PrimitiveSet::Builder() const +{ + return myBuilder; +} + +// ======================================================================= +// function : SetBuilder +// purpose : +// ======================================================================= +template +void BVH_PrimitiveSet::SetBuilder (NCollection_Handle >& theBuilder) +{ + myBuilder = theBuilder; +} diff --git a/src/BVH/BVH_Properties.cxx b/src/BVH/BVH_Properties.cxx new file mode 100644 index 0000000000..ab5ba78323 --- /dev/null +++ b/src/BVH/BVH_Properties.cxx @@ -0,0 +1,22 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +//! Abstract properties of geometric object. +BVH_Properties::~BVH_Properties() +{ + // +} \ No newline at end of file diff --git a/src/BVH/BVH_Properties.hxx b/src/BVH/BVH_Properties.hxx new file mode 100644 index 0000000000..e0be636965 --- /dev/null +++ b/src/BVH/BVH_Properties.hxx @@ -0,0 +1,74 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BVH_Properties_Header +#define _BVH_Properties_Header + +#include + +#include + +//! Abstract properties of geometric object. +class BVH_Properties +{ +public: + + //! Releases resources of object properties. + Standard_EXPORT virtual ~BVH_Properties() = 0; + +}; + +//! Stores transform properties of geometric object. +template +class BVH_Transform : public BVH_Properties +{ +public: + + //! Type of transformation matrix. + typedef typename BVHTools::MatrixType::Type BVH_MatNt; + +public: + + //! Creates new identity transformation. + BVH_Transform(); + + //! Creates new transformation with specified matrix. + BVH_Transform (const BVH_MatNt& theTransform); + + //! Releases resources of transformation properties. + virtual ~BVH_Transform(); + + //! Returns transformation matrix. + const BVH_MatNt& Transform() const; + + //! Sets new transformation matrix. + void SetTransform (const BVH_MatNt& theTransform); + + //! Returns inversed transformation matrix. + const BVH_MatNt& Inversed() const; + + //! Applies transformation matrix to bounding box. + BVH_Box Apply (const BVH_Box& theBox) const; + +protected: + + BVH_MatNt myTransform; //!< Transformation matrix + BVH_MatNt myTransformInversed; //!< Inversed transformation matrix + +}; + +#include + +#endif // _BVH_Properties_Header diff --git a/src/BVH/BVH_Properties.lxx b/src/BVH/BVH_Properties.lxx new file mode 100644 index 0000000000..abe767ad24 --- /dev/null +++ b/src/BVH/BVH_Properties.lxx @@ -0,0 +1,223 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +// ======================================================================= +// function : BVH_Transform +// purpose : +// ======================================================================= +template +BVH_Transform::BVH_Transform() +{ + // +} + +// ======================================================================= +// function : BVH_Transform +// purpose : +// ======================================================================= +template +BVH_Transform::BVH_Transform (const BVH_MatNt& theTransform) +: myTransform (theTransform) +{ + // +} + +// ======================================================================= +// function : ~BVH_Transform +// purpose : +// ======================================================================= +template +BVH_Transform::~BVH_Transform() +{ + // +} + +// ======================================================================= +// function : Transform +// purpose : +// ======================================================================= +template +const typename BVH_Transform::BVH_MatNt& BVH_Transform::Transform() const +{ + return myTransform; +} + +namespace BVHTools +{ + template struct MatrixOp + { + // Not implemented + }; + + template struct MatrixOp + { + typedef typename BVHTools::MatrixType::Type BVH_Mat4t; + + static void Inverse (const BVH_Mat4t& theIn, + BVH_Mat4t& theOut) + { + theIn.Inverted (theOut); + } + + typedef typename BVHTools::VectorType::Type BVH_Vec4t; + + static BVH_Vec4t Multiply (const BVH_Mat4t& theMat, + const BVH_Vec4t& theVec) + { + BVH_Vec4t aOut = theMat * theVec; + return aOut * static_cast (1.0 / aOut.w()); + } + }; +} + +// ======================================================================= +// function : SetTransform +// purpose : +// ======================================================================= +template +void BVH_Transform::SetTransform (const BVH_MatNt& theTransform) +{ + myTransform = theTransform; + BVHTools::MatrixOp::Inverse (myTransform, myTransformInversed); +} + +// ======================================================================= +// function : Inversed +// purpose : +// ======================================================================= +template +const typename BVH_Transform::BVH_MatNt& BVH_Transform::Inversed() const +{ + return myTransformInversed; +} + +namespace BVHTools +{ + template + struct UnitVector + { + // Not implemented + }; + + template + struct UnitVector + { + typedef typename BVHTools::VectorType::Type BVH_Vec2t; + + static BVH_Vec2t DX() + { + return BVH_Vec2t (static_cast (1.0), + static_cast (0.0)); + } + + static BVH_Vec2t DY() + { + return BVH_Vec2t (static_cast (0.0), + static_cast (1.0)); + } + + static BVH_Vec2t DZ() + { + return BVH_Vec2t (static_cast (0.0), + static_cast (0.0)); + } + }; + + template + struct UnitVector + { + typedef typename BVHTools::VectorType::Type BVH_Vec3t; + + static BVH_Vec3t DX() + { + return BVH_Vec3t (static_cast (1.0), + static_cast (0.0), + static_cast (0.0)); + } + + static BVH_Vec3t DY() + { + return BVH_Vec3t (static_cast (0.0), + static_cast (1.0), + static_cast (0.0)); + } + + static BVH_Vec3t DZ() + { + return BVH_Vec3t (static_cast (0.0), + static_cast (0.0), + static_cast (1.0)); + } + }; + + template + struct UnitVector + { + typedef typename BVHTools::VectorType::Type BVH_Vec4t; + + static BVH_Vec4t DX() + { + return BVH_Vec4t (static_cast (1.0), + static_cast (0.0), + static_cast (0.0), + static_cast (0.0)); + } + + static BVH_Vec4t DY() + { + return BVH_Vec4t (static_cast (0.0), + static_cast (1.0), + static_cast (0.0), + static_cast (0.0)); + } + + static BVH_Vec4t DZ() + { + return BVH_Vec4t (static_cast (0.0), + static_cast (0.0), + static_cast (1.0), + static_cast (0.0)); + } + }; +} + +// ======================================================================= +// function : Apply +// purpose : +// ======================================================================= +template +BVH_Box BVH_Transform::Apply (const BVH_Box& theBox) const +{ + typename BVH_Box::BVH_VecNt aSize = theBox.Size(); + + BVH_Box aBox; + for (Standard_Integer aX = 0; aX <= 1; ++aX) + { + for (Standard_Integer aY = 0; aY <= 1; ++aY) + { + for (Standard_Integer aZ = 0; aZ <= 1; ++aZ) + { + typename BVH_Box::BVH_VecNt aCorner = theBox.CornerMin() + + BVHTools::UnitVector::DX() * aSize * static_cast (aX) + + BVHTools::UnitVector::DY() * aSize * static_cast (aY) + + BVHTools::UnitVector::DZ() * aSize * static_cast (aZ); + + aBox.Add (BVHTools::MatrixOp::Multiply (myTransform, aCorner)); + } + } + } + + return aBox; +} diff --git a/src/BVH/BVH_Set.hxx b/src/BVH/BVH_Set.hxx new file mode 100644 index 0000000000..e2abaedfd6 --- /dev/null +++ b/src/BVH/BVH_Set.hxx @@ -0,0 +1,60 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BVH_Set_Header +#define _BVH_Set_Header + +#include + +//! Set of abstract entities to build BVH. +template +class BVH_Set +{ +public: + + typedef BVH_Box BVH_BoxNt; + +public: + + //! Creates new abstract set of objects. + BVH_Set(); + + //! Releases resources of set of objects. + virtual ~BVH_Set() = 0; + + //! Returns AABB of entire set of objects. + virtual BVH_Box Box() const; + +public: + + //! Return total number of objects. + virtual Standard_Integer Size() const = 0; + + //! Returns AABB of specified object. + virtual BVH_Box Box (const Standard_Integer theIndex) const = 0; + + //! Returns centroid position in specified axis. + virtual T Center (const Standard_Integer theIndex, + const Standard_Integer theAxis) const = 0; + + //! Swaps indices of two specified objects in the set. + virtual void Swap (const Standard_Integer theIndex1, + const Standard_Integer theIndex2) = 0; + +}; + +#include + +#endif // _BVH_Set_Header diff --git a/src/BVH/BVH_Set.lxx b/src/BVH/BVH_Set.lxx new file mode 100644 index 0000000000..6fd58ea6fc --- /dev/null +++ b/src/BVH/BVH_Set.lxx @@ -0,0 +1,49 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +// ======================================================================= +// function : BVH_Set +// purpose : +// ======================================================================= +template +BVH_Set::BVH_Set() +{ + // +} + +// ======================================================================= +// function : ~BVH_Set +// purpose : +// ======================================================================= +template +BVH_Set::~BVH_Set() +{ + // +} + +// ======================================================================= +// function : Box +// purpose : +// ======================================================================= +template +BVH_Box BVH_Set::Box() const +{ + BVH_Box aBox; + for (Standard_Integer anIndex = 0; anIndex < Size(); ++anIndex) + { + aBox.Combine (Box (anIndex)); + } + return aBox; +} diff --git a/src/BVH/BVH_Sorter.hxx b/src/BVH/BVH_Sorter.hxx new file mode 100644 index 0000000000..9d50929c3c --- /dev/null +++ b/src/BVH/BVH_Sorter.hxx @@ -0,0 +1,41 @@ +// Created on: 2014-01-10 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BVH_Sorter_Header +#define _BVH_Sorter_Header + +#include + +//! Performs centroid-based sorting of abstract set. +template +class BVH_Sorter +{ +public: + + //! Sorts the set by centroids coordinates in specified axis. + static void Perform (BVH_Set* theSet, + const Standard_Integer theAxis); + + //! Sorts the set by centroids coordinates in specified axis. + static void Perform (BVH_Set* theSet, + const Standard_Integer theAxis, + const Standard_Integer theBegElement, + const Standard_Integer theEndElement); + +}; + +#include + +#endif // _BVH_Sorter_Header diff --git a/src/BVH/BVH_Sorter.lxx b/src/BVH/BVH_Sorter.lxx new file mode 100644 index 0000000000..e80c9c02c9 --- /dev/null +++ b/src/BVH/BVH_Sorter.lxx @@ -0,0 +1,75 @@ +// Created on: 2014-01-10 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +// ======================================================================= +// function : Perform +// purpose : +// ======================================================================= +template +void BVH_Sorter::Perform (BVH_Set* theSet, + const Standard_Integer theAxis) +{ + Perform (theSet, theAxis, 0, theSet->Size() - 1); +} + +// ======================================================================= +// function : Perform +// purpose : +// ======================================================================= +template +void BVH_Sorter::Perform (BVH_Set* theSet, + const Standard_Integer theAxis, + const Standard_Integer theBegElement, + const Standard_Integer theEndElement) +{ + Standard_Integer aLft = theBegElement; + Standard_Integer aRgh = theEndElement; + + T aPivot = theSet->Center ((aRgh + aLft) / 2, theAxis); + + while (aLft < aRgh) + { + while (theSet->Center (aLft, theAxis) < aPivot && aLft < theEndElement) + { + ++aLft; + } + + while (theSet->Center (aRgh, theAxis) > aPivot && aRgh > theBegElement) + { + --aRgh; + } + + if (aLft <= aRgh) + { + if (aLft != aRgh) + { + theSet->Swap (aLft, aRgh); + } + + ++aLft; + --aRgh; + } + } + + if (aRgh > theBegElement) + { + Perform (theSet, theAxis, theBegElement, aRgh); + } + + if (aLft < theEndElement) + { + Perform (theSet, theAxis, aLft, theEndElement); + } +} diff --git a/src/BVH/BVH_SpatialMedianBuilder.hxx b/src/BVH/BVH_SpatialMedianBuilder.hxx new file mode 100644 index 0000000000..c38b9340ed --- /dev/null +++ b/src/BVH/BVH_SpatialMedianBuilder.hxx @@ -0,0 +1,38 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BVH_SpatialMedianBuilder_Header +#define _BVH_SpatialMedianBuilder_Header + +#include + +//! Performs building of BVH tree using spatial median split algorithm. +template +class BVH_SpatialMedianBuilder : public BVH_BinnedBuilder +{ +public: + + //! Creates spatial median split builder. + BVH_SpatialMedianBuilder (const Standard_Integer theLeafNodeSize = 5, + const Standard_Integer theMaxTreeDepth = 32); + + //! Releases resources of spatial median split builder. + virtual ~BVH_SpatialMedianBuilder(); + +}; + +#include + +#endif // _BVH_SpatialMedianBuilder_Header diff --git a/src/BVH/BVH_SpatialMedianBuilder.lxx b/src/BVH/BVH_SpatialMedianBuilder.lxx new file mode 100644 index 0000000000..e677a804ef --- /dev/null +++ b/src/BVH/BVH_SpatialMedianBuilder.lxx @@ -0,0 +1,39 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +// ======================================================================= +// function : BVH_SpatialMedianBuilder +// purpose : +// ======================================================================= +template +BVH_SpatialMedianBuilder::BVH_SpatialMedianBuilder (const Standard_Integer theLeafNodeSize, + const Standard_Integer theMaxTreeDepth) +: BVH_BinnedBuilder (theLeafNodeSize, + theMaxTreeDepth) +{ + // +} + +// ======================================================================= +// function : ~BVH_SpatialMedianBuilder +// purpose : +// ======================================================================= +template +BVH_SpatialMedianBuilder::~BVH_SpatialMedianBuilder() +{ + // +} diff --git a/src/BVH/BVH_SweepPlaneBuilder.hxx b/src/BVH/BVH_SweepPlaneBuilder.hxx new file mode 100644 index 0000000000..eedc993f8c --- /dev/null +++ b/src/BVH/BVH_SweepPlaneBuilder.hxx @@ -0,0 +1,45 @@ +// Created on: 2014-01-09 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BVH_SweepPlaneBuilder_Header +#define _BVH_SweepPlaneBuilder_Header + +#include + +//! Performs building of BVH tree using sweep plane SAH algorithm. +template +class BVH_SweepPlaneBuilder : public BVH_Builder +{ +public: + + //! Creates sweep plane SAH BVH builder. + BVH_SweepPlaneBuilder (const Standard_Integer theLeafNodeSize = 5, + const Standard_Integer theMaxTreeDepth = 32); + + //! Releases resources of sweep plane SAH BVH builder. + virtual ~BVH_SweepPlaneBuilder(); + +protected: + + //! Builds specified BVH node. + virtual void BuildNode (BVH_Set* theSet, + BVH_Tree* theBVH, + const Standard_Integer theNode); + +}; + +#include + +#endif // _BVH_SweepPlaneBuilder_Header diff --git a/src/BVH/BVH_SweepPlaneBuilder.lxx b/src/BVH/BVH_SweepPlaneBuilder.lxx new file mode 100644 index 0000000000..d186d05cad --- /dev/null +++ b/src/BVH/BVH_SweepPlaneBuilder.lxx @@ -0,0 +1,183 @@ +// Created on: 2014-01-09 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +// ======================================================================= +// function : BVH_SweepPlaneBuilder +// purpose : +// ======================================================================= +template +BVH_SweepPlaneBuilder::BVH_SweepPlaneBuilder (const Standard_Integer theLeafNodeSize, + const Standard_Integer theMaxTreeDepth) +: BVH_Builder (theLeafNodeSize, + theMaxTreeDepth) +{ + // +} + +// ======================================================================= +// function : ~BVH_SweepPlaneBuilder +// purpose : +// ======================================================================= +template +BVH_SweepPlaneBuilder::~BVH_SweepPlaneBuilder() +{ + // +} + +// ======================================================================= +// function : BuildNode +// purpose : +// ======================================================================= +template +void BVH_SweepPlaneBuilder::BuildNode (BVH_Set* theSet, + BVH_Tree* theBVH, + const Standard_Integer theNode) +{ + const Standard_Integer aNodeBegPrimitive = theBVH->BegPrimitive (theNode); + const Standard_Integer aNodeEndPrimitive = theBVH->EndPrimitive (theNode); + const Standard_Integer aNodeNbPrimitives = theBVH->NbPrimitives (theNode); + + // Parameters for storing best split + Standard_Integer aMinSplitAxis = -1; + Standard_Integer aMinSplitIndex = 0; + + Standard_Real* aLftSet = new Standard_Real[aNodeNbPrimitives]; + Standard_Real* aRghSet = new Standard_Real[aNodeNbPrimitives]; + + Standard_Real aMinSplitCost = std::numeric_limits::max(); + + // Find best split + for (Standard_Integer anAxis = 0; anAxis < (N < 4 ? N : 3); ++anAxis) + { + const T aNodeSize = BVHTools::VecComp::Get (theBVH->MaxPoint (theNode), anAxis) - + BVHTools::VecComp::Get (theBVH->MinPoint (theNode), anAxis); + if (aNodeSize <= THE_NODE_MIN_SIZE) + { + continue; + } + + BVH_Sorter::Perform (theSet, anAxis, aNodeBegPrimitive, aNodeEndPrimitive); + + BVH_Box aLftBox; + BVH_Box aRghBox; + + *aLftSet = std::numeric_limits::max(); + *aRghSet = std::numeric_limits::max(); + + // Sweep from left + for (Standard_Integer anIndex = 1; anIndex < aNodeNbPrimitives; ++anIndex) + { + aLftBox.Combine (theSet->Box (anIndex + aNodeBegPrimitive - 1)); + + aLftSet[anIndex] = static_cast (aLftBox.Area()); + } + + // Sweep from right + for (Standard_Integer anIndex = 1; anIndex < aNodeNbPrimitives; ++anIndex) + { + aRghBox.Combine (theSet->Box (aNodeEndPrimitive - anIndex + 1)); + + aRghSet[anIndex] = static_cast (aRghBox.Area()); + } + + // Find best split using simplified SAH + for (Standard_Integer aNbLft = 1, aNbRgh = aNodeNbPrimitives - 1; aNbLft < aNodeNbPrimitives; ++aNbLft, --aNbRgh) + { + Standard_Real aCost = (aLftSet[aNbLft] /* / aNodeArea */) * aNbLft + + (aRghSet[aNbRgh] /* / aNodeArea */) * aNbRgh; + + if (aCost < aMinSplitCost) + { + aMinSplitCost = aCost; + aMinSplitAxis = anAxis; + aMinSplitIndex = aNbLft; + } + } + } + + if (aMinSplitAxis == -1) + { + return; + } + + theBVH->SetInner (theNode); + + if (aMinSplitAxis != (N < 4 ? N - 1 : 2)) + { + BVH_Sorter::Perform (theSet, aMinSplitAxis, aNodeBegPrimitive, aNodeEndPrimitive); + } + + BVH_Box aMinSplitBoxLft; + BVH_Box aMinSplitBoxRgh; + + // Compute bounding boxes for selected split plane + for (Standard_Integer anIndex = aNodeBegPrimitive; anIndex < aMinSplitIndex + aNodeBegPrimitive; ++anIndex) + { + aMinSplitBoxLft.Combine (theSet->Box (anIndex)); + } + + for (Standard_Integer anIndex = aNodeEndPrimitive; anIndex >= aMinSplitIndex + aNodeBegPrimitive; --anIndex) + { + aMinSplitBoxRgh.Combine (theSet->Box (anIndex)); + } + + const Standard_Integer aMiddle = aNodeBegPrimitive + aMinSplitIndex; + + static const Standard_Integer aLftNode = 1; + static const Standard_Integer aRghNode = 2; + + // Setting up tasks for child nodes + for (Standard_Integer aSide = aLftNode; aSide <= aRghNode; ++aSide) + { + typename BVH_Box::BVH_VecNt aChildMinPoint = (aSide == aLftNode) + ? aMinSplitBoxLft.CornerMin() + : aMinSplitBoxRgh.CornerMin(); + typename BVH_Box::BVH_VecNt aChildMaxPoint = (aSide == aLftNode) + ? aMinSplitBoxLft.CornerMax() + : aMinSplitBoxRgh.CornerMax(); + + Standard_Integer aChildBegPrimitive = (aSide == aLftNode) + ? aNodeBegPrimitive + : aMiddle; + Standard_Integer aChildEndPrimitive = (aSide == aLftNode) + ? aMiddle - 1 + : aNodeEndPrimitive; + + Standard_Integer aChildIndex = theBVH->AddLeafNode (aChildMinPoint, aChildMaxPoint, + aChildBegPrimitive, aChildEndPrimitive); + + theBVH->Level (aChildIndex) = theBVH->Level (theNode) + 1; + + // Check to see if child node must be split + const Standard_Integer aChildNbPimitives = (aSide == aLftNode) + ? aMiddle - aNodeBegPrimitive + : aNodeEndPrimitive - aMiddle + 1; + + if (aSide == aLftNode) + theBVH->LeftChild (theNode) = aChildIndex; + else + theBVH->RightChild (theNode) = aChildIndex; + + const Standard_Boolean isLeaf = aChildNbPimitives <= BVH_Builder::myLeafNodeSize + || theBVH->Level (aChildIndex) >= BVH_Builder::myMaxTreeDepth; + + if (!isLeaf) + { + BVH_Builder::myTasksQueue.Append (aChildIndex); + } + } +} diff --git a/src/BVH/BVH_Tree.hxx b/src/BVH/BVH_Tree.hxx new file mode 100644 index 0000000000..b64e5b90b2 --- /dev/null +++ b/src/BVH/BVH_Tree.hxx @@ -0,0 +1,239 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BVH_Tree_Header +#define _BVH_Tree_Header + +#include + +#include + +//! Stores parameters of bounding volume hierarchy (BVH). +//! Bounding volume hierarchy (BVH) organizes geometric objects in +//! the tree based on spatial relationships. Each node in the tree +//! contains an axis-aligned bounding box of all the objects below +//! it. Bounding volume hierarchies are used in many algorithms to +//! support efficient operations on the sets of geometric objects, +//! such as collision detection, ray-tracing, searching of nearest +//! objects, and view frustum culling. +template +class BVH_Tree +{ +public: + + typedef typename BVH_Box::BVH_VecNt BVH_VecNt; + +public: + + //! Returns minimum point of the given node. + BVH_VecNt& MinPoint (const Standard_Integer theNodeIndex) + { + return BVHTools::ArrayOp::ChangeValue (myMinPointBuffer, theNodeIndex); + } + + //! Returns maximum point of the given node. + BVH_VecNt& MaxPoint (const Standard_Integer theNodeIndex) + { + return BVHTools::ArrayOp::ChangeValue (myMaxPointBuffer, theNodeIndex); + } + + //! Returns minimum point of the given node. + const BVH_VecNt& MinPoint (const Standard_Integer theNodeIndex) const + { + return BVHTools::ArrayOp::Value (myMinPointBuffer, theNodeIndex); + } + + //! Returns maximum point of the given node. + const BVH_VecNt& MaxPoint (const Standard_Integer theNodeIndex) const + { + return BVHTools::ArrayOp::Value (myMaxPointBuffer, theNodeIndex); + } + + //! Returns index of left child of the given inner node. + Standard_Integer& LeftChild (const Standard_Integer theNodeIndex) + { + return BVHTools::ArrayOp::ChangeValue (myNodeInfoBuffer, theNodeIndex).y(); + } + + //! Returns index of left child of the given inner node. + Standard_Integer LeftChild (const Standard_Integer theNodeIndex) const + { + return BVHTools::ArrayOp::Value (myNodeInfoBuffer, theNodeIndex).y(); + } + + //! Returns index of right child of the given inner node. + Standard_Integer& RightChild (const Standard_Integer theNodeIndex) + { + return BVHTools::ArrayOp::ChangeValue (myNodeInfoBuffer, theNodeIndex).z(); + } + + //! Returns index of right child of the given inner node. + Standard_Integer RightChild (const Standard_Integer theNodeIndex) const + { + return BVHTools::ArrayOp::Value (myNodeInfoBuffer, theNodeIndex).z(); + } + + //! Returns index of first primitive of the given leaf node. + Standard_Integer& BegPrimitive (const Standard_Integer theNodeIndex) + { + return BVHTools::ArrayOp::ChangeValue (myNodeInfoBuffer, theNodeIndex).y(); + } + + //! Returns index of first primitive of the given leaf node. + Standard_Integer BegPrimitive (const Standard_Integer theNodeIndex) const + { + return BVHTools::ArrayOp::Value (myNodeInfoBuffer, theNodeIndex).y(); + } + + //! Returns index of last primitive of the given leaf node. + Standard_Integer& EndPrimitive (const Standard_Integer theNodeIndex) + { + return BVHTools::ArrayOp::ChangeValue (myNodeInfoBuffer, theNodeIndex).z(); + } + + //! Returns index of last primitive of the given leaf node. + Standard_Integer EndPrimitive (const Standard_Integer theNodeIndex) const + { + return BVHTools::ArrayOp::Value (myNodeInfoBuffer, theNodeIndex).z(); + } + + //! Returns number of primitives for the given tree node. + Standard_Integer NbPrimitives (const Standard_Integer theNodeIndex) const + { + return EndPrimitive (theNodeIndex) - BegPrimitive (theNodeIndex) + 1; + } + + //! Returns level (depth) of the given node. + Standard_Integer& Level (const Standard_Integer theNodeIndex) + { + return BVHTools::ArrayOp::ChangeValue (myNodeInfoBuffer, theNodeIndex).w(); + } + + //! Returns level (depth) of the given node. + Standard_Integer Level (const Standard_Integer theNodeIndex) const + { + return BVHTools::ArrayOp::Value (myNodeInfoBuffer, theNodeIndex).w(); + } + + //! Is node a leaf (outer)? + Standard_Boolean IsOuter (const Standard_Integer theNodeIndex) const + { + return BVHTools::ArrayOp::Value (myNodeInfoBuffer, theNodeIndex).x() > 0; + } + + //! Sets node type to 'outer'. + void SetOuter (const Standard_Integer theNodeIndex) + { + BVHTools::ArrayOp::ChangeValue (myNodeInfoBuffer, theNodeIndex).x() = 1; + } + + //! Sets node type to 'inner'. + void SetInner (const Standard_Integer theNodeIndex) + { + BVHTools::ArrayOp::ChangeValue (myNodeInfoBuffer, theNodeIndex).x() = 0; + } + + //! Returns total number of BVH nodes. + Standard_Integer Length() const + { + return BVHTools::ArrayOp::Size (myNodeInfoBuffer); + } + +public: + + //! Removes all BVH nodes. + void Clear(); + + //! Adds new leaf node to the BVH. + Standard_Integer AddLeafNode (const BVH_VecNt& theMinPoint, + const BVH_VecNt& theMaxPoint, + const Standard_Integer theBegElem, + const Standard_Integer theEndElem); + + //! Adds new inner node to the BVH. + Standard_Integer AddInnerNode (const BVH_VecNt& theMinPoint, + const BVH_VecNt& theMaxPoint, + const Standard_Integer theLftChild, + const Standard_Integer theRghChild); + + //! Adds new leaf node to the BVH. + Standard_Integer AddLeafNode (const BVH_Box& theAABB, + const Standard_Integer theBegElem, + const Standard_Integer theEndElem); + + //! Adds new inner node to the BVH. + Standard_Integer AddInnerNode (const BVH_Box& theAABB, + const Standard_Integer theLftChild, + const Standard_Integer theRghChild); + + //! Returns value of SAH (surface area heuristic). + //! Allows to compare the quality of BVH trees constructed for + //! the same sets of geometric objects with different methods. + T EstimateSAH() const; + +public: + + //! Returns array of node min points. + typename BVHTools::ArrayType::Type& MinPointBuffer() + { + return myMinPointBuffer; + } + + //! Returns array of node min points. + const typename BVHTools::ArrayType::Type& MinPointBuffer() const + { + return myMinPointBuffer; + } + + //! Returns array of node max points. + typename BVHTools::ArrayType::Type& MaxPointBuffer() + { + return myMaxPointBuffer; + } + + //! Returns array of node max points. + const typename BVHTools::ArrayType::Type& MaxPointBuffer() const + { + return myMaxPointBuffer; + } + + //! Returns array of node data records. + BVH_Array4i& NodeInfoBuffer() + { + return myNodeInfoBuffer; + } + + //! Returns array of node data records. + const BVH_Array4i& NodeInfoBuffer() const + { + return myNodeInfoBuffer; + } + +protected: + + //! Array of node minimum points. + typename BVHTools::ArrayType::Type myMinPointBuffer; + + //! Array of node maximum points. + typename BVHTools::ArrayType::Type myMaxPointBuffer; + + //! Array of node data records. + BVH_Array4i myNodeInfoBuffer; + +}; + +#include + +#endif // _BVH_Tree_Header diff --git a/src/BVH/BVH_Tree.lxx b/src/BVH/BVH_Tree.lxx new file mode 100644 index 0000000000..211fdb5587 --- /dev/null +++ b/src/BVH/BVH_Tree.lxx @@ -0,0 +1,139 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +// ======================================================================= +// function : Clear +// purpose : +// ======================================================================= +template +void BVH_Tree::Clear() +{ + BVHTools::ArrayOp::Clear (myMinPointBuffer); + BVHTools::ArrayOp::Clear (myMaxPointBuffer); + + BVHTools::ArrayOp::Clear (myNodeInfoBuffer); +} + +// ======================================================================= +// function : AddLeafNode +// purpose : +// ======================================================================= +template +Standard_Integer BVH_Tree::AddLeafNode (const BVH_VecNt& theMinPoint, + const BVH_VecNt& theMaxPoint, + const Standard_Integer theBegElem, + const Standard_Integer theEndElem) +{ + BVHTools::ArrayOp::Append (myMinPointBuffer, theMinPoint); + BVHTools::ArrayOp::Append (myMaxPointBuffer, theMaxPoint); + + BVHTools::ArrayOp::Append (myNodeInfoBuffer, BVH_Vec4i (1, theBegElem, theEndElem, 0)); + + return static_cast (BVHTools::ArrayOp::Size (myNodeInfoBuffer) - 1); +} + +// ======================================================================= +// function : AddInnerNode +// purpose : +// ======================================================================= +template +Standard_Integer BVH_Tree::AddInnerNode (const BVH_VecNt& theMinPoint, + const BVH_VecNt& theMaxPoint, + const Standard_Integer theLftChild, + const Standard_Integer theRghChild) +{ + BVHTools::ArrayOp::Append (myMinPointBuffer, theMinPoint); + BVHTools::ArrayOp::Append (myMaxPointBuffer, theMaxPoint); + + BVHTools::ArrayOp::Append (myNodeInfoBuffer, BVH_Vec4i (0, theLftChild, theRghChild, 0)); + + return static_cast (BVHTools::ArrayOp::Size (myNodeInfoBuffer) - 1); +} + +// ======================================================================= +// function : AddLeafNode +// purpose : +// ======================================================================= +template +Standard_Integer BVH_Tree::AddLeafNode (const BVH_Box& theAABB, + const Standard_Integer theBegElem, + const Standard_Integer theEndElem) +{ + return AddLeafNode (theAABB.CornerMin(), theAABB.CornerMax(), theBegElem, theEndElem); +} + +// ======================================================================= +// function : AddInnerNode +// purpose : +// ======================================================================= +template +Standard_Integer BVH_Tree::AddInnerNode (const BVH_Box& theAABB, + const Standard_Integer theLftChild, + const Standard_Integer theRghChild) +{ + return AddInnerNode (theAABB.CornerMin(), theAABB.CornerMax(), theLftChild, theRghChild); +} + +namespace BVHTools +{ + template + void EstimateSAH (const BVH_Tree* theTree, + const Standard_Integer theNode, + T theProbability, + T& theSAH) + { + BVH_Box aBox (theTree->MinPoint (theNode), + theTree->MaxPoint (theNode)); + + if (theTree->IsOuter (theNode)) + { + theSAH += theProbability * (theTree->EndPrimitive (theNode) - theTree->BegPrimitive (theNode) + 1); + } + else + { + theSAH += theProbability * static_cast (2.0); + + BVH_Box aLftBox (theTree->MinPoint (theTree->LeftChild (theNode)), + theTree->MaxPoint (theTree->LeftChild (theNode))); + + if (theProbability > 0.0) + { + EstimateSAH (theTree, theTree->LeftChild (theNode), + theProbability * aLftBox.Area() / aBox.Area(), theSAH); + } + + BVH_Box aRghBox (theTree->MinPoint (theTree->RightChild (theNode)), + theTree->MaxPoint (theTree->RightChild (theNode))); + + if (theProbability > 0.0) + { + EstimateSAH (theTree, theTree->RightChild (theNode), + theProbability * aRghBox.Area() / aBox.Area(), theSAH); + } + } + } +} + +// ======================================================================= +// function : EstimateSAH +// purpose : +// ======================================================================= +template +T BVH_Tree::EstimateSAH() const +{ + T aSAH = static_cast (0.0); + BVHTools::EstimateSAH (this, 0, static_cast (1.0), aSAH); + return aSAH; +} diff --git a/src/BVH/BVH_Triangulation.hxx b/src/BVH/BVH_Triangulation.hxx new file mode 100644 index 0000000000..ebc99f242e --- /dev/null +++ b/src/BVH/BVH_Triangulation.hxx @@ -0,0 +1,65 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BVH_Triangulation_Header +#define _BVH_Triangulation_Header + +#include + +//! Triangulation as an example of primitive set. +template +class BVH_Triangulation : public BVH_PrimitiveSet +{ +public: + + typedef typename BVHTools::VectorType::Type BVH_VecNt; + +public: + + //! Creates new triangulation. + BVH_Triangulation(); + + //! Releases resources of geometric object. + virtual ~BVH_Triangulation(); + +public: + + //! Array of vertex coordinates. + typename BVHTools::ArrayType::Type Vertices; + + //! Array of indices of triangle indicies vertices. + BVH_Array4i Elements; + +public: + + //! Return total number of triangles. + virtual Standard_Integer Size() const; + + //! Returns AABB of specified triangle. + virtual BVH_Box Box (const Standard_Integer theIndex) const; + + //! Returns centroid position in specified axis. + virtual T Center (const Standard_Integer theIndex, + const Standard_Integer theAxis) const; + + //! Swaps indices of two specified triangles. + virtual void Swap (const Standard_Integer theIndex1, + const Standard_Integer theIndex2); + +}; + +#include + +#endif // _BVH_Triangulation_Header diff --git a/src/BVH/BVH_Triangulation.lxx b/src/BVH/BVH_Triangulation.lxx new file mode 100644 index 0000000000..4e2e0ae234 --- /dev/null +++ b/src/BVH/BVH_Triangulation.lxx @@ -0,0 +1,97 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +// ======================================================================= +// function : BVH_Triangulation +// purpose : +// ======================================================================= +template +BVH_Triangulation::BVH_Triangulation() +{ + // +} + +// ======================================================================= +// function : ~BVH_Triangulation +// purpose : +// ======================================================================= +template +BVH_Triangulation::~BVH_Triangulation() +{ + // +} + +// ======================================================================= +// function : Size +// purpose : +// ======================================================================= +template +Standard_Integer BVH_Triangulation::Size() const +{ + return BVHTools::ArrayOp::Size (Elements); +} + +// ======================================================================= +// function : Box +// purpose : +// ======================================================================= +template +BVH_Box BVH_Triangulation::Box (const Standard_Integer theIndex) const +{ + const BVH_Vec4i& anIndex = BVHTools::ArrayOp::Value (Elements, theIndex); + + const BVH_VecNt& aPoint0 = BVHTools::ArrayOp::Value (Vertices, anIndex.x()); + const BVH_VecNt& aPoint1 = BVHTools::ArrayOp::Value (Vertices, anIndex.y()); + const BVH_VecNt& aPoint2 = BVHTools::ArrayOp::Value (Vertices, anIndex.z()); + + const BVH_VecNt aMinPoint = aPoint0.cwiseMin (aPoint1.cwiseMin (aPoint2)); + const BVH_VecNt aMaxPoint = aPoint0.cwiseMax (aPoint1.cwiseMax (aPoint2)); + + return BVH_Box (aMinPoint, aMaxPoint); +} + +// ======================================================================= +// function : Center +// purpose : +// ======================================================================= +template +T BVH_Triangulation::Center (const Standard_Integer theIndex, + const Standard_Integer theAxis) const +{ + const BVH_Vec4i& anIndex = BVHTools::ArrayOp::Value (Elements, theIndex); + + const BVH_VecNt& aPoint0 = BVHTools::ArrayOp::Value (Vertices, anIndex.x()); + const BVH_VecNt& aPoint1 = BVHTools::ArrayOp::Value (Vertices, anIndex.y()); + const BVH_VecNt& aPoint2 = BVHTools::ArrayOp::Value (Vertices, anIndex.z()); + + return ( BVHTools::VecComp::Get (aPoint0, theAxis) + + BVHTools::VecComp::Get (aPoint1, theAxis) + + BVHTools::VecComp::Get (aPoint2, theAxis) ) * static_cast (1.0 / 3.0); +} + +// ======================================================================= +// function : Swap +// purpose : +// ======================================================================= +template +void BVH_Triangulation::Swap (const Standard_Integer theIndex1, + const Standard_Integer theIndex2) +{ + BVH_Vec4i anIndices1 = BVHTools::ArrayOp::Value (Elements, theIndex1); + BVH_Vec4i anIndices2 = BVHTools::ArrayOp::Value (Elements, theIndex2); + + BVHTools::ArrayOp::ChangeValue (Elements, theIndex1) = anIndices2; + BVHTools::ArrayOp::ChangeValue (Elements, theIndex2) = anIndices1; +} diff --git a/src/BVH/BVH_Types.hxx b/src/BVH/BVH_Types.hxx new file mode 100644 index 0000000000..de6d39d49b --- /dev/null +++ b/src/BVH/BVH_Types.hxx @@ -0,0 +1,130 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BVH_Types_Header +#define _BVH_Types_Header + +// Use this macro to switch between STL and OCCT vector types +#define _BVH_USE_STD_VECTOR_ + +#include +#include +#include +#include +#include +#include + +#include + +namespace BVHTools +{ + //! Allows to fast switching between Eigen and NCollection vectors. + template struct VectorType + { + // Not implemented + }; + + template struct VectorType + { + typedef T Type; + }; + + template struct VectorType + { + typedef NCollection_Vec2 Type; + }; + + template struct VectorType + { + typedef NCollection_Vec3 Type; + }; + + template struct VectorType + { + typedef NCollection_Vec4 Type; + }; + + template struct ArrayType + { + #ifndef _BVH_USE_STD_VECTOR_ + typedef NCollection_Vector::Type> Type; + #else + typedef std::vector::Type> Type; + #endif + }; + + //! Allows to fast switching between Eigen and NCollection matrices. + template struct MatrixType + { + // Not implemented + }; + + template struct MatrixType + { + typedef NCollection_Mat4 Type; + }; +} + +//! 2D vector of integers. +typedef BVHTools::VectorType::Type BVH_Vec2i; +//! 3D vector of integers. +typedef BVHTools::VectorType::Type BVH_Vec3i; +//! 4D vector of integers. +typedef BVHTools::VectorType::Type BVH_Vec4i; + +//! Array of 2D vectors of integers. +typedef BVHTools::ArrayType::Type BVH_Array2i; +//! Array of 3D vectors of integers. +typedef BVHTools::ArrayType::Type BVH_Array3i; +//! Array of 4D vectors of integers. +typedef BVHTools::ArrayType::Type BVH_Array4i; + +//! 2D vector of single precision reals. +typedef BVHTools::VectorType::Type BVH_Vec2f; +//! 3D vector of single precision reals. +typedef BVHTools::VectorType::Type BVH_Vec3f; +//! 4D vector of single precision reals. +typedef BVHTools::VectorType::Type BVH_Vec4f; + +//! Array of 2D vectors of single precision reals. +typedef BVHTools::ArrayType::Type BVH_Array2f; +//! Array of 3D vectors of single precision reals. +typedef BVHTools::ArrayType::Type BVH_Array3f; +//! Array of 4D vectors of single precision reals. +typedef BVHTools::ArrayType::Type BVH_Array4f; + +//! 2D vector of double precision reals. +typedef BVHTools::VectorType::Type BVH_Vec2d; +//! 3D vector of double precision reals. +typedef BVHTools::VectorType::Type BVH_Vec3d; +//! 4D vector of double precision reals. +typedef BVHTools::VectorType::Type BVH_Vec4d; + +//! Array of 2D vectors of double precision reals. +typedef BVHTools::ArrayType::Type BVH_Array2d; +//! Array of 3D vectors of double precision reals. +typedef BVHTools::ArrayType::Type BVH_Array3d; +//! Array of 4D vectors of double precision reals. +typedef BVHTools::ArrayType::Type BVH_Array4d; + +//! 4x4 matrix of single precision reals. +typedef BVHTools::MatrixType::Type BVH_Mat4f; + +//! 4x4 matrix of double precision reals. +typedef BVHTools::MatrixType::Type BVH_Mat4d; + +#include + +#endif // _BVH_Types_Header diff --git a/src/BVH/BVH_Types.lxx b/src/BVH/BVH_Types.lxx new file mode 100644 index 0000000000..37fc0b4fea --- /dev/null +++ b/src/BVH/BVH_Types.lxx @@ -0,0 +1,112 @@ +// Created on: 2013-12-20 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +namespace BVHTools +{ + template struct VecComp + { + // Not implemented + }; + + template struct VecComp + { + typedef typename BVHTools::VectorType::Type BVH_Vec2t; + + static T Get (const BVH_Vec2t& theVec, + const Standard_Integer theAxis) + { + return theAxis == 0 ? theVec.x() : theVec.y(); + } + }; + + template struct VecComp + { + typedef typename BVHTools::VectorType::Type BVH_Vec3t; + + static T Get (const BVH_Vec3t& theVec, + const Standard_Integer theAxis) + { + return theAxis == 0 ? theVec.x() : ( theAxis == 1 ? theVec.y() : theVec.z() ); + } + }; + + template struct VecComp + { + typedef typename BVHTools::VectorType::Type BVH_Vec4t; + + static T Get (const BVH_Vec4t& theVec, + const Standard_Integer theAxis) + { + return theAxis == 0 + ? theVec.x() + : (theAxis == 1 ? theVec.y() : ( theAxis == 2 ? theVec.z() : theVec.w() )); + } + }; + + template struct ArrayOp + { + typedef typename BVHTools::ArrayType::Type BVH_ArrayNt; + + static inline + const typename BVHTools::VectorType::Type& Value (const BVH_ArrayNt& theArray, + const Standard_Integer theIndex) + { + #ifdef _BVH_USE_STD_VECTOR_ + return theArray.at (theIndex); + #else + return theArray.Value (theIndex); + #endif + } + + static inline + typename BVHTools::VectorType::Type& ChangeValue (BVH_ArrayNt& theArray, + const Standard_Integer theIndex) + { + #ifdef _BVH_USE_STD_VECTOR_ + return theArray.at (theIndex); + #else + return theArray.ChangeValue (theIndex); + #endif + } + + static inline void Append (BVH_ArrayNt& theArray, + const typename BVHTools::VectorType::Type& theElement) + { + #ifdef _BVH_USE_STD_VECTOR_ + theArray.push_back (theElement); + #else + theArray.Append (theElement); + #endif + } + + static inline Standard_Integer Size (const BVH_ArrayNt& theArray) + { + #ifdef _BVH_USE_STD_VECTOR_ + return static_cast (theArray.size()); + #else + return static_cast (theArray.Size()); + #endif + } + + static inline void Clear (BVH_ArrayNt& theArray) + { + #ifdef _BVH_USE_STD_VECTOR_ + theArray.clear(); + #else + theArray.Clear(); + #endif + } + }; +} diff --git a/src/BVH/FILES b/src/BVH/FILES new file mode 100644 index 0000000000..54d882bc58 --- /dev/null +++ b/src/BVH/FILES @@ -0,0 +1,32 @@ +BVH.cxx +BVH_BinnedBuilder.hxx +BVH_BinnedBuilder.lxx +BVH_Box.hxx +BVH_Box.lxx +BVH_Builder.hxx +BVH_Builder.lxx +BVH_Geometry.hxx +BVH_Geometry.lxx +BVH_Object.hxx +BVH_Object.lxx +BVH_ObjectSet.hxx +BVH_ObjectSet.lxx +BVH_PrimitiveSet.hxx +BVH_PrimitiveSet.lxx +BVH_Properties.hxx +BVH_Properties.lxx +BVH_Properties.cxx +BVH_Set.hxx +BVH_Set.lxx +BVH_Sorter.hxx +BVH_Sorter.lxx +BVH_SpatialMedianBuilder.hxx +BVH_SpatialMedianBuilder.lxx +BVH_SweepPlaneBuilder.hxx +BVH_SweepPlaneBuilder.lxx +BVH_Tree.hxx +BVH_Tree.lxx +BVH_Triangulation.hxx +BVH_Triangulation.lxx +BVH_Types.hxx +BVH_Types.lxx diff --git a/src/NCollection/NCollection_Vec2.hxx b/src/NCollection/NCollection_Vec2.hxx index 3d1e675632..c7abfdecf5 100644 --- a/src/NCollection/NCollection_Vec2.hxx +++ b/src/NCollection/NCollection_Vec2.hxx @@ -161,6 +161,20 @@ public: v[1] * theFactor); } + //! Compute component-wise minimum of two vectors. + NCollection_Vec2 cwiseMin (const NCollection_Vec2& theVec) const + { + return NCollection_Vec2 (Min (v[0], theVec.v[0]), + Min (v[1], theVec.v[1])); + } + + //! Compute component-wise maximum of two vectors. + NCollection_Vec2 cwiseMax (const NCollection_Vec2& theVec) const + { + return NCollection_Vec2 (Max (v[0], theVec.v[0]), + Max (v[1], theVec.v[1])); + } + //! Compute per-component multiplication by scale factor. NCollection_Vec2& operator*= (const Element_t theFactor) { diff --git a/src/NCollection/NCollection_Vec3.hxx b/src/NCollection/NCollection_Vec3.hxx index f6ff42b4af..fdc9bad4ff 100644 --- a/src/NCollection/NCollection_Vec3.hxx +++ b/src/NCollection/NCollection_Vec3.hxx @@ -234,6 +234,22 @@ public: return aCopyVec3; } + //! Compute component-wise minimum of two vectors. + NCollection_Vec3 cwiseMin (const NCollection_Vec3& theVec) const + { + return NCollection_Vec3 (Min (v[0], theVec.v[0]), + Min (v[1], theVec.v[1]), + Min (v[2], theVec.v[2])); + } + + //! Compute component-wise maximum of two vectors. + NCollection_Vec3 cwiseMax (const NCollection_Vec3& theVec) const + { + return NCollection_Vec3 (Max (v[0], theVec.v[0]), + Max (v[1], theVec.v[1]), + Max (v[2], theVec.v[2])); + } + //! Compute per-component division by scale factor. NCollection_Vec3& operator/= (const Element_t theInvFactor) { diff --git a/src/NCollection/NCollection_Vec4.hxx b/src/NCollection/NCollection_Vec4.hxx index 27e5437143..234ec45cc4 100644 --- a/src/NCollection/NCollection_Vec4.hxx +++ b/src/NCollection/NCollection_Vec4.hxx @@ -284,6 +284,24 @@ public: return aCopyVec4; } + //! Compute component-wise minimum of two vectors. + NCollection_Vec4 cwiseMin (const NCollection_Vec4& theVec) const + { + return NCollection_Vec4 (Min (v[0], theVec.v[0]), + Min (v[1], theVec.v[1]), + Min (v[2], theVec.v[2]), + Min (v[3], theVec.v[3])); + } + + //! Compute component-wise maximum of two vectors. + NCollection_Vec4 cwiseMax (const NCollection_Vec4& theVec) const + { + return NCollection_Vec4 (Max (v[0], theVec.v[0]), + Max (v[1], theVec.v[1]), + Max (v[2], theVec.v[2]), + Max (v[3], theVec.v[3])); + } + //! Compute per-component division by scale factor. NCollection_Vec4& operator/= (const Element_t theInvFactor) { diff --git a/src/TKMath/PACKAGES b/src/TKMath/PACKAGES index 8364e76071..b2ab173f7b 100755 --- a/src/TKMath/PACKAGES +++ b/src/TKMath/PACKAGES @@ -10,6 +10,7 @@ Poly CSLib Convert Bnd +BVH gp TColgp TopLoc