File indexing completed on 2026-04-09 07:48:57
0001
0002 #include <csignal>
0003 #include "scuda.h"
0004 #include "squad.h"
0005 #include "stran.h"
0006 #include "OpticksCSG.h"
0007
0008 #include "SSim.hh"
0009 #include "stree.h"
0010 #include "snd.hh"
0011 #include "s_bb.h"
0012
0013 #include "ssys.h"
0014 #include "SLOG.hh"
0015
0016 #include "CSGNode.h"
0017 #include "CSGFoundry.h"
0018 #include "CSGImport.h"
0019
0020 const plog::Severity CSGImport::LEVEL = SLOG::EnvLevel("CSGImport", "DEBUG" );
0021
0022 const int CSGImport::LVID = ssys::getenvint("LVID", -1);
0023 const int CSGImport::NDID = ssys::getenvint("NDID", -1);
0024
0025
0026 CSGImport::CSGImport( CSGFoundry* fd_ )
0027 :
0028 fd(fd_),
0029 st(nullptr)
0030 {
0031 LOG_IF(fatal, fd == nullptr) << " fd(CSGFoundry) required " ;
0032 assert( fd ) ;
0033 }
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 void CSGImport::import()
0046 {
0047 LOG(LEVEL) << "[" ;
0048
0049 st = fd->sim ? fd->sim->tree : nullptr ;
0050 LOG_IF(fatal, st == nullptr) << " fd.sim(SSim) fd.st(stree) required " ;
0051 assert(st);
0052
0053
0054 importNames();
0055 importSolid();
0056 importInst();
0057
0058 LOG(LEVEL) << "]" ;
0059 }
0060
0061
0062 void CSGImport::importNames()
0063 {
0064 st->get_mmlabel( fd->mmlabel);
0065 st->get_meshname(fd->meshname);
0066 }
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 void CSGImport::importSolid()
0083 {
0084 int num_ridx = st->get_num_ridx() ;
0085 for(int ridx=0 ; ridx < num_ridx ; ridx++)
0086 {
0087 char ridx_type = st->get_ridx_type(ridx) ;
0088 switch(ridx_type)
0089 {
0090 case 'R': importSolidGlobal( ridx, ridx_type ) ; break ;
0091 case 'T': importSolidGlobal( ridx, ridx_type ) ; break ;
0092 case 'F': importSolidFactor( ridx, ridx_type ) ; break ;
0093 }
0094 }
0095 }
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114 CSGSolid* CSGImport::importSolidRemainder_OLD(int ridx, const char* rlabel)
0115 {
0116 assert( ridx == 0 );
0117 int num_rem = st->rem.size() ;
0118
0119 LOG(LEVEL)
0120 << " ridx " << ridx
0121 << " rlabel " << rlabel
0122 << " num_rem " << num_rem
0123 ;
0124
0125 std::array<float,6> bb = {} ;
0126 CSGSolid* so = fd->addSolid(num_rem, rlabel);
0127
0128 for(int i=0 ; i < num_rem ; i++)
0129 {
0130 int primIdx = i ;
0131 const snode& node = st->rem[primIdx] ;
0132 CSGPrim* pr = importPrim( primIdx, node ) ;
0133 assert( pr );
0134 s_bb::IncludeAABB( bb.data(), pr->AABB() );
0135 }
0136 s_bb::CenterExtent( &(so->center_extent.x), bb.data() );
0137 return so ;
0138 }
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151 CSGSolid* CSGImport::importSolidGlobal(int ridx, char ridx_type )
0152 {
0153 assert( ridx_type == 'R' || ridx_type == 'T' );
0154
0155 std::string _rlabel = CSGSolid::MakeLabel(ridx_type,ridx) ;
0156 const char* rlabel = _rlabel.c_str();
0157
0158
0159 const std::vector<snode>* src = st->get_node_vector(ridx_type) ;
0160 assert( src );
0161
0162 int num_src = src->size() ;
0163
0164 LOG(LEVEL)
0165 << " ridx " << ridx
0166 << " ridx_type " << ridx_type
0167 << " rlabel " << rlabel
0168 << " num_src " << num_src
0169 ;
0170
0171 std::array<float,6> bb = {} ;
0172 CSGSolid* so = fd->addSolid(num_src, rlabel);
0173 so->setIntent(ridx_type);
0174
0175 for(int i=0 ; i < num_src ; i++)
0176 {
0177 int primIdx = i ;
0178 const snode& node = (*src)[primIdx] ;
0179 CSGPrim* pr = importPrim( primIdx, node ) ;
0180 assert( pr );
0181 s_bb::IncludeAABB( bb.data(), pr->AABB() );
0182 }
0183 s_bb::CenterExtent( &(so->center_extent.x), bb.data() );
0184 return so ;
0185 }
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205 CSGSolid* CSGImport::importSolidFactor(int ridx, char ridx_type )
0206 {
0207 assert( ridx > 0 );
0208 assert( ridx_type == 'F' );
0209
0210 std::string _rlabel = CSGSolid::MakeLabel(ridx_type,ridx) ;
0211 const char* rlabel = _rlabel.c_str();
0212
0213
0214 int num_rem = st->get_num_remainder() ;
0215 assert( num_rem == 1 ) ;
0216
0217 int num_factor = st->factor.size() ;
0218 assert( ridx - num_rem < num_factor );
0219
0220 const sfactor& sf = st->factor[ridx-num_rem] ;
0221 int subtree = sf.subtree ;
0222
0223 CSGSolid* so = fd->addSolid(subtree, rlabel);
0224 so->setIntent(ridx_type);
0225
0226 int q_repeat_index = ridx ;
0227 int q_repeat_ordinal = 0 ;
0228
0229 std::vector<snode> nodes ;
0230 st->get_repeat_node(nodes, q_repeat_index, q_repeat_ordinal) ;
0231
0232 LOG(LEVEL)
0233 << " ridx " << ridx
0234 << " ridx_type " << ridx_type
0235 << " num_rem " << num_rem
0236 << " rlabel " << rlabel
0237 << " num_factor " << num_factor
0238 << " nodes.size " << nodes.size()
0239 << " subtree " << subtree
0240 ;
0241
0242 assert( subtree == int(nodes.size()) );
0243
0244 std::array<float,6> bb = {} ;
0245
0246 for(int i=0 ; i < subtree ; i++)
0247 {
0248 int primIdx = i ;
0249 const snode& node = nodes[primIdx] ;
0250
0251 CSGPrim* pr = importPrim( primIdx, node );
0252 assert( pr );
0253 pr->setRepeatIdx(ridx);
0254
0255 s_bb::IncludeAABB( bb.data(), pr->AABB() );
0256 }
0257 s_bb::CenterExtent( &(so->center_extent.x), bb.data() );
0258
0259 return so ;
0260 }
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293 CSGPrim* CSGImport::importPrim(int primIdx, const snode& node )
0294 {
0295 int lvid = node.lvid ;
0296 const char* name = fd->getMeshName(lvid) ;
0297 bool strip = true ;
0298 std::string soname = st->get_lvid_soname(lvid, strip);
0299
0300
0301 const sn* rt = sn::GetLVRoot(lvid);
0302 assert(rt);
0303 int idx_rc = rt->check_idx("CSGImport::importPrim.check_idx");
0304
0305
0306
0307
0308 std::vector<const sn*> nds ;
0309 sn::GetLVNodesComplete(nds, lvid);
0310 int bn = nds.size();
0311
0312
0313
0314 std::vector<const sn*> lns ;
0315 sn::GetLVListnodes( lns, lvid );
0316 int num_sub_total = sn::GetChildTotal( lns );
0317
0318 int ln = lns.size();
0319 bool ln_expect = ln == 0 || ln == 1 ;
0320
0321
0322 bool dump_LVID = node.lvid == LVID || ln > 0 || idx_rc > 0 ;
0323 if(dump_LVID) std::cout
0324 << "[CSGImport::importPrim.dump_LVID:" << dump_LVID
0325 << " node.lvid " << node.lvid
0326 << " idx_rc " << idx_rc
0327 << " LVID " << LVID
0328 << " name " << ( name ? name : "-" )
0329 << " soname " << soname
0330 << " primIdx " << primIdx
0331 << " bn " << bn << "(binary nodes)"
0332 << " ln(subset of bn) " << ln
0333 << " ln_expect " << ( ln_expect ? "YES" : "NO " )
0334 << " num_sub_total " << num_sub_total
0335 << "\n"
0336 << "[rt.render\n"
0337 << rt->render()
0338 << "]rt.render\n"
0339 ;
0340
0341 if(dump_LVID && ln > 0 ) std::cout
0342 << ".CSGImport::importPrim dumping as ln > 0 : solid contains listnode"
0343 << std::endl
0344 ;
0345
0346 assert( ln_expect );
0347
0348
0349
0350
0351 CSGPrim* pr = fd->addPrim( bn + num_sub_total );
0352
0353 pr->setMeshIdx(lvid);
0354 pr->setPrimIdx(primIdx);
0355
0356 std::stringstream ss ;
0357 std::ostream* out = dump_LVID ? &ss : nullptr ;
0358
0359 std::array<float,6> bb = {} ;
0360
0361 CSGNode* root = nullptr ;
0362
0363
0364 std::vector<const sn*> subs ;
0365
0366 int sub_offset = 0 ;
0367 sub_offset += bn ;
0368
0369
0370
0371
0372
0373
0374
0375
0376 for(int i=0 ; i < bn ; i++)
0377 {
0378 int partIdx = i ;
0379 const sn* nd = nds[partIdx];
0380
0381 CSGNode* n = nullptr ;
0382 if(nd && nd->is_listnode())
0383 {
0384 n = importListnode(pr->nodeOffset(), partIdx, node, nd ) ;
0385
0386 int num_sub = nd->child.size() ;
0387 for(int j=0 ; j < num_sub ; j++)
0388 {
0389 const sn* c = nd->child[j];
0390 subs.push_back(c);
0391 }
0392 n->setSubNum(num_sub);
0393 n->setSubOffset(sub_offset);
0394 sub_offset += num_sub ;
0395 }
0396 else
0397 {
0398 n = importNode(pr->nodeOffset(), partIdx, node, nd ) ;
0399 }
0400 assert(n);
0401 if(root == nullptr) root = n ;
0402
0403 if(!n->is_complemented_primitive()) s_bb::IncludeAABB( bb.data(), n->AABB(), out );
0404 }
0405
0406 assert( sub_offset == bn + num_sub_total );
0407 assert( int(subs.size()) == num_sub_total );
0408
0409
0410
0411 for( int i=0 ; i < num_sub_total ; i++ )
0412 {
0413 const sn* nd = subs[i];
0414 CSGNode* n = importNode(pr->nodeOffset(), i, node, nd );
0415 assert( n );
0416 if(!n->is_complemented_primitive()) s_bb::IncludeAABB( bb.data(), n->AABB(), out );
0417 }
0418
0419
0420 pr->setAABB( bb.data() );
0421
0422 assert( root );
0423
0424
0425
0426
0427
0428
0429
0430 if(CSG::IsCompound(root->typecode()) && !CSG::IsList(root->typecode()))
0431 {
0432 assert( bn > 0 );
0433 root->setSubNum( bn );
0434 root->setSubOffset( 0 );
0435 }
0436
0437
0438 LOG_IF(info, dump_LVID ) << ss.str() ;
0439 LOG(LEVEL)
0440 << " primIdx " << std::setw(4) << primIdx
0441 << " lvid " << std::setw(3) << lvid
0442 << " binaryNodes(bn) " << std::setw(3) << bn
0443 << " : "
0444 << name
0445 ;
0446
0447 if(dump_LVID) std::cout
0448 << "]CSGImport::importPrim.dump_LVID:" << dump_LVID
0449 << " node.lvid " << node.lvid
0450 << " LVID " << LVID
0451 << " name " << ( name ? name : "-" )
0452 << " soname " << soname
0453 << std::endl
0454 ;
0455
0456
0457 return pr ;
0458 }
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531 CSGNode* CSGImport::importNode(int nodeOffset, int partIdx, const snode& node, const sn* nd)
0532 {
0533 if(nd) assert( node.lvid == nd->lvid );
0534
0535 int typecode = nd ? nd->typecode : CSG_ZERO ;
0536 bool leaf = CSG::IsLeaf(typecode) ;
0537
0538 bool external_bbox_is_expected = CSG::ExpectExternalBBox(typecode);
0539
0540
0541 bool expect = external_bbox_is_expected == false ;
0542 LOG_IF(fatal, !expect)
0543 << " NOT EXPECTING LEAF WITH EXTERNAL BBOX EXPECTED "
0544 << " for node of type " << CSG::Name(typecode)
0545 << " nd.lvid " << ( nd ? nd->lvid : -1 )
0546 ;
0547 assert(expect);
0548 if(!expect) std::raise(SIGINT);
0549
0550 std::array<double,6> bb ;
0551 double* aabb = leaf ? bb.data() : nullptr ;
0552
0553 std::ostream* out = nullptr ;
0554 stree::VTR* t_stack = nullptr ;
0555
0556 const Tran<double>* tv = leaf ? st->get_combined_tran_and_aabb( aabb, node, nd, out, t_stack ) : nullptr ;
0557 unsigned tranIdx = tv ? 1 + fd->addTran(tv) : 0 ;
0558
0559 CSGNode* n = fd->addNode();
0560 n->setTypecode(typecode);
0561 n->setBoundary(node.boundary);
0562 n->setComplement( nd ? nd->complement : false );
0563 n->setTransform(tranIdx);
0564 n->setParam_Narrow( nd ? nd->getPA_data() : nullptr );
0565 n->setAABB_Narrow(aabb ? aabb : nullptr );
0566
0567 return n ;
0568 }
0569
0570 CSGNode* CSGImport::importListnode(int nodeOffset, int partIdx, const snode& node, const sn* nd)
0571 {
0572 if(nd) assert( node.lvid == nd->lvid );
0573 assert( nd->is_listnode() );
0574 int typecode = nd->typecode ;
0575
0576 CSGNode* n = fd->addNode();
0577 n->setTypecode(typecode);
0578 n->setBoundary(node.boundary);
0579
0580 return n ;
0581 }
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597 void CSGImport::importInst()
0598 {
0599 fd->addInstanceVector( st->inst_f4 );
0600 }
0601
0602
0603