Back to home page

EIC code displayed by LXR

 
 

    


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

0001 #pragma once
0002 /**
0003 s_csg.h : Manage persisting of CSG constituent nodes
0004 ======================================================
0005 
0006 Canonical instance stree::_csg is instanciated with the stree
0007 
0008 Holds node tree info, param, bbox, transforms of CSG constituent nodes.
0009 
0010 NB: Restrict this to handling persisting only.
0011 Doing other things here such as node finding
0012 leads to circular dependencies.
0013 
0014 Note that this just does persisting managed from _csg member of stree,
0015 other than very low level accessors access to sn nodes is done
0016 via sn.h methods such as::
0017 
0018    sn::GetLVNodes
0019 
0020 
0021 
0022 **/
0023 
0024 #include "ssys.h"
0025 
0026 #include "s_pa.h"
0027 #include "s_bb.h"
0028 #include "s_tv.h"
0029 #include "sn.h"
0030 
0031 #include "NPFold.h"
0032 #include "SYSRAP_API_EXPORT.hh"
0033 
0034 
0035 struct SYSRAP_API s_csg
0036 {
0037     static s_csg* INSTANCE ;
0038     static s_csg* Get();
0039     static NPFold* Serialize();
0040     static void Import(const NPFold* fold);
0041     static void Load(const char* base) ;
0042     static std::string Desc();
0043 
0044     int level ;
0045     s_pa::POOL* pa ;
0046     s_bb::POOL* bb ;
0047     s_tv::POOL* tv ;
0048     sn::POOL*   nd ;
0049 
0050     s_csg();
0051     void init();
0052 
0053     int total_size() const ;
0054     std::string brief() const ;
0055     std::string desc() const ;
0056 
0057     NPFold* serialize() const ;
0058     void import(const NPFold* fold);
0059 
0060     int num_pa() const ;
0061     int num_bb() const ;
0062     int num_tv() const ;
0063     int num_nd() const ;
0064 
0065     // low level accessors by index
0066     s_pa* get_pa(int idx) const ;
0067     s_bb* get_bb(int idx) const ;
0068     s_tv* get_tv(int idx) const ;
0069     sn*   get_nd(int idx) const ;
0070 
0071 };
0072 
0073 
0074 inline s_csg* s_csg::Get() { return INSTANCE ; }
0075 
0076 inline NPFold* s_csg::Serialize()
0077 {
0078     assert(INSTANCE);
0079     return INSTANCE ? INSTANCE->serialize() : nullptr ;
0080 }
0081 
0082 inline void s_csg::Import(const NPFold* fold)
0083 {
0084     if(INSTANCE == nullptr) new s_csg ;
0085     assert( INSTANCE ) ;
0086 
0087     int tot = INSTANCE->total_size() ;
0088     if(tot != 0) std::cerr << INSTANCE->brief() ;
0089 
0090     assert( tot == 0 && "s_csg::Import into an already populated pool is not supported" );
0091     INSTANCE->import(fold);
0092 }
0093 
0094 inline void s_csg::Load(const char* base)
0095 {
0096     NPFold* fold = NPFold::Load(base);
0097     Import(fold);
0098 }
0099 
0100 inline std::string s_csg::Desc()
0101 {
0102     std::stringstream ss ;
0103     ss << "s_csg::Desc INSTANCE " << ( INSTANCE ? "YES" : "NO " ) << std::endl ;
0104     if(INSTANCE) ss << INSTANCE->brief() << std::endl ;
0105     if(INSTANCE) ss << INSTANCE->desc() << std::endl ;
0106     std::string str = ss.str();
0107     return str ;
0108 }
0109 
0110 
0111 
0112 
0113 inline s_csg::s_csg()
0114     :
0115     level(ssys::getenvint("s_csg_level",0)),
0116     pa(new s_pa::POOL("pa")),
0117     bb(new s_bb::POOL("bb")),
0118     tv(new s_tv::POOL("tv")),
0119     nd(new   sn::POOL("nd"))
0120 {
0121     if(level > 0) std::cerr << "s_csg::s_csg s_csg_level : " << level << std::endl ;
0122     init();
0123 }
0124 
0125 inline void s_csg::init()
0126 {
0127     INSTANCE = this ;
0128     s_pa::SetPOOL(pa) ;
0129     s_bb::SetPOOL(bb) ;
0130     s_tv::SetPOOL(tv) ;
0131     sn::SetPOOL(nd) ;
0132 }
0133 
0134 inline int s_csg::total_size() const
0135 {
0136     return num_pa() + num_bb() + num_tv() + num_nd() ;
0137 }
0138 
0139 inline int s_csg::num_pa() const { return pa->size() ; }
0140 inline int s_csg::num_bb() const { return bb->size() ; }
0141 inline int s_csg::num_tv() const { return tv->size() ; }
0142 inline int s_csg::num_nd() const { return nd->size() ; }
0143 
0144 inline std::string s_csg::brief() const
0145 {
0146     std::stringstream ss ;
0147     ss << "s_csg::brief"
0148        << " total_size " << total_size()
0149        << " num_pa " << num_pa()
0150        << " num_bb " << num_bb()
0151        << " num_tv " << num_tv()
0152        << " num_nd " << num_nd()
0153        << std::endl
0154        << " pa : " << ( pa ? pa->brief() : "-" ) << std::endl
0155        << " bb : " << ( bb ? bb->brief() : "-" ) << std::endl
0156        << " tv : " << ( tv ? tv->brief() : "-" ) << std::endl
0157        << " nd : " << ( nd ? nd->brief() : "-" )
0158        << std::endl
0159        ;
0160     std::string str = ss.str();
0161     return str ;
0162 }
0163 
0164 inline std::string s_csg::desc() const
0165 {
0166     std::stringstream ss ;
0167     ss << "s_csg::desc total_size " << total_size()  ;
0168     ss << ( pa ? pa->desc() : "-" ) << std::endl ;
0169     ss << ( bb ? bb->desc() : "-" ) << std::endl ;
0170     ss << ( tv ? tv->desc() : "-" ) << std::endl ;
0171     ss << ( nd ? nd->desc() : "-" ) << std::endl ;
0172     std::string str = ss.str();
0173     return str ;
0174 }
0175 
0176 /**
0177 s_csg::serialize
0178 -----------------
0179 
0180 In preparation for serialization sn::PrepareToSerialize is invoked
0181 which sets identity transforms on any sn nodes without transforms.
0182 See sn_test::Serialize_Import for details.
0183 
0184 **/
0185 
0186 
0187 inline NPFold* s_csg::serialize() const
0188 {
0189     sn::PrepareToSerialize();
0190 
0191     if(level > 0) std::cerr << "s_csg::serialize s_csg_level : " << level << std::endl ;
0192     NPFold* fold = new NPFold ;
0193     fold->add(  sn::NAME, nd->serialize<int>() );
0194     fold->add(s_bb::NAME, bb->serialize<double>() );
0195     fold->add(s_pa::NAME, pa->serialize<double>() );
0196     fold->add(s_tv::NAME, tv->serialize<double>() );
0197     return fold ;
0198 }
0199 
0200 
0201 
0202 /**
0203 s_csg::import
0204 --------------
0205 
0206 NB transforms are imported before nodes
0207 so the transform hookup during node import works.
0208 
0209 That ordering is required because the sn have pointers
0210 referencing the transforms, hence transforms must be imported first.
0211 
0212 Similarly the aabb and param will need to be imported before the sn.
0213 Notice the ordering of the sn import doesnt matter because the full _sn
0214 buffer gets imported in one go prior to doing any sn hookup.
0215 
0216 **/
0217 
0218 inline void s_csg::import(const NPFold* fold)
0219 {
0220     if(level > 0) std::cerr
0221         << "s_csg::import "
0222         << " s_csg_level " << level
0223         << " fold " << ( fold ? fold->desc() : "-" )
0224         << std::endl
0225         ;
0226 
0227     pa->import<double>(fold->get(s_pa::NAME)) ;
0228     bb->import<double>(fold->get(s_bb::NAME)) ;
0229     tv->import<double>(fold->get(s_tv::NAME)) ;
0230     nd->import<int>(   fold->get(  sn::NAME)) ;
0231 }
0232 
0233 
0234 inline s_pa* s_csg::get_pa(int idx) const { return pa->getbyidx(idx) ; }
0235 inline s_bb* s_csg::get_bb(int idx) const { return bb->getbyidx(idx) ; }
0236 inline s_tv* s_csg::get_tv(int idx) const { return tv->getbyidx(idx) ; }
0237 inline sn*   s_csg::get_nd(int idx) const { return nd->getbyidx(idx) ; }
0238 
0239