File indexing completed on 2026-04-09 07:48:57
0001 #pragma once
0002 #include "squad.h"
0003
0004 #if defined(__CUDACC__) || defined(__CUDABE__)
0005 #define NODE_METHOD __device__
0006 #else
0007 #define NODE_METHOD
0008 #endif
0009
0010
0011 #if defined(__CUDACC__) || defined(__CUDABE__)
0012 #else
0013 #endif
0014
0015 #include "CSG_API_EXPORT.hh"
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 struct CSG_API CSGNode
0197 {
0198 quad q0 ;
0199 quad q1 ;
0200 quad q2 ;
0201 quad q3 ;
0202
0203
0204 NODE_METHOD unsigned planeIdx() const { return q0.u.x ; }
0205 NODE_METHOD unsigned planeNum() const { return q0.u.y ; }
0206 NODE_METHOD void setPlaneIdx(unsigned idx){ q0.u.x = idx ; }
0207 NODE_METHOD void setPlaneNum(unsigned num){ q0.u.y = num ; }
0208
0209
0210 NODE_METHOD unsigned subNum() const { return q0.u.x ; }
0211 NODE_METHOD unsigned subOffset() const { return q0.u.y ; }
0212
0213 NODE_METHOD void setSubNum(unsigned num){ q0.u.x = num ; }
0214 NODE_METHOD void setSubOffset(unsigned num){ q0.u.y = num ; }
0215
0216
0217
0218 #if defined(__CUDACC__) || defined(__CUDABE__)
0219 #else
0220 NODE_METHOD void getParam_( double& x , double& y , double& z , double& w , double& z1, double& z2 ) const
0221 {
0222 x = q0.f.x ;
0223 y = q0.f.y ;
0224 z = q0.f.z ;
0225 w = q0.f.w ;
0226 z1 = q1.f.x ;
0227 z2 = q1.f.y ;
0228 }
0229 #endif
0230
0231 NODE_METHOD void getParam( float& x , float& y , float& z , float& w , float& z1, float& z2 ) const
0232 {
0233 x = q0.f.x ;
0234 y = q0.f.y ;
0235 z = q0.f.z ;
0236 w = q0.f.w ;
0237 z1 = q1.f.x ;
0238 z2 = q1.f.y ;
0239 }
0240 NODE_METHOD void setParam( float x , float y , float z , float w , float z1, float z2 )
0241 {
0242 q0.f.x = x ;
0243 q0.f.y = y ;
0244 q0.f.z = z ;
0245 q0.f.w = w ;
0246 q1.f.x = z1 ;
0247 q1.f.y = z2 ;
0248 }
0249
0250
0251
0252
0253
0254
0255
0256 NODE_METHOD bool hasStrayInt() const
0257 {
0258 return ( q3.u.z == 1 || q3.u.z == 2 ) && ( q0.u.x == 3 || q0.u.x == 7 || q0.u.x == 15 ) ;
0259
0260 }
0261
0262 NODE_METHOD void setParam(const float* p)
0263 {
0264 if(!p) return ;
0265 q0.f.x = *(p+0) ;
0266 q0.f.y = *(p+1) ;
0267 q0.f.z = *(p+2) ;
0268 q0.f.w = *(p+3) ;
0269 q1.f.x = *(p+4) ;
0270 q1.f.y = *(p+5) ;
0271 }
0272
0273 NODE_METHOD void setParam_Narrow(const double* p)
0274 {
0275 if(!p) return ;
0276 q0.f.x = *(p+0) ;
0277 q0.f.y = *(p+1) ;
0278 q0.f.z = *(p+2) ;
0279 q0.f.w = *(p+3) ;
0280 q1.f.x = *(p+4) ;
0281 q1.f.y = *(p+5) ;
0282 }
0283
0284
0285
0286 NODE_METHOD void getYRange(float& y0, float& y1) const ;
0287
0288 NODE_METHOD void setAABBLocal();
0289 NODE_METHOD void setAABB( float x0, float y0, float z0, float x1, float y1, float z1){ q2.f.x = x0 ; q2.f.y = y0 ; q2.f.z = z0 ; q2.f.w = x1 ; q3.f.x = y1 ; q3.f.y = z1 ; }
0290 NODE_METHOD void setAABB( float e ){ q2.f.x = -e ; q2.f.y = -e ; q2.f.z = -e ; q2.f.w = e ; q3.f.x = e ; q3.f.y = e ; }
0291 NODE_METHOD void setAABB(const float* p)
0292 {
0293 if(!p) return ;
0294 q2.f.x = *(p+0) ;
0295 q2.f.y = *(p+1) ;
0296 q2.f.z = *(p+2) ;
0297 q2.f.w = *(p+3) ;
0298 q3.f.x = *(p+4) ;
0299 q3.f.y = *(p+5) ;
0300 }
0301
0302 NODE_METHOD void setAABB_Narrow(const double* p)
0303 {
0304 if(!p) return ;
0305 q2.f.x = *(p+0) ;
0306 q2.f.y = *(p+1) ;
0307 q2.f.z = *(p+2) ;
0308 q2.f.w = *(p+3) ;
0309 q3.f.x = *(p+4) ;
0310 q3.f.y = *(p+5) ;
0311 }
0312
0313 NODE_METHOD float* AABB() { return &q2.f.x ; }
0314 NODE_METHOD const float* AABB() const { return &q2.f.x ; }
0315 NODE_METHOD const float3 mn() const { return make_float3(q2.f.x, q2.f.y, q2.f.z) ; }
0316 NODE_METHOD const float3 mx() const { return make_float3(q2.f.w, q3.f.x, q3.f.y) ; }
0317 NODE_METHOD float extent() const
0318 {
0319 float3 d = make_float3( q2.f.w - q2.f.x, q3.f.x - q2.f.y, q3.f.y - q2.f.z );
0320 return fmaxf(fmaxf(d.x, d.y), d.z) /2.f ;
0321 }
0322
0323
0324 NODE_METHOD unsigned boundary() const { return q1.u.z ; }
0325 NODE_METHOD void setBoundary(unsigned bnd){ q1.u.z = bnd ; }
0326
0327 NODE_METHOD unsigned index() const { return q1.u.w ; }
0328 NODE_METHOD void setIndex(unsigned idx){ q1.u.w = idx ; }
0329
0330 NODE_METHOD unsigned typecode() const { return q3.u.z ; }
0331 NODE_METHOD void setTypecode(unsigned tc){ q3.u.z = tc ; }
0332
0333 NODE_METHOD unsigned typemask() const { return 1 << q3.u.z ; }
0334
0335 NODE_METHOD void zeroTransformComplement(){ q3.u.w = 0 ; }
0336 NODE_METHOD void setTransform( unsigned idx ){ setTransformComplement(idx, is_complement() ) ; }
0337 NODE_METHOD void setComplement( bool complement ){ setTransformComplement( gtransformIdx(), complement) ; }
0338 NODE_METHOD void setTransformComplement( unsigned idx, bool complement ){ q3.u.w = ( idx & 0x7fffffff ) | ( (int(complement) << 31) & 0x80000000) ; }
0339
0340 NODE_METHOD unsigned gtransformIdx() const { return q3.u.w & 0x7fffffff ; }
0341 NODE_METHOD bool is_complement() const { return q3.u.w & 0x80000000 ; }
0342
0343
0344 NODE_METHOD float radius() const { return q0.f.w ; } ;
0345 NODE_METHOD float z1() const { return q1.f.x ; } ;
0346 NODE_METHOD float z2() const { return q1.f.y ; } ;
0347
0348
0349
0350 #if defined(__CUDACC__) || defined(__CUDABE__)
0351 #else
0352 static bool IsDiff( const CSGNode& a , const CSGNode& b );
0353 static std::string Addr(unsigned repeatIdx, unsigned primIdx, unsigned partIdxRel );
0354
0355 static std::string Desc(const float* fval, int numval=6, int wid=7, int prec=1 );
0356 std::string desc() const ;
0357 std::string tag() const ;
0358
0359
0360 std::string brief() const ;
0361 static void Dump(const CSGNode* n, unsigned ni, const char* label);
0362
0363 bool is_compound() const ;
0364 bool is_operator() const ;
0365 bool is_intersection() const ;
0366 bool is_union() const ;
0367 bool is_difference() const ;
0368 bool is_primitive() const ;
0369 bool is_complemented_primitive() const ;
0370 bool is_zero() const ;
0371
0372 static unsigned AncestorTypeMask( const CSGNode* root, unsigned partIdxRel, bool dump );
0373 static unsigned Depth( unsigned partIdxRel );
0374 static bool IsOnlyUnionMask( unsigned atm );
0375 static bool IsOnlyIntersectionMask( unsigned atm );
0376 static bool IsOnlyDifferenceMask( unsigned atm );
0377
0378 static void Copy(CSGNode& b, const CSGNode& a)
0379 {
0380 b.q0.f.x = a.q0.f.x ; b.q0.f.y = a.q0.f.y ; b.q0.f.z = a.q0.f.z ; b.q0.f.w = a.q0.f.w ;
0381 b.q1.f.x = a.q1.f.x ; b.q1.f.y = a.q1.f.y ; b.q1.f.z = a.q1.f.z ; b.q1.f.w = a.q1.f.w ;
0382 b.q2.f.x = a.q2.f.x ; b.q2.f.y = a.q2.f.y ; b.q2.f.z = a.q2.f.z ; b.q2.f.w = a.q2.f.w ;
0383 b.q3.f.x = a.q3.f.x ; b.q3.f.y = a.q3.f.y ; b.q3.f.z = a.q3.f.z ; b.q3.f.w = a.q3.f.w ;
0384 }
0385
0386 static const float UNBOUNDED_DEFAULT_EXTENT ;
0387
0388 static CSGNode Union();
0389 static CSGNode Intersection();
0390 static CSGNode Difference();
0391 static CSGNode BooleanOperator(unsigned op, int num_sub);
0392
0393 static CSGNode Overlap( int num_sub, int sub_offset);
0394 static CSGNode Contiguous( int num_sub, int sub_offset);
0395 static CSGNode Discontiguous(int num_sub, int sub_offset);
0396 static CSGNode ListHeader(unsigned type, int num_sub, int sub_offset);
0397
0398
0399 static CSGNode Zero();
0400 static CSGNode Sphere(float radius);
0401 static CSGNode ZSphere(float radius, float z1, float z2);
0402 static CSGNode Cone(float r1, float z1, float r2, float z2);
0403 static CSGNode OldCone(float r1, float z1, float r2, float z2);
0404 static CSGNode Hyperboloid(float r0, float zf, float z1, float z2);
0405 static CSGNode Box3(float fx, float fy, float fz );
0406 static CSGNode Box3(float fullside);
0407 static CSGNode Plane(float nx, float ny, float nz, float d);
0408 static CSGNode Slab(float nx, float ny, float nz, float d1, float d2 ) ;
0409 static CSGNode HalfSpace(float nx, float ny, float nz, float nw );
0410
0411 static CSGNode* HalfCylinder(float nx, float ny, float nz, float nw, float radius, float z0, float z1 );
0412 static CSGNode* HalfCylinder();
0413
0414
0415 static CSGNode Cylinder( float radius, float z1, float z2) ;
0416 static CSGNode OldCylinder(float radius, float z1, float z2);
0417
0418 static CSGNode InfCylinder(float radius, float hz ) ;
0419 static CSGNode InfPhiCut( float startPhi_pi, float deltaPhi_pi ) ;
0420 static CSGNode InfThetaCut(float startTheta_pi, float deltaTheta_pi ) ;
0421 static CSGNode Disc(float px, float py, float ir, float r, float z1, float z2);
0422
0423 static CSGNode MakeDemo(const char* name);
0424 static CSGNode Make( unsigned typecode );
0425 static CSGNode Make( unsigned typecode, const float* param6, const float* aabb);
0426 static CSGNode MakeNarrow( unsigned typecode, const double* param6, const double* aabb);
0427
0428 #endif
0429
0430 };
0431
0432
0433
0434 #if defined(__CUDACC__) || defined(__CUDABE__)
0435 #else
0436
0437
0438 inline std::ostream& operator<<(std::ostream& os, const CSGNode& n)
0439 {
0440 os
0441 << std::endl
0442 << "q0 " << n.q0 << std::endl
0443 << "q1 " << n.q1 << std::endl
0444 << "q2 " << n.q2 << std::endl
0445 << "q3 " << n.q3 << std::endl
0446 ;
0447 return os;
0448 }
0449
0450 #endif
0451
0452
0453
0454