File indexing completed on 2026-04-09 07:48:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <csignal>
0011 #include "SSim.hh"
0012 #include "SSys.hh"
0013 #include "SPath.hh"
0014 #include "NP.hh"
0015 #include "OPTICKS_LOG.hh"
0016
0017 #include "CSGFoundry.h"
0018 #include "CSGMaker.h"
0019 #include "CSGQuery.h"
0020 #include "CSGDraw.h"
0021
0022
0023 struct CSGQueryTest
0024 {
0025 static const int VERBOSE ;
0026
0027 const CSGFoundry* fd ;
0028 const CSGQuery* q ;
0029 CSGDraw* d ;
0030 int gsid ;
0031
0032 static const char* DUMP ;
0033 int dump ;
0034 bool dump_hit ;
0035 bool dump_miss ;
0036 bool dump_dist ;
0037
0038 const char* name ;
0039 float3 ray_origin ;
0040 float3 ray_direction ;
0041 float tmin ;
0042 int num ;
0043
0044
0045 std::vector<quad4>* isects ;
0046 CSGQueryTest();
0047
0048 void create_isects();
0049 std::string config(
0050 const char* _name,
0051 const char* _ray_origin,
0052 const char* _ray_direction,
0053 const char* _tmin,
0054 const char* _num
0055 );
0056
0057 void operator()( char mode);
0058 void save() const ;
0059
0060 void intersect(int idx, float3* mod_ray_origin=nullptr , float3* mod_ray_direction=nullptr);
0061 void distance(int idx, float3* mod_ray_origin=nullptr );
0062
0063 void OneIntersection();
0064 void OneDistance();
0065 void Load();
0066 void XScan();
0067 void LookForSeam();
0068 void PhiScan();
0069 void AxisScan();
0070 void PacmanPhiLine0();
0071 void PacmanPhiLine1();
0072 void PacmanPhiLine2();
0073 };
0074
0075 const char* CSGQueryTest::DUMP=" ( 0:no 1:hit 2:miss 3:hit+miss ) " ;
0076 const int CSGQueryTest::VERBOSE = SSys::getenvint("VERBOSE", 0 );
0077
0078
0079 CSGQueryTest::CSGQueryTest()
0080 :
0081 fd(CSGFoundry::Load()),
0082 q(new CSGQuery(fd)),
0083 d(new CSGDraw(q,'Z')),
0084 gsid(0),
0085 dump(SSys::getenvint("DUMP",0)),
0086 dump_hit( (dump & 1) != 0 ),
0087 dump_miss( (dump & 2) != 0 ),
0088 dump_dist( (dump & 4) != 0 ),
0089 name("noname"),
0090 isects(nullptr)
0091 {
0092 if(VERBOSE > 0 )
0093 {
0094 LOG(info) << " GEOM " << fd->geom ;
0095 LOG(info) << d->desc();
0096 }
0097 }
0098
0099 void CSGQueryTest::operator()( char mode)
0100 {
0101 LOG_IF(info, VERBOSE > 0) << " mode " << mode ;
0102 bool bad_mode = false ;
0103
0104 switch(mode)
0105 {
0106 case 'O': OneIntersection() ; break ;
0107 case 'D': OneDistance() ; break ;
0108 case 'L': Load() ; break ;
0109 case 'S': LookForSeam() ; break ;
0110 case 'X': XScan() ; break ;
0111 case 'P': PhiScan() ; break ;
0112 case 'A': AxisScan() ; break ;
0113 case '0': PacmanPhiLine0() ; break ;
0114 case '1': PacmanPhiLine1() ; break ;
0115 case '2': PacmanPhiLine2() ; break ;
0116 default: bad_mode = true ; break ;
0117 }
0118
0119 LOG_IF(error, bad_mode ) << " bad_mode [" << mode << "]" ;
0120 assert( bad_mode == false );
0121
0122 }
0123
0124 void CSGQueryTest::create_isects()
0125 {
0126 assert( num > 0 );
0127 isects = new std::vector<quad4>(num) ;
0128
0129 if( num == 1 )
0130 {
0131 dump_hit = true ;
0132 dump_miss = true ;
0133 dump_dist = true ;
0134 }
0135
0136 }
0137
0138 std::string CSGQueryTest::config(
0139 const char* _name,
0140 const char* _ray_origin,
0141 const char* _ray_direction,
0142 const char* _tmin,
0143 const char* _num
0144 )
0145 {
0146 name = strdup(_name);
0147
0148 qvals(ray_origin , "ORI", _ray_origin );
0149 qvals(ray_direction, "DIR", _ray_direction );
0150 qvals(tmin , "TMIN", _tmin );
0151 qvals(num , "NUM", _num );
0152
0153 ray_direction = normalize(ray_direction);
0154
0155 create_isects();
0156
0157 std::stringstream ss ;
0158 ss
0159 << " name " << name << std::endl
0160 << " dump " << dump
0161
0162 << " dump_hit " << dump_hit
0163 << " dump_miss " << dump_miss
0164 << DUMP
0165 << std::endl
0166 << " ORI ray_origin " << ray_origin << std::endl
0167 << " DIR ray_direction " << ray_direction << std::endl
0168 << " TMIN tmin " << tmin << std::endl
0169 << " GSID gsid " << gsid << std::endl
0170 << " NUM num " << num << std::endl
0171 ;
0172
0173 std::string s = ss.str();
0174
0175 LOG_IF(info, VERBOSE > 0) << std::endl << s ;
0176 return s ;
0177 }
0178
0179 void CSGQueryTest::intersect(int idx, float3* mod_ray_origin, float3* mod_ray_direction )
0180 {
0181 assert( idx < num );
0182 quad4& isect = (*isects)[idx] ;
0183
0184 bool valid_intersect = q->intersect(isect, tmin,
0185 mod_ray_origin ? *mod_ray_origin : ray_origin,
0186 mod_ray_direction ? *mod_ray_direction : ray_direction,
0187 gsid );
0188
0189 bool do_dump = ( dump_hit && valid_intersect ) || ( dump_miss && !valid_intersect );
0190 if(do_dump) std::cout << CSGQuery::Desc( isect, name, &valid_intersect ) << std::endl ;
0191 }
0192
0193 void CSGQueryTest::distance(int idx, float3* mod_ray_origin )
0194 {
0195 assert( idx < num );
0196 quad4& isect = (*isects)[idx] ;
0197
0198 q->distance( isect, mod_ray_origin ? *mod_ray_origin : ray_origin );
0199
0200 if(dump_dist) std::cout << CSGQuery::Desc( isect, name, nullptr ) << std::endl ;
0201 }
0202
0203
0204 void CSGQueryTest::save() const
0205 {
0206 NP::Write("/tmp", "CSGQueryTest.npy", (float*)isects->data(), isects->size(), 4, 4 );
0207 }
0208
0209 void CSGQueryTest::XScan()
0210 {
0211 config("XScan", "0,0,0", "0,0,1", "0", "10" );
0212
0213 float3 ray_direction_0 = ray_direction ;
0214 float3 ray_direction_1 = ray_direction ;
0215 ray_direction_0.z = 1.f ;
0216 ray_direction_1.z = -1.f ;
0217
0218 ray_direction_0 = normalize(ray_direction_0 );
0219 ray_direction_1 = normalize(ray_direction_1 );
0220
0221 for(int i=0 ; i < num ; i++)
0222 {
0223 ray_origin.x = float(i - num/2) ;
0224 intersect( 2*i+0, nullptr, &ray_direction_0 );
0225 intersect( 2*i+1, nullptr, &ray_direction_1 );
0226 }
0227 }
0228
0229 void CSGQueryTest::PhiScan()
0230 {
0231 config("PhiScan", "0,0,0", "1,0,0", "0", "12" );
0232
0233 for(int i=0 ; i < num ; i++)
0234 {
0235 double fphi = double(i)/double(num-1) ;
0236 double fphi_deg = fphi*360. ;
0237 double phi = fphi*2.*M_PIf ;
0238
0239 ray_direction.x = std::cos( phi );
0240 ray_direction.y = std::sin( phi );
0241 ray_direction.z = 0.f ;
0242
0243 std::cout << " i " << std::setw(3) << i << " fphi " << fphi << " fphi_deg " << fphi_deg << std::endl ;
0244 intersect(i);
0245 }
0246 }
0247
0248 void CSGQueryTest::AxisScan()
0249 {
0250 config("AxisScan", "-200,0,0", "1,0,0", "0", "100" );
0251 for( int i=0 ; i < num ; i++)
0252 {
0253 ray_origin.z = float(i-num/2) ;
0254 intersect(i);
0255 }
0256 }
0257 void CSGQueryTest::LookForSeam()
0258 {
0259 config("LookForSeam", "-200,0,10", "1,0,0", "0", "1" );
0260 intersect(0);
0261 }
0262 void CSGQueryTest::PacmanPhiLine0()
0263 {
0264 config("PacmanPhiLine0", "0,0,0", "1,1,0", "0", "1" );
0265 intersect(0);
0266 }
0267 void CSGQueryTest::PacmanPhiLine1()
0268 {
0269 config("PacmanPhiLine1", "0,0,0", "1,-1,0", "0", "1" );
0270 intersect(0);
0271 }
0272 void CSGQueryTest::PacmanPhiLine2()
0273 {
0274 config("PacmanPhiLine1", "1,1,0", "1,1,0", "0", "1" );
0275 intersect(0);
0276 }
0277 void CSGQueryTest::OneIntersection()
0278 {
0279 config("One", "-150,0,0", "1,0,0", "0", "1" );
0280 intersect(0);
0281 }
0282 void CSGQueryTest::OneDistance()
0283 {
0284 config("Dist", "-150,0,0", "1,0,0", "0", "1" );
0285 distance(0);
0286 }
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309 void CSGQueryTest::Load()
0310 {
0311 const char* defaultpath = "$TMP/CSGOptiX/CSGOptiXRenderTest/dy_1_dx_1.npy" ;
0312 const char* loadpath_ = SSys::getenvvar("LOAD", defaultpath ) ;
0313 int create_dirs = 0 ;
0314 const char* loadpath = SPath::Resolve(loadpath_, create_dirs) ;
0315
0316 NP* a = NP::Load(loadpath);
0317
0318 int2 yx ;
0319 qvals( yx, "YX", "0,0" );
0320 int iy = yx.x ;
0321 int ix = yx.y ;
0322
0323 LOG(info) << " a " << a->sstr() << " LOAD loadpath " << loadpath << " YX ( " << iy << "," << ix << " )" ;
0324
0325 assert( a->shape.size() == 4 );
0326 int ni = a->shape[0] ;
0327 int nj = a->shape[1] ;
0328 int nk = a->shape[2] ;
0329 int nl = a->shape[3] ;
0330
0331 int ny = ni ;
0332 int nx = nj ;
0333
0334
0335 bool a_expect = nk == 4 && nl == 4 && ix < nx && iy < ny ;
0336 assert(a_expect );
0337 if(!a_expect) std::raise(SIGINT);
0338
0339
0340 quad4 load_isect ;
0341 load_isect.zero();
0342
0343 unsigned itemoffset = iy*nx + ix ;
0344
0345 unsigned itembytes = sizeof(float)*4*4 ;
0346 void* dst = &load_isect.q0.f.x ;
0347 void* src = a->bytes() + itembytes*itemoffset ;
0348
0349 memcpy( dst, src, itembytes );
0350
0351 LOG_IF(info, VERBOSE > 0)
0352 << "load_isect " << std::endl
0353 << " q0.f " << load_isect.q0.f << std::endl
0354 << " q1.f " << load_isect.q1.f << std::endl
0355 << " q2.f " << load_isect.q2.f << std::endl
0356 << " q3.f " << load_isect.q3.f << std::endl
0357 ;
0358
0359 ray_origin.x = load_isect.q2.f.x ;
0360 ray_origin.y = load_isect.q2.f.y ;
0361 ray_origin.z = load_isect.q2.f.z ;
0362 tmin = load_isect.q2.f.w ;
0363
0364 ray_direction.x = load_isect.q3.f.x ;
0365 ray_direction.y = load_isect.q3.f.y ;
0366 ray_direction.z = load_isect.q3.f.z ;
0367
0368 num = 1 ;
0369 create_isects();
0370 intersect(0);
0371 }
0372
0373
0374 int main(int argc, char** argv)
0375 {
0376 OPTICKS_LOG(argc, argv);
0377
0378 char mode = argc > 1 ? argv[1][0] : 'O' ;
0379 if( SSys::getenvbool("YX") ) mode = 'L' ;
0380
0381 SSim::Create();
0382
0383 CSGQueryTest t ;
0384 t(mode);
0385
0386 return 0 ;
0387 }
0388