10 #ifndef ApproxMVBB_ComputeApproxMVBB_hpp 11 #define ApproxMVBB_ComputeApproxMVBB_hpp 16 #include ApproxMVBB_TypeDefs_INCLUDE_FILE 20 #include ApproxMVBB_OOBB_INCLUDE_FILE 39 template<
typename Derived>
41 const MatrixBase<Derived> & points,
42 const unsigned int nPoints,
47 using IndexType =
typename Derived::Index;
49 if(nPoints > points.cols() || nPoints < 2) {
50 ApproxMVBB_ERRORMSG(
"Wrong arguments!" <<
"sample nPoints: (>2) " << nPoints <<
" of points: " << points.cols() << std::endl )
53 newPoints.resize(3,nPoints);
56 unsigned int gridSize = std::max( static_cast<unsigned int>( std::sqrt( static_cast<double>(nPoints) / 2.0 )) , 1U );
62 IndexType halfSampleSize = gridSize*gridSize;
64 struct BottomTopPoints{
65 IndexType bottomIdx = 0;
73 std::vector< BottomTopPoints > boundaryPoints(halfSampleSize);
75 using LongInt =
long long int;
85 IndexType size = points.cols();
86 for(IndexType i=0; i<size; ++i) {
88 K_p = A_KI * points.col(i);
90 idx = ( (K_p - oobb.
m_minPoint).head<2>().array() * dxdyInv ).
template cast<LongInt>();
92 idx(0) = std::max( std::min( LongInt(gridSize-1), idx(0)), 0LL );
93 idx(1) = std::max( std::min( LongInt(gridSize-1), idx(1)), 0LL );
99 auto & pB = boundaryPoints[idx(0) + idx(1)*gridSize];
101 if( pB.bottomIdx == 0) {
102 pB.bottomIdx = pB.topIdx = i+1;
103 pB.bottomZ = pB.topZ = K_p(2);
105 if( pB.topZ < K_p(2) ) {
109 if( pB.bottomZ > K_p(2) ) {
121 for(IndexType i=0; i<halfSampleSize; ++i) {
122 if( boundaryPoints[i].bottomIdx != 0 ) {
127 newPoints.col(k++) = points.col(boundaryPoints[i].topIdx-1);
128 if(boundaryPoints[i].topIdx != boundaryPoints[i].bottomIdx) {
133 newPoints.col(k++) = points.col(boundaryPoints[i].bottomIdx-1);
143 typename std::make_unsigned<IndexType>::type
144 > dis(0, points.cols()-1);
146 while( k < nPoints) {
149 newPoints.col(k++) = points.col( s );
163 template<
typename Derived>
166 unsigned int nLoops = 10,
167 PREC volumeAcceptFactor = 1e-6,
168 PREC minBoxExtent = 1e-12
172 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived,3,Eigen::Dynamic)
174 if( oobb.
volume() == 0.0 || nLoops == 0) {
179 PREC volumeAcceptTol = oobb.
volume() * volumeAcceptFactor;
182 unsigned int cacheIdx = 0;
187 for(
unsigned int loop = 0; loop < nLoops; ++loop ) {
194 for(
unsigned char i=0; i<3 && i<loop; ++i) {
195 PREC dotp = std::abs(dir.dot(dirCache[i]));
196 if( std::abs(dotp - 1.0) <= 1e-3 ) {
204 dirCache[cacheIdx] = dir;
205 cacheIdx = (cacheIdx + 1) % 3;
233 template<
typename Derived>
237 const unsigned int gridSize = 5,
238 const unsigned int optLoops = 6,
239 PREC volumeAcceptFactor = 1e-6,
240 PREC minBoxExtent = 1e-12
243 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived,3,Eigen::Dynamic)
260 for(
int x = -
int(gridSize); x <= (int)gridSize; ++x ) {
261 for(
int y = -
int(gridSize); y <= (int)gridSize; ++y ) {
262 for(
int z = 0; z <= (int)gridSize; ++z ) {
269 dir = x*dir1 + y*dir2 + z*dir3;
279 res =
optimizeMVBB(points,res,optLoops,volumeAcceptFactor,minBoxExtent);
282 if(res.volume() < oobb.
volume() ) {
284 ApproxMVBB_MSGLOG_L2(
"gridSearch: new volume: " << res.volume() << std::endl <<
"for dir: " << dir.transpose() << std::endl; )
300 template<
typename Derived>
303 const unsigned int optLoops = 10,
307 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived,3,Eigen::Dynamic)
309 using namespace PointFunctions;
310 auto pp = estimateDiameter<3>(points, epsilon, seed );
315 if( ( dirZ.array() <= 0.0).all() ) {
320 if( (dirZ.array() == 0.0).all() ) {
324 ApproxMVBB_MSGLOG_L1(
"estimated 3d diameter: " << dirZ.transpose() <<
" eps: " << epsilon << std::endl;)
330 OOBB oobb = proj.computeMVBBApprox(dirZ,points,epsilon);
338 template<
typename Derived >
341 const unsigned int pointSamples = 400,
342 const unsigned int gridSize = 5,
343 const unsigned int mvbbDiamOptLoops = 0,
344 const unsigned int mvbbGridSearchOptLoops = 6,
348 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived,3,Eigen::Dynamic)
355 if(pointSamples<points.cols()) {
376 #endif // ApproxMVBB_hpp Eigen::Array< Scalar, 2, 1 > Array2
std::enable_if< std::is_integral< T >::value, T >::type gcd3(T a, T b, T c)
OOBB computeMVBB(const Vector3 &zDir, const MatrixBase< Derived > &points)
These are some container definitions.
#define ApproxMVBB_MSGLOG_L3(message)
APPROXMVBB_EXPORT OOBB approximateMVBB(const MatrixBase< Derived > &points, const PREC epsilon, const unsigned int pointSamples=400, const unsigned int gridSize=5, const unsigned int mvbbDiamOptLoops=0, const unsigned int mvbbGridSearchOptLoops=6, std::size_t seed=ApproxMVBB::RandomGenerators::defaultSeed)
#define ApproxMVBB_ERRORMSG(message)
Vector3 getDirection(unsigned int i) const
ApproxMVBB_DEFINE_MATRIX_TYPES ApproxMVBB_DEFINE_POINTS_CONFIG_TYPES APPROXMVBB_EXPORT void samplePointsGrid(Matrix3Dyn &newPoints, const MatrixBase< Derived > &points, const unsigned int nPoints, OOBB &oobb, std::size_t seed=ApproxMVBB::RandomGenerators::defaultSeed)
APPROXMVBB_EXPORT OOBB optimizeMVBB(const MatrixBase< Derived > &points, OOBB oobb, unsigned int nLoops=10, PREC volumeAcceptFactor=1e-6, PREC minBoxExtent=1e-12)
static const uint64_t defaultSeed
MatrixStatDyn< 3 > Matrix3Dyn
void expandToMinExtentAbsolute(PREC minExtent)
Eigen::Matrix< Scalar, 3, 3 > Matrix33
Quaternion m_q_KI
Rotation of frame I to frame K, corresponds to a transformation A_IK;.
Vector3 m_minPoint
in K Frame
#define ApproxMVBB_DEFINE_POINTS_CONFIG_TYPES
#define ApproxMVBB_MSGLOG_L2(message)
std::uniform_int_distribution< T > DefaultUniformUIntDistribution
APPROXMVBB_EXPORT OOBB approximateMVBBDiam(const MatrixBase< Derived > &points, const PREC epsilon, const unsigned int optLoops=10, std::size_t seed=ApproxMVBB::RandomGenerators::defaultSeed)
APPROXMVBB_EXPORT OOBB approximateMVBBGridSearch(const MatrixBase< Derived > &points, OOBB oobb, PREC epsilon, const unsigned int gridSize=5, const unsigned int optLoops=6, PREC volumeAcceptFactor=1e-6, PREC minBoxExtent=1e-12)
Eigen::Matrix< Scalar, 3, 1 > Vector3
#define ApproxMVBB_DEFINE_MATRIX_TYPES
#define ApproxMVBB_MSGLOG_L1(message)