Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /**
0002 ~/o/sysrap/tests/sn_test.cc
0003 =============================
0004 
0005 ::
0006 
0007     ~/o/sysrap/tests/sn_test.sh
0008     sn__level=5 ~/o/sysrap/tests/sn_test.sh
0009 
0010 
0011 * https://stackoverflow.com/questions/77005/how-to-automatically-generate-a-stacktrace-when-my-program-crashes
0012 
0013 **/
0014 
0015 #include <iostream>
0016 #include <iomanip>
0017 #include <cassert>
0018 #include "OpticksCSG.h"
0019 #include "ssys.h"
0020 #include "s_csg.h"
0021 
0022 #include "NPX.h"
0023 
0024 const char* FOLD = getenv("FOLD");
0025 
0026 #include "sn.h"
0027 
0028 void Desc()
0029 {
0030 #ifdef WITH_CHILD
0031     if(sn::level() > -1) std::cout << "WITH_CHILD " ;
0032 #else
0033     if(sn::level() > -1) std::cout << "NOT:WITH_CHILD " ;
0034 #endif
0035     std::cout << " level : " << sn::level() << std::endl ;
0036 }
0037 
0038 
0039 
0040 
0041 sn* manual_tree_0()
0042 {
0043     sn* l = sn::Prim(CSG_SPHERE);
0044     sn* r = sn::Prim(CSG_BOX3);
0045     sn* b = sn::Create(CSG_DIFFERENCE, l, r );
0046     return b ;
0047 }
0048 
0049 sn* manual_tree_1()
0050 {
0051     sn* l = sn::Prim(CSG_SPHERE);
0052     sn* r = sn::Prim(CSG_BOX3);
0053     sn* b = sn::Create(CSG_UNION, l, r );
0054     return b ;
0055 }
0056 sn* manual_tree_2()
0057 {
0058     sn* l = manual_tree_0() ;
0059     sn* r = manual_tree_1() ;
0060     sn* b = sn::Create(CSG_UNION, l, r );
0061     return b ;
0062 }
0063 sn* manual_tree_3()
0064 {
0065     sn* l = manual_tree_0() ;
0066     sn* r = sn::Prim(CSG_BOX3);
0067     sn* b = sn::Create(CSG_UNION, l, r );
0068     return b ;
0069 }
0070 sn* manual_tree_4()
0071 {
0072     sn* l = sn::Prim(CSG_SPHERE);
0073     sn* r = sn::Prim(CSG_BOX3);
0074 
0075     glm::tmat4x4<double> t(1.);
0076     t[3][2] = 1000. ;
0077     r->setXF(t);
0078 
0079     sn* b = sn::Create(CSG_UNION, l, r );
0080     return b ;
0081 }
0082 
0083 
0084 /**
0085 list_tree
0086 ----------
0087 
0088 0::
0089 
0090       sp
0091 
0092 
0093 1::
0094 
0095         u
0096 
0097      sp    sp
0098 
0099 2::
0100 
0101             u
0102 
0103         u      sp
0104 
0105      sp    sp
0106 
0107 3::
0108 
0109 
0110                 u
0111 
0112             u       sp
0113 
0114         u      sp
0115 
0116      sp    sp
0117 
0118 
0119 
0120 **/
0121 
0122 
0123 sn* list_tree(int num)
0124 {
0125     sn* n = sn::Sphere(100.) ;
0126     for(int i=0 ; i < num ; i++) n = sn::Create(CSG_UNION, n, sn::Sphere(100.) );
0127     return n ;
0128 }
0129 
0130 sn* difference_and_list_tree(int num)
0131 {
0132     sn* l = sn::Sphere(100.);
0133     sn* r = sn::Box3(100.);
0134     sn* b = sn::Create(CSG_DIFFERENCE, l, r );
0135 
0136     sn* n = b ;
0137     for(int i=0 ; i < num ; i++)
0138     {
0139         sn* s = sn::Sphere(100.);
0140         s->set_hint_listnode_prim_discontiguous();
0141         n = sn::Create(CSG_UNION, n, s );
0142     }
0143 
0144     int lvid = 0 ;
0145     n->postconvert(lvid);
0146 
0147     return n ;
0148 }
0149 
0150 
0151 sn* manual_tree(int it)
0152 {
0153     sn* t = nullptr ;
0154     switch(it)
0155     {
0156         case 0: t = manual_tree_0() ; break ;
0157         case 1: t = manual_tree_1() ; break ;
0158         case 2: t = manual_tree_2() ; break ;
0159         case 3: t = manual_tree_3() ; break ;
0160         case 4: t = manual_tree_4() ; break ;
0161     }
0162     assert(t);
0163     return t ;
0164 }
0165 
0166 
0167 
0168 struct sn_test
0169 {
0170     static int idx_0();
0171     static int BinaryTreeHeight();
0172     static int ZeroTree();
0173     static int CommonOperatorTypeTree(int num_leaves);
0174     static int CommonOperatorTypeTree();
0175     static int label();
0176     static int positivize();
0177     static int pool();
0178     static int Simple();
0179     static int set_left();
0180     static int serialize_0();
0181     static int serialize_1();
0182     static int import_0();
0183     static int import_1();
0184     static int dtor_0();
0185     static int dtor_1();
0186     static int set_child();
0187     static int disown_child_0();
0188     static int set_right_0();
0189     static int create_0();
0190     static int list_tree_0();
0191     static int difference_and_list_tree_0();
0192     static int CreateSmallerTreeWithListNode_0();
0193     static int deepcopy_0();
0194     static int deepcopy_1_leaking();
0195     static int CreateSmallerTreeWithListNode_2();
0196     static int next_sibling();
0197 
0198     static int Serialize();
0199     static int Import();
0200     static int Serialize_Import();
0201 
0202     static int OrderPrim_();
0203 
0204     static int ALL();
0205     static int main();
0206 };
0207 
0208 
0209 int sn_test::idx_0()
0210 {
0211     sn* a0 = sn::Sphere(100.);
0212     sn* b0 = sn::Box3(100.);
0213 
0214     sn* a0_1 = sn::Get(0) ;
0215     sn* b0_1 = sn::Get(1) ;
0216 
0217 
0218     assert( a0->idx() == 0 );
0219     assert( a0_1 == a0 );
0220 
0221     assert( b0->idx() == 1 );
0222     assert( b0_1 == b0 );
0223 
0224     delete a0 ;
0225     delete b0 ;
0226 
0227 
0228     sn* a1 = sn::Sphere(100.);
0229     assert( a1->idx() == 0 );
0230 
0231     delete a1 ;
0232 
0233     sn::Check_LEAK("sn_test::idx_0");
0234     return 0 ;
0235 }
0236 
0237 
0238 int sn_test::BinaryTreeHeight()
0239 {
0240     if(sn::level() > 0) std::cout << "[ sn_test::BinaryTreeHeight "  << std::endl ;
0241     for(int i=0 ; i < 512 ; i++)
0242     {
0243         int h0 = sn::BinaryTreeHeight(i) ;
0244         int h1 = sn::BinaryTreeHeight_1(i) ;
0245 
0246         if(sn::level() > 2) std::cout
0247            << " i " << std::setw(5) << i
0248            << " h0 " << std::setw(5) << h0
0249            << " h1 " << std::setw(5) << h1
0250            << std::endl
0251            ;
0252         assert( h0 == h1 );
0253     }
0254     if(sn::level() > 0) std::cout << "] sn_test::BinaryTreeHeight "  << std::endl ;
0255 
0256     sn::Check_LEAK("BinaryTreeHeight");
0257     return 0 ;
0258 }
0259 
0260 int sn_test::ZeroTree()
0261 {
0262     int num_leaves = 8 ;
0263     if(sn::level() > 0 ) std::cout << "[ sn_test::ZeroTree num_leaves " << num_leaves << std::endl ;
0264 
0265     int oper = 1 ;
0266     sn* root = sn::ZeroTree(num_leaves, oper );
0267 
0268     if(sn::level() > 1) std::cout << root->render(5) ;
0269     if(sn::level() > 1) std::cout << root->render(1) ;
0270 
0271     if(sn::level() > 1) std::cout << sn::Desc();
0272     if(!sn::LEAK) delete root ;
0273     if(sn::level() > 1) std::cout << sn::Desc();
0274 
0275     if(sn::level() > 0) std::cout << "] sn_test::ZeroTree num_leaves " << num_leaves << std::endl ;
0276     sn::Check_LEAK("ZeroTree");
0277     return 0 ;
0278 }
0279 
0280 int sn_test::CommonOperatorTypeTree(int num_leaves)
0281 {
0282     if(sn::level() > 1) std::cout << "[sn_test::CommonOperatorTypeTree num_leaves " << num_leaves << std::endl ;
0283     if(sn::level() > 1) std::cout << sn::Desc();
0284 
0285     std::vector<int> leaftypes ;
0286     for(int t=0 ; t < num_leaves ; t++) leaftypes.push_back( CSG_LEAF+t );
0287 
0288     sn* root = sn::CommonOperatorTypeTree(leaftypes, CSG_UNION ) ;
0289 
0290     if(sn::level() > 1) std::cout << sn::Desc(root);
0291 
0292     if(sn::level() > 0) std::cout << "sn_test::CommonOperatorTypeTree num_leaves " << std::setw(2) << num_leaves << " root: " << root->desc() << std::endl ;
0293 
0294     if(!sn::LEAK) delete root ;
0295 
0296     if(sn::level() > 0) std::cout << sn::Desc();
0297     if(sn::level() > 1) std::cout << "]sn_test::CommonOperatorTypeTree num_leaves " << num_leaves << std::endl ;
0298     sn::Check_LEAK("CommonOperatorTypeTree", num_leaves);
0299     return 0 ;
0300 }
0301 
0302 int sn_test::CommonOperatorTypeTree()
0303 {
0304     if(sn::level() > 0) std::cout << "[ sn_test::CommonOperatorTypeTree " << std::endl ;
0305     int N = 32 ;
0306     for(int nl=1 ; nl < N ; nl++) sn_test::CommonOperatorTypeTree(nl);
0307     if(sn::level() > 0) std::cout << "] sn_test::CommonOperatorTypeTree " << std::endl ;
0308     sn::Check_LEAK("CommonOperatorTypeTree");
0309     return 0 ;
0310 }
0311 
0312 
0313 int sn_test::label()
0314 {
0315     int it = 3 ;
0316     if(sn::level() > 0) std::cout << "[ sn_test::label it " << it  << std::endl ;
0317 
0318     sn* t = manual_tree(it);
0319 
0320     t->labeltree();
0321 
0322     if(sn::level() > 1) std::cout << t->render(3) ;
0323 
0324     if(!sn::LEAK) delete t ;
0325     if(sn::level() > 0) std::cout << "] sn_test::label it " << it  << std::endl ;
0326     sn::Check_LEAK("label");
0327     return 0 ;
0328 }
0329 
0330 int sn_test::positivize()
0331 {
0332     int it = ssys::getenvint("TREE", 3) ;
0333     if(sn::level() > 0) std::cout << "[ sn_test::positivize it " << it  << std::endl ;
0334 
0335     sn* t = manual_tree(it);
0336 
0337     int mode = ssys::getenvint("MODE", 4) ;
0338 
0339     t->labeltree();
0340     if(sn::level() > 1) std::cout << t->render(mode) ;
0341 
0342     t->positivize();
0343     if(sn::level() > 1) std::cout << t->render(mode) ;
0344 
0345     if(!sn::LEAK) delete t ;
0346     if(sn::level() > 0) std::cout << "] sn_test::positivize it " << it  << std::endl ;
0347     sn::Check_LEAK("positivize");
0348     return 0 ;
0349 }
0350 
0351 int sn_test::pool()
0352 {
0353     if(sn::level() > 0) std::cout << "[ sn_test::pool " << std::endl ;
0354     assert( sn::pool->size() == 0  );
0355     sn* a = sn::Zero() ;
0356 
0357 
0358     assert( sn::pool->size() == 1  );
0359     sn* b = sn::Zero() ;
0360 
0361     assert( sn::pool->size() == 2  );
0362     sn* c = sn::Zero() ;
0363 
0364     assert( sn::pool->size() == 3  );
0365 
0366 
0367     if(sn::level() > 1) std::cout << sn::Desc() ;
0368 
0369 
0370     delete c ;
0371     assert( sn::pool->size() == 2  );
0372 
0373     delete a ;
0374     assert( sn::pool->size() == 1  );
0375 
0376     delete b ;
0377     assert( sn::pool->size() == 0  );
0378 
0379     if(sn::level() > 0) std::cout << "] sn_test::pool " << std::endl ;
0380     sn::Check_LEAK("pool");
0381     return 0 ;
0382 }
0383 
0384 int sn_test::Simple()
0385 {
0386     int it = 3 ;
0387     if(sn::level() > 0) std::cout << "[ sn_test::Simple it " << it << std::endl ;
0388 
0389     sn* t = manual_tree(it);
0390 
0391     t->labeltree();
0392 
0393     if(sn::level() > 1) std::cout << t->render(5) ;
0394     if(sn::level() > 1) std::cout << sn::Desc() ;
0395 
0396     if(!sn::LEAK) delete t ;
0397     if(sn::level() > 0) std::cout << "] sn_test::Simple it " << it << std::endl ;
0398     sn::Check_LEAK("Simple");
0399     return 0 ;
0400 }
0401 
0402 int sn_test::set_left()
0403 {
0404     if(sn::level() > 0) std::cout << "[ sn_test::set_left" << std::endl ;
0405 
0406     sn* l = sn::Prim(CSG_SPHERE);
0407     sn* r = sn::Prim(CSG_BOX3);
0408     sn* b = sn::Create(CSG_UNION, l, r );
0409 
0410     sn* al = sn::Prim(CSG_BOX3) ;
0411 
0412     b->set_left(al, false);
0413 
0414     if(sn::level() > 1) std::cout << sn::Desc() ;
0415 
0416     delete b ;
0417     if(sn::level() > 1) std::cout << sn::Desc() ;
0418 
0419     if(sn::level() > 0) std::cout << "] sn_test::set_left" << std::endl ;
0420     sn::Check_LEAK("set_left");
0421     return 0 ;
0422 }
0423 
0424 int sn_test::serialize_0()
0425 {
0426     int lev = 0 ;
0427     int it = 3 ;
0428     if(sn::level() > lev) std::cout << "[ sn_test::serialize_0 it " << it  << std::endl ;
0429 
0430     sn* t = manual_tree(it);
0431     if(sn::level() > lev) std::cout << t->render(5) ;
0432     if(sn::level() > lev) std::cout << sn::Desc();
0433 
0434     int num_root = sn::pool->num_root() ;
0435     if(sn::level() > lev) std::cout << " num_root " << num_root << std::endl ;
0436 
0437     std::vector<_sn> buf ;
0438     sn::pool->serialize_(buf);
0439 
0440     delete t ;
0441 
0442     NP* a = NPX::ArrayFromVec_<int, _sn>(buf, _sn::ITEM) ;
0443 
0444     //NP* a = NP::Make<int>( buf.size(), _sn::NV ) ;
0445     //a->read2<int>((int*)buf.data());
0446 
0447     if(sn::level() > lev) std::cout << " save to " << FOLD << "/" << sn::NAME << std::endl ;
0448     a->save(FOLD, sn::NAME);
0449 
0450     if(sn::level() > lev) std::cout << "] sn_test::serialize buf.size() " << buf.size()  << std::endl ;
0451     if(sn::level() > lev) std::cout << sn::pool->Desc(buf) << std::endl ;
0452 
0453     sn::Check_LEAK("serialize_0");
0454     return 0 ;
0455 }
0456 
0457 int sn_test::serialize_1()
0458 {
0459     int lev = 0 ;
0460     int it = 3 ;
0461     if(sn::level() > lev) std::cout << "[ sn_test::serialize_1 it " << it  << std::endl ;
0462 
0463     sn* t = manual_tree(it);
0464     if(sn::level() > lev) std::cout << t->render(5) ;
0465     if(sn::level() > lev) std::cout << sn::Desc();
0466 
0467     int num_root = sn::pool->num_root() ;
0468     if(sn::level() > lev) std::cout << " num_root " << num_root << std::endl ;
0469 
0470     NP* a = sn::pool->serialize<int>() ;
0471 
0472     delete t ;
0473 
0474     if(sn::level() > lev) std::cout << " save to " << FOLD << "/" << sn::NAME << std::endl ;
0475 
0476     a->save(FOLD, sn::NAME);
0477 
0478     sn::Check_LEAK("serialize_1");
0479     return 0 ;
0480 }
0481 
0482 int sn_test::import_0()
0483 {
0484     int lev = 0 ;
0485     if(sn::level() > lev) std::cout << "[ sn_test::import_0 " << std::endl ;
0486 
0487     if(sn::level() > lev) std::cout << " load from " << FOLD << "/" << sn::NAME << std::endl ;
0488     NP* a = NP::Load(FOLD, sn::NAME );
0489     std::vector<_sn> buf(a->shape[0]) ;
0490     a->write<int>((int*)buf.data());
0491 
0492 
0493 
0494     sn::pool->import_(buf);
0495 
0496     if(sn::level() > lev) std::cout << sn::pool->Desc(buf) << std::endl ;
0497 
0498     int num_root = sn::pool->num_root() ;
0499     if(sn::level() > lev) std::cout << " num_root " << num_root << std::endl ;
0500     if(sn::level() > lev) std::cout << sn::Desc();
0501 
0502 
0503     sn* root = sn::pool->get_root(0) ;
0504     if(root && sn::level() > lev) std::cout << root->render(5);
0505     delete root ;
0506 
0507     if(sn::level() > lev) std::cout << "] sn_test::import_0 " << std::endl ;
0508     sn::Check_LEAK("import_0");
0509     return 0 ;
0510 }
0511 
0512 int sn_test::import_1()
0513 {
0514     int lev = 0 ;
0515     if(sn::level() > lev) std::cout << "[ sn_test::import_1 " << std::endl ;
0516 
0517     if(sn::level() > lev) std::cout << " load from " << FOLD << "/" << sn::NAME << std::endl ;
0518     NP* a = NP::Load(FOLD, sn::NAME );
0519 
0520     sn::pool->import<int>(a);
0521 
0522     int num_root = sn::pool->num_root() ;
0523     if(sn::level() > lev) std::cout << " num_root " << num_root << std::endl ;
0524     if(sn::level() > lev) std::cout << sn::Desc();
0525 
0526     sn* root = sn::pool->get_root(0) ;
0527     if(root && sn::level() > lev) std::cout << root->render(5);
0528     delete root ;
0529 
0530     if(sn::level() > lev) std::cout << "] sn_test::import_1 " << std::endl ;
0531     sn::Check_LEAK("import_1");
0532     return 0 ;
0533 }
0534 
0535 
0536 
0537 
0538 
0539 
0540 
0541 int sn_test::dtor_0()
0542 {
0543     sn* n = sn::Zero();
0544     delete n ;
0545     sn::Check_LEAK("dtor_0");
0546     return 0 ;
0547 }
0548 int sn_test::dtor_1()
0549 {
0550     sn* a = sn::Prim(100);
0551     sn* b = sn::Prim(101);
0552     sn* c = sn::Create(1, a, b );
0553     delete c ;
0554     sn::Check_LEAK("dtor_1");
0555     return 0 ;
0556 }
0557 
0558 
0559 /**
0560 
0561 
0562 8 leaves needs no pruning::
0563 
0564                                    1
0565 
0566                   10                               11
0567 
0568            100           101                 110             111
0569 
0570         1000 1001    1010  1011         1100   1101       1110  1111
0571 
0572 
0573 7 leaves, just needs one bileaf converted to a prim::
0574 
0575                                    1
0576 
0577                   10                               11
0578 
0579            100           101                 110             111
0580 
0581         1000 1001    1010  1011         1100   1101
0582 
0583 
0584 
0585 6 leaves needs two bileaf converted to prims::
0586 
0587 
0588                                    1
0589 
0590                   10                               11
0591 
0592            100           101                 110             111
0593 
0594         1000 1001    1010  1011
0595 
0596 
0597 **/
0598 
0599 
0600 int sn_test::set_child()
0601 {
0602     sn* a = sn::Prim(100);
0603     sn* b = sn::Prim(101);
0604     sn* c = sn::Create(1, a, b );
0605 
0606     if(sn::level() > 0) std::cout << c->render(1) ;
0607 
0608     sn* a2 = sn::Prim(200);
0609     sn* b2 = sn::Prim(201);
0610 
0611     c->set_child(0, a2, false);
0612     c->set_child(1, b2, false);
0613 
0614     if(sn::level() > 0) std::cout << c->render(1) ;
0615 
0616     delete c ;
0617 
0618     sn::Check_LEAK("set_child");
0619     return 0 ;
0620 }
0621 
0622 int sn_test::disown_child_0()
0623 {
0624     sn* a = sn::Sphere(100.);
0625     sn* b = sn::Box3(100.);
0626     sn* c = sn::Create(1, a, b );
0627 
0628     c->disown_child(b);
0629 
0630     return 0 ;
0631 }
0632 
0633 
0634 int sn_test::set_right_0()
0635 {
0636     sn* a = sn::Sphere(100.);
0637     sn* b = sn::Box3(100.);
0638     sn* c = sn::Create(1, a, b );
0639 
0640     sn* b2 = sn::Sphere(100.);
0641 
0642     c->set_right(b2, false );    // this will delete b
0643     c->set_lvid(100);
0644 
0645     std::cout
0646         << "sn_test::set_right_0\n"
0647         << " c.render\n "
0648         << c->render()
0649         ;
0650 
0651     delete c ;
0652 
0653     sn::Check_LEAK("sn_test::set_right_0");
0654 
0655     return 0 ;
0656 }
0657 
0658 
0659 
0660 
0661 
0662 int sn_test::create_0()
0663 {
0664     sn* a = sn::Prim(100);
0665     sn* b = sn::Prim(101);
0666     sn* c = sn::Create(1, a, b );
0667     delete c ;
0668 
0669     sn::Check_LEAK("create_0");
0670     return 0 ;
0671 }
0672 
0673 int sn_test::list_tree_0()
0674 {
0675     sn* a = list_tree(8) ;
0676 
0677     std::cout
0678         << "[ sn_test::list_tree_0 : a.render \n"
0679         << a->render()
0680         << "] sn_test::list_tree_0 : a.render \n"
0681         ;
0682 
0683 
0684     delete a ;
0685 
0686     sn::Check_LEAK("list_tree_0");
0687     return 0 ;
0688 }
0689 
0690 
0691 int sn_test::difference_and_list_tree_0()
0692 {
0693     sn* a = difference_and_list_tree(8) ;
0694 
0695     std::cout
0696         << "[ sn_test::difference_and_list_tree_0 : a.render \n"
0697         << a->render()
0698         << "] sn_test::difference_and_list_tree_0 : a.render \n"
0699         ;
0700 
0701 
0702     delete a ;
0703 
0704     sn::Check_LEAK("difference_and_list_tree_0");
0705     return 0 ;
0706 }
0707 
0708 
0709 int sn_test::CreateSmallerTreeWithListNode_0()
0710 {
0711     sn* r0 = difference_and_list_tree(8) ;
0712     r0->set_lvid(100);
0713 
0714 
0715     int q_note = sn::HINT_LISTNODE_PRIM_DISCONTIGUOUS ;
0716     sn* r1 = sn::CreateSmallerTreeWithListNode(r0, q_note) ;
0717     r1->set_lvid(200);
0718 
0719 
0720     sn* r0_check = sn::GetLVRoot(100) ;
0721     assert( r0_check == r0 );
0722 
0723     sn* r1_check = sn::GetLVRoot(200) ;
0724     assert( r1_check == r1 );
0725 
0726 
0727     std::cout << "sn_test::CreateSmallerTreeWithListNode_0 : r0.rdr \n" << r0->rdr() << "\n" ;
0728     std::cout << "sn_test::CreateSmallerTreeWithListNode_0 : r1.rdr \n" << r1->rdr() << "\n" ;
0729 
0730 
0731     r0->check_idx("sn_test::CreateSmallerTreeWithListNode_0.r0");
0732     r1->check_idx("sn_test::CreateSmallerTreeWithListNode_0.r1");
0733 
0734 
0735     delete r0 ;
0736     delete r1 ;
0737 
0738     sn::Check_LEAK("sn_test::CreateSmallerTreeWithListNode_0");
0739     return 0 ;
0740 }
0741 
0742 
0743 
0744 
0745 
0746 int sn_test::deepcopy_0()
0747 {
0748 
0749     std::cout << "sn_test::deepcopy_0 : sn* a = sn::Prim(101) \n" ;
0750     sn* a = sn::Prim(101);
0751     std::cout << "sn_test::deepcopy_0 : sn* b = sn::Prim(102) \n" ;
0752     sn* b = sn::Prim(102);
0753     std::cout << "sn_test::deepcopy_0 : sn* c0 = sn::Create(1,a,b) \n" ;
0754     sn* c0 = sn::Create(1, a, b );
0755 
0756     if(sn::level() > 0) std::cout << c0->render(1) ;
0757     if(sn::level() > 0) std::cout << c0->desc_r() ;
0758 
0759     std::cout << "sn_test::deepcopy_0 : sn* c1 = c0->deepcopy() \n" ;
0760     sn* c1 = c0->deepcopy();
0761 
0762     c1->set_lvid(88);
0763 
0764     std::cout << "c0.render_parent\n" << c0->render_parent() << "\n" ;
0765     std::cout << "c1.render_parent\n" << c1->render_parent() << "\n" ;
0766 
0767 
0768     sn* c1_check = sn::GetLVRoot(88) ;
0769     assert( c1 == c1_check );
0770 
0771 
0772 
0773 
0774 #ifdef WITH_CHILD
0775     assert( c1->child.size() == c0->child.size() );
0776 #endif
0777 
0778     std::cout << "sn_test::deepcopy_0 : delete c0 \n" ;
0779     delete c0 ;
0780 
0781     if(sn::level() > 0) std::cout << c1->render(1) ;
0782     if(sn::level() > 0) std::cout << c1->desc_r() ;
0783 
0784     std::cout << "sn_test::deepcopy_0 : delete c1 \n" ;
0785     delete c1 ;
0786 
0787     sn::Check_LEAK("deepcopy_0");
0788     return 0 ;
0789 }
0790 
0791 /**
0792 sn_test::deepcopy_1_leaking
0793 -----------------------------
0794 
0795 NB the child vector is shallow copied by this default copy ctor
0796 which causes the cp and c to both think they own a and b
0797 which will cause ownership isses when delete
0798 
0799 hence cannot easily clean up this situation
0800 
0801 **/
0802 
0803 int sn_test::deepcopy_1_leaking()
0804 {
0805     sn* a = sn::Prim(100);
0806     sn* b = sn::Prim(101);
0807     sn* c = sn::Create(1, a, b );
0808 
0809     std::cout << "c\n " << c->desc_child() << std::endl ;
0810 
0811     sn* cp = new sn(*c) ;
0812     std::cout << "cp\n" << cp->desc_child() << std::endl ;
0813 
0814     //sn::Check_LEAK("deepcopy_1_leaking");
0815     return 0 ;
0816 }
0817 
0818 
0819 int sn_test::CreateSmallerTreeWithListNode_2()
0820 {
0821     sn* r0 = difference_and_list_tree(8) ;
0822     r0->check_idx("sn_test::CreateSmallerTreeWithListNode_2.r0.bef");
0823     r0->set_lvid(100);
0824     r0->check_idx("sn_test::CreateSmallerTreeWithListNode_2.r0.aft");
0825 
0826     std::cout
0827         << "sn_test::CreateSmallerTreeWithListNode_2\n"
0828         << "r0.render\n"
0829         << r0->render()
0830         << "\n"
0831         ;
0832 
0833 
0834     sn* r1 = sn::CreateSmallerTreeWithListNode_discontiguous(r0) ;
0835 
0836 
0837 
0838     r1->check_idx("sn_test::CreateSmallerTreeWithListNode_2.r1.bef");
0839     r1->set_lvid(200);
0840     r1->check_idx("sn_test::CreateSmallerTreeWithListNode_2.r1.aft");
0841 
0842 
0843     std::cout
0844         << "sn_test::CreateSmallerTreeWithListNode_2\n"
0845         << "r1.render\n"
0846         << r1->render()
0847         ;
0848 
0849     delete r0 ;
0850     delete r1 ;
0851 
0852     sn::Check_LEAK("sn_test::CreateSmallerTreeWithListNode_2");
0853 
0854     return 0 ;
0855 }
0856 
0857 
0858 
0859 
0860 
0861 
0862 
0863 int sn_test::next_sibling()
0864 {
0865     int lev = 0 ;
0866 
0867     sn* a = sn::Prim(100);
0868     sn* b = sn::Prim(101);
0869     sn* c = sn::Create(1, a, b );
0870 
0871     int ia = a->sibling_index() ;
0872     int ib = b->sibling_index() ;
0873 
0874     if(sn::level() > lev) std::cerr << "sn_test::next_sibling ia  " << ia  << std::endl ;
0875     if(sn::level() > lev) std::cerr << "sn_test::next_sibling ib  " << ib  << std::endl ;
0876 
0877     const sn* x = a->next_sibling() ;
0878     const sn* y = b->next_sibling() ;
0879     const sn* z = c->next_sibling() ;
0880 
0881     if(sn::level() > lev) std::cerr << "sn_test::next_sibling x: " << ( x ? "Y" : "N" ) << std::endl ;
0882     if(sn::level() > lev) std::cerr << "sn_test::next_sibling y: " << ( y ? "Y" : "N" ) << std::endl ;
0883     if(sn::level() > lev) std::cerr << "sn_test::next_sibling z: " << ( z ? "Y" : "N" ) << std::endl ;
0884 
0885     assert( x == b );
0886     assert( y == nullptr );
0887     assert( z == nullptr );
0888 
0889     delete c ;
0890 
0891     sn::Check_LEAK("next_sibling");
0892     return 0 ;
0893 }
0894 
0895 int sn_test::Serialize()
0896 {
0897     int lev = -1 ;
0898     int it = 4 ;
0899     if(sn::level() > lev) std::cout << "[ sn_test::Serialize it " << it  << std::endl ;
0900 
0901     sn* t = manual_tree(it);
0902 
0903     if(sn::level() > lev) std::cout << t->render(5) ;
0904     if(sn::level() > lev) std::cout << sn::Desc();
0905 
0906     std::cout << "t.desc_r\n[\n" << t->desc_r() << "\n]\n" ;
0907     std::cout << "t.detail_r\n[\n" << t->detail_r() << "\n]\n" ;
0908 
0909     NPFold* fold = s_csg::Serialize() ;
0910 
0911     delete t ;
0912 
0913     fold->save(FOLD) ;
0914 
0915     if(sn::level() > lev) std::cout << "] sn_test::Serialize it " << it  << std::endl ;
0916 
0917     sn::Check_LEAK("Serialize");
0918 
0919     return 0 ;
0920 }
0921 
0922 
0923 int sn_test::Import()
0924 {
0925     NPFold* fold = NPFold::Load(FOLD) ;
0926 
0927     s_csg::Import( fold );
0928 
0929 
0930     std::cout << s_tv::pool->desc() ;
0931 
0932     sn* t = sn::pool->get_root(0) ;
0933 
0934     std::cout << t->render(0) ;
0935 
0936 
0937     std::cout << "t.desc_r\n[\n" << t->desc_r() << "\n]\n" ;
0938     std::cout << "t.detail_r\n[\n" << t->detail_r() << "\n]\n" ;
0939 
0940 
0941 
0942 
0943     sn* r = t->last_child();
0944 
0945     s_tv* xform = r->xform ;
0946 
0947     std::cout << ( xform ? xform->desc() : "xform-null" ) << std::endl ;
0948 
0949 
0950 
0951 
0952 
0953     std::cout << "sn_test::Import.delete_t[\n" ;
0954     delete t ;
0955     std::cout << "sn_test::Import.delete_t]\n" ;
0956 
0957 
0958     sn::Check_LEAK("Import");
0959 
0960     return 0 ;
0961 }
0962 
0963 
0964 /**
0965 sn_test::Serialize_Import
0966 --------------------------
0967 
0968 This captured an issue where sn nodes without transforms magically acquired
0969 them after import, where the erroneously acquired transform is the last one in the CSG pool.
0970 
0971 To avoid this issue, added the below which adds identity transforms to any sn without
0972 a transform. The sn::PrepareToSerialize is invoked from s_csg::serialize
0973 to ensure every node can travel appropriately::
0974 
0975     sn::PrepareToSerialize
0976     sn::prepare_to_serialize
0977 
0978 **/
0979 
0980 
0981 int sn_test::Serialize_Import()
0982 {
0983     int lev = -1 ;
0984     int it = 4 ;
0985     if(sn::level() > lev) std::cout << "[ sn_test::Serialize_Import it " << it  << std::endl ;
0986     sn* t0 = manual_tree(it);
0987 
0988     std::cout << "t0.desc_r\n[\n" << t0->desc_r() << "\n]\n" ;
0989     std::cout << "t0.detail_r\n[\n" << t0->detail_r() << "\n]\n" ;
0990 
0991     NPFold* fold0 = s_csg::Serialize() ;
0992     delete t0 ;
0993     fold0->save(FOLD) ;
0994 
0995     delete fold0 ;
0996 
0997 
0998     NPFold* fold1 = NPFold::Load(FOLD) ;
0999     s_csg::Import( fold1 );
1000 
1001     std::cout << s_tv::pool->desc() ;
1002 
1003     sn* t1 = sn::pool->get_root(0) ;
1004 
1005     std::cout << t1->render(0) ;
1006 
1007 
1008     std::cout << "t1.desc_r\n[\n" << t1->desc_r() << "\n]\n" ;
1009     std::cout << "t1.detail_r\n[\n" << t1->detail_r() << "\n]\n" ;
1010 
1011 
1012     delete t1 ;
1013     delete fold1 ;
1014 
1015     return 0;
1016 }
1017 
1018 
1019 int sn_test::OrderPrim_()
1020 {
1021     std::vector<sn*> prim0 ;
1022     sn* a = sn::Cylinder(100., -200., -100. );
1023     sn* b = sn::Cylinder( 50., -100.,    0. );
1024     sn* c = sn::Cylinder( 60.,    0.,  100. );
1025     sn* d = sn::Cylinder( 70.,  100.,  200. );
1026 
1027     prim0.push_back(a) ;
1028     prim0.push_back(b) ;
1029     prim0.push_back(c) ;
1030     prim0.push_back(d) ;
1031 
1032     std::reverse( prim0.begin(), prim0.end() );
1033 
1034     sn* root = sn::UnionTree(prim0);
1035     root->setAABB_TreeFrame_All();
1036 
1037     bool reverse = false ;
1038 
1039     std::cout
1040         << "sn_test::OrderPrim"
1041         << std::endl
1042         << " root->desc_prim_all() "
1043         << root->desc_prim_all(reverse)
1044         << std::endl
1045         ;
1046 
1047     std::vector<const sn*> prim ;
1048     root->collect_prim(prim);
1049     assert(prim.size() == prim0.size() );
1050 
1051     std::cout
1052         << " sn::DescPrim(prim) asis from  : root->collect_prim(prim)  "
1053         << std::endl
1054         <<  sn::DescPrim(prim)
1055         << std::endl
1056         ;
1057 
1058     bool ascending = true ;
1059 
1060     sn::OrderPrim<const sn>( prim, sn::AABB_ZMin, ascending  );
1061     std::cout
1062         << " sn::DescPrim(prim) after : sn::OrderPrim<const sn>( prim, sn::AABB_ZMin ) "
1063         << std::endl
1064         <<  sn::DescPrim(prim)
1065         << std::endl
1066         ;
1067 
1068     sn::OrderPrim<const sn>( prim, sn::AABB_XMin, ascending  );
1069     std::cout
1070         << " sn::DescPrim(prim) after : sn::OrderPrim<const sn>( prim, sn::AABB_XMin ) "
1071         << std::endl
1072         <<  sn::DescPrim(prim)
1073         << std::endl
1074         ;
1075 
1076     sn::OrderPrim<const sn>( prim, sn::AABB_XMax, ascending  );
1077     std::cout
1078         << " sn::DescPrim(prim) after : sn::OrderPrim<const sn>( prim, sn::AABB_XMax ) "
1079         << std::endl
1080         <<  sn::DescPrim(prim)
1081         << std::endl
1082         ;
1083 
1084     return 0 ;
1085 }
1086 
1087 
1088 int sn_test::ALL()
1089 {
1090     int rc = 0 ;
1091     rc += BinaryTreeHeight();
1092     rc += ZeroTree();
1093     rc += CommonOperatorTypeTree();
1094     rc += Serialize();
1095     rc += label();
1096     rc += positivize();
1097     rc += pool();
1098     rc += Simple();
1099     rc += set_left();
1100     rc += serialize_0();
1101     rc += serialize_1();
1102     rc += import_0();
1103     rc += import_1();
1104     rc += dtor_0();
1105     rc += dtor_1();
1106     rc += set_child();
1107     rc += deepcopy_0();
1108     //rc += deepcopy_1_leaking();
1109     rc += next_sibling();
1110     rc += Serialize();
1111 
1112     return rc ;
1113 }
1114 
1115 
1116 /**
1117 sn_test::main
1118 ------------------
1119 
1120 Before fixing sn::deepcopy with sn::disown_child some of the below
1121 CommonOperatorTypeTree tests segmented or hung
1122 **/
1123 
1124 int sn_test::main()
1125 {
1126     const char* TEST = ssys::getenvvar("TEST","ALL") ;
1127 
1128     int rc = 0 ;
1129     if(      strcmp(TEST, "idx_0") == 0 ) rc = idx_0() ;
1130     else if( strcmp(TEST, "BinaryTreeHeight") == 0 ) rc = BinaryTreeHeight() ;
1131     else if( strcmp(TEST, "ZeroTree")==0) rc = ZeroTree();
1132     else if( strcmp(TEST, "CommonOperatorTypeTree")==0) rc = CommonOperatorTypeTree();
1133     else if( strcmp(TEST, "CommonOperatorTypeTree1")==0) rc = CommonOperatorTypeTree(1);
1134     else if( strcmp(TEST, "CommonOperatorTypeTree4")==0) rc = CommonOperatorTypeTree(4);
1135     else if( strcmp(TEST, "CommonOperatorTypeTree32")==0) rc = CommonOperatorTypeTree(32);
1136     else if( strcmp(TEST, "Serialize")==0)  rc = Serialize();
1137     else if( strcmp(TEST, "Serialize_Import")==0)  rc = Serialize_Import();
1138     else if( strcmp(TEST, "label")==0)      rc = label();
1139     else if( strcmp(TEST, "positivize")==0) rc = positivize();
1140     else if( strcmp(TEST, "pool")==0)       rc = pool();
1141     else if( strcmp(TEST, "Simple")==0)     rc = Simple();
1142     else if( strcmp(TEST, "set_left")==0)     rc = set_left();
1143     //else if( strcmp(TEST, "serialize_0")==0)     rc = serialize_0();
1144     else if( strcmp(TEST, "serialize_1")==0)     rc = serialize_1();
1145     //else if( strcmp(TEST, "import_0")==0)     rc = import_0();
1146     else if( strcmp(TEST, "import_1")==0)     rc = import_1();
1147     else if( strcmp(TEST, "dtor_0")==0)     rc = dtor_0();
1148     else if( strcmp(TEST, "dtor_1")==0)     rc = dtor_1();
1149     else if( strcmp(TEST, "set_child")==0)     rc = set_child();
1150     else if( strcmp(TEST, "disown_child_0")==0)     rc = disown_child_0();
1151     else if( strcmp(TEST, "set_right_0")==0)     rc = set_right_0();
1152     else if( strcmp(TEST, "create_0")==0)     rc = create_0();
1153     else if( strcmp(TEST, "list_tree_0")==0)     rc = list_tree_0();
1154     else if( strcmp(TEST, "difference_and_list_tree_0")==0)     rc = difference_and_list_tree_0();
1155     else if( strcmp(TEST, "CreateSmallerTreeWithListNode_0")==0)     rc = CreateSmallerTreeWithListNode_0();
1156     else if( strcmp(TEST, "deepcopy_0")==0)     rc = deepcopy_0();
1157     else if( strcmp(TEST, "deepcopy_1_leaking")==0)  rc = deepcopy_1_leaking();
1158     else if( strcmp(TEST, "CreateSmallerTreeWithListNode_2")==0)     rc = CreateSmallerTreeWithListNode_2();
1159     else if( strcmp(TEST, "next_sibling")==0)        rc = next_sibling();
1160     else if( strcmp(TEST, "Serialize")==0)        rc = Serialize();
1161     else if( strcmp(TEST, "Import")==0)        rc = Import();
1162     else if( strcmp(TEST, "OrderPrim")==0)     rc = OrderPrim_();
1163     else if( strcmp(TEST, "ALL")==0)           rc = ALL();
1164 
1165     return rc ;
1166 }
1167 
1168 int main(int argc, char** argv)
1169 {
1170     s_csg* _csg = new s_csg ;
1171     std::cout << _csg->brief() ;
1172     return sn_test::main() ;
1173 }
1174