File indexing completed on 2025-01-18 10:03:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef BVH_SweepPlaneBuilder_HeaderFile
0017 #define BVH_SweepPlaneBuilder_HeaderFile
0018
0019 #include <BVH_QueueBuilder.hxx>
0020 #include <BVH_QuickSorter.hxx>
0021 #include <NCollection_Array1.hxx>
0022
0023
0024 template<class T, int N>
0025 class BVH_SweepPlaneBuilder : public BVH_QueueBuilder<T, N>
0026 {
0027 public:
0028
0029
0030 BVH_SweepPlaneBuilder (const Standard_Integer theLeafNodeSize = BVH_Constants_LeafNodeSizeDefault,
0031 const Standard_Integer theMaxTreeDepth = BVH_Constants_MaxTreeDepth,
0032 const Standard_Integer theNumOfThreads = 1)
0033 : BVH_QueueBuilder<T, N> (theLeafNodeSize,
0034 theMaxTreeDepth,
0035 theNumOfThreads) {}
0036
0037
0038 virtual ~BVH_SweepPlaneBuilder() {}
0039
0040 protected:
0041
0042
0043 typename BVH_QueueBuilder<T, N>::BVH_ChildNodes buildNode (BVH_Set<T, N>* theSet,
0044 BVH_Tree<T, N>* theBVH,
0045 const Standard_Integer theNode) const Standard_OVERRIDE
0046 {
0047 const Standard_Integer aNodeBegPrimitive = theBVH->BegPrimitive (theNode);
0048 const Standard_Integer aNodeEndPrimitive = theBVH->EndPrimitive (theNode);
0049 const Standard_Integer aNodeNbPrimitives = theBVH->NbPrimitives (theNode);
0050 if (aNodeEndPrimitive - aNodeBegPrimitive < BVH_Builder<T, N>::myLeafNodeSize)
0051 {
0052 return typename BVH_QueueBuilder<T, N>::BVH_ChildNodes();
0053 }
0054
0055
0056 Standard_Integer aMinSplitAxis = -1;
0057 Standard_Integer aMinSplitIndex = 0;
0058
0059 NCollection_Array1<Standard_Real> aLftSet (0, aNodeNbPrimitives - 1);
0060 NCollection_Array1<Standard_Real> aRghSet (0, aNodeNbPrimitives - 1);
0061 Standard_Real aMinSplitCost = std::numeric_limits<Standard_Real>::max();
0062
0063
0064 for (Standard_Integer anAxis = 0; anAxis < (N < 4 ? N : 3); ++anAxis)
0065 {
0066 const T aNodeSize = BVH::VecComp<T, N>::Get (theBVH->MaxPoint (theNode), anAxis) -
0067 BVH::VecComp<T, N>::Get (theBVH->MinPoint (theNode), anAxis);
0068 if (aNodeSize <= BVH::THE_NODE_MIN_SIZE)
0069 {
0070 continue;
0071 }
0072
0073 BVH_QuickSorter<T, N> (anAxis).Perform (theSet, aNodeBegPrimitive, aNodeEndPrimitive);
0074 BVH_Box<T, N> aLftBox;
0075 BVH_Box<T, N> aRghBox;
0076 aLftSet.ChangeFirst() = std::numeric_limits<T>::max();
0077 aRghSet.ChangeFirst() = std::numeric_limits<T>::max();
0078
0079
0080 for (Standard_Integer anIndex = 1; anIndex < aNodeNbPrimitives; ++anIndex)
0081 {
0082 aLftBox.Combine (theSet->Box (anIndex + aNodeBegPrimitive - 1));
0083 aLftSet (anIndex) = static_cast<Standard_Real> (aLftBox.Area());
0084 }
0085
0086
0087 for (Standard_Integer anIndex = 1; anIndex < aNodeNbPrimitives; ++anIndex)
0088 {
0089 aRghBox.Combine (theSet->Box (aNodeEndPrimitive - anIndex + 1));
0090 aRghSet (anIndex) = static_cast<Standard_Real> (aRghBox.Area());
0091 }
0092
0093
0094 for (Standard_Integer aNbLft = 1, aNbRgh = aNodeNbPrimitives - 1; aNbLft < aNodeNbPrimitives; ++aNbLft, --aNbRgh)
0095 {
0096 Standard_Real aCost = (aLftSet (aNbLft) ) * aNbLft +
0097 (aRghSet (aNbRgh) ) * aNbRgh;
0098 if (aCost < aMinSplitCost)
0099 {
0100 aMinSplitCost = aCost;
0101 aMinSplitAxis = anAxis;
0102 aMinSplitIndex = aNbLft;
0103 }
0104 }
0105 }
0106
0107 if (aMinSplitAxis == -1)
0108 {
0109 return typename BVH_QueueBuilder<T, N>::BVH_ChildNodes();
0110 }
0111
0112 theBVH->SetInner (theNode);
0113 if (aMinSplitAxis != (N < 4 ? N - 1 : 2))
0114 {
0115 BVH_QuickSorter<T, N> (aMinSplitAxis).Perform (theSet, aNodeBegPrimitive, aNodeEndPrimitive);
0116 }
0117
0118 BVH_Box<T, N> aMinSplitBoxLft;
0119 BVH_Box<T, N> aMinSplitBoxRgh;
0120
0121
0122 for (Standard_Integer anIndex = aNodeBegPrimitive; anIndex < aMinSplitIndex + aNodeBegPrimitive; ++anIndex)
0123 {
0124 aMinSplitBoxLft.Combine (theSet->Box (anIndex));
0125 }
0126
0127 for (Standard_Integer anIndex = aNodeEndPrimitive; anIndex >= aMinSplitIndex + aNodeBegPrimitive; --anIndex)
0128 {
0129 aMinSplitBoxRgh.Combine (theSet->Box (anIndex));
0130 }
0131
0132 const Standard_Integer aMiddle = aNodeBegPrimitive + aMinSplitIndex;
0133 typedef typename BVH_QueueBuilder<T, N>::BVH_PrimitiveRange Range;
0134 return typename BVH_QueueBuilder<T, N>::BVH_ChildNodes (aMinSplitBoxLft,
0135 aMinSplitBoxRgh,
0136 Range (aNodeBegPrimitive, aMiddle - 1),
0137 Range (aMiddle, aNodeEndPrimitive));
0138 }
0139
0140 };
0141
0142 #endif