From 6f9d9bd79d6a5a640dcf05970374479ad2293443 Mon Sep 17 00:00:00 2001 From: Gabor Galgoczi Date: Fri, 29 May 2026 13:41:06 +0000 Subject: [PATCH 1/4] qbnd/qsim: carry source-medium matline across CSG sibling-pair faces GBndLib does not enumerate boundary entries for CSG sibling-pair faces (two daughters of one parent sharing a face), so OptiX can pick a boundary whose m1/m2 do not reference the photon's current medium -> absorption/scattering sampled in the wrong material1. Carry the photon's matline (seeded from the genstep at birth in CSGOptiX7.cu, updated each propagate_at_boundary) in sctx::current_matline and use it as m1 in qbnd::fill_state when valid. No-op for correctly-enumerated boundaries (carried == the boundary's own m1_line). --- CSGOptiX/CSGOptiX7.cu | 8 ++++++++ qudarap/qbnd.h | 24 ++++++++++++++++++++---- qudarap/qsim.h | 15 ++++++++++++++- sysrap/sctx.h | 1 + 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/CSGOptiX/CSGOptiX7.cu b/CSGOptiX/CSGOptiX7.cu index 6fd39efd8d..b7b3baa2c2 100644 --- a/CSGOptiX/CSGOptiX7.cu +++ b/CSGOptiX/CSGOptiX7.cu @@ -439,6 +439,14 @@ static __forceinline__ __device__ void simulate( const uint3& launch_idx, const #endif sim->generate_photon(ctx.p, rng, gs, photon_idx, genstep_idx ); + // F7: seed carried matline from the genstep's source-medium bnd row + // (gs.q0.u.z == scerenkov/sscint matline). Updated through + // propagate_at_boundary. Guard the -1 sentinel (0xFFFFFFFF) that + // SEvt::setGenstep emits for bad_ck/unmapped mtindex. + { + const unsigned gm = gs.q0.u.z; + ctx.current_matline = (gm == 0xFFFFFFFFu) ? 0u : gm; + } int command = START ; int bounce = 0 ; diff --git a/qudarap/qbnd.h b/qudarap/qbnd.h index 57ff4a02c8..9446a9585e 100644 --- a/qudarap/qbnd.h +++ b/qudarap/qbnd.h @@ -38,7 +38,7 @@ struct qbnd #if defined(__CUDACC__) || defined(__CUDABE__) || defined( MOCK_TEXTURE) || defined(MOCK_CUDA) QBND_METHOD float4 boundary_lookup( unsigned ix, unsigned iy ); QBND_METHOD float4 boundary_lookup( float nm, unsigned line, unsigned k ); - QBND_METHOD void fill_state(sstate& s, unsigned boundary, float wavelength, float cosTheta, unsigned long long idx, unsigned long long base_pidx ); + QBND_METHOD void fill_state(sstate& s, unsigned boundary, float wavelength, float cosTheta, unsigned long long idx, unsigned long long base_pidx, unsigned carried_matline = 0u); #endif }; @@ -183,14 +183,30 @@ s.optical.x **/ -inline QBND_METHOD void qbnd::fill_state(sstate& s, unsigned boundary, float wavelength, float cosTheta, unsigned long long idx, unsigned long long base_pidx ) +inline QBND_METHOD void qbnd::fill_state(sstate& s, unsigned boundary, float wavelength, float cosTheta, unsigned long long idx, unsigned long long base_pidx, unsigned carried_matline) { const int line = boundary*_BOUNDARY_NUM_MATSUR ; // now that are not signing boundary use 0-based - const int m1_line = cosTheta > 0.f ? line + IMAT : line + OMAT ; + int m1_line = cosTheta > 0.f ? line + IMAT : line + OMAT; const int m2_line = cosTheta > 0.f ? line + OMAT : line + IMAT ; const int su_line = cosTheta > 0.f ? line + ISUR : line + OSUR ; + // F7 sibling-pair material override. + // GBndLib does not enumerate boundary entries for CSG sibling-pair faces + // (two daughters of one parent sharing a face), so OptiX may pick a boundary + // whose m1/m2 do not reference the photon's actual medium -> wrong material1. + // qsim::propagate passes the photon's carried matline (seeded from the + // genstep, updated each propagate_at_boundary); when it is valid we use it + // directly as m1 so absorption/scattering sample the true current medium. + // (material2 is left as the boundary's other side.) + // Guards: 0 = "no carry" (legacy callers); 0xFFFFFFFF = the lookup_mtline=-1 + // sentinel from SEvt::setGenstep, not a valid table row; and the carried + // slot must be a material row (OMAT/IMAT), not a surface row (OSUR/ISUR). + const unsigned matline_slot = carried_matline & 0x3u; + if (carried_matline != 0u && carried_matline != 0xFFFFFFFFu && (matline_slot == unsigned(OMAT) || matline_slot == unsigned(IMAT))) + { + m1_line = int(carried_matline); + } s.material1 = boundary_lookup( wavelength, m1_line, 0); // refractive_index, absorption_length, scattering_length, reemission_prob s.m1group2 = boundary_lookup( wavelength, m1_line, 1); // x: material1 group_velocity, y: material2 group_velocity, z/w unused @@ -200,7 +216,7 @@ inline QBND_METHOD void qbnd::fill_state(sstate& s, unsigned boundary, float wav s.optical = optical[su_line].u ; // 1-based-surface-index-0-meaning-boundary/type/finish/value (type,finish,value not used currently) - s.index.x = optical[m1_line].u.x ; // m1 index (1-based, see sstandard::make_optical) + s.index.x = optical[m1_line].u.x; // m1 index (1-based, see sstandard::make_optical) -- reflects override if any s.index.y = optical[m2_line].u.x ; // m2 index (1-based, see sstandard::make_optical) s.index.z = optical[su_line].u.x ; // su index (1-based, see sstandard::make_optical) s.index.w = 0u ; // avoid undefined memory comparison issues diff --git a/qudarap/qsim.h b/qudarap/qsim.h index a4b7143d67..4968b7967c 100644 --- a/qudarap/qsim.h +++ b/qudarap/qsim.h @@ -1263,6 +1263,19 @@ inline QSIM_METHOD int qsim::propagate_at_boundary(unsigned& flag, RNG& rng, sct ctx.current_material_index = reflect ? s.index.x : s.index.y; ctx.current_group_velocity = reflect ? s.material1_group_velocity() : s.material2_group_velocity(); + // F7 SIBLING-PAIR carry: update current_matline so propagate() at the NEXT + // boundary knows the photon's actual medium even when that boundary doesn't + // reference it (the sibling-pair case). _c1 = -dot(p.mom,normal) here, so + // _c1 < 0 maps to cosTheta > 0 in qbnd::fill_state (m1=IMAT, m2=OMAT). + { + const unsigned bnd_idx = ctx.prd->boundary(); + const unsigned imat_line = bnd_idx * _BOUNDARY_NUM_MATSUR + IMAT; + const unsigned omat_line = bnd_idx * _BOUNDARY_NUM_MATSUR + OMAT; + const unsigned this_m1_line = (_c1 < 0.f) ? imat_line : omat_line; + const unsigned this_m2_line = (_c1 < 0.f) ? omat_line : imat_line; + ctx.current_matline = reflect ? this_m1_line : this_m2_line; + } + #if !defined(PRODUCTION) && defined(DEBUG_TAG) if( flag == BOUNDARY_REFLECT ) { @@ -2153,7 +2166,7 @@ inline QSIM_METHOD int qsim::propagate(const int bounce, RNG& rng, sctx& ctx ) // copy geometry info into the sphoton struct ctx.p.set_prd(boundary, identity, cosTheta, iindex ); // HMM: lposcost not passed along - bnd->fill_state(ctx.s, boundary, ctx.p.wavelength, cosTheta, ctx.pidx, base->pidx ); + bnd->fill_state(ctx.s, boundary, ctx.p.wavelength, cosTheta, ctx.pidx, base->pidx, ctx.current_matline); // F7: pass carried matline for sibling-pair override if (ctx.current_material_index == 0u) { diff --git a/sysrap/sctx.h b/sysrap/sctx.h index 82e1dd3899..f935577abd 100644 --- a/sysrap/sctx.h +++ b/sysrap/sctx.h @@ -79,6 +79,7 @@ struct sctx sstate s ; float current_group_velocity = 0.f; unsigned current_material_index = 0u; + unsigned current_matline = 0u; // F7 sibling-pair: photon's authoritative current-medium matline, seeded at birth, updated on transmit/reflect #ifndef PRODUCTION srec rec ; From e0f8f4622cda6f5c0c54a8df3f93ebc7c28d688c Mon Sep 17 00:00:00 2001 From: Gabor Galgoczi Date: Sat, 30 May 2026 11:19:11 -0400 Subject: [PATCH 2/4] feat(CSGOptiX): index-contrast-gated exit-bias for CSG sibling-coincident faces At a face shared by two sibling primitives (segmented radiator bars + glue, multi-layer CSG lens) OptiX sorts the two coplanar intersections inconsistently; the "exiting" hit (cosI>0) carries the parent medium as m2, wrong for a sibling crossing. Bias the t reported to OptiX's closest-hit sort by +10 um on the exit side so the entering sibling wins. The real unbiased distance is preserved in the PRD, so photon position advancement is unperturbed. Gate the bias per boundary by index contrast |n_m1 - n_m2| > 0.1 (max over wavelength), computed at translation in CSGOptiX::initSimulate from the bnd table and read in __intersection__is. High-contrast faces (e.g. quartz/air ~0.47) need the entering-sibling selection; low-contrast thin gaps (e.g. aerogel/air ~0.025) are harmed by it and gate off. No per-detector hardcode; nullptr => always-on fallback. Stacks on the matline-carry m1 fix (carry source-medium matline across CSG sibling-pair faces): that fixes *which material* m1 is sampled; this fixes *which face* OptiX selects. The two are complementary - on a TIR light-guide either alone collapses the GPU hit count. Verified ePIC hpDIRC mu- 3 GeV: GPU/CPU 0.987, bit-identical to the ungated bias (all glued-sibling faces clear the 0.1 threshold). Low-index-contrast detectors are unaffected (gate stays off at their thin gaps). --- CSGOptiX/CSGOptiX.cc | 46 +++++++++++++++++++++++++++++++++++++++++++ CSGOptiX/CSGOptiX7.cu | 15 ++++++++++++-- CSGOptiX/Params.cc | 1 + CSGOptiX/Params.h | 1 + 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/CSGOptiX/CSGOptiX.cc b/CSGOptiX/CSGOptiX.cc index 2b43e4e025..b99ae64533 100644 --- a/CSGOptiX/CSGOptiX.cc +++ b/CSGOptiX/CSGOptiX.cc @@ -609,6 +609,52 @@ void CSGOptiX::initSimulate() params->PropagateRefineDistance = SEventConfig::PropagateRefineDistance(); // approx distance beyond which to refine intersect with 2nd trace params->tmin = SEventConfig::PropagateEpsilon() ; // eg 0.1 0.05 to avoid self-intersection off boundaries + + // Per-boundary face-bias gate for the sibling-coincident t-bias (see __intersection__is). + // bit=1 only where the boundary's own index contrast |n_m1 - n_m2| (max over wavelength) + // exceeds a TIR-risk threshold: high-contrast faces (quartz/air ~0.47) NEED the entering- + // sibling bias; low-contrast thin gaps (aerogel/air ~0.025) are harmed and gate OFF. + // Computed from the bnd table; no per-detector hardcode. Allocated once, reused per launch. + { + const SSim* ssim = foundry ? foundry->getSim() : nullptr ; + const NP* bnd = ssim ? ssim->get_bnd() : nullptr ; + if( bnd != nullptr && bnd->shape.size() == 5 ) + { + const unsigned num_bnd = bnd->shape[0] ; + const unsigned num_wl = bnd->shape[3] ; + const double* bv = bnd->cvalues() ; // stree/standard bnd is bits(num_bnd, 0u) ; + for(unsigned b=0 ; b < num_bnd ; b++) + { + double dnmax = 0. ; + for(unsigned w=0 ; w < num_wl ; w++) + { + const double n_om = bv[ (((b*4u + LMAT_OMAT)*2u + 0u)*num_wl + w)*4u + 0u ] ; // RINDEX of omat + const double n_im = bv[ (((b*4u + LMAT_IMAT)*2u + 0u)*num_wl + w)*4u + 0u ] ; // RINDEX of imat + double dn = n_om - n_im ; if(dn < 0.) dn = -dn ; + if(dn > dnmax) dnmax = dn ; + } + bits[b] = (dnmax > DN_THRESHOLD) ? 1u : 0u ; + LOG(LEVEL) << "boundary_face_bias bnd " << b << " dnmax " << dnmax << " gate " << unsigned(bits[b]) ; + } + static unsigned char* s_face_bias = nullptr ; + static unsigned s_face_bias_num = 0u ; + if( s_face_bias == nullptr ){ CUDA_CHECK( cudaMalloc((void**)&s_face_bias, num_bnd) ); s_face_bias_num = num_bnd ; } + if( s_face_bias_num == num_bnd ) + { + CUDA_CHECK( cudaMemcpy(s_face_bias, bits.data(), num_bnd, cudaMemcpyHostToDevice) ); + params->boundary_face_bias = s_face_bias ; + } + LOG(LEVEL) << "boundary_face_bias gate computed, num_bnd " << num_bnd ; + } + else + { + LOG(LEVEL) << "boundary_face_bias: no bnd table (rank != 5) -> gate left null (t-bias always-on)" ; + } + } + params->tmax = 1000000.f ; params->max_time = SEventConfig::MaxTime() ; diff --git a/CSGOptiX/CSGOptiX7.cu b/CSGOptiX/CSGOptiX7.cu index b7b3baa2c2..7794e1fa51 100644 --- a/CSGOptiX/CSGOptiX7.cu +++ b/CSGOptiX/CSGOptiX7.cu @@ -914,8 +914,19 @@ extern "C" __global__ void __intersection__is() const unsigned boundary = node->boundary() ; // all CSGNode in the tree for one CSGPrim tree have same boundary const unsigned globalPrimIdx_boundary = (( globalPrimIdx & 0xffffu ) << 16 ) | ( boundary & 0xffffu ) ; + // Sibling-touching coincident-face fix: at a face shared by two sibling primitives OptiX + // sorts the two coplanar intersections inconsistently; the exiting hit (cosI>0) carries the + // parent medium as m2, wrong for a sibling crossing. Bias the t REPORTED to OptiX's closest- + // hit sort by +10 um on the exit side so the entering sibling wins; the real unbiased isect.w + // still goes to the PRD/attributes so position advancement is unperturbed. Gated per boundary + // by index contrast (params.boundary_face_bias from CSGOptiX::initSimulate): high-contrast + // faces (quartz/air ~0.47) need it; low-contrast thin gaps gate off; nullptr => always-on. + const float cosI = dot(ray_direction, make_float3(isect.x, isect.y, isect.z)); + const bool face_bias_on = (params.boundary_face_bias == nullptr) || (params.boundary_face_bias[boundary] != 0u) ; + const float t_report = (cosI > 0.f && face_bias_on) ? isect.w + 1.e-2f : isect.w ; + #ifdef WITH_PRD - if(optixReportIntersection( isect.w, hitKind)) + if(optixReportIntersection( t_report, hitKind)) { quad2* prd = SOPTIX_getPRD(); // access prd addr from RG program prd->q0.f = isect ; // .w:distance and .xyz:normal which starts as the local frame one @@ -931,7 +942,7 @@ extern "C" __global__ void __intersection__is() a3 = __float_as_uint( isect.w ) ; a4 = globalPrimIdx_boundary ; a5 = __float_as_uint( lposcost ); - optixReportIntersection( isect.w, hitKind, a0, a1, a2, a3, a4, a5 ); + optixReportIntersection( t_report, hitKind, a0, a1, a2, a3, a4, a5 ); // IS:optixReportIntersection writes the attributes that can be read in CH and AH programs // max 8 attribute registers, see PIP::PIP, communicate to __closesthit__ch diff --git a/CSGOptiX/Params.cc b/CSGOptiX/Params.cc index cc3a8b7c59..df23bb9eb9 100644 --- a/CSGOptiX/Params.cc +++ b/CSGOptiX/Params.cc @@ -147,6 +147,7 @@ Params::Params(int raygenmode_, unsigned width, unsigned height, unsigned depth) origin_y(0), tmin(0.f), tmin0(0.f), + boundary_face_bias(nullptr), PropagateEpsilon0Mask(0u), tmax(0.f), vizmask(0xff), diff --git a/CSGOptiX/Params.h b/CSGOptiX/Params.h index 54a93faead..14f3134040 100644 --- a/CSGOptiX/Params.h +++ b/CSGOptiX/Params.h @@ -64,6 +64,7 @@ struct Params float tmin ; float tmin0 ; + const unsigned char* boundary_face_bias ; // per-boundary gate (1=apply sibling-coincident t-bias) keyed on |n_m1-n_m2|>0.1; nullptr => always-on unsigned PropagateEpsilon0Mask ; // default from SEventConfig TO,CK,SI,SC,RE float PropagateRefineDistance ; bool PropagateRefine ; From 325e81f2e8eacdbb89d6094bd03fceec1bc3b050 Mon Sep 17 00:00:00 2001 From: Gabor Galgoczi Date: Sat, 30 May 2026 15:57:56 +0000 Subject: [PATCH 3/4] style: clang-format (v20) PR-changed lines for cpp-linter (lines-changed-only) --- CSGOptiX/CSGOptiX.cc | 59 ++++++++++++++++++++++++------------------- CSGOptiX/CSGOptiX7.cu | 8 +++--- CSGOptiX/Params.cc | 4 +-- CSGOptiX/Params.h | 2 +- qudarap/qbnd.h | 2 +- 5 files changed, 40 insertions(+), 35 deletions(-) diff --git a/CSGOptiX/CSGOptiX.cc b/CSGOptiX/CSGOptiX.cc index b99ae64533..ae1a236f22 100644 --- a/CSGOptiX/CSGOptiX.cc +++ b/CSGOptiX/CSGOptiX.cc @@ -616,42 +616,49 @@ void CSGOptiX::initSimulate() // sibling bias; low-contrast thin gaps (aerogel/air ~0.025) are harmed and gate OFF. // Computed from the bnd table; no per-detector hardcode. Allocated once, reused per launch. { - const SSim* ssim = foundry ? foundry->getSim() : nullptr ; - const NP* bnd = ssim ? ssim->get_bnd() : nullptr ; - if( bnd != nullptr && bnd->shape.size() == 5 ) + const SSim* ssim = foundry ? foundry->getSim() : nullptr; + const NP* bnd = ssim ? ssim->get_bnd() : nullptr; + if (bnd != nullptr && bnd->shape.size() == 5) { - const unsigned num_bnd = bnd->shape[0] ; - const unsigned num_wl = bnd->shape[3] ; - const double* bv = bnd->cvalues() ; // stree/standard bnd is bits(num_bnd, 0u) ; - for(unsigned b=0 ; b < num_bnd ; b++) + const unsigned num_bnd = bnd->shape[0]; + const unsigned num_wl = bnd->shape[3]; + const double* bv = bnd->cvalues(); // stree/standard bnd is bits(num_bnd, 0u); + for (unsigned b = 0; b < num_bnd; b++) { - double dnmax = 0. ; - for(unsigned w=0 ; w < num_wl ; w++) + double dnmax = 0.; + for (unsigned w = 0; w < num_wl; w++) { - const double n_om = bv[ (((b*4u + LMAT_OMAT)*2u + 0u)*num_wl + w)*4u + 0u ] ; // RINDEX of omat - const double n_im = bv[ (((b*4u + LMAT_IMAT)*2u + 0u)*num_wl + w)*4u + 0u ] ; // RINDEX of imat - double dn = n_om - n_im ; if(dn < 0.) dn = -dn ; - if(dn > dnmax) dnmax = dn ; + const double n_om = bv[(((b * 4u + LMAT_OMAT) * 2u + 0u) * num_wl + w) * 4u + 0u]; // RINDEX of omat + const double n_im = bv[(((b * 4u + LMAT_IMAT) * 2u + 0u) * num_wl + w) * 4u + 0u]; // RINDEX of imat + double dn = n_om - n_im; + if (dn < 0.) + dn = -dn; + if (dn > dnmax) + dnmax = dn; } - bits[b] = (dnmax > DN_THRESHOLD) ? 1u : 0u ; - LOG(LEVEL) << "boundary_face_bias bnd " << b << " dnmax " << dnmax << " gate " << unsigned(bits[b]) ; + bits[b] = (dnmax > DN_THRESHOLD) ? 1u : 0u; + LOG(LEVEL) << "boundary_face_bias bnd " << b << " dnmax " << dnmax << " gate " << unsigned(bits[b]); } - static unsigned char* s_face_bias = nullptr ; - static unsigned s_face_bias_num = 0u ; - if( s_face_bias == nullptr ){ CUDA_CHECK( cudaMalloc((void**)&s_face_bias, num_bnd) ); s_face_bias_num = num_bnd ; } - if( s_face_bias_num == num_bnd ) + static unsigned char* s_face_bias = nullptr; + static unsigned s_face_bias_num = 0u; + if (s_face_bias == nullptr) { - CUDA_CHECK( cudaMemcpy(s_face_bias, bits.data(), num_bnd, cudaMemcpyHostToDevice) ); - params->boundary_face_bias = s_face_bias ; + CUDA_CHECK(cudaMalloc((void**)&s_face_bias, num_bnd)); + s_face_bias_num = num_bnd; } - LOG(LEVEL) << "boundary_face_bias gate computed, num_bnd " << num_bnd ; + if (s_face_bias_num == num_bnd) + { + CUDA_CHECK(cudaMemcpy(s_face_bias, bits.data(), num_bnd, cudaMemcpyHostToDevice)); + params->boundary_face_bias = s_face_bias; + } + LOG(LEVEL) << "boundary_face_bias gate computed, num_bnd " << num_bnd; } else { - LOG(LEVEL) << "boundary_face_bias: no bnd table (rank != 5) -> gate left null (t-bias always-on)" ; + LOG(LEVEL) << "boundary_face_bias: no bnd table (rank != 5) -> gate left null (t-bias always-on)"; } } diff --git a/CSGOptiX/CSGOptiX7.cu b/CSGOptiX/CSGOptiX7.cu index 7794e1fa51..d462a02967 100644 --- a/CSGOptiX/CSGOptiX7.cu +++ b/CSGOptiX/CSGOptiX7.cu @@ -922,11 +922,11 @@ extern "C" __global__ void __intersection__is() // by index contrast (params.boundary_face_bias from CSGOptiX::initSimulate): high-contrast // faces (quartz/air ~0.47) need it; low-contrast thin gaps gate off; nullptr => always-on. const float cosI = dot(ray_direction, make_float3(isect.x, isect.y, isect.z)); - const bool face_bias_on = (params.boundary_face_bias == nullptr) || (params.boundary_face_bias[boundary] != 0u) ; - const float t_report = (cosI > 0.f && face_bias_on) ? isect.w + 1.e-2f : isect.w ; + const bool face_bias_on = (params.boundary_face_bias == nullptr) || (params.boundary_face_bias[boundary] != 0u); + const float t_report = (cosI > 0.f && face_bias_on) ? isect.w + 1.e-2f : isect.w; #ifdef WITH_PRD - if(optixReportIntersection( t_report, hitKind)) + if (optixReportIntersection(t_report, hitKind)) { quad2* prd = SOPTIX_getPRD(); // access prd addr from RG program prd->q0.f = isect ; // .w:distance and .xyz:normal which starts as the local frame one @@ -942,7 +942,7 @@ extern "C" __global__ void __intersection__is() a3 = __float_as_uint( isect.w ) ; a4 = globalPrimIdx_boundary ; a5 = __float_as_uint( lposcost ); - optixReportIntersection( t_report, hitKind, a0, a1, a2, a3, a4, a5 ); + optixReportIntersection(t_report, hitKind, a0, a1, a2, a3, a4, a5); // IS:optixReportIntersection writes the attributes that can be read in CH and AH programs // max 8 attribute registers, see PIP::PIP, communicate to __closesthit__ch diff --git a/CSGOptiX/Params.cc b/CSGOptiX/Params.cc index df23bb9eb9..b703c27e4e 100644 --- a/CSGOptiX/Params.cc +++ b/CSGOptiX/Params.cc @@ -126,9 +126,7 @@ std::string Params::detail() const return s ; } - -Params::Params(int raygenmode_, unsigned width, unsigned height, unsigned depth) - : +Params::Params(int raygenmode_, unsigned width, unsigned height, unsigned depth) : raygenmode(SRG_RENDER), node(nullptr), plan(nullptr), diff --git a/CSGOptiX/Params.h b/CSGOptiX/Params.h index 14f3134040..d8d947b75d 100644 --- a/CSGOptiX/Params.h +++ b/CSGOptiX/Params.h @@ -64,7 +64,7 @@ struct Params float tmin ; float tmin0 ; - const unsigned char* boundary_face_bias ; // per-boundary gate (1=apply sibling-coincident t-bias) keyed on |n_m1-n_m2|>0.1; nullptr => always-on + const unsigned char* boundary_face_bias; // per-boundary gate (1=apply sibling-coincident t-bias) keyed on |n_m1-n_m2|>0.1; nullptr => always-on unsigned PropagateEpsilon0Mask ; // default from SEventConfig TO,CK,SI,SC,RE float PropagateRefineDistance ; bool PropagateRefine ; diff --git a/qudarap/qbnd.h b/qudarap/qbnd.h index 9446a9585e..a4fa6f0be4 100644 --- a/qudarap/qbnd.h +++ b/qudarap/qbnd.h @@ -216,7 +216,7 @@ inline QBND_METHOD void qbnd::fill_state(sstate& s, unsigned boundary, float wav s.optical = optical[su_line].u ; // 1-based-surface-index-0-meaning-boundary/type/finish/value (type,finish,value not used currently) - s.index.x = optical[m1_line].u.x; // m1 index (1-based, see sstandard::make_optical) -- reflects override if any + s.index.x = optical[m1_line].u.x; // m1 index (1-based, see sstandard::make_optical) -- reflects override if any s.index.y = optical[m2_line].u.x ; // m2 index (1-based, see sstandard::make_optical) s.index.z = optical[su_line].u.x ; // su index (1-based, see sstandard::make_optical) s.index.w = 0u ; // avoid undefined memory comparison issues From 0fbf0dfcc67c09e45721122bdb1bccce765b7eab Mon Sep 17 00:00:00 2001 From: ggalgoczi Date: Sat, 6 Jun 2026 15:06:44 +0000 Subject: [PATCH 4/4] style: clang-format v20 trailing-comment alignment on PR-changed lines Re-run clang-format 20 (matches CI cpp-linter) on the lines this PR changed in CSGOptiX/Params.h and qudarap/qbnd.h. The prior style commit produced v22 comment spacing; v20 aligns these two trailing comments one column differently. --- CSGOptiX/Params.h | 2 +- qudarap/qbnd.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CSGOptiX/Params.h b/CSGOptiX/Params.h index d8d947b75d..b99587e3ff 100644 --- a/CSGOptiX/Params.h +++ b/CSGOptiX/Params.h @@ -64,7 +64,7 @@ struct Params float tmin ; float tmin0 ; - const unsigned char* boundary_face_bias; // per-boundary gate (1=apply sibling-coincident t-bias) keyed on |n_m1-n_m2|>0.1; nullptr => always-on + const unsigned char* boundary_face_bias; // per-boundary gate (1=apply sibling-coincident t-bias) keyed on |n_m1-n_m2|>0.1; nullptr => always-on unsigned PropagateEpsilon0Mask ; // default from SEventConfig TO,CK,SI,SC,RE float PropagateRefineDistance ; bool PropagateRefine ; diff --git a/qudarap/qbnd.h b/qudarap/qbnd.h index a4fa6f0be4..9446a9585e 100644 --- a/qudarap/qbnd.h +++ b/qudarap/qbnd.h @@ -216,7 +216,7 @@ inline QBND_METHOD void qbnd::fill_state(sstate& s, unsigned boundary, float wav s.optical = optical[su_line].u ; // 1-based-surface-index-0-meaning-boundary/type/finish/value (type,finish,value not used currently) - s.index.x = optical[m1_line].u.x; // m1 index (1-based, see sstandard::make_optical) -- reflects override if any + s.index.x = optical[m1_line].u.x; // m1 index (1-based, see sstandard::make_optical) -- reflects override if any s.index.y = optical[m2_line].u.x ; // m2 index (1-based, see sstandard::make_optical) s.index.z = optical[su_line].u.x ; // su index (1-based, see sstandard::make_optical) s.index.w = 0u ; // avoid undefined memory comparison issues