File indexing completed on 2026-04-09 07:49:28
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #pragma once
0021
0022 typedef enum {
0023 CSG_ZERO=0,
0024 CSG_OFFSET_LIST=4,
0025 CSG_OFFSET_LEAF=7,
0026
0027 CSG_TREE=1,
0028 CSG_UNION=1,
0029 CSG_INTERSECTION=2,
0030 CSG_DIFFERENCE=3,
0031
0032 CSG_NODE=11,
0033 CSG_LIST=11,
0034 CSG_CONTIGUOUS=11,
0035 CSG_DISCONTIGUOUS=12,
0036 CSG_OVERLAP=13,
0037
0038 CSG_LEAF=101,
0039 CSG_SPHERE=101,
0040 CSG_BOX=102,
0041 CSG_ZSPHERE=103,
0042 CSG_TUBS=104,
0043 CSG_CYLINDER=105,
0044 CSG_SLAB=106,
0045 CSG_PLANE=107,
0046 CSG_CONE=108,
0047 CSG_EXBB=109,
0048 CSG_BOX3=110,
0049 CSG_TRAPEZOID=111,
0050 CSG_CONVEXPOLYHEDRON=112,
0051 CSG_DISC=113,
0052 CSG_SEGMENT=114,
0053 CSG_ELLIPSOID=115,
0054 CSG_TORUS=116,
0055 CSG_HYPERBOLOID=117,
0056 CSG_CUBIC=118,
0057 CSG_INFCYLINDER=119,
0058 CSG_OLDCYLINDER=120,
0059 CSG_PHICUT=121,
0060 CSG_THETACUT=122,
0061 CSG_OLDCONE=123,
0062 CSG_CUTCYLINDER=124,
0063 CSG_HALFSPACE=125,
0064 CSG_NOTSUPPORTED=126,
0065 CSG_UNDEFINED=127,
0066
0067 CSG_OBSOLETE=1000,
0068 CSG_PARTLIST=1001,
0069 CSG_FLAGPARTLIST=1002,
0070 CSG_FLAGNODETREE=1003,
0071 CSG_FLAGINVISIBLE=1004,
0072 CSG_PMT=1005,
0073 CSG_ZLENS=1006,
0074 CSG_PRISM=1007,
0075 CSG_LAST=1008
0076
0077 } OpticksCSG_t ;
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 #ifndef __CUDACC__
0096
0097 #include <string>
0098 #include <sstream>
0099 #include <cstring>
0100 #include <cassert>
0101
0102 #include <vector>
0103 #include <sstream>
0104
0105
0106 static const char* CSG_ZERO_ = "zero" ;
0107
0108
0109
0110 static const char* CSG_INTERSECTION_ = "intersection" ;
0111 static const char* CSG_UNION_ = "union" ;
0112 static const char* CSG_DIFFERENCE_ = "difference" ;
0113
0114
0115 static const char* CSG_CONTIGUOUS_ = "contiguous" ;
0116 static const char* CSG_DISCONTIGUOUS_ = "discontiguous" ;
0117 static const char* CSG_OVERLAP_ = "overlap" ;
0118
0119 static const char* _CSG_CONTIGUOUS = "CSG_CONTIGUOUS" ;
0120 static const char* _CSG_DISCONTIGUOUS = "CSG_DISCONTIGUOUS" ;
0121 static const char* _CSG_OVERLAP = "CSG_OVERLAP" ;
0122 static const char* _CSG_EXBB = "CSG_EXBB" ;
0123
0124
0125
0126 static const char* CSG_SPHERE_ = "sphere" ;
0127 static const char* CSG_BOX_ = "box" ;
0128 static const char* CSG_ZSPHERE_ = "zsphere" ;
0129 static const char* CSG_TUBS_ = "tubs" ;
0130 static const char* CSG_CYLINDER_ = "cylinder" ;
0131 static const char* CSG_CUTCYLINDER_ = "cutcylinder" ;
0132 static const char* CSG_SLAB_ = "slab" ;
0133 static const char* CSG_PLANE_ = "plane" ;
0134 static const char* CSG_CONE_ = "cone" ;
0135 static const char* CSG_OLDCONE_ = "oldcone" ;
0136 static const char* CSG_BOX3_ = "box3" ;
0137 static const char* CSG_TRAPEZOID_ = "trapezoid" ;
0138 static const char* CSG_CONVEXPOLYHEDRON_ = "convexpolyhedron" ;
0139 static const char* CSG_DISC_ = "disc" ;
0140 static const char* CSG_SEGMENT_ = "segment" ;
0141 static const char* CSG_ELLIPSOID_ = "ellipsoid" ;
0142 static const char* CSG_TORUS_ = "torus" ;
0143 static const char* CSG_HYPERBOLOID_ = "hyperboloid" ;
0144 static const char* CSG_CUBIC_ = "cubic" ;
0145 static const char* CSG_INFCYLINDER_ = "infcylinder" ;
0146 static const char* CSG_OLDCYLINDER_ = "oldcylinder" ;
0147 static const char* CSG_PHICUT_ = "phicut" ;
0148 static const char* CSG_THETACUT_ = "thetacut" ;
0149 static const char* CSG_HALFSPACE_ = "halfspace" ;
0150 static const char* CSG_NOTSUPPORTED_ = "notsupported" ;
0151 static const char* CSG_UNDEFINED_ = "ERROR_undefined" ;
0152 static const char* CSG_EXBB_ = "externalbb" ;
0153
0154
0155 static const char* CSG_OBSOLETE_ = "obsolete" ;
0156 static const char* CSG_PARTLIST_ = "partlist" ;
0157 static const char* CSG_FLAGPARTLIST_ = "flagpartlist" ;
0158 static const char* CSG_FLAGNODETREE_ = "flagnodetree" ;
0159 static const char* CSG_FLAGINVISIBLE_ = "flaginvisible" ;
0160 static const char* CSG_PMT_ = "pmt" ;
0161 static const char* CSG_ZLENS_ = "zlens" ;
0162 static const char* CSG_PRISM_ = "prism" ;
0163 static const char* CSG_LAST_ = "last" ;
0164
0165
0166
0167 struct CSG
0168 {
0169 static int BooleanOperator(char op)
0170 {
0171 int typecode = CSG_ZERO ;
0172 switch(op)
0173 {
0174 case 'U': typecode = CSG_UNION ; break ;
0175 case 'I': typecode = CSG_INTERSECTION ; break ;
0176 case 'D': typecode = CSG_DIFFERENCE ; break ;
0177 }
0178 assert( typecode != CSG_ZERO );
0179 return typecode ;
0180 }
0181
0182 static int TypeCode(const char* nodename)
0183 {
0184 int tc = CSG_UNDEFINED ;
0185 if( strcmp(nodename, CSG_ZERO_) == 0) tc = CSG_ZERO ;
0186 else if(strcmp(nodename, CSG_BOX_) == 0) tc = CSG_BOX ;
0187 else if(strcmp(nodename, CSG_BOX3_) == 0) tc = CSG_BOX3 ;
0188 else if(strcmp(nodename, CSG_SPHERE_) == 0) tc = CSG_SPHERE ;
0189 else if(strcmp(nodename, CSG_ZSPHERE_) == 0) tc = CSG_ZSPHERE ;
0190 else if(strcmp(nodename, CSG_ZLENS_) == 0) tc = CSG_ZLENS ;
0191 else if(strcmp(nodename, CSG_PMT_) == 0) tc = CSG_PMT ;
0192 else if(strcmp(nodename, CSG_PRISM_) == 0) tc = CSG_PRISM ;
0193 else if(strcmp(nodename, CSG_TUBS_) == 0) tc = CSG_TUBS ;
0194 else if(strcmp(nodename, CSG_CYLINDER_) == 0) tc = CSG_CYLINDER ;
0195 else if(strcmp(nodename, CSG_CUTCYLINDER_) == 0) tc = CSG_CUTCYLINDER ;
0196 else if(strcmp(nodename, CSG_INFCYLINDER_) == 0) tc = CSG_INFCYLINDER ;
0197 else if(strcmp(nodename, CSG_OLDCYLINDER_) == 0) tc = CSG_OLDCYLINDER ;
0198 else if(strcmp(nodename, CSG_DISC_) == 0) tc = CSG_DISC ;
0199 else if(strcmp(nodename, CSG_SLAB_) == 0) tc = CSG_SLAB ;
0200 else if(strcmp(nodename, CSG_PLANE_) == 0) tc = CSG_PLANE ;
0201 else if(strcmp(nodename, CSG_CONE_) == 0) tc = CSG_CONE ;
0202 else if(strcmp(nodename, CSG_OLDCONE_) == 0) tc = CSG_OLDCONE ;
0203 else if(strcmp(nodename, CSG_TRAPEZOID_) == 0) tc = CSG_TRAPEZOID ;
0204 else if(strcmp(nodename, CSG_ELLIPSOID_) == 0) tc = CSG_ELLIPSOID ;
0205 else if(strcmp(nodename, CSG_TORUS_) == 0) tc = CSG_TORUS ;
0206 else if(strcmp(nodename, CSG_HYPERBOLOID_) == 0) tc = CSG_HYPERBOLOID ;
0207 else if(strcmp(nodename, CSG_CUBIC_) == 0) tc = CSG_CUBIC ;
0208 else if(strcmp(nodename, CSG_SEGMENT_) == 0) tc = CSG_SEGMENT ;
0209 else if(strcmp(nodename, CSG_PHICUT_) == 0) tc = CSG_PHICUT ;
0210 else if(strcmp(nodename, CSG_THETACUT_) == 0) tc = CSG_THETACUT ;
0211 else if(strcmp(nodename, CSG_HALFSPACE_) == 0) tc = CSG_HALFSPACE ;
0212 else if(strcmp(nodename, CSG_NOTSUPPORTED_) == 0) tc = CSG_NOTSUPPORTED ;
0213 else if(strcmp(nodename, CSG_DISCONTIGUOUS_) == 0) tc = CSG_DISCONTIGUOUS ;
0214 else if(strcmp(nodename, CSG_CONTIGUOUS_) == 0) tc = CSG_CONTIGUOUS ;
0215 else if(strcmp(nodename, CSG_OVERLAP_) == 0) tc = CSG_OVERLAP ;
0216 else if(strcmp(nodename, CSG_CONVEXPOLYHEDRON_) == 0) tc = CSG_CONVEXPOLYHEDRON ;
0217 else if(strcmp(nodename, CSG_INTERSECTION_) == 0) tc = CSG_INTERSECTION ;
0218 else if(strcmp(nodename, CSG_UNION_) == 0) tc = CSG_UNION ;
0219 else if(strcmp(nodename, CSG_DIFFERENCE_) == 0) tc = CSG_DIFFERENCE ;
0220 else if(strcmp(nodename, CSG_PARTLIST_) == 0) tc = CSG_PARTLIST ;
0221 else if(strcmp(nodename, CSG_FLAGPARTLIST_) == 0) tc = CSG_FLAGPARTLIST ;
0222 else if(strcmp(nodename, CSG_FLAGNODETREE_) == 0) tc = CSG_FLAGNODETREE ;
0223 else if(strcmp(nodename, CSG_FLAGINVISIBLE_) == 0) tc = CSG_FLAGINVISIBLE ;
0224 return tc ;
0225 }
0226
0227 static void TypeCodeVec(std::vector<int>& typecode, const char* names, char delim=',' )
0228 {
0229 std::stringstream nn;
0230 nn.str(names) ;
0231 std::string n ;
0232 while (std::getline(nn, n, delim))
0233 {
0234 int tc = TypeCode(n.c_str());
0235 if( tc == CSG_UNDEFINED ) continue ;
0236 typecode.push_back( tc );
0237 }
0238 }
0239
0240 static int DeMorganSwap( int type )
0241 {
0242 int t = CSG_ZERO ;
0243 switch(type)
0244 {
0245 case CSG_INTERSECTION: t = CSG_UNION ; break ;
0246 case CSG_UNION: t = CSG_INTERSECTION ; break ;
0247 default: t = CSG_ZERO ; break ;
0248 }
0249 assert( t != CSG_ZERO );
0250 return t ;
0251 }
0252
0253 static const char* Name( int type )
0254 {
0255 const char* s = NULL ;
0256 switch(type)
0257 {
0258 case CSG_ZERO: s = CSG_ZERO_ ; break ;
0259
0260
0261 case CSG_UNION: s = CSG_UNION_ ; break ;
0262 case CSG_INTERSECTION: s = CSG_INTERSECTION_ ; break ;
0263 case CSG_DIFFERENCE: s = CSG_DIFFERENCE_ ; break ;
0264
0265
0266 case CSG_CONTIGUOUS: s = CSG_CONTIGUOUS_ ; break ;
0267 case CSG_DISCONTIGUOUS: s = CSG_DISCONTIGUOUS_ ; break ;
0268 case CSG_OVERLAP: s = CSG_OVERLAP_ ; break ;
0269
0270
0271 case CSG_SPHERE: s = CSG_SPHERE_ ; break ;
0272 case CSG_BOX: s = CSG_BOX_ ; break ;
0273 case CSG_ZSPHERE: s = CSG_ZSPHERE_ ; break ;
0274 case CSG_TUBS: s = CSG_TUBS_ ; break ;
0275 case CSG_CYLINDER: s = CSG_CYLINDER_ ; break ;
0276 case CSG_CUTCYLINDER: s = CSG_CUTCYLINDER_ ; break ;
0277 case CSG_SLAB: s = CSG_SLAB_ ; break ;
0278 case CSG_PLANE: s = CSG_PLANE_ ; break ;
0279 case CSG_CONE: s = CSG_CONE_ ; break ;
0280 case CSG_OLDCONE: s = CSG_OLDCONE_ ; break ;
0281 case CSG_BOX3: s = CSG_BOX3_ ; break ;
0282 case CSG_TRAPEZOID: s = CSG_TRAPEZOID_ ; break ;
0283 case CSG_CONVEXPOLYHEDRON: s = CSG_CONVEXPOLYHEDRON_ ; break ;
0284 case CSG_DISC: s = CSG_DISC_ ; break ;
0285 case CSG_SEGMENT: s = CSG_SEGMENT_ ; break ;
0286 case CSG_ELLIPSOID: s = CSG_ELLIPSOID_ ; break ;
0287 case CSG_TORUS: s = CSG_TORUS_ ; break ;
0288 case CSG_HYPERBOLOID: s = CSG_HYPERBOLOID_ ; break ;
0289 case CSG_CUBIC: s = CSG_CUBIC_ ; break ;
0290 case CSG_INFCYLINDER: s = CSG_INFCYLINDER_ ; break ;
0291 case CSG_OLDCYLINDER: s = CSG_OLDCYLINDER_ ; break ;
0292 case CSG_PHICUT: s = CSG_PHICUT_ ; break ;
0293 case CSG_THETACUT: s = CSG_THETACUT_ ; break ;
0294 case CSG_HALFSPACE: s = CSG_HALFSPACE_ ; break ;
0295 case CSG_NOTSUPPORTED: s = CSG_NOTSUPPORTED_ ; break ;
0296 case CSG_UNDEFINED: s = CSG_UNDEFINED_ ; break ;
0297
0298 case CSG_EXBB: s = CSG_EXBB_ ; break ;
0299 case CSG_OBSOLETE: s = CSG_OBSOLETE_ ; break ;
0300 case CSG_PARTLIST: s = CSG_PARTLIST_ ; break ;
0301 case CSG_FLAGPARTLIST: s = CSG_FLAGPARTLIST_ ; break ;
0302 case CSG_FLAGNODETREE: s = CSG_FLAGNODETREE_ ; break ;
0303 case CSG_FLAGINVISIBLE: s = CSG_FLAGINVISIBLE_ ; break ;
0304 case CSG_PMT: s = CSG_PMT_ ; break ;
0305 case CSG_ZLENS: s = CSG_ZLENS_ ; break ;
0306 case CSG_PRISM: s = CSG_PRISM_ ; break ;
0307 case CSG_LAST: s = CSG_LAST_ ; break ;
0308 default: s = CSG_UNDEFINED_ ; break ;
0309 }
0310 return s ;
0311 }
0312
0313 static std::string Tag(int type)
0314 {
0315 assert( type > -1 );
0316 const char* name = Name(type);
0317 assert(strlen(name) > 2 );
0318 std::string s(name, name+2) ;
0319 return s ;
0320 }
0321 static std::string Tag(int type, bool complement)
0322 {
0323 std::stringstream ss ;
0324 ss << ( complement ? "!" : "" ) << Tag(type);
0325 std::string str = ss.str();
0326 return str ;
0327 }
0328
0329
0330 static bool Exists(int type ) { return Name(type) != NULL ; }
0331
0332
0333
0334 static bool IsTree(int type) { return (type == CSG_INTERSECTION || type == CSG_UNION || type == CSG_DIFFERENCE) ; }
0335 static bool IsOperator(int type) { return (type == CSG_INTERSECTION || type == CSG_UNION || type == CSG_DIFFERENCE) ; }
0336
0337 static bool IsList(int type){ return (type == CSG_CONTIGUOUS || type == CSG_DISCONTIGUOUS || type == CSG_OVERLAP ) ; }
0338 static bool IsCompound(int type){ return type < CSG_LEAF && type > CSG_ZERO ; }
0339 static bool IsPrimitive(int type){ return type >= CSG_LEAF ; }
0340 static bool IsLeaf(int type){ return type >= CSG_LEAF ; }
0341 static bool IsUnion(int type) { return type == CSG_UNION ; }
0342 static bool IsIntersection(int type) { return type == CSG_INTERSECTION ; }
0343 static bool IsDifference(int type) { return type == CSG_DIFFERENCE ; }
0344 static bool IsZero(int type) { return type == CSG_ZERO ; }
0345 static bool IsNotsupported(int type) { return type == CSG_NOTSUPPORTED ; }
0346
0347
0348
0349 static bool ExpectExternalBBox(int type)
0350 {
0351 return type == CSG_CONVEXPOLYHEDRON || type == CSG_CONTIGUOUS || type == CSG_DISCONTIGUOUS || type == CSG_OVERLAP ;
0352 }
0353
0354 static bool IsUnbounded(int type)
0355 {
0356 return type == CSG_PHICUT || type == CSG_THETACUT || type == CSG_INFCYLINDER || type == CSG_PLANE || type == CSG_SLAB || type == CSG_HALFSPACE ;
0357 }
0358 static bool CanZNudge(int type)
0359 {
0360 return type == CSG_CYLINDER || type == CSG_CONE || type == CSG_DISC || type == CSG_ZSPHERE ;
0361 }
0362
0363 static bool IsPositiveMask( unsigned mask )
0364 {
0365 return ( mask & Mask(CSG_DIFFERENCE) ) == 0 ;
0366 }
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402 static int OffsetType(int type)
0403 {
0404 int offset_type = CSG_ZERO ;
0405 if( type == CSG_ZERO ) offset_type = type ;
0406 else if( CSG::IsTree(type) ) offset_type = type ;
0407 else if( CSG::IsList(type) ) offset_type = type - CSG_LIST + CSG_OFFSET_LIST ;
0408 else if( CSG::IsLeaf(type) ) offset_type = type - CSG_LEAF + CSG_OFFSET_LEAF ;
0409 return offset_type ;
0410 }
0411
0412 static int TypeFromOffsetType( int offsetType )
0413 {
0414 int type = CSG_ZERO ;
0415 if( offsetType < CSG_OFFSET_LIST )
0416 {
0417 type = offsetType ;
0418 }
0419 else if( offsetType < CSG_OFFSET_LEAF )
0420 {
0421 type = offsetType - CSG_OFFSET_LIST + CSG_LIST ;
0422 }
0423 else
0424 {
0425 type = offsetType - CSG_OFFSET_LEAF + CSG_LEAF ;
0426 }
0427 return type ;
0428 }
0429
0430 static unsigned Mask(int type)
0431 {
0432
0433 int offset_type = OffsetType(type);
0434 assert( offset_type < 32 );
0435 unsigned mask = 0x1 << offset_type ;
0436 return mask ;
0437 }
0438
0439 static std::string TypeMask( unsigned mask )
0440 {
0441 std::stringstream ss ;
0442 if((mask & Mask(CSG_UNION)) != 0) ss << Tag(CSG_UNION) << " " ;
0443 if((mask & Mask(CSG_INTERSECTION)) != 0) ss << Tag(CSG_INTERSECTION) << " " ;
0444 if((mask & Mask(CSG_DIFFERENCE)) != 0) ss << Tag(CSG_DIFFERENCE) << " " ;
0445 std::string s = ss.str();
0446 return s ;
0447 }
0448
0449 static std::string MaskString(unsigned qmask)
0450 {
0451 std::stringstream ss ;
0452 for(unsigned i=0 ; i < 32 ; i++)
0453 {
0454 int type = TypeFromOffsetType(i) ;
0455 unsigned typemask = Mask(type);
0456
0457 if((qmask & typemask) != 0 )
0458 {
0459 ss << CSG::Name(type) << " " ;
0460 }
0461 }
0462 return ss.str();
0463 }
0464
0465
0466 static bool HasPlanes(int type)
0467 {
0468 return (type == CSG_TRAPEZOID || type == CSG_CONVEXPOLYHEDRON || type == CSG_SEGMENT ) ;
0469 }
0470
0471
0472 static int HintCode(const char* name)
0473 {
0474 int hintcode = CSG_ZERO ;
0475 if( strstr(name, _CSG_CONTIGUOUS) != nullptr) hintcode = CSG_CONTIGUOUS ;
0476 else if(strstr(name, _CSG_DISCONTIGUOUS) != nullptr) hintcode = CSG_DISCONTIGUOUS ;
0477 else if(strstr(name, _CSG_OVERLAP) != nullptr) hintcode = CSG_OVERLAP ;
0478 else if(strstr(name, _CSG_EXBB) != nullptr) hintcode = CSG_EXBB ;
0479 return hintcode ;
0480 }
0481 static std::string MaskDesc( unsigned mask )
0482 {
0483 std::stringstream ss ;
0484 if( mask & Mask(CSG_UNION)) ss << "union " ;
0485 if( mask & Mask(CSG_INTERSECTION)) ss << "intersection " ;
0486 if( mask & Mask(CSG_DIFFERENCE )) ss << "difference " ;
0487 return ss.str() ;
0488 }
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498 static int MonoOperator( unsigned mask )
0499 {
0500 int op = CSG_ZERO ;
0501 if( Mask(CSG_UNION) == mask ) op = CSG_UNION ;
0502 else if( Mask(CSG_INTERSECTION) == mask ) op = CSG_INTERSECTION ;
0503 else if( Mask(CSG_DIFFERENCE) == mask ) op = CSG_ZERO ;
0504 return op ;
0505 }
0506
0507
0508 };
0509
0510
0511 #endif
0512