Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /**
0002 stree_create_test.cc
0003 =======================
0004 
0005 This test creates a simple geometry from scratch, following 
0006 the general approach of u4/U4Tree.h, and then uses that geometry to 
0007 compare query results with expections, for example checking::
0008 
0009     stree::get_combined_transform 
0010 
0011 For querying with more complex loaded geometries see *stree_load_test.cc**
0012 **/
0013 
0014 #include <cstdlib>
0015 #include "stree.h"
0016 #include "stra.h"
0017 #include "stran.h"
0018 #include "ssys.h"
0019 
0020 const char* FOLD = getenv("FOLD"); 
0021 const bool VERBOSE = ssys::getenvbool("VERBOSE"); 
0022 const int LVID = ssys::getenvint("LVID", 4); 
0023 
0024 struct Dummy
0025 {
0026     static std::string Dig(int nidx); 
0027     static sn* Boolean(int lvid, int it); 
0028     static int LV(int nidx); 
0029     static int NumChild(int nidx); 
0030     static const Tran<double>* Transform(int it); 
0031     static const Tran<double>* Product( const std::vector<int>& its); 
0032     static const Tran<double>* Expected(int ie); 
0033     static sn* Solid(int lvid); 
0034     static const char* SolidName(int lvid); 
0035     static constexpr const int NUM_LVID = 5 ; 
0036 };
0037 
0038 inline std::string Dummy::Dig(int nidx)
0039 {
0040     std::stringstream ss ; 
0041     ss << "Dummy" << nidx ; 
0042     std::string str = ss.str(); 
0043     return str ; 
0044 }
0045 inline sn* Dummy::Boolean(int lvid, int it)
0046 {
0047     sn* root = nullptr ; 
0048     if( lvid == 4 )
0049     {
0050         sn* l = sn::Sphere(100.) ; 
0051         sn* r = sn::Box3(100.) ;         
0052         const Tran<double>* tv = Transform(it) ;  
0053         r->setXF(tv->t, tv->v );  
0054         root = sn::Boolean(CSG_UNION, l, r);   
0055     }
0056     return root ; 
0057 }
0058 inline int Dummy::LV(int nidx)
0059 {
0060     int lv = 0 ; 
0061     switch(nidx)
0062     {
0063         case 0: lv = 0 ; break ; 
0064         case 1: lv = 1 ; break ; 
0065         case 2: lv = 2 ; break ; 
0066         case 3: lv = 3 ; break ; 
0067         case 4: lv = 4 ; break ; 
0068     }
0069     return lv ; 
0070 }
0071 inline int Dummy::NumChild(int nidx)
0072 {
0073     int nc = 0 ; 
0074     switch(nidx)
0075     {
0076         case 0: nc = 1 ; break ; 
0077         case 1: nc = 1 ; break ; 
0078         case 2: nc = 1 ; break ; 
0079         case 3: nc = 1 ; break ; 
0080         case 4: nc = 0 ; break ; 
0081     }
0082     return nc ; 
0083 }
0084 inline const Tran<double>*  Dummy::Transform(int it)
0085 {
0086     const Tran<double>* tr = nullptr ; 
0087     switch(it)
0088     {
0089         case -1: tr = Tran<double>::make_identity()                 ; break ; 
0090         case  0: tr = Tran<double>::make_identity()                 ; break ; 
0091         case  1: tr = Tran<double>::make_translate( 0., 0., 100.)   ; break ; 
0092         case  2: tr = Tran<double>::make_translate( 1000., 0., 0.)  ; break ; 
0093         case  3: tr = Tran<double>::make_rotate_a2b(   1., 0., 0., 0., 0., 1., false ) ; break ; 
0094         case  4: tr = Tran<double>::make_identity()                 ; break ; 
0095         case 100: tr = Tran<double>::make_rotate( 0., 0., 1., 45. ) ; break ; 
0096     }
0097     assert(tr); 
0098     return tr ; 
0099 }
0100 
0101 inline const Tran<double>* Dummy::Product(const std::vector<int>& its)
0102 {
0103     std::vector<const Tran<double>*> trs ; 
0104     int num_tr = its.size(); 
0105     for(int i=0 ; i < num_tr ; i++)
0106     {
0107         int it = its[i] ; 
0108         const Tran<double>* tr = Transform(it); 
0109         trs.push_back(tr); 
0110     }
0111     const Tran<double>* prd = Tran<double>::product( trs, false );  
0112     return prd ; 
0113 }
0114 
0115 inline const Tran<double>* Dummy::Expected(int ie)
0116 {
0117     std::vector<int> its = {0,1,2,3,4} ; 
0118     if( ie == 1 ) its.push_back(100) ; 
0119     return Product(its) ; 
0120 }
0121 inline sn* Dummy::Solid(int lvid)
0122 {
0123     sn* root = nullptr ; 
0124     switch(lvid)
0125     {
0126         case  0:  root = sn::Sphere(100.)                ; break ; 
0127         case  1:  root = sn::Box3(100.)                  ; break ; 
0128         case  2:  root = sn::Cylinder(100., -10., 10. )  ; break ; 
0129         case  3:  root = sn::Box3(100.);                 ; break ; 
0130         case  4:  root = Dummy::Boolean(lvid, 100)        ; break ;   
0131     }
0132     return root ; 
0133 }
0134 inline const char* Dummy::SolidName(int lvid)
0135 {
0136     const char* n = nullptr ; 
0137     switch(lvid)
0138     {
0139         case 0: n = "0_Sphere"     ; break ; 
0140         case 1: n = "1_Box"        ; break ; 
0141         case 2: n = "2_Cylinder"   ; break ; 
0142         case 3: n = "3_Box"        ; break ; 
0143         case 4: n = "4_Boolean"    ; break ; 
0144     }
0145     return strdup(n); 
0146 }
0147 
0148 
0149 struct stree_create
0150 {
0151     stree* st ; 
0152     stree_create( stree* st_) ; 
0153     void init(); 
0154     void initSolids(); 
0155     void initSolid(int lvid); 
0156     void initNodes(); 
0157     int  initNodes_r( int depth, int sibdex, int parent  ); 
0158 }; 
0159 
0160 inline stree_create::stree_create( stree* st_)
0161     :
0162     st(st_)
0163 {
0164     init(); 
0165 }
0166 inline void stree_create::init()
0167 {   
0168     initSolids(); 
0169     initNodes(); 
0170 }
0171 inline void stree_create::initSolids()
0172 {
0173     for(int lvid=0 ; lvid < Dummy::NUM_LVID ; lvid++) initSolid(lvid); 
0174 }
0175 inline void stree_create::initSolid(int lvid )
0176 {
0177     assert( int(st->solids.size()) == lvid );
0178 
0179     sn* root = Dummy::Solid(lvid);
0180     assert( root != nullptr );
0181     root->set_lvid(lvid) ;  
0182 
0183     const char* name = Dummy::SolidName(lvid) ; 
0184 
0185     st->soname.push_back(name);
0186     st->solids.push_back(root);
0187 }
0188 inline void stree_create::initNodes()
0189 {   
0190     int nidx = initNodes_r(0, -1, -1 );
0191     assert( 0 == nidx );
0192 }
0193 inline int stree_create::initNodes_r( int depth, int sibdex, int parent  )
0194 {
0195     int nidx = st->nds.size() ;  // 0-based node index
0196 
0197     int copyno = nidx ; 
0198     int boundary = 0 ; 
0199 
0200     int lvid = Dummy::LV(nidx); 
0201     std::string dig = Dummy::Dig(nidx) ;  
0202     int num_child = Dummy::NumChild(nidx) ; 
0203 
0204     const Tran<double>* tv = Dummy::Transform(nidx); 
0205     //const Tran<double>* tv = Dummy::Transform(-1);    // -1 switches to all identity transforms
0206 
0207     snode nd ; 
0208 
0209     nd.index = nidx ;
0210     nd.depth = depth ;   
0211     nd.sibdex = sibdex ; 
0212     nd.parent = parent ;   
0213 
0214     nd.num_child = num_child ; 
0215     nd.first_child = -1 ;     // gets changed inplace from lower recursion level 
0216     nd.next_sibling = -1 ; 
0217     nd.lvid = lvid ; 
0218 
0219     nd.copyno = copyno ; 
0220     nd.sensor_id = -1 ;  
0221     nd.sensor_index = -1 ;
0222     nd.repeat_index = 0 ; 
0223 
0224     nd.repeat_ordinal = -1 ;
0225     nd.boundary = boundary ; 
0226 
0227     st->nds.push_back(nd); 
0228     st->digs.push_back(dig); 
0229     st->m2w.push_back(tv->t);  
0230     st->w2m.push_back(tv->v);  
0231 
0232     if(sibdex == 0 && nd.parent > -1) st->nds[nd.parent].first_child = nd.index ;
0233     // record first_child nidx into parent snode by reaching up thru the recursion levels 
0234 
0235     int p_sib = -1 ;
0236     int i_sib = -1 ;
0237     for (int i=0 ; i < num_child ; i++ )
0238     {
0239         p_sib = i_sib ;    // node index of previous child gets set for i > 0
0240         i_sib = initNodes_r( depth+1, i, nd.index );
0241 
0242         if(p_sib > -1) st->nds[p_sib].next_sibling = i_sib ;
0243         // after first child : reach back to previous sibling snode to set the sib->sib linkage, default -1
0244     }
0245     return nd.index ;
0246 }
0247 
0248 void test_get_combined_transform( const stree& st, int lvid )
0249 {
0250     std::vector<snode> nodes ; 
0251     st.find_lvid_nodes_(nodes, lvid); 
0252 
0253     std::vector<sn*> nds ; 
0254     sn::GetLVNodes(nds, lvid);  
0255 
0256     int num_nodes = nodes.size() ; 
0257     int num_nds = nds.size(); 
0258 
0259     std::cout 
0260         << "test_get_combined_transform" << std::endl 
0261         << " lvid " << lvid << std::endl
0262         << " nodes(vols) : " << num_nodes 
0263         << std::endl
0264         << " nds(csg) : " << num_nds 
0265         << std::endl
0266         ;  
0267 
0268     std::cout << "nodes(vols)" << std::endl << snode::Brief_(nodes) ; 
0269     std::cout << "nds(csg)" << std::endl << sn::Brief(nds) ; 
0270 
0271     assert( num_nodes == 1 ); 
0272     assert( num_nds == 3 ); 
0273 
0274     const snode& node = nodes[0] ; 
0275 
0276 
0277     std::stringstream ss ; 
0278     for(int i=0 ; i < num_nds ; i++)
0279     {
0280         const sn* nd = nds[i]; 
0281         Tran<double>* tv = Tran<double>::make_identity_(); 
0282 
0283         const Tran<double>* ex = Dummy::Expected(i); 
0284 
0285         ss << " i " << i 
0286            << std::endl 
0287            ; 
0288 
0289         std::ostream* out = VERBOSE ? &ss : nullptr ; 
0290         st.get_combined_transform(tv->t, tv->v, node, nd, out );
0291 
0292         ss  << " tv " 
0293             << std::endl
0294             << tv->desc() 
0295             << std::endl
0296             << " expected " 
0297             << std::endl
0298             << ex->desc() 
0299             << std::endl
0300             ; 
0301     }
0302 
0303    std::string str = ss.str(); 
0304    std::cout << str ; 
0305 
0306 }
0307 
0308 int main(int argc, char** argv)
0309 {
0310     stree st ; 
0311     stree_create stc(&st);
0312     st.save(FOLD); 
0313     test_get_combined_transform(st, LVID); 
0314     return 0 ; 
0315 }
0316