Back to home page

EIC code displayed by LXR

 
 

    


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

0001 #include "scsg.hh"
0002 #include "ssys.h"
0003 #include "NPFold.h"
0004 #include "NPX.h"
0005 
0006 scsg::scsg()
0007     :
0008     level(ssys::getenvint("scsg_level", 0))
0009 {
0010     init(); 
0011 }
0012 
0013 /**
0014 scsg::init
0015 ------------
0016 
0017 Reserving sufficient IMAX prevents realloc of the vectors,
0018 however it is better to code in a way to avoid the need to 
0019 reserve in order to avoid issues happening once the total 
0020 number of nodes exceeds the IMAX.   
0021 
0022 DO THIS BY NOT USING POINTERS OR REFERNCES OBTAINED
0023 BEFORE PUSH_BACK TO A VECTOR AFTER THE PUSH_BACK.
0024 THAT MEANS DO THE Add LAST THING IN METHODS
0025 AND DO NOT STORE POINTERS OR REFERENCES
0026 
0027 **/
0028 
0029 void scsg::init()
0030 {
0031     /*
0032     node.reserve(IMAX);   
0033     param.reserve(IMAX);   
0034     xform.reserve(IMAX);   
0035     aabb.reserve(IMAX);   
0036     */ 
0037     snd::SetPOOL(this);
0038 }
0039 
0040 
0041 template<typename T>
0042 int scsg::add_(const T& obj, std::vector<T>& vec) 
0043 {
0044     int idx = vec.size(); 
0045     vec.push_back(obj);  
0046     return idx ; 
0047 }
0048 
0049 
0050 /**
0051 scsg::add_<snd>
0052 ----------------
0053 
0054 Template specialization for adding snd that checks for 
0055 realloc and auto-sets snd::index
0056 
0057 **/
0058 
0059 template<>
0060 int scsg::add_(const snd& obj, std::vector<snd>& vec) 
0061 {
0062     int idx = vec.size(); 
0063 
0064     const snd* ptr0_before = &vec[0] ; 
0065     vec.push_back(obj); 
0066     const snd* ptr0_after = &vec[0] ; 
0067     
0068     if( ptr0_before != ptr0_after && level > 0) 
0069     {
0070         std::cerr << "scsg::add_<snd> DETECTED REALLOC AT idx " << idx << std::endl ;  
0071     }
0072 
0073     vec[idx].index = idx ;   // template specialization for snd : record the index into the added snd
0074     return idx  ; 
0075 }
0076 
0077 
0078 int scsg::addND(const snd& nd) { return add_<snd>(nd, node)  ; }
0079 int scsg::addPA(const spa& pa) { return add_<spa>(pa, param) ; }
0080 int scsg::addBB(const sbb& bb) { return add_<sbb>(bb, aabb)  ; } 
0081 int scsg::addXF(const sxf& xf) { return add_<sxf>(xf, xform) ; }
0082 
0083 
0084 template<typename T>
0085 const T* scsg::get(int idx, const std::vector<T>& vec) const  
0086 {
0087     assert( idx < int(vec.size()) ); 
0088     return idx < 0 ? nullptr : &vec[idx] ; 
0089 }
0090 const snd* scsg::getND(int idx) const { return get<snd>(idx, node)  ; }
0091 const spa* scsg::getPA(int idx) const { return get<spa>(idx, param) ; }
0092 const sbb* scsg::getBB(int idx) const { return get<sbb>(idx, aabb)  ; } 
0093 const sxf* scsg::getXF(int idx) const { return get<sxf>(idx, xform) ; }
0094 
0095 
0096 
0097 
0098 template<typename T>
0099 T* scsg::get_(int idx, std::vector<T>& vec) 
0100 {
0101     assert( idx < int(vec.size()) ); 
0102     return idx < 0 ? nullptr : &vec[idx] ; 
0103 }
0104 
0105 snd* scsg::getND_(int idx) { return get_<snd>(idx, node)  ; }
0106 spa* scsg::getPA_(int idx) { return get_<spa>(idx, param) ; }
0107 sbb* scsg::getBB_(int idx) { return get_<sbb>(idx, aabb)  ; } 
0108 sxf* scsg::getXF_(int idx) { return get_<sxf>(idx, xform) ; }
0109 
0110 
0111 
0112 
0113 
0114 
0115 
0116 
0117 
0118 template<typename T>
0119 std::string scsg::desc_(int idx, const std::vector<T>& vec) const   
0120 {
0121     int w = 3 ; 
0122     int num_obj = vec.size() ; 
0123 
0124     std::stringstream ss ; 
0125     ss << T::NAME << ":" << std::setw(w) << idx << " " ;  
0126     if(idx < 0) 
0127     {
0128         ss << "(none)" ; 
0129     }
0130     else if( idx >= num_obj )
0131     {
0132         ss << "(invalid)" ; 
0133     }
0134     else
0135     {
0136         const T& obj = vec[idx] ;  
0137         ss << obj.desc() ; 
0138     }
0139     std::string str = ss.str(); 
0140     return str ; 
0141 }
0142 
0143 
0144 std::string scsg::descND(int idx) const { return desc_<snd>(idx, node); }
0145 std::string scsg::descPA(int idx) const { return desc_<spa>(idx, param); }
0146 std::string scsg::descBB(int idx) const { return desc_<sbb>(idx, aabb); }
0147 std::string scsg::descXF(int idx) const { return desc_<sxf>(idx, xform); }
0148 
0149 
0150 
0151 
0152 
0153 std::string scsg::brief() const
0154 {
0155     std::stringstream ss ; 
0156     ss << "scsg" 
0157        << " node " << node.size() 
0158        << " param " << param.size() 
0159        << " aabb " << aabb.size() 
0160        << " xform " << xform.size() 
0161        ;
0162     std::string str = ss.str(); 
0163     return str ; 
0164 }
0165 std::string scsg::desc() const 
0166 {
0167     std::stringstream ss ; 
0168     ss << brief() << std::endl ; 
0169     for(int idx=0 ; idx < int(node.size()) ; idx++) ss << descND(idx) << std::endl ; 
0170     std::string str = ss.str(); 
0171     return str ; 
0172 }
0173 
0174 
0175 NPFold* scsg::serialize() const 
0176 {
0177     NPFold* fold = new NPFold ; 
0178     fold->add("node",  NPX::ArrayFromVec<int,    snd>(node)); 
0179     fold->add("param", NPX::ArrayFromVec<double, spa>(param)); 
0180     fold->add("aabb",  NPX::ArrayFromVec<double, sbb>(aabb)); 
0181     fold->add("xform", NPX::ArrayFromVec<double, sxf>(xform, 2, 4, 4)); 
0182     return fold ; 
0183 }
0184 void scsg::import(const NPFold* fold) 
0185 { 
0186     NPX::VecFromArray<snd>(node,  fold->get("node"));  // NB the vec are cleared first 
0187     NPX::VecFromArray<spa>(param, fold->get("param")); 
0188     NPX::VecFromArray<sbb>(aabb,  fold->get("aabb")); 
0189     NPX::VecFromArray<sxf>(xform, fold->get("xform")); 
0190 }
0191 
0192 
0193 
0194 
0195 
0196 
0197 
0198 
0199 
0200 /**
0201 scsg::getLVID : all nodes associated with the *lvid* root 
0202 ------------------------------------------------------------
0203 
0204 Collect *snd* CSG nodes with snd::lvid matching *q_lvid* 
0205 
0206 **/
0207 
0208 void scsg::getLVID( std::vector<snd>& nds, int q_lvid ) const 
0209 {
0210     int num_node = node.size(); 
0211     for(int i=0 ; i < num_node ; i++)
0212     {
0213         const snd& nd = node[i] ; 
0214         if(nd.lvid == q_lvid) nds.push_back(nd) ; 
0215     }
0216 }
0217 
0218 /**
0219 scsg::getLVRoot
0220 ----------------
0221 
0222 Returns first *snd* node for *lvid* with snd::is_root true
0223 
0224 **/
0225 
0226 const snd* scsg::getLVRoot(int lvid ) const 
0227 {
0228     const snd* root = nullptr ; 
0229 
0230     int count = 0 ; 
0231     int num_node = node.size(); 
0232     for(int i=0 ; i < num_node ; i++)
0233     {
0234         const snd& nd = node[i] ; 
0235         if(nd.lvid == lvid && nd.is_root()) 
0236         {
0237             root = &nd ; 
0238             count += 1 ; 
0239         }
0240     }
0241     assert( count <= 1 ); 
0242     return root ; 
0243 }
0244 
0245