File indexing completed on 2026-04-09 07:49:46
0001 #pragma once
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 #include "ssys.h"
0044 #include "stree.h"
0045 #include "svec.h"
0046
0047 #include "SName.h"
0048 #include "SMesh.h"
0049 #include "SMeshGroup.h"
0050 #include "SBitSet.h"
0051 #include "SGeoConfig.hh"
0052
0053 struct SScene
0054 {
0055 static constexpr const char* __level = "SScene__level" ;
0056
0057 static constexpr const char* BASE = "$CFBaseFromGEOM/CSGFoundry/SSim" ;
0058 static constexpr const char* RELDIR = "scene" ;
0059
0060 static constexpr const char* MESHGROUP = "meshgroup" ;
0061 static constexpr const char* MESHMERGE = "meshmerge" ;
0062 static constexpr const char* FRAME = "frame" ;
0063 static constexpr const char* INST_TRAN = "inst_tran.npy" ;
0064 static constexpr const char* INST_COL3 = "inst_col3.npy" ;
0065 static constexpr const char* INST_INFO = "inst_info.npy" ;
0066 static constexpr const char* SONAME = "soname.txt" ;
0067
0068 int level ;
0069 std::vector<std::string> soname ;
0070 SName* id ;
0071
0072 std::vector<const SMeshGroup*> meshgroup ;
0073 std::vector<const SMesh*> meshmerge ;
0074 std::vector<sfr> frame ;
0075
0076 std::vector<int4> inst_info ;
0077
0078 std::vector<glm::tmat4x4<float>> inst_tran ;
0079 std::vector<glm::tvec4<int32_t>> inst_col3 ;
0080
0081
0082 static SScene* Load_(const char* dir=BASE);
0083 static SScene* Load(const char* dir=BASE);
0084
0085 SScene();
0086 void check() const ;
0087
0088 void initFromTree(const stree* st);
0089
0090 void initFromTree_soname(const stree* st);
0091 void initFromTree_Remainder( const stree* st);
0092 void initFromTree_Triangulate(const stree* st);
0093 void initFromTree_Global(const stree* st, char ridx_type, int ridx );
0094
0095 void initFromTree_Factor(const stree* st);
0096 void initFromTree_Factor_(int ridx, const stree* st);
0097 void initFromTree_Node(SMeshGroup* mg, int ridx, const snode& node, const stree* st);
0098 void initFromTree_Instance (const stree* st);
0099
0100 const SMeshGroup* getMeshGroup(int idx) const ;
0101 const SMesh* getMeshMerge(int idx) const ;
0102
0103
0104 const SMesh* get_mm(int mmidx) const ;
0105 const float* get_mn(int mmidx) const ;
0106 const float* get_mx(int mmidx) const ;
0107 const float* get_ce(int mmidx) const ;
0108
0109 bool is_empty() const ;
0110 std::string desc() const ;
0111 std::string descDetail() const ;
0112 std::string descSize() const ;
0113 std::string descInstInfo() const ;
0114 std::string descCol3() const ;
0115 std::string descFrame() const ;
0116 std::string descRange() const ;
0117
0118 void findSubMesh(std::vector<const SMesh*>& subs, int lvid) const ;
0119 std::string descSubMesh(const std::vector<const SMesh*>& subs) const ;
0120
0121 static std::string DescCompare(const SScene* a, const SScene* b);
0122
0123
0124 NPFold* serialize_meshmerge() const ;
0125 void import_meshmerge(const NPFold* _meshmerge ) ;
0126
0127 NPFold* serialize_meshgroup() const ;
0128 void import_meshgroup(const NPFold* _meshgroup ) ;
0129
0130 NPFold* serialize_frame() const ;
0131 void import_frame(const NPFold* _frame ) ;
0132
0133 NPFold* serialize() const ;
0134 void import_(const NPFold* fold);
0135
0136 void save(const char* dir) const ;
0137 void load(const char* dir);
0138
0139 void addFrames(const char* path, const stree* st);
0140 void addFrame( const sfr& _f);
0141
0142 sfr getFrame(int _idx=-1) const ;
0143
0144 static SScene* CopySelect( const SScene* src, const SBitSet* elv );
0145 SScene* copy(const SBitSet* elv=nullptr) const ;
0146
0147 static int Compare(const SScene* a, const SScene* b);
0148
0149 };
0150
0151
0152
0153
0154 inline SScene* SScene::Load_(const char* _base)
0155 {
0156 int level = ssys::getenvint(__level, 0);
0157 const char* base = spath::ResolveTopLevel(_base) ;
0158 if(level > 0) std::cout << "[SScene::Load_ _base[" << ( _base ? _base : "-" ) << "]\n" ;
0159 SScene* src = nullptr ;
0160 if(base)
0161 {
0162 src = new SScene ;
0163 src->load(base);
0164 src->check();
0165 }
0166 if(level > 0) std::cout << "]SScene::Load_ base[" << ( base ? base : "-" ) << "]\n" ;
0167 return src ;
0168 }
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 inline SScene* SScene::Load(const char* base)
0184 {
0185 SScene* src = Load_( base );
0186 if(src == nullptr) std::cerr
0187 << "SScene::Load_ FAILED "
0188 << " base[" << ( base ? base : "-" ) << "]"
0189 << "\n"
0190 ;
0191 if(src == nullptr) return nullptr ;
0192
0193 const SBitSet* elv = SGeoConfig::ELV(src->id);
0194 SScene* dst = src->copy(elv);
0195 return dst ;
0196 }
0197
0198
0199 inline SScene::SScene()
0200 :
0201 level(ssys::getenvint(__level, 0)),
0202 id(new SName(soname))
0203 {
0204 }
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 inline void SScene::check() const
0219 {
0220 int num_frame = frame.size();
0221 bool num_frame_expect = num_frame > 0 ;
0222
0223 if(!num_frame_expect) std::cout
0224 << "SScene::check"
0225 << " num_frame " << num_frame
0226 << " num_frame_expect " << ( num_frame_expect ? "YES" : "NO " )
0227 << " (expect more than zero frames) "
0228 << "\n"
0229 ;
0230
0231 assert( num_frame_expect );
0232 assert( meshmerge.size() == meshgroup.size() );
0233 }
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264 inline void SScene::initFromTree(const stree* st)
0265 {
0266 initFromTree_soname(st);
0267 initFromTree_Remainder(st);
0268 initFromTree_Factor(st);
0269 initFromTree_Triangulate(st);
0270
0271 initFromTree_Instance(st);
0272
0273 addFrames("$SScene__initFromTree_addFrames", st );
0274 }
0275
0276 inline void SScene::initFromTree_soname(const stree* st)
0277 {
0278 st->get_meshname(soname);
0279 }
0280
0281 inline void SScene::initFromTree_Remainder(const stree* st)
0282 {
0283 [[maybe_unused]] int num_rem = st->get_num_remainder();
0284 assert( num_rem == 1 );
0285 int ridx = 0 ;
0286 initFromTree_Global( st, 'R', ridx );
0287 }
0288 inline void SScene::initFromTree_Triangulate(const stree* st)
0289 {
0290 int num_rem = st->get_num_remainder();
0291 int num_fac = st->get_num_factor();
0292 int num_tri = st->get_num_triangulated();
0293
0294 assert( num_rem == 1 );
0295 assert( num_tri == 1 || num_tri == 0 );
0296
0297 if(num_tri == 1 )
0298 {
0299 int ridx = num_rem + num_fac + 0 ;
0300 initFromTree_Global( st, 'T', ridx );
0301 }
0302 }
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312 inline void SScene::initFromTree_Global(const stree* st, char ridx_type, int ridx )
0313 {
0314 assert( ridx_type == 'R' || ridx_type == 'T' );
0315 const std::vector<snode>* _nodes = st->get_node_vector(ridx_type) ;
0316 assert( _nodes );
0317
0318 int num_node = _nodes->size() ;
0319
0320 if(level>0) std::cout
0321 << "[ SScene::initFromTree_Global"
0322 << " level " << level
0323 << " num_node " << num_node
0324 << " ridx_type " << ridx_type
0325 << " ridx " << ridx
0326 << std::endl
0327 ;
0328
0329 SMeshGroup* mg = new SMeshGroup ;
0330 for(int i=0 ; i < num_node ; i++)
0331 {
0332 const snode& node = (*_nodes)[i];
0333 initFromTree_Node(mg, ridx, node, st);
0334 }
0335 const SMesh* _mesh = SMesh::Concatenate( mg->subs, ridx );
0336 meshmerge.push_back(_mesh);
0337 meshgroup.push_back(mg);
0338
0339 if(level>0) std::cout
0340 << "] SScene::initFromTree_Global"
0341 << " level " << level
0342 << " num_node " << num_node
0343 << " ridx_type " << ridx_type
0344 << " ridx " << ridx
0345 << std::endl
0346 ;
0347 }
0348
0349 inline void SScene::initFromTree_Factor(const stree* st)
0350 {
0351 int num_rem = st->get_num_remainder();
0352 assert( num_rem == 1 );
0353
0354 int num_fac = st->get_num_factor();
0355 for(int i=0 ; i < num_fac ; i++) initFromTree_Factor_(num_rem+i, st);
0356 }
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376 inline void SScene::initFromTree_Factor_(int ridx, const stree* st)
0377 {
0378 assert( ridx > 0 );
0379 int q_repeat_index = ridx ;
0380 int q_repeat_ordinal = 0 ;
0381 std::vector<snode> nodes ;
0382 st->get_repeat_node(nodes, q_repeat_index, q_repeat_ordinal) ;
0383 int num_node = nodes.size();
0384
0385 if(level>0) std::cout
0386 << "SScene::initFromTree_Factor"
0387 << " level " << level
0388 << " ridx " << ridx
0389 << " num_node " << num_node
0390 << std::endl
0391 ;
0392
0393 SMeshGroup* mg = new SMeshGroup ;
0394 for(int i=0 ; i < num_node ; i++)
0395 {
0396 const snode& node = nodes[i];
0397 initFromTree_Node(mg, ridx, node, st);
0398 }
0399 const SMesh* _mesh = SMesh::Concatenate( mg->subs, ridx );
0400 meshmerge.push_back(_mesh);
0401 meshgroup.push_back(mg);
0402 }
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429 inline void SScene::initFromTree_Node(SMeshGroup* mg, int ridx, const snode& node, const stree* st)
0430 {
0431 glm::tmat4x4<double> m2w(1.);
0432 glm::tmat4x4<double> w2m(1.);
0433 bool local = true ;
0434 bool reverse = false ;
0435 std::ostream* out = nullptr ;
0436 stree::VTR* t_stack = nullptr ;
0437
0438 st->get_node_product(m2w, w2m, node.index, local, reverse, out, t_stack );
0439 bool is_identity_m2w = stra<double>::IsIdentity(m2w) ;
0440
0441 const char* so = st->soname[node.lvid].c_str();
0442
0443
0444 const NPFold* fold = st->mesh->get_subfold(so) ;
0445 assert(fold);
0446 const SMesh* _mesh = SMesh::Import( fold, &m2w );
0447
0448 mg->subs.push_back(_mesh);
0449 mg->names.push_back(so);
0450
0451
0452 if(level>0) std::cout
0453 << "SScene::initFromTree_Node"
0454 << " node.lvid " << node.lvid
0455 << " st.soname[node.lvid] " << st->soname[node.lvid]
0456 << " _mesh " << _mesh->brief()
0457 << " is_identity_m2w " << ( is_identity_m2w ? "YES" : "NO " )
0458 << std::endl
0459 ;
0460
0461 if(level>0 && !is_identity_m2w) std::cout << _mesh->descTransform() << std::endl ;
0462 }
0463
0464 inline void SScene::initFromTree_Instance(const stree* st)
0465 {
0466 inst_info = st->inst_info ;
0467
0468
0469 strid::NarrowDecodeClear(inst_tran, inst_col3, st->inst );
0470
0471 }
0472
0473
0474
0475 inline const SMeshGroup* SScene::getMeshGroup(int idx) const
0476 {
0477 return idx < int(meshgroup.size()) ? meshgroup[idx] : nullptr ;
0478 }
0479 inline const SMesh* SScene::getMeshMerge(int idx) const
0480 {
0481 return idx < int(meshmerge.size()) ? meshmerge[idx] : nullptr ;
0482 }
0483
0484
0485
0486 inline const SMesh* SScene::get_mm(int mmidx) const
0487 {
0488 const SMesh* mm = mmidx < int(meshmerge.size()) ? meshmerge[mmidx] : nullptr ;
0489 return mm ;
0490 }
0491 inline const float* SScene::get_mn(int mmidx) const
0492 {
0493 const SMesh* mm = get_mm(mmidx);
0494 return mm ? mm->get_mn() : nullptr ;
0495 }
0496 inline const float* SScene::get_mx(int mmidx) const
0497 {
0498 const SMesh* mm = get_mm(mmidx);
0499 return mm ? mm->get_mx() : nullptr ;
0500 }
0501 inline const float* SScene::get_ce(int mmidx) const
0502 {
0503 const SMesh* mm = get_mm(mmidx);
0504 return mm ? mm->get_ce() : nullptr ;
0505 }
0506
0507
0508 inline bool SScene::is_empty() const
0509 {
0510 return meshmerge.size() == 0 && meshgroup.size() == 0 && inst_info.size() == 0 && inst_tran.size() == 0 ;
0511 }
0512
0513
0514 inline std::string SScene::desc() const
0515 {
0516 std::stringstream ss ;
0517 ss << "[ SScene::desc \n" ;
0518 ss << " is_empty " << ( is_empty() ? "YES" : "NO " ) << "\n" ;
0519 ss << descSize() ;
0520 ss << descInstInfo() ;
0521 ss << descCol3() ;
0522
0523 ss << "] SScene::desc \n" ;
0524 std::string str = ss.str();
0525 return str ;
0526 }
0527
0528 inline std::string SScene::descDetail() const
0529 {
0530 std::stringstream ss ;
0531 ss << "[ SScene::detail \n" ;
0532 ss << descRange() ;
0533 ss << "] SScene::detail \n" ;
0534 std::string str = ss.str();
0535 return str ;
0536 }
0537
0538
0539
0540 inline std::string SScene::descSize() const
0541 {
0542 std::stringstream ss ;
0543 ss << "SScene::descSize"
0544 << " meshmerge " << meshmerge.size()
0545 << " meshgroup " << meshgroup.size()
0546 << " inst_info " << inst_info.size()
0547 << " inst_col3 " << inst_col3.size()
0548 << " inst_tran " << inst_tran.size()
0549 << std::endl
0550 ;
0551 std::string str = ss.str();
0552 return str ;
0553 }
0554
0555 inline std::string SScene::descInstInfo() const
0556 {
0557 std::stringstream ss ;
0558 ss << "[SScene::descInstInfo {ridx, inst_count, inst_offset, 0} " << std::endl ;
0559 int num_inst_info = inst_info.size();
0560 int tot_inst = 0 ;
0561 for(int i=0 ; i < num_inst_info ; i++)
0562 {
0563 const int4& info = inst_info[i] ;
0564 ss
0565 << "{"
0566 << std::setw(3) << info.x
0567 << ","
0568 << std::setw(7) << info.y
0569 << ","
0570 << std::setw(7) << info.z
0571 << ","
0572 << std::setw(3) << info.w
0573 << "}"
0574 << std::endl
0575 ;
0576 tot_inst += info.y ;
0577 }
0578 ss << "]SScene::descInstInfo tot_inst " << tot_inst << std::endl ;
0579 std::string str = ss.str();
0580 return str ;
0581 }
0582
0583
0584
0585 inline std::string SScene::descCol3() const
0586 {
0587 std::stringstream ss ;
0588 ss << "[SScene::descCol3 {ins_idx, gas_idx, sen_id, sen_idx} " << std::endl ;
0589 int num_inst_col3 = inst_col3.size();
0590 int edge = 100 ;
0591
0592 for(int i=0 ; i < num_inst_col3 ; i++)
0593 {
0594 if( i < edge || i > (num_inst_col3 - edge))
0595 {
0596 const glm::tvec4<int32_t>& col3 = inst_col3[i] ;
0597 ss
0598 << "{"
0599 << std::setw(3) << col3.x
0600 << ","
0601 << std::setw(7) << col3.y
0602 << ","
0603 << std::setw(7) << col3.z
0604 << ","
0605 << std::setw(3) << col3.w
0606 << "}"
0607 << std::endl
0608 ;
0609 }
0610
0611 }
0612 ss << "]SScene::descCol3 " << std::endl ;
0613 std::string str = ss.str();
0614 return str ;
0615 }
0616
0617
0618
0619
0620 inline std::string SScene::descFrame() const
0621 {
0622 int num_frame = frame.size();
0623 std::stringstream ss ;
0624 ss << "[SScene::descFrame num_frame " << num_frame << std::endl ;
0625 for(int i=0 ; i < num_frame ; i++)
0626 {
0627 const sfr& f = frame[i];
0628 ss << f.desc() ;
0629 }
0630 ss << "]SScene::descFrame num_frame " << num_frame << std::endl ;
0631 std::string str = ss.str();
0632 return str ;
0633 }
0634
0635 inline std::string SScene::descRange() const
0636 {
0637 int num_mm = meshmerge.size();
0638 [[maybe_unused]] int num_mg = meshgroup.size();
0639 assert( num_mm == num_mg );
0640 int num = num_mm ;
0641
0642 std::stringstream ss ;
0643 ss << "[SScene::descRange num " << num << std::endl ;
0644 for(int i=0 ; i < num ; i++)
0645 {
0646 const SMeshGroup* mg = meshgroup[i] ;
0647 const SMesh* mm = meshmerge[i] ;
0648 ss << "mg[" << i << "]\n" << mg->descRange(&soname) << "\n" ;
0649 ss << "mm[" << i << "]\n" << mm->descRange() << "\n" ;
0650 }
0651 ss << "]SScene::descRange num " << num << std::endl ;
0652 std::string str = ss.str();
0653 return str ;
0654 }
0655
0656
0657 inline void SScene::findSubMesh(std::vector<const SMesh*>& subs, int lvid) const
0658 {
0659 size_t num_mg = meshgroup.size();
0660 std::cout << "SScene::findSubMesh lvid " << lvid << " num_mg " << num_mg << "\n" ;
0661 for(size_t i=0 ; i < num_mg ; i++)
0662 {
0663 const SMeshGroup* mg = meshgroup[i] ;
0664 mg->findSubMesh(subs, lvid);
0665 }
0666 }
0667
0668 inline std::string SScene::descSubMesh(const std::vector<const SMesh*>& subs) const
0669 {
0670 return SMeshGroup::DescSubMesh(subs, &soname);
0671 }
0672
0673
0674
0675
0676 inline std::string SScene::DescCompare(const SScene* a, const SScene* b)
0677 {
0678 std::stringstream ss ;
0679 ss << "A.descSize " << a->descSize() << "\n" ;
0680 ss << "B.descSize " << b->descSize() << "\n" ;
0681
0682 ss << "A.descInstInfo " << a->descInstInfo() << "\n" ;
0683 ss << "B.descInstInfo " << b->descInstInfo() << "\n" ;
0684
0685 std::string str = ss.str();
0686 return str ;
0687 }
0688
0689
0690
0691 inline NPFold* SScene::serialize_meshmerge() const
0692 {
0693 NPFold* _meshmerge = new NPFold ;
0694 int num_meshmerge = meshmerge.size();
0695 for(int i=0 ; i < num_meshmerge ; i++)
0696 {
0697 const SMesh* m = meshmerge[i] ;
0698 _meshmerge->add_subfold( m->name, m->serialize() );
0699 }
0700 return _meshmerge ;
0701 }
0702
0703 inline NPFold* SScene::serialize_meshgroup() const
0704 {
0705 NPFold* _meshgroup = new NPFold ;
0706 int num_meshgroup = meshgroup.size();
0707 for(int i=0 ; i < num_meshgroup ; i++)
0708 {
0709 const SMeshGroup* mg = meshgroup[i] ;
0710 const char* name = SMesh::FormName(i);
0711 _meshgroup->add_subfold( name, mg->serialize() );
0712 }
0713 return _meshgroup ;
0714 }
0715
0716
0717
0718
0719
0720
0721 inline void SScene::import_meshmerge(const NPFold* _meshmerge )
0722 {
0723 int num_meshmerge = _meshmerge ? _meshmerge->get_num_subfold() : 0 ;
0724 if(level>0) std::cout << "[SScene::import_meshmerge num_meshmerge " << num_meshmerge << "\n" ;
0725 for(int i=0 ; i < num_meshmerge ; i++)
0726 {
0727 const NPFold* sub = _meshmerge->get_subfold(i);
0728 const SMesh* m = SMesh::Import(sub) ;
0729 meshmerge.push_back(m);
0730 }
0731 if(level>0) std::cout << "]SScene::import_meshmerge num_meshmerge " << num_meshmerge << "\n" ;
0732 }
0733
0734 inline void SScene::import_meshgroup(const NPFold* _meshgroup )
0735 {
0736 int num_meshgroup = _meshgroup ? _meshgroup->get_num_subfold() : 0 ;
0737 if(level>0) std::cout << "[SScene::import_meshgroup num_meshgroup " << num_meshgroup << "\n" ;
0738 for(int i=0 ; i < num_meshgroup ; i++)
0739 {
0740 const NPFold* sub = _meshgroup->get_subfold(i);
0741 const SMeshGroup* mg = SMeshGroup::Import(sub) ;
0742 meshgroup.push_back(mg);
0743 }
0744 if(level>0) std::cout << "]SScene::import_meshgroup num_meshgroup " << num_meshgroup << "\n" ;
0745 }
0746
0747
0748 inline NPFold* SScene::serialize_frame() const
0749 {
0750 NPFold* _frame = new NPFold ;
0751 int num_frame = frame.size();
0752 for(int i=0 ; i < num_frame ; i++)
0753 {
0754 const sfr& f = frame[i] ;
0755 std::string key = f.get_key() ;
0756 _frame->add( key.c_str(), f.serialize() );
0757 }
0758 return _frame ;
0759 }
0760
0761 inline void SScene::import_frame(const NPFold* _frame )
0762 {
0763 int num_frame = _frame ? _frame->num_items() : 0 ;
0764 for(int i=0 ; i < num_frame ; i++)
0765 {
0766 const NP* a = _frame->get_array(i);
0767 sfr f = sfr::Import(a) ;
0768 frame.push_back(f);
0769 }
0770 }
0771
0772
0773
0774 inline NPFold* SScene::serialize() const
0775 {
0776 NPFold* _meshmerge = serialize_meshmerge() ;
0777 NPFold* _meshgroup = serialize_meshgroup() ;
0778 NPFold* _frame = serialize_frame() ;
0779 NP* _inst_tran = NPX::ArrayFromVec<float, glm::tmat4x4<float>>( inst_tran, 4, 4) ;
0780 NP* _inst_info = NPX::ArrayFromVec<int,int4>( inst_info, 4 ) ;
0781 NP* _inst_col3 = NPX::ArrayFromVec<int,glm::tvec4<int32_t>>( inst_col3, 4 ) ;
0782 NP* _soname = NPX::Holder(soname) ;
0783
0784 NPFold* fold = new NPFold ;
0785 fold->add_subfold( MESHMERGE, _meshmerge );
0786 fold->add_subfold( MESHGROUP, _meshgroup );
0787 fold->add_subfold( FRAME, _frame );
0788 fold->add( INST_INFO, _inst_info );
0789 fold->add( INST_TRAN, _inst_tran );
0790 fold->add( INST_COL3, _inst_col3 );
0791 fold->add( SONAME, _soname );
0792
0793 return fold ;
0794 }
0795 inline void SScene::import_(const NPFold* fold)
0796 {
0797 if(level>0) std::cout << "[SScene::import \n" ;
0798 if(fold == nullptr) std::cerr << "SScene::import called with NULL fold argument\n" ;
0799 if(fold == nullptr) return ;
0800
0801 const NPFold* _meshmerge = fold->get_subfold(MESHMERGE );
0802 const NPFold* _meshgroup = fold->get_subfold(MESHGROUP );
0803 const NPFold* _frame = fold->get_subfold(FRAME );
0804 import_meshmerge( _meshmerge );
0805 import_meshgroup( _meshgroup );
0806 import_frame( _frame );
0807
0808 const NP* _inst_info = fold->get(INST_INFO);
0809 const NP* _inst_tran = fold->get(INST_TRAN);
0810 const NP* _inst_col3 = fold->get(INST_COL3);
0811 const NP* _soname = fold->get(SONAME) ;
0812
0813 stree::ImportArray<glm::tmat4x4<float>, float>( inst_tran, _inst_tran, INST_TRAN );
0814 stree::ImportArray<int4, int>( inst_info, _inst_info, INST_INFO );
0815 stree::ImportArray<glm::tvec4<int32_t>, int>( inst_col3, _inst_col3, INST_COL3 );
0816 stree::ImportNames( soname, _soname , SONAME);
0817
0818 if(level>0) std::cout << "]SScene::import \n" ;
0819 }
0820
0821 inline void SScene::save(const char* dir) const
0822 {
0823 NPFold* fold = serialize();
0824 fold->save(dir, RELDIR);
0825 }
0826 inline void SScene::load(const char* dir)
0827 {
0828 if(level>0) std::cout << "SScene::load dir " << ( dir ? dir : "-" ) << "\n" ;
0829 NPFold* fold = NPFold::Load(dir, RELDIR);
0830 import_(fold);
0831 }
0832
0833
0834
0835
0836
0837
0838
0839
0840
0841
0842
0843
0844
0845
0846
0847
0848
0849
0850
0851
0852
0853
0854
0855
0856
0857
0858
0859
0860
0861
0862
0863
0864
0865
0866
0867
0868
0869
0870
0871
0872
0873
0874
0875
0876
0877
0878
0879
0880
0881
0882
0883
0884
0885
0886
0887
0888
0889
0890
0891
0892
0893
0894
0895
0896
0897
0898 inline void SScene::addFrames(const char* path, const stree* st)
0899 {
0900 std::string framespec ;
0901 bool framespec_exists = spath::Read( framespec, path );
0902
0903 if(framespec_exists)
0904 {
0905 std::vector<std::string> lines ;
0906 sstr::SplitTrimSuppress(framespec.c_str(), '\n', lines) ;
0907
0908 int num_line = lines.size();
0909 for(int i=0 ; i < num_line ; i++)
0910 {
0911 const std::string& line = lines[i];
0912 std::string _spec = sstr::StripComment(line);
0913 const char* spec = _spec.c_str();
0914 if(spec == nullptr) continue ;
0915 if(strlen(spec) == 0) continue ;
0916
0917 bool has_frame = st->has_frame(spec);
0918 if(!has_frame)
0919 {
0920 std::cout
0921 << "SScene::addFrames FAIL to find frame "
0922 << " spec [" << ( spec ? spec : "-" ) << "]\n"
0923 << " line [" << line << "]\n"
0924 ;
0925 continue ;
0926 }
0927
0928 sfr f = st->get_frame(spec);
0929 addFrame(f);
0930 }
0931 }
0932 else
0933 {
0934 std::cout << "SScene::addFrames framespec path [" << ( path ? path : "-" ) << "] does not exist \n" ;
0935 }
0936
0937
0938 const float* _ce = get_ce(0) ;
0939 sfr f0 = sfr::MakeFromCE(_ce) ;
0940 f0.set_name("MakeFromCE0");
0941 addFrame(f0);
0942
0943
0944
0945
0946
0947
0948
0949
0950
0951
0952
0953
0954
0955
0956
0957
0958 }
0959
0960
0961 inline void SScene::addFrame( const sfr& _f)
0962 {
0963 sfr f = _f ;
0964 f.set_idx( frame.size() );
0965 frame.push_back(f);
0966 }
0967
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979 inline sfr SScene::getFrame(int _idx) const
0980 {
0981 int num_frame = frame.size();
0982 bool num_frame_expect = num_frame > 0 ;
0983 int idx = ( _idx > -1 && _idx < num_frame ) ? _idx : num_frame-1 ;
0984
0985 if(!num_frame_expect) std::cout
0986 << "SScene::getFrame"
0987 << " num_frame " << num_frame
0988 << " num_frame_expect " << ( num_frame_expect ? "YES" : "NO " )
0989 << " _idx " << _idx
0990 << " idx " << idx
0991 << "\n"
0992 ;
0993
0994 assert( num_frame_expect );
0995
0996 const sfr& f = frame[idx] ;
0997
0998
0999 assert( f.get_idx() == idx );
1000 return f ;
1001 }
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032 inline SScene* SScene::CopySelect( const SScene* src, const SBitSet* elv )
1033 {
1034 SScene* dst = new SScene ;
1035 dst->soname = src->soname ;
1036 int s_num_mg = src->meshgroup.size() ;
1037
1038 int* solidMap = new int[s_num_mg];
1039
1040
1041 for(int i=0 ; i < s_num_mg ; i++)
1042 {
1043 int s_SolidIdx = i ;
1044 solidMap[i] = -1 ;
1045
1046 const SMeshGroup* s_mg = src->meshgroup[i] ;
1047 SMeshGroup* d_mg = s_mg->copy(elv) ;
1048 if( d_mg == nullptr ) continue ;
1049
1050 int d_SolidIdx = dst->meshgroup.size() ;
1051 solidMap[s_SolidIdx] = d_SolidIdx ;
1052
1053 dst->meshgroup.push_back(d_mg);
1054
1055
1056 int ridx = d_SolidIdx ;
1057
1058 const SMesh* d_mesh = SMesh::Concatenate( d_mg->subs, ridx );
1059 dst->meshmerge.push_back(d_mesh);
1060 }
1061
1062
1063 int d_num_mg = dst->meshgroup.size() ;
1064
1065 if(src->level>0) std::cout << "SScene::CopySelect d_num_mg " << d_num_mg << "\n" ;
1066
1067
1068 dst->inst_info.resize(d_num_mg);
1069 for(int i=0 ; i < d_num_mg ; i++)
1070 {
1071 int d_ridx = i ;
1072 dst->inst_info[d_ridx].x = d_ridx ;
1073 dst->inst_info[d_ridx].y = 0 ;
1074 dst->inst_info[d_ridx].z = 0 ;
1075 dst->inst_info[d_ridx].w = 0 ;
1076 }
1077
1078
1079 dst->frame = src->frame ;
1080
1081 [[maybe_unused]] int s_inst_info_num = src->inst_info.size() ;
1082 [[maybe_unused]] int s_inst_tran_num = src->inst_tran.size() ;
1083 [[maybe_unused]] int s_inst_col3_num = src->inst_col3.size() ;
1084 assert( s_inst_info_num == s_num_mg );
1085 assert( s_inst_tran_num == s_inst_col3_num );
1086
1087 std::vector<int4>& d_inst_info = dst->inst_info ;
1088 std::vector<glm::tvec4<int32_t>>& d_inst_col3 = dst->inst_col3 ;
1089 std::vector<glm::tmat4x4<float>>& d_inst_tran = dst->inst_tran ;
1090
1091
1092
1093 for(int i=0 ; i < s_inst_col3_num ; i++)
1094 {
1095 const glm::tmat4x4<float>& _s_inst_tran = src->inst_tran[i] ;
1096 const glm::tvec4<int32_t>& _s_inst_col3 = src->inst_col3[i] ;
1097
1098 [[maybe_unused]] int32_t s_inst_idx = _s_inst_col3.x ;
1099 int32_t s_gas_idx = _s_inst_col3.y ;
1100
1101 assert( s_inst_idx == i );
1102 assert( s_gas_idx < s_num_mg );
1103
1104 int d_gas_idx = solidMap[s_gas_idx];
1105 assert( d_gas_idx < d_num_mg );
1106
1107 bool live_instance = d_gas_idx > -1 ;
1108
1109 if(live_instance)
1110 {
1111 glm::tmat4x4<float> _d_inst_tran = _s_inst_tran ;
1112
1113 int d_inst_offset = d_inst_tran.size();
1114 d_inst_tran.push_back(_d_inst_tran);
1115 d_inst_col3.push_back( { d_inst_offset, d_gas_idx, _s_inst_col3.z, _s_inst_col3.w } );
1116 }
1117 }
1118
1119 int d_inst_col3_num = d_inst_col3.size();
1120 for(int i=0 ; i < d_inst_col3_num ; i++)
1121 {
1122 int& d_gas_idx = d_inst_col3[i].y ;
1123 int d_ridx = d_gas_idx ;
1124 d_inst_info[d_ridx].y += 1 ;
1125 }
1126
1127
1128
1129 int offset = 0 ;
1130 for(int i=0 ; i < d_num_mg ; i++)
1131 {
1132 int d_ridx = i ;
1133 d_inst_info[d_ridx].z = offset ;
1134 offset += d_inst_info[d_ridx].y ;
1135 }
1136
1137 return dst ;
1138 }
1139
1140
1141 inline SScene* SScene::copy(const SBitSet* elv) const
1142 {
1143 return CopySelect(this, elv);
1144 }
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156 inline int SScene::Compare(const SScene* a, const SScene* b)
1157 {
1158 bool dump = false ;
1159 std::stringstream ss ;
1160 std::ostream* out = dump ? &ss : nullptr ;
1161
1162 int mismatch = 0 ;
1163 mismatch += svec<int4>::Compare( "inst_info", a->inst_info, b->inst_info, out );
1164 mismatch += svec<glm::tmat4x4<float>>::Compare( "inst_tran", a->inst_tran, b->inst_tran, out );
1165 mismatch += svec<glm::tvec4<int32_t>>::Compare( "inst_col3", a->inst_col3, b->inst_col3, out );
1166
1167
1168 if(dump) std::cout << "SScene::Compare mismatch " << mismatch << "\n" ;
1169 if(out) std::cout << ss.str() << "\n" ;
1170
1171 return mismatch ;
1172 }
1173
1174
1175
1176