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
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 void scsg::init()
0030 {
0031
0032
0033
0034
0035
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
0052
0053
0054
0055
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 ;
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"));
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
0202
0203
0204
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
0220
0221
0222
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