File indexing completed on 2026-04-09 07:48:55
0001
0002 #include <csignal>
0003 #include "scuda.h"
0004 #include "sqat4.h"
0005 #include "ssys.h"
0006
0007 #ifdef WITH_S_BB
0008 #include "s_bb.h"
0009 #else
0010 #include "saabb.h"
0011 #endif
0012
0013 #include "SLOG.hh"
0014
0015 #include "SBitSet.h"
0016 #include "OpticksCSG.h"
0017
0018 #include "CSGFoundry.h"
0019 #include "CSGSolid.h"
0020 #include "CSGPrim.h"
0021 #include "CSGNode.h"
0022
0023 #include "CSGCopy.h"
0024
0025
0026 const plog::Severity CSGCopy::LEVEL = SLOG::EnvLevel("CSGCopy", "DEBUG" );
0027 const int CSGCopy::DUMP_RIDX = ssys::getenvint("DUMP_RIDX", -1) ;
0028 const int CSGCopy::DUMP_NPS = ssys::getenvint("DUMP_NPS", 0) ;
0029
0030
0031
0032 CSGFoundry* CSGCopy::Clone(const CSGFoundry* src )
0033 {
0034 CSGCopy cpy(src, nullptr);
0035 cpy.copy();
0036 LOG(info) << cpy.desc();
0037 return cpy.dst ;
0038 }
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 CSGFoundry* CSGCopy::Select(const CSGFoundry* src, const SBitSet* elv )
0052 {
0053 CSGCopy cpy(src, elv);
0054 cpy.copy();
0055 LOG(LEVEL) << cpy.desc();
0056 return cpy.dst ;
0057 }
0058
0059 CSGCopy::CSGCopy(const CSGFoundry* src_, const SBitSet* elv_)
0060 :
0061 src(src_),
0062 sNumSolid(src->getNumSolid()),
0063 solidMap(new int[sNumSolid]),
0064 sSolidIdx(~0u),
0065 elv(elv_),
0066 identical(elv ? elv->is_all_set() : true),
0067 identical_bbox_cheat(identical && true),
0068 dst(new CSGFoundry)
0069 {
0070 }
0071
0072 std::string CSGCopy::desc() const
0073 {
0074 std::stringstream ss ;
0075 ss
0076 << std::endl
0077 << "src:"
0078 << src->desc()
0079 << std::endl
0080 << "dst:"
0081 << dst->desc()
0082 << std::endl
0083 ;
0084 std::string s = ss.str();
0085 return s ;
0086 }
0087
0088 CSGCopy::~CSGCopy()
0089 {
0090 delete [] solidMap ;
0091 }
0092
0093 unsigned CSGCopy::Dump( unsigned sSolidIdx )
0094 {
0095 return ( DUMP_RIDX >= 0 && unsigned(DUMP_RIDX) == sSolidIdx ) ? DUMP_NPS : 0u ;
0096 }
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 void CSGCopy::copy()
0118 {
0119 CSGFoundry::CopyNames(dst, src );
0120
0121
0122
0123
0124 for(unsigned i=0 ; i < sNumSolid ; i++)
0125 {
0126 sSolidIdx = i ;
0127 solidMap[sSolidIdx] = -1 ;
0128
0129 unsigned dump_ = Dump(sSolidIdx);
0130 bool dump_solid = dump_ & 0x1 ;
0131 LOG_IF(info, dump_solid)
0132 << "sSolidIdx " << sSolidIdx
0133 << " DUMP_RIDX " << DUMP_RIDX
0134 << " DUMP_NPS " << DUMP_NPS
0135 << " dump_solid " << dump_solid
0136 ;
0137
0138 const CSGSolid* sso = src->getSolid(sSolidIdx);
0139 unsigned numSelectedPrim = src->getNumSelectedPrimInSolid(sso, elv );
0140 const std::string& solidMMLabel = src->getSolidMMLabel(sSolidIdx);
0141
0142 char sIntent = sso->getIntent();
0143
0144 LOG(LEVEL)
0145 << " sSolidIdx/sNumSolid/numSelectedPrim"
0146 << std::setw(2) << sSolidIdx
0147 << "/"
0148 << std::setw(2) << sNumSolid
0149 << "/"
0150 << std::setw(4) << numSelectedPrim
0151 << " [" << sIntent << "] "
0152 << ": "
0153 << solidMMLabel
0154 ;
0155
0156 LOG_IF(LEVEL, dump_solid) << " sso " << sso->desc() << " numSelectedPrim " << numSelectedPrim << " solidMMLabel " << solidMMLabel ;
0157
0158 if( numSelectedPrim == 0 ) continue ;
0159
0160 dst->addSolidMMLabel( solidMMLabel.c_str() );
0161
0162 unsigned dSolidIdx = dst->getNumSolid() ;
0163 if( elv == nullptr ) assert( dSolidIdx == sSolidIdx );
0164
0165 CSGSolid* dso = dst->addSolid(numSelectedPrim, sso->label );
0166 int dPrimOffset = dso->primOffset ;
0167 assert( dPrimOffset == int(dst->prim.size()) );
0168
0169 CSGSolid::CopyIntent( dso, sso );
0170
0171
0172
0173 solidMap[sSolidIdx] = dSolidIdx ;
0174
0175 #ifdef WITH_S_BB
0176 s_bb solid_bb = {} ;
0177 #else
0178 AABB solid_bb = {} ;
0179 #endif
0180
0181 copySolidPrim(solid_bb, dPrimOffset, sso);
0182
0183 unsigned numSelectedPrimCheck = dst->prim.size() - dPrimOffset ;
0184 bool numSelectedPrim_expect = numSelectedPrim == numSelectedPrimCheck ;
0185 assert( numSelectedPrim_expect );
0186 if(!numSelectedPrim_expect) std::raise(SIGINT);
0187
0188 if(identical_bbox_cheat)
0189 {
0190 dso->center_extent = sso->center_extent ;
0191 }
0192 else
0193 {
0194 #ifdef WITH_S_BB
0195 float* ce = &(dso->center_extent.x) ;
0196 solid_bb.center_extent( ce ) ;
0197 #else
0198 dso->center_extent = solid_bb.center_extent();
0199 #endif
0200 }
0201
0202 LOG_IF(LEVEL, dump_solid) << " dso " << dso->desc() ;
0203
0204 }
0205
0206 copySolidInstances();
0207 }
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221 #ifdef WITH_S_BB
0222 void CSGCopy::copySolidPrim(s_bb& solid_bb, int dPrimOffset, const CSGSolid* sso )
0223 #else
0224 void CSGCopy::copySolidPrim(AABB& solid_bb, int dPrimOffset, const CSGSolid* sso )
0225 #endif
0226 {
0227 unsigned dump_ = Dump(sSolidIdx);
0228 bool dump_prim = ( dump_ & 0x2 ) != 0u ;
0229
0230 for(int primIdx=sso->primOffset ; primIdx < sso->primOffset+sso->numPrim ; primIdx++)
0231 {
0232 const CSGPrim* spr = src->getPrim(primIdx);
0233 unsigned meshIdx = spr->meshIdx() ;
0234 unsigned repeatIdx = spr->repeatIdx() ;
0235 bool selected = elv == nullptr ? true : elv->is_set(meshIdx) ;
0236 if( selected == false ) continue ;
0237
0238 unsigned numNode = spr->numNode() ;
0239 unsigned dPrimIdx_global = dst->getNumPrim() ;
0240 unsigned dPrimIdx_local = dPrimIdx_global - dPrimOffset ;
0241
0242 CSGPrim* dpr = dst->addPrim(numNode, -1 );
0243 if( identical ) assert( dpr->nodeOffset() == spr->nodeOffset() );
0244
0245 dpr->setMeshIdx(meshIdx);
0246 dpr->setRepeatIdx(repeatIdx);
0247 dpr->setPrimIdx(dPrimIdx_local);
0248
0249 #ifdef WITH_S_BB
0250 s_bb prim_bb = {} ;
0251 #else
0252 AABB prim_bb = {} ;
0253 #endif
0254 copyPrimNodes(prim_bb, spr );
0255
0256 if(identical_bbox_cheat)
0257 {
0258 dpr->setAABB( spr->AABB() );
0259 }
0260 else
0261 {
0262 #ifdef WITH_S_BB
0263 prim_bb.write<float>( dpr->AABB_() );
0264 #else
0265 dpr->setAABB( prim_bb.data() );
0266 #endif
0267 }
0268
0269 unsigned mismatch = 0 ;
0270 std::string cf = AABB::Compare(mismatch, spr->AABB(), dpr->AABB(), 1, 1e-6 ) ;
0271 if ( dump_prim && mismatch > 0 )
0272 {
0273 std::cout << std::endl ;
0274 std::cout << "spr " << spr->desc() << std::endl ;
0275 std::cout << "dpr " << dpr->desc() << std::endl ;
0276 std::cout << "prim_bb " << std::setw(20) << " " << prim_bb.desc() << std::endl ;
0277 std::cout << " AABB::Compare " << cf << std::endl ;
0278 }
0279
0280 solid_bb.include_aabb(prim_bb.data());
0281 }
0282 }
0283
0284
0285
0286
0287
0288
0289
0290
0291 #ifdef WITH_S_BB
0292 void CSGCopy::copyPrimNodes(s_bb& prim_bb, const CSGPrim* spr )
0293 #else
0294 void CSGCopy::copyPrimNodes(AABB& prim_bb, const CSGPrim* spr )
0295 #endif
0296 {
0297 for(int nodeIdx=spr->nodeOffset() ; nodeIdx < spr->nodeOffset()+spr->numNode() ; nodeIdx++)
0298 {
0299 copyNode( prim_bb, nodeIdx );
0300 }
0301 }
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312 #ifdef WITH_S_BB
0313 void CSGCopy::copyNode(s_bb& prim_bb, unsigned nodeIdx )
0314 #else
0315 void CSGCopy::copyNode(AABB& prim_bb, unsigned nodeIdx )
0316 #endif
0317 {
0318 unsigned dump_ = Dump(sSolidIdx);
0319 bool dump_node = ( dump_ & 0x4 ) != 0u ;
0320
0321 const CSGNode* snd = src->getNode(nodeIdx);
0322 unsigned stypecode = snd->typecode();
0323 unsigned sTranIdx = snd->gtransformIdx();
0324 bool complement = snd->is_complement();
0325 bool has_planes = CSG::HasPlanes(stypecode) ;
0326 bool has_transform = sTranIdx > 0u ;
0327
0328 std::vector<float4> splanes ;
0329 src->getNodePlanes(splanes, snd);
0330
0331 unsigned dTranIdx = 0u ;
0332 const qat4* tra = nullptr ;
0333 const qat4* itr = nullptr ;
0334
0335 if(has_transform)
0336 {
0337 tra = src->getTran(sTranIdx-1u) ;
0338 itr = src->getItra(sTranIdx-1u) ;
0339 dTranIdx = 1u + dst->addTran( tra, itr ) ;
0340 }
0341
0342 CSGNode nd = {} ;
0343 CSGNode::Copy(nd, *snd );
0344
0345 CSGNode* dnd = dst->addNode(nd, &splanes, nullptr);
0346
0347 dnd->setTransformComplement( dTranIdx, complement );
0348
0349 if( identical )
0350 {
0351 assert( dnd->planeNum() == snd->planeNum() );
0352 assert( dnd->planeIdx() == snd->planeIdx() );
0353 }
0354
0355 bool negated = dnd->is_complemented_primitive();
0356 bool zero = dnd->typecode() == CSG_ZERO ;
0357 bool include_bb = negated == false && zero == false ;
0358
0359 float* naabb = dnd->AABB();
0360
0361
0362 if(include_bb)
0363 {
0364 if( identical_bbox_cheat )
0365 {
0366 LOG(debug) << " identical_bbox_cheat : do nothing : as dumb CSGNode::Copy already copies bbox ";
0367 }
0368 else
0369 {
0370 dnd->setAABBLocal() ;
0371 if(tra) tra->transform_aabb_inplace( naabb );
0372 #ifdef WITH_S_BB
0373 prim_bb.include_aabb_widen( naabb );
0374 #else
0375 prim_bb.include_aabb( naabb );
0376 #endif
0377 }
0378 }
0379
0380
0381 if(dump_node) std::cout
0382 << " nd " << std::setw(6) << nodeIdx
0383 << " tc " << std::setw(4) << stypecode
0384 << " st " << std::setw(4) << sTranIdx
0385 << " dt " << std::setw(4) << dTranIdx
0386 << " cn " << std::setw(12) << CSG::Name(stypecode)
0387 << " hp " << has_planes
0388 << " ht " << has_transform
0389 << " ng " << negated
0390 << " ib " << include_bb
0391 #ifdef WITH_S_BB
0392 << " bb " << s_bb::Desc(naabb)
0393 #else
0394 << " bb " << AABB::Desc(naabb)
0395 #endif
0396 << std::endl
0397 ;
0398 }
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417 void CSGCopy::copySolidInstances()
0418 {
0419 unsigned sNumInst = src->getNumInst();
0420
0421 LOG(LEVEL) << " sNumInst " << sNumInst ;
0422
0423 for(unsigned i=0 ; i < sNumInst ; i++)
0424 {
0425 int sInstIdx = i ;
0426 const qat4* ins = src->getInst(sInstIdx) ;
0427
0428 int ins_idx, gas_idx, sensor_identifier, sensor_index ;
0429 ins->getIdentity(ins_idx, gas_idx, sensor_identifier, sensor_index );
0430
0431 LOG(debug)
0432 << " sInstIdx " << sInstIdx
0433 << " ins_idx " << ins_idx
0434 << " gas_idx " << gas_idx
0435 << " sensor_identifier " << sensor_identifier
0436 << " sensor_index " << sensor_index
0437 ;
0438
0439 assert( ins_idx == sInstIdx );
0440 assert( gas_idx < int(sNumSolid) );
0441
0442 int sSolidIdx = gas_idx ;
0443 int dSolidIdx = solidMap[sSolidIdx] ;
0444
0445
0446 if( dSolidIdx > -1 )
0447 {
0448 const float* tr16 = ins->cdata();
0449 bool firstcall = false ;
0450 dst->addInstance(tr16, dSolidIdx, sensor_identifier, sensor_index, firstcall );
0451 }
0452 }
0453 }
0454