Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:49:29

0001 #pragma once
0002 /**
0003 s_bb.h
0004 ========
0005 
0006 * ctor adds to the pool
0007 * dtor removes from the pool
0008 
0009 */
0010 
0011 #include <string>
0012 #include <sstream>
0013 #include <iomanip>
0014 
0015 #include "s_pool.h"
0016 
0017 struct _s_bb
0018 {
0019     static constexpr const char* ITEM = "6" ;
0020 
0021     double x0 ;
0022     double y0 ;
0023     double z0 ;
0024     double x1 ;
0025     double y1 ;
0026     double z1 ;
0027 };
0028 
0029 #include "SYSRAP_API_EXPORT.hh"
0030 
0031 struct SYSRAP_API s_bb
0032 {
0033     static constexpr const int NUM = 6 ;
0034     static constexpr const char* NAME = "s_bb.npy" ;
0035     static constexpr const bool LEAK = false ;
0036     typedef s_pool<s_bb,_s_bb> POOL ;
0037     static POOL* pool ;
0038     static void SetPOOL( POOL* pool_ );
0039     static int level() ;
0040     //static bool IsZero( const double* v );
0041     static void Serialize( _s_bb& p, const s_bb* o );
0042     static s_bb* Import(  const _s_bb* p, const std::vector<_s_bb>& buf );
0043 
0044     s_bb();
0045     ~s_bb();
0046     s_bb* copy() const ;
0047 
0048     int pid ;
0049 
0050     double x0 ;
0051     double y0 ;
0052     double z0 ;
0053     double x1 ;
0054     double y1 ;
0055     double z1 ;
0056 
0057 
0058     const double* cdata() const { return &x0 ; }
0059     double* data() {              return &x0 ; }
0060 
0061     bool is_root() const { return true ; }
0062     std::string desc() const ;
0063     template<typename T> void write( T* dst ) const ;
0064 
0065     template<typename T> static std::string Desc( const T* aabb );
0066     template<typename T> static bool AllZero( const T* aabb );
0067     template<typename T> static bool Degenerate( const T* aabb );
0068 
0069     template<typename T, int N> static std::string Desc_( const T* v );
0070     template<typename T, int N> static std::string DescNumPy_( const T* v, const char* symbol = "bb", bool imp = false );
0071     template<typename T, int N> static bool AllZero_( const T* v );
0072     template<typename T, int N> static bool Degenerate_( const T* v );
0073 
0074     template<typename S, typename T>
0075     static void IncludePoint( T* aabb,  const S* other_point );
0076 
0077     template<typename S, typename T>
0078     static void IncludeAABB(  T* aabb,  const S* other_aabb , std::ostream* out=nullptr  );
0079 
0080     template<typename T> static T    Extent( const T* aabb ) ;
0081     template<typename T> static T    AbsMax( const T* aabb ) ;
0082     template<typename T> static void CenterExtent( T* ce,  const T* aabb ) ;
0083 
0084     void include_point(      const double* point );
0085     void include_point_widen( const float*  point );
0086     void include_aabb(       const double* aabb  );
0087     void include_aabb_widen(  const float* aabb  );
0088 
0089     template<typename T>
0090     void center_extent( T* ce ) const ;
0091 
0092     template<typename T>
0093     static bool HasOverlap( const T* a,  const T* b ) ;
0094 
0095 };
0096 
0097 inline void s_bb::SetPOOL( POOL* pool_ ){ pool = pool_ ; }
0098 inline int s_bb::level() {  return pool ? pool->level : ssys::getenvint("sn__level",-1) ; } // static
0099 
0100 
0101 inline void s_bb::Serialize( _s_bb& p, const s_bb* o )
0102 {
0103     p.x0 = o->x0 ;
0104     p.y0 = o->y0 ;
0105     p.z0 = o->z0 ;
0106     p.x1 = o->x1 ;
0107     p.y1 = o->y1 ;
0108     p.z1 = o->z1 ;
0109 }
0110 inline s_bb* s_bb::Import( const _s_bb* p, const std::vector<_s_bb>& )
0111 {
0112     s_bb* o = new s_bb ;
0113     o->x0 = p->x0 ;
0114     o->y0 = p->y0 ;
0115     o->z0 = p->z0 ;
0116     o->x1 = p->x1 ;
0117     o->y1 = p->y1 ;
0118     o->z1 = p->z1 ;
0119     return o ;
0120 }
0121 
0122 
0123 inline s_bb::s_bb()
0124     :
0125     pid(pool ? pool->add(this) : -1),
0126     x0(0.),
0127     y0(0.),
0128     z0(0.),
0129     x1(0.),
0130     y1(0.),
0131     z1(0.)
0132 {
0133     if(level() > 1) std::cerr << "s_bb::s_bb pid " << pid << std::endl ;
0134 }
0135 inline s_bb::~s_bb()
0136 {
0137     if(level() > 1) std::cerr << "s_bb::~s_bb pid " << pid << std::endl ;
0138     if(pool) pool->remove(this);
0139 }
0140 
0141 /**
0142 s_bb::copy
0143 -----------
0144 
0145 Note that *pid* is not copied, as pid is set by s_pool::add within the ctor.
0146 This is because pid is only relevant to the persisting architecture
0147 rather than being part of the payload.
0148 
0149 **/
0150 
0151 inline s_bb* s_bb::copy() const
0152 {
0153     s_bb* n = new s_bb ;
0154     n->x0 = x0 ;
0155     n->y0 = y0 ;
0156     n->z0 = z0 ;
0157     n->x1 = x1 ;
0158     n->y1 = y1 ;
0159     n->z1 = z1 ;
0160     return n ;
0161 }
0162 
0163 inline std::string s_bb::desc() const { return Desc(cdata()) ; }
0164 
0165 template<typename T>
0166 inline void s_bb::write( T* dst ) const
0167 {
0168     const double* src = cdata();
0169     for(int i=0 ; i < NUM ; i++) dst[i] = T(src[i]) ;
0170 }
0171 
0172 
0173 
0174 template<typename T>
0175 inline std::string s_bb::Desc( const T* aabb ) // static
0176 {
0177     return Desc_<T,6>(aabb);
0178 }
0179 template<typename T, int N>
0180 inline std::string s_bb::Desc_( const T* v ) // static
0181 {
0182     int w = 10 ;
0183     int p = 3 ;
0184     bool all_zero = AllZero_<T,N>(v);
0185     bool degenerate = Degenerate_<T,N>(v);
0186     std::stringstream ss ;
0187     ss << "[" ;
0188     for(int i=0 ; i < N ; i++)
0189         ss << std::fixed << std::setw(w) << std::setprecision(p) << v[i] << ( i < N - 1 ? "," : "" )  ;
0190     ss << "]"
0191        << ( all_zero ? " ALL_ZERO" : "" )
0192        << ( degenerate ? " DEGENERATE" : "" )
0193        ;
0194     std::string str = ss.str();
0195     return str ;
0196 }
0197 
0198 template<typename T, int N>
0199 inline std::string s_bb::DescNumPy_( const T* v, const char* symbol, bool imp ) // static
0200 {
0201     int w = 10 ;
0202     int p = 3 ;
0203 
0204     std::stringstream ss ;
0205     if(imp) ss << "import numpy as np " ;
0206     ss << " ; " << symbol << " = np.array([" ;
0207     for(int i=0 ; i < N ; i++)
0208         ss << std::fixed << std::setw(w) << std::setprecision(p) << v[i] << ( i < N - 1 ? "," : "" )  ;
0209     ss << "]) " ;
0210     std::string str = ss.str();
0211     return str ;
0212 }
0213 
0214 
0215 
0216 
0217 
0218 template<typename T>
0219 inline bool s_bb::AllZero( const T* v ) // static
0220 {
0221     return AllZero_<T,6>(v) ;
0222 }
0223 template<typename T, int N>
0224 inline bool s_bb::AllZero_( const T* v ) // static
0225 {
0226     int count = 0 ;
0227     for(int i=0 ; i < N ; i++) if(std::abs(v[i]) == T(0.)) count += 1 ;
0228     return count == N ;
0229 }
0230 
0231 
0232 
0233 template<typename T>
0234 inline bool s_bb::Degenerate( const T* v ) // static
0235 {
0236     return Degenerate_<T,6>(v) ;
0237 }
0238 template<typename T, int N>
0239 inline bool s_bb::Degenerate_( const T* v ) // static
0240 {
0241     int count = 0 ;
0242     for(int i=0 ; i < N/2 ; i++) if(v[i] == v[i+N/2]) count += 1 ;
0243     return count == N/2 ;
0244 }
0245 
0246 
0247 
0248 
0249 
0250 /**
0251 s_bb::IncludePoint
0252 -------------------
0253 
0254 When aabb starts empty the point is adopted as both min and max
0255 without any comparisons.
0256 
0257 HMM: AN ALL ZERO POINT IS TREATED AS VALID
0258 
0259 **/
0260 
0261 template<typename S,typename T>
0262 inline void s_bb::IncludePoint( T* aabb,  const S* point ) // static
0263 {
0264     bool adopt = AllZero(aabb) ;
0265     assert( NUM == 6 );
0266     for(int i=0 ; i < 3   ; i++) aabb[i] = adopt ? T(point[i])   : std::min( aabb[i], T(point[i])   );
0267     for(int i=3 ; i < NUM ; i++) aabb[i] = adopt ? T(point[i-3]) : std::min( aabb[i], T(point[i-3]) );
0268 }
0269 
0270 
0271 
0272 /**
0273 s_bb::IncludeAABB
0274 ------------------
0275 
0276 When aabb starts empty and the other_aabb is not empty the
0277 other_aabb is adopted with no comparisons.
0278 Otherwise when both have values the min and max of the
0279 aabb gets set by comparison.
0280 
0281 NB all zero other_aabb values causes an early exit and no combination
0282 as such an other_aabb is regarded as unset
0283 
0284 **/
0285 
0286 template<typename S,typename T>
0287 inline void s_bb::IncludeAABB(  T* aabb,  const S* other_aabb, std::ostream* out  ) // static
0288 {
0289     bool other_aabb_zero = AllZero(other_aabb) ;
0290     if(other_aabb_zero) return ;
0291 
0292     bool aabb_zero = AllZero(aabb) ;
0293 
0294     if(out) *out
0295         << "s_bb::IncludeAABB "
0296         << std::endl
0297         << " inital_aabb  " << Desc(aabb)
0298         << std::endl
0299         << " other_aabb   " << Desc(other_aabb)  << ( aabb_zero ? " ADOPT OTHER AS STARTING" : "COMBINE" )
0300         << std::endl
0301         ;
0302 
0303     assert( NUM == 6 );
0304     for(int i=0 ; i < 3   ; i++) aabb[i] = aabb_zero ? T(other_aabb[i]) : std::min(aabb[i], T(other_aabb[i]) ) ;
0305     for(int i=3 ; i < NUM ; i++) aabb[i] = aabb_zero ? T(other_aabb[i]) : std::max(aabb[i], T(other_aabb[i]) ) ;
0306 
0307     if(out) *out
0308         << " updated_aabb " << Desc(aabb)
0309         << std::endl
0310         ;
0311 }
0312 
0313 
0314 
0315 
0316 
0317 
0318 
0319 
0320 
0321 
0322 
0323 
0324 template<typename T>
0325 inline T s_bb::Extent( const T* aabb )  // static
0326 {
0327     return std::max(std::max(aabb[3+0]-aabb[0],aabb[3+1]-aabb[1]),aabb[3+2]-aabb[2])/T(2.) ;
0328 }
0329 
0330 template<typename T>
0331 inline T s_bb::AbsMax( const T* aabb )  // static
0332 {
0333     T mx = 0. ;
0334     for(int i=0 ; i < 6 ; i++)
0335     {
0336         T amx = std::abs(aabb[i]);
0337         if( amx > mx ) mx = amx ;
0338     }
0339     return mx ;
0340 }
0341 
0342 
0343 
0344 template<typename T>
0345 inline void s_bb::CenterExtent( T* ce,  const T* aabb )  // static
0346 {
0347     for(int i=0 ; i < 3 ; i++) ce[i] = (aabb[i] + aabb[i+3])/T(2.) ;
0348     ce[3] = Extent(aabb) ;
0349 }
0350 
0351 
0352 
0353 inline void s_bb::include_point( const double* point )
0354 {
0355     IncludePoint<double,double>( data(), point );
0356 }
0357 inline void s_bb::include_point_widen( const float* point )
0358 {
0359     IncludePoint<float,double>( data(), point );
0360 }
0361 
0362 
0363 inline void s_bb::include_aabb(  const double* aabb  )
0364 {
0365     IncludeAABB<double,double>( data(), aabb );
0366 }
0367 /**
0368 
0369 s_bb::include_aabb_widen
0370 --------------------------
0371 
0372 Widening is needed because CSGNode/CSGPrim are float based.
0373 Keeping those in double and only narrowing just before the
0374 upload is a possibility.  That is not totally trivial however
0375 because they carry integers in some of the elements.
0376 
0377 **/
0378 
0379 inline void s_bb::include_aabb_widen(  const float* aabb  )
0380 {
0381     IncludeAABB<float,double>( data(), aabb );
0382 }
0383 
0384 
0385 /**
0386 s_bb::center_extent
0387 --------------------
0388 
0389 Prior to 2026/02/03 the division by 2. was omitted giving double the extent.
0390 However bbox not effected, so probably limited effect.
0391 
0392 Used by CSGCopy::copy
0393 
0394 **/
0395 
0396 template<typename T>
0397 inline void s_bb::center_extent( T* ce ) const
0398 {
0399     ce[0] = ( x0 + x1 )/2. ;
0400     ce[1] = ( y0 + y1 )/2. ;
0401     ce[2] = ( z0 + z1 )/2. ;
0402     ce[3] = std::max(std::max(x1-x0,y1-y0),z1-z0)/2. ;
0403 }
0404 
0405 
0406 template<typename T>
0407 inline bool s_bb::HasOverlap( const T* a,  const T* b )
0408 {
0409     return (a[0] <= b[3] && a[3] >= b[0]) && // X overlap
0410            (a[1] <= b[4] && a[4] >= b[1]) && // Y overlap
0411            (a[2] <= b[5] && a[5] >= b[2]);   // Z overlap
0412 }
0413 
0414 
0415 
0416 
0417 
0418