Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:48:57

0001 
0002 #if defined(__CUDACC__) || defined(__CUDABE__)
0003 #else
0004 
0005 #include "scuda.h"
0006 #include "sqat4.h"
0007 
0008 #include "SMesh.h"
0009 #include "SMeshGroup.h"
0010 #include "ssys.h"
0011 
0012 #include "CSGPrim.h"
0013 
0014 #include <vector>
0015 #include <iostream>
0016 #include <iomanip>
0017 #include <sstream>
0018 #include <cassert>
0019 #include <cstring>
0020 #include <algorithm>
0021 
0022 
0023 std::string CSGPrim::desc() const
0024 {
0025     std::stringstream ss ;
0026     ss
0027       << "CSGPrim"
0028       << " numNode/node/tran/plan"
0029       << std::setw(4) << numNode() << " "
0030       << std::setw(4) << nodeOffset() << " "
0031       << std::setw(4) << tranOffset() << " "
0032       << std::setw(4) << planOffset() << " "
0033       << "sbtOffset/meshIdx/repeatIdx/primIdx "
0034       << std::setw(4) << sbtIndexOffset() << " "
0035       << std::setw(4) << meshIdx() << " "
0036       << std::setw(4) << repeatIdx() << " "
0037       << std::setw(4) << primIdx()
0038       << " mn " << mn()
0039       << " mx " << mx()
0040       ;
0041     std::string str = ss.str();
0042     return str ;
0043 }
0044 
0045 std::string CSGPrim::descRange() const
0046 {
0047     float3 mn3 = mn();
0048     float3 mx3 = mx();
0049     float4 ce4 = ce();
0050 
0051     std::array<float,4> _ce = {ce4.x, ce4.y, ce4.z,ce4.w};
0052     std::array<float,6> _bb = {mn3.x, mn3.y, mn3.z, mx3.x, mx3.y, mx3.z};
0053 
0054     std::stringstream ss ;
0055     ss << "CSGPrim::descRange" ;
0056     ss << " ce " << s_bb::Desc_<float,4>( _ce.data() ) ;
0057     ss << " bb " << s_bb::Desc_<float,6>( _bb.data()) ;
0058     ss << " lvid " << std::setw(3) << meshIdx() ;
0059     ss << " ridx " << std::setw(4) << repeatIdx() ;
0060     ss << " pidx " << std::setw(5) << primIdx() ;
0061     std::string str = ss.str();
0062     return str ;
0063 }
0064 
0065 
0066 std::string CSGPrim::descRangeNumPy() const
0067 {
0068     float3 mn3 = mn();
0069     float3 mx3 = mx();
0070     float4 ce4 = ce();
0071 
0072     std::array<float,4> _ce = {ce4.x, ce4.y, ce4.z,ce4.w};
0073     std::array<float,6> _bb = {mn3.x, mn3.y, mn3.z, mx3.x, mx3.y, mx3.z};
0074 
0075     std::stringstream ss ;
0076     ss << s_bb::DescNumPy_<float,4>( _ce.data(), "ce", false ) ;
0077     ss << s_bb::DescNumPy_<float,6>( _bb.data(), "bb", false ) ;
0078     ss << " # CSGPrim::descRangeNumPy " ;
0079     ss << " lvid " << std::setw(3) << meshIdx() ;
0080     ss << " ridx " << std::setw(4) << repeatIdx() ;
0081     ss << " pidx " << std::setw(5) << primIdx() ;
0082     std::string str = ss.str();
0083     return str ;
0084 }
0085 
0086 
0087 
0088 
0089 /**
0090 CSGPrim::DescRange
0091 -------------------
0092 
0093 Displays coordinate ranges and extent of the analytic CSGPrim and triangulated SMesh.
0094 
0095 **/
0096 
0097 
0098 std::string CSGPrim::DescRange(const CSGPrim* prim, int primOffset, int numPrim, const std::vector<std::string>* soname, const SMeshGroup* mg ) // static
0099 {
0100     int NUMPY = ssys::getenvint(CSGPrim__DescRange_NUMPY,0);
0101     bool NAMEONLY = ssys::getenvint(CSGPrim__DescRange_NAMEONLY,0) > 0;
0102 
0103     size_t num_so = soname ? soname->size() : 0 ;
0104     int mg_subs = mg ? mg->subs.size() : 0 ;
0105     float EXTENT_DIFF = ssys::getenvfloat(CSGPrim__DescRange_EXTENT_DIFF, 200.f );
0106     float EXTENT_MINI = ssys::getenvfloat(CSGPrim__DescRange_EXTENT_MINI,   0.f );
0107 
0108     std::vector<float>* CE_ZMIN_ZMAX = ssys::getenvfloatvec(CSGPrim__DescRange_CE_ZMIN_ZMAX, nullptr ); // nullptr when no envvar
0109     float CE_ZMIN = CE_ZMIN_ZMAX ? (*CE_ZMIN_ZMAX)[0] : 0.f ;
0110     float CE_ZMAX = CE_ZMIN_ZMAX ? (*CE_ZMIN_ZMAX)[1] : 0.f ;
0111 
0112     std::vector<float>* CE_YMIN_YMAX = ssys::getenvfloatvec(CSGPrim__DescRange_CE_YMIN_YMAX, nullptr ); // nullptr when no envvar
0113     float CE_YMIN = CE_YMIN_YMAX ? (*CE_YMIN_YMAX)[0] : 0.f ;
0114     float CE_YMAX = CE_YMIN_YMAX ? (*CE_YMIN_YMAX)[1] : 0.f ;
0115 
0116     std::vector<float>* CE_XMIN_XMAX = ssys::getenvfloatvec(CSGPrim__DescRange_CE_XMIN_XMAX, nullptr ); // nullptr when no envvar
0117     float CE_XMIN = CE_XMIN_XMAX ? (*CE_XMIN_XMAX)[0] : 0.f ;
0118     float CE_XMAX = CE_XMIN_XMAX ? (*CE_XMIN_XMAX)[1] : 0.f ;
0119 
0120 
0121 
0122 
0123     std::stringstream tt ;
0124     tt
0125        << " numPrim " << numPrim
0126        << " mg_subs " << mg_subs
0127        << "\n"
0128        << " EXTENT_MINI : " << std::setw(10) << std::fixed << std::setprecision(3) << EXTENT_MINI
0129        << " [" << CSGPrim__DescRange_EXTENT_MINI << "]"
0130        << "\n"
0131        << " EXTENT_DIFF : " << std::setw(10) << std::fixed << std::setprecision(3) << EXTENT_DIFF
0132        << " [" << CSGPrim__DescRange_EXTENT_DIFF << "]"
0133        << "\n"
0134        << " [" << CSGPrim__DescRange_CE_ZMIN_ZMAX << "]"
0135        << " CE_ZMIN : " << std::setw(10) << std::fixed << std::setprecision(3) << CE_ZMIN
0136        << " CE_ZMAX : " << std::setw(10) << std::fixed << std::setprecision(3) << CE_ZMAX
0137        << "\n"
0138        << " [" << CSGPrim__DescRange_CE_YMIN_YMAX << "]"
0139        << " CE_YMIN : " << std::setw(10) << std::fixed << std::setprecision(3) << CE_YMIN
0140        << " CE_YMAX : " << std::setw(10) << std::fixed << std::setprecision(3) << CE_YMAX
0141        << "\n"
0142        << " [" << CSGPrim__DescRange_CE_XMIN_XMAX << "]"
0143        << " CE_XMIN : " << std::setw(10) << std::fixed << std::setprecision(3) << CE_XMIN
0144        << " CE_XMAX : " << std::setw(10) << std::fixed << std::setprecision(3) << CE_XMAX
0145        << "\n"
0146        ;
0147 
0148     std::string ctx = tt.str();
0149 
0150     std::stringstream ss ;
0151     if(!NAMEONLY) ss << "[CSGPrim::Desc"
0152        << ctx
0153        ;
0154 
0155 
0156     // TODO: make the order controllable by envvar
0157 
0158     // order the prim SMesh by maximum z
0159     std::vector<unsigned> idx(numPrim);
0160 
0161     std::iota(idx.begin(), idx.end(), 0u);  // fill 0,1,2,...,numPrim-1
0162     //using order_functor = SMesh::zmax_functor ;
0163     //using order_functor = SMesh::extent_functor ;
0164 
0165     //using order_functor = CSGPrim::zmax_functor ;
0166     using order_functor = CSGPrim::extent_functor ;
0167     order_functor order_fn {} ;
0168 
0169     std::stable_sort(idx.begin(), idx.end(),
0170         [&](unsigned a, unsigned b) -> bool {
0171             return order_fn(prim[primOffset+a]) > order_fn(prim[primOffset+b]);
0172         });
0173 
0174     int count = 0 ;
0175 
0176     for(int j=0 ; j < numPrim ; j++ )
0177     {
0178         unsigned i = idx[j] ;
0179         const SMesh* sub = mg ? mg->subs[i] : nullptr ;
0180         const CSGPrim& pr = prim[primOffset + i];
0181         unsigned lvid = pr.meshIdx();
0182 
0183         if(sub)
0184         {
0185             assert( sub->lvid == int(lvid) );
0186         }
0187 
0188         float4 pr_ce = pr.ce();
0189 
0190         bool extent_in_range = EXTENT_MINI == 0.f ? true : pr_ce.w >= EXTENT_MINI ;
0191         bool cez_in_range =  CE_ZMIN_ZMAX ? ( pr_ce.z > CE_ZMIN && pr_ce.z < CE_ZMAX ) : true ;
0192         bool cey_in_range =  CE_YMIN_YMAX ? ( pr_ce.y > CE_YMIN && pr_ce.y < CE_YMAX ) : true ;
0193         bool cex_in_range =  CE_XMIN_XMAX ? ( pr_ce.x > CE_XMIN && pr_ce.x < CE_XMAX ) : true ;
0194 
0195         if(!extent_in_range) continue ;
0196         if(!cez_in_range) continue ;
0197         if(!cey_in_range) continue ;
0198         if(!cex_in_range) continue ;
0199 
0200 
0201         count += 1 ;
0202 
0203         const glm::tvec4<float>* sub_ce = sub ? &(sub->ce) : nullptr ;
0204         const glm::tmat4x4<double>* sub_tr0 = sub ? &(sub->tr0) : nullptr ;
0205         const char* sub_loaddir = sub ? sub->loaddir : nullptr ;
0206 
0207         float extent_diff = sub_ce ? (*sub_ce).w - pr_ce.w : 0. ;
0208 
0209         const char* so = lvid < num_so ? (*soname)[lvid].c_str() : nullptr ;
0210 
0211         if(NAMEONLY)
0212         {
0213             ss << ( so ? so : "-" ) << "\n" ;
0214         }
0215         else
0216         {
0217 
0218             ss
0219                 << std::setw(4) << i
0220                 << " : "
0221                 << ( NUMPY ? pr.descRangeNumPy() : pr.descRange() )
0222                 << " so[" << ( so ? so : "-" ) << "]"
0223                 << "\n"
0224                 ;
0225 
0226         }
0227 
0228         if(sub) ss
0229             << std::setw(4) << i
0230             << " : "
0231             << ( NUMPY ? sub->descRangeNumPy() : sub->descRange() )
0232             << " so[" << ( so ? so : "-" ) << "]"
0233             << " extent_diff " << std::setw(10) << std::fixed << std::setprecision(3) << extent_diff
0234             << "\n"
0235             ;
0236 
0237         if( std::abs(extent_diff) > EXTENT_DIFF )
0238         {
0239             ss
0240                << " extent_diff > EXTENT_DIFF : "
0241                << " extent_diff : " << std::setw(10) << std::fixed << std::setprecision(3) << extent_diff
0242                << "\n"
0243                ;
0244             if(sub_tr0) ss << " sub_tr0\n" << stra<double>::Desc(*sub_tr0) << "\n"  ;
0245             if(sub_loaddir) ss << " sub_loaddir [" << sub_loaddir << "]\n" ;
0246         }
0247     }
0248 
0249     if(!NAMEONLY) ss
0250         << ctx
0251         << "]CSGPrim::Desc\n"
0252         ;
0253 
0254     std::string str = ss.str() ;
0255     return count == 0 ? "" : str ;
0256 }
0257 
0258 
0259 
0260 
0261 
0262 
0263 
0264 
0265 
0266 bool CSGPrim::IsDiff( const CSGPrim& a , const CSGPrim& b )
0267 {
0268     return false ;
0269 }
0270 
0271 
0272 
0273 
0274 /**
0275 CSGPrim::MakeSpec
0276 -------------------
0277 
0278 Specification providing pointers to access all the AABB of *numPrim* CSGPrim,
0279 canonically invoked by CSGFoundry::getPrimSpecHost and CSGFoundry::getPrimSpecDevice
0280 which provide the CSGPrim bbox pointers for all CSGPrim within a CSGSolid.::
0281 
0282     1075     const CSGSolid* so = solid.data() + solidIdx ;  // get the primOffset from CPU side solid
0283     1076     SCSGPrimSpec ps = CSGPrim::MakeSpec( d_prim,  so->primOffset, so->numPrim ); ;
0284 
0285 This can be done very simply for both host and device due to the contiguous storage
0286 of the CSGPrim in the foundry and fixed strides.
0287 
0288 SCSGPrimSpec::primitiveIndexOffset
0289     Primitive index bias, applied in optixGetPrimitiveIndex() so the primIdx
0290     obtained in closesthit__ch__ is absolute to the entire geometry
0291     instead of the default of being local to the compound solid.
0292     (see GAS_Builder::MakeCustomPrimitivesBI_11N)
0293 
0294     This primIdx obtained for each intersect is combined with the
0295     optixGetInstanceId() to give the intersect identity.
0296 
0297 
0298 How to implement Prim selection ?
0299 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0300 
0301 Applying Prim selection based on meshIdx/lvIdx of each
0302 Prim still requires to iterate over them all.
0303 Better to apply selection in one place only.
0304 So where to apply prim selection ?
0305 
0306 SCSGPrimSpec is too late as the prim array handled
0307 there needs to be memory contiguous.
0308 This suggests addition of selected_prim to CSGFoundry::
0309 
0310     std::vector<CSGPrim>  prim ;
0311     std::vector<CSGPrim>  selected_prim ;
0312 
0313 Must also ensure no blind passing of primOffsets as they
0314 will be invalid.
0315 
0316 
0317 
0318 
0319 
0320 **/
0321 
0322 SCSGPrimSpec CSGPrim::MakeSpec( const CSGPrim* prim0,  unsigned primIdx, unsigned numPrim ) // static
0323 {
0324     const CSGPrim* prim = prim0 + primIdx ;
0325 
0326     SCSGPrimSpec ps ;
0327     ps.aabb = prim->AABB() ;
0328     ps.sbtIndexOffset = prim->sbtIndexOffsetPtr() ;
0329     ps.num_prim = numPrim ;
0330     ps.stride_in_bytes = sizeof(CSGPrim);
0331     ps.primitiveIndexOffset = primIdx ;
0332 
0333     return ps ;
0334 }
0335 
0336 #endif
0337 
0338