File indexing completed on 2026-04-09 07:48:57
0001 #if defined(__CUDACC__) || defined(__CUDABE__)
0002 #else
0003
0004 #include <iostream>
0005 #include <sstream>
0006 #include <iomanip>
0007
0008 #include "scuda.h"
0009 #include "sgeomtools.h"
0010 #include "SThetaCut.hh"
0011 #include "SPhiCut.hh"
0012 #include "OpticksCSG.h"
0013 #include "SLOG.hh"
0014
0015 #include "CSGNode.h"
0016
0017
0018
0019 const float CSGNode::UNBOUNDED_DEFAULT_EXTENT = 0.f ;
0020
0021
0022 bool CSGNode::IsDiff( const CSGNode& a , const CSGNode& b )
0023 {
0024 return false ;
0025 }
0026
0027 std::string CSGNode::Addr(unsigned repeatIdx, unsigned primIdx, unsigned partIdxRel )
0028 {
0029 int wid = 10 ;
0030 std::stringstream ss ;
0031 ss
0032 << std::setw(2) << std::setfill('0') << repeatIdx
0033 << "/"
0034 << std::setw(3) << std::setfill('0') << primIdx
0035 << "/"
0036 << std::setw(3) << std::setfill('0') << partIdxRel
0037 ;
0038 std::string s = ss.str();
0039 std::stringstream tt ;
0040 tt << std::setw(wid) << s ;
0041 std::string t = tt.str();
0042 return t ;
0043 }
0044
0045 std::string CSGNode::Desc(const float* fval, int numval, int wid, int prec )
0046 {
0047 std::stringstream ss ;
0048 for(int p=0 ; p < numval ; p++)
0049 ss << std::fixed << std::setw(wid) << std::setprecision(prec) << *(fval+p) << " " ;
0050 std::string s = ss.str();
0051 return s ;
0052 }
0053
0054 std::string CSGNode::desc() const
0055 {
0056 const float* aabb = AABB();
0057 unsigned trIdx = gtransformIdx();
0058 bool compound = is_compound();
0059
0060 int subNum_ = compound ? subNum() : -1 ;
0061 int subOffset_ = compound ? subOffset() : -1 ;
0062
0063 std::stringstream ss ;
0064 ss
0065 << "CSGNode "
0066 << std::setw(5) << index()
0067 << " "
0068 << brief()
0069 << " aabb: " << Desc( aabb, 6, 7, 1 )
0070 << " trIdx: " << std::setw(5) << trIdx
0071 << " subNum: " << std::setw(3) << subNum_
0072 << " subOffset:: " << std::setw(3) << subOffset_
0073 ;
0074
0075 std::string s = ss.str();
0076 return s ;
0077 }
0078
0079 std::string CSGNode::tag() const
0080 {
0081 return CSG::Tag((OpticksCSG_t)typecode()) ;
0082 }
0083
0084
0085 std::string CSGNode::brief() const
0086 {
0087 std::stringstream ss ;
0088 ss
0089 << ( is_complement() ? "!" : " " )
0090 << tag()
0091 ;
0092 std::string s = ss.str();
0093 return s ;
0094 }
0095
0096
0097
0098 void CSGNode::Dump(const CSGNode* n_, unsigned ni, const char* label)
0099 {
0100 std::cout << "CSGNode::Dump ni " << ni << " " ;
0101 if(label) std::cout << label ;
0102 std::cout << std::endl ;
0103
0104 for(unsigned i=0 ; i < ni ; i++)
0105 {
0106 const CSGNode* n = n_ + i ;
0107 std::cout << "(" << i << ")" << std::endl ;
0108 std::cout
0109 << " node.q0.f.xyzw ( "
0110 << std::setw(10) << std::fixed << std::setprecision(3) << n->q0.f.x
0111 << std::setw(10) << std::fixed << std::setprecision(3) << n->q0.f.y
0112 << std::setw(10) << std::fixed << std::setprecision(3) << n->q0.f.z
0113 << std::setw(10) << std::fixed << std::setprecision(3) << n->q0.f.w
0114 << " ) "
0115 << std::endl
0116 << " node.q1.f.xyzw ( "
0117 << std::setw(10) << std::fixed << std::setprecision(3) << n->q1.f.x
0118 << std::setw(10) << std::fixed << std::setprecision(3) << n->q1.f.y
0119 << std::setw(10) << std::fixed << std::setprecision(3) << n->q1.f.z
0120 << std::setw(10) << std::fixed << std::setprecision(3) << n->q1.f.w
0121 << " ) "
0122 << std::endl
0123 << " node.q2.f.xyzw ( "
0124 << std::setw(10) << std::fixed << std::setprecision(3) << n->q2.f.x
0125 << std::setw(10) << std::fixed << std::setprecision(3) << n->q2.f.y
0126 << std::setw(10) << std::fixed << std::setprecision(3) << n->q2.f.z
0127 << std::setw(10) << std::fixed << std::setprecision(3) << n->q2.f.w
0128 << " ) "
0129 << std::endl
0130 << " node.q3.f.xyzw ( "
0131 << std::setw(10) << std::fixed << std::setprecision(3) << n->q3.f.x
0132 << std::setw(10) << std::fixed << std::setprecision(3) << n->q3.f.y
0133 << std::setw(10) << std::fixed << std::setprecision(3) << n->q3.f.z
0134 << std::setw(10) << std::fixed << std::setprecision(3) << n->q3.f.w
0135 << " ) "
0136 << std::endl
0137 ;
0138
0139 std::cout
0140 << " node.q0.i.xyzw ( "
0141 << std::setw(10) << n->q0.i.x
0142 << std::setw(10) << n->q0.i.y
0143 << std::setw(10) << n->q0.i.z
0144 << std::setw(10) << n->q0.i.w
0145 << " ) "
0146 << std::endl
0147 << " node.q1.i.xyzw ( "
0148 << std::setw(10) << n->q1.i.x
0149 << std::setw(10) << n->q1.i.y
0150 << std::setw(10) << n->q1.i.z
0151 << std::setw(10) << n->q1.i.w
0152 << " ) "
0153 << std::endl
0154 << " node.q2.i.xyzw ( "
0155 << std::setw(10) << n->q2.i.x
0156 << std::setw(10) << n->q2.i.y
0157 << std::setw(10) << n->q2.i.z
0158 << std::setw(10) << n->q2.i.w
0159 << " ) "
0160 << std::endl
0161 << " node.q3.i.xyzw ( "
0162 << std::setw(10) << n->q3.i.x
0163 << std::setw(10) << n->q3.i.y
0164 << std::setw(10) << n->q3.i.z
0165 << std::setw(10) << n->q3.i.w
0166 << " ) "
0167 << std::endl
0168 ;
0169 }
0170 }
0171
0172
0173
0174 CSGNode CSGNode::Union(){ return CSGNode::BooleanOperator(CSG_UNION,-1) ; }
0175 CSGNode CSGNode::Intersection(){ return CSGNode::BooleanOperator(CSG_INTERSECTION,-1) ; }
0176 CSGNode CSGNode::Difference(){ return CSGNode::BooleanOperator(CSG_DIFFERENCE,-1) ; }
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 CSGNode CSGNode::BooleanOperator(unsigned op, int num_sub)
0189 {
0190 assert( CSG::IsOperator((OpticksCSG_t)op) );
0191 CSGNode nd = {} ;
0192 nd.setTypecode(op) ;
0193 if( num_sub > 0 )
0194 {
0195 nd.setSubNum(num_sub);
0196 }
0197 return nd ;
0198 }
0199
0200 CSGNode CSGNode::Overlap( int num_sub, int sub_offset){ return CSGNode::ListHeader( CSG_OVERLAP, num_sub, sub_offset ); }
0201 CSGNode CSGNode::Contiguous( int num_sub, int sub_offset){ return CSGNode::ListHeader( CSG_CONTIGUOUS, num_sub, sub_offset ); }
0202 CSGNode CSGNode::Discontiguous(int num_sub, int sub_offset){ return CSGNode::ListHeader( CSG_DISCONTIGUOUS, num_sub, sub_offset ); }
0203
0204 CSGNode CSGNode::ListHeader(unsigned type, int num_sub, int sub_offset )
0205 {
0206 CSGNode nd = {} ;
0207 switch(type)
0208 {
0209 case CSG_OVERLAP: nd.setTypecode(CSG_OVERLAP) ; break ;
0210 case CSG_CONTIGUOUS: nd.setTypecode(CSG_CONTIGUOUS) ; break ;
0211 case CSG_DISCONTIGUOUS: nd.setTypecode(CSG_DISCONTIGUOUS) ; break ;
0212 default: assert(0) ;
0213 }
0214 if(num_sub > 0)
0215 {
0216 nd.setSubNum(num_sub);
0217 }
0218 if(sub_offset > 0)
0219 {
0220 nd.setSubOffset(sub_offset);
0221 }
0222 return nd ;
0223 }
0224
0225
0226
0227 bool CSGNode::is_compound() const
0228 {
0229 return CSG::IsCompound((OpticksCSG_t)typecode()) ;
0230 }
0231 bool CSGNode::is_operator() const
0232 {
0233 unsigned tc = typecode();
0234 return CSG::IsOperator((OpticksCSG_t)tc) ;
0235 }
0236 bool CSGNode::is_intersection() const
0237 {
0238 unsigned tc = typecode();
0239 return CSG::IsIntersection((OpticksCSG_t)tc) ;
0240 }
0241 bool CSGNode::is_union() const
0242 {
0243 unsigned tc = typecode();
0244 return CSG::IsUnion((OpticksCSG_t)tc) ;
0245 }
0246 bool CSGNode::is_difference() const
0247 {
0248 unsigned tc = typecode();
0249 return CSG::IsDifference((OpticksCSG_t)tc) ;
0250 }
0251 bool CSGNode::is_zero() const
0252 {
0253 unsigned tc = typecode();
0254 return CSG::IsZero((OpticksCSG_t)tc) ;
0255 }
0256 bool CSGNode::is_primitive() const
0257 {
0258 unsigned tc = typecode();
0259 return CSG::IsPrimitive((OpticksCSG_t)tc) ;
0260 }
0261 bool CSGNode::is_complemented_primitive() const
0262 {
0263 return is_complement() && is_primitive() ;
0264 }
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290 unsigned CSGNode::AncestorTypeMask( const CSGNode* root, unsigned partIdxRel, bool dump )
0291 {
0292 unsigned atm = 0u ;
0293
0294 int parentIdxRel = ((partIdxRel + 1) >> 1) - 1 ;
0295
0296 while( parentIdxRel > -1 )
0297 {
0298 const CSGNode* p = root + parentIdxRel ;
0299
0300 atm |= p->typemask() ;
0301
0302 if(dump) std::cout << std::setw(3) << parentIdxRel << " " << p->desc() << std::endl ;
0303
0304 parentIdxRel = ((parentIdxRel + 1) >> 1) - 1 ;
0305 }
0306
0307 return atm ;
0308 }
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338 unsigned CSGNode::Depth( unsigned partIdxRel )
0339 {
0340 int parentIdxRel = ((partIdxRel + 1) >> 1) - 1 ;
0341 unsigned depth = 0 ;
0342 while( parentIdxRel > -1 )
0343 {
0344 parentIdxRel = ((parentIdxRel + 1) >> 1) - 1 ;
0345 depth += 1 ;
0346 }
0347 return depth ;
0348 }
0349
0350
0351
0352
0353 bool CSGNode::IsOnlyUnionMask( unsigned atm )
0354 {
0355 return atm == CSG::Mask(CSG_UNION) ;
0356 }
0357
0358 bool CSGNode::IsOnlyIntersectionMask( unsigned atm )
0359 {
0360 return atm == CSG::Mask(CSG_INTERSECTION) ;
0361 }
0362
0363 bool CSGNode::IsOnlyDifferenceMask( unsigned atm )
0364 {
0365 return atm == CSG::Mask(CSG_DIFFERENCE) ;
0366 }
0367
0368 void CSGNode::getYRange(float& y0, float& y1) const
0369 {
0370 unsigned tc = typecode();
0371 if( tc == CSG_BOX3 )
0372 {
0373 float fx, fy, fz, a, b, c ;
0374 getParam( fx, fy, fz, a, b, c );
0375
0376 y0 = -fy*0.5f ;
0377 y1 = fy*0.5f ;
0378 }
0379 }
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392 void CSGNode::setAABBLocal()
0393 {
0394 unsigned tc = typecode();
0395 if(tc == CSG_SPHERE)
0396 {
0397 float r = radius();
0398 setAABB( -r, -r, -r, r, r, r );
0399 }
0400 else if(tc == CSG_ZSPHERE)
0401 {
0402 float r = radius();
0403 float z1_ = z1();
0404 float z2_ = z2();
0405 assert( z2_ > z1_ );
0406 setAABB( -r, -r, z1_, r, r, z2_ );
0407 }
0408 else if( tc == CSG_CONE )
0409 {
0410 float r1, z1, r2, z2, a, b ;
0411 getParam( r1, z1, r2, z2, a, b );
0412 float rmax = fmaxf(r1, r2) ;
0413 setAABB( -rmax, -rmax, z1, rmax, rmax, z2 );
0414 }
0415 else if( tc == CSG_BOX3 )
0416 {
0417 float fx, fy, fz, a, b, c ;
0418 getParam( fx, fy, fz, a, b, c );
0419 setAABB( -fx*0.5f , -fy*0.5f, -fz*0.5f, fx*0.5f , fy*0.5f, fz*0.5f );
0420 }
0421 else if( tc == CSG_CYLINDER || tc == CSG_OLDCYLINDER )
0422 {
0423 float px, py, a, radius, z1, z2 ;
0424 getParam( px, py, a, radius, z1, z2) ;
0425 setAABB( px-radius, py-radius, z1, px+radius, py+radius, z2 );
0426 }
0427 else if( tc == CSG_DISC )
0428 {
0429 float px, py, ir, r, z1, z2 ;
0430 getParam( px, py, ir, r, z1, z2 );
0431 setAABB( px - r , py - r , z1, px + r, py + r, z2 );
0432 }
0433 else if( tc == CSG_HYPERBOLOID )
0434 {
0435 float r0, zf, z1, z2, a, b ;
0436 getParam(r0, zf, z1, z2, a, b ) ;
0437
0438 assert( z1 < z2 );
0439 const float rr0 = r0*r0 ;
0440 const float z1s = z1/zf ;
0441 const float z2s = z2/zf ;
0442
0443 const float rr1 = rr0 * ( z1s*z1s + 1.f ) ;
0444 const float rr2 = rr0 * ( z2s*z2s + 1.f ) ;
0445 const float rmx = sqrtf(fmaxf( rr1, rr2 )) ;
0446
0447 setAABB( -rmx, -rmx, z1, rmx, rmx, z2 );
0448 }
0449 else if( tc == CSG_TORUS )
0450 {
0451
0452 double rmin, rmax, rtor, startPhi_deg, deltaPhi_deg, zero ;
0453 getParam_(rmin, rmax, rtor, startPhi_deg, deltaPhi_deg, zero) ;
0454
0455 double rext = rtor+rmax ;
0456 double rint = rtor-rmax ;
0457 double startPhi = startPhi_deg/180.*M_PI ;
0458 double deltaPhi = deltaPhi_deg/180.*M_PI ;
0459 double2 pmin ;
0460 double2 pmax ;
0461 sgeomtools::DiskExtent(rint, rext, startPhi, deltaPhi, pmin, pmax );
0462
0463 setAABB( pmin.x, pmin.y, -rmax, pmax.x, pmax.y, +rmax );
0464
0465 }
0466 else if( tc == CSG_UNION || tc == CSG_INTERSECTION || tc == CSG_DIFFERENCE )
0467 {
0468 setAABB( 0.f );
0469 }
0470 else if( tc == CSG_CONTIGUOUS || tc == CSG_DISCONTIGUOUS )
0471 {
0472
0473
0474 setAABB( 0.f );
0475 }
0476 else if( tc == CSG_NOTSUPPORTED )
0477 {
0478 setAABB( 0.f );
0479
0480 }
0481 else if( tc == CSG_HALFSPACE )
0482 {
0483 setAABB( 0.f );
0484 }
0485 else if( tc == CSG_CUTCYLINDER )
0486 {
0487 setAABB( UNBOUNDED_DEFAULT_EXTENT );
0488 }
0489 else if( tc == CSG_ZERO )
0490 {
0491 setAABB( UNBOUNDED_DEFAULT_EXTENT );
0492 }
0493 else if( tc == CSG_PHICUT )
0494 {
0495 setAABB( UNBOUNDED_DEFAULT_EXTENT );
0496 }
0497 else if( tc == CSG_THETACUT )
0498 {
0499 setAABB( UNBOUNDED_DEFAULT_EXTENT );
0500 }
0501 else
0502 {
0503 LOG(fatal) << " not implemented for tc " << tc << " CSG::Name(tc) " << CSG::Name(tc) ;
0504 assert(0);
0505 setAABB( 0.f );
0506 }
0507 }
0508
0509
0510
0511 CSGNode CSGNode::Zero()
0512 {
0513 CSGNode nd = {} ;
0514 nd.setAABB( -0.f, -0.f, -0.f, 0.f, 0.f, 0.f );
0515 nd.setTypecode(CSG_ZERO) ;
0516 return nd ;
0517 }
0518 CSGNode CSGNode::Sphere(float radius)
0519 {
0520 assert( radius > 0.f);
0521 CSGNode nd = {} ;
0522 nd.setParam( 0.f, 0.f, 0.f, radius, 0.f, 0.f );
0523 nd.setAABB( -radius, -radius, -radius, radius, radius, radius );
0524 nd.setTypecode(CSG_SPHERE) ;
0525 return nd ;
0526 }
0527 CSGNode CSGNode::ZSphere(float radius, float z1, float z2)
0528 {
0529 assert( radius > 0.f);
0530 assert( z2 > z1 );
0531 CSGNode nd = {} ;
0532 nd.setParam( 0.f, 0.f, 0.f, radius, z1, z2 );
0533 nd.setAABB( -radius, -radius, z1, radius, radius, z2 );
0534 nd.setTypecode(CSG_ZSPHERE) ;
0535 return nd ;
0536 }
0537
0538 CSGNode CSGNode::Cone(float r1, float z1, float r2, float z2)
0539 {
0540 assert( z2 > z1 );
0541 float rmax = fmaxf(r1, r2) ;
0542 CSGNode nd = {} ;
0543 nd.setParam( r1, z1, r2, z2, 0.f, 0.f ) ;
0544 nd.setAABB( -rmax, -rmax, z1, rmax, rmax, z2 );
0545 nd.setTypecode(CSG_CONE) ;
0546 return nd ;
0547 }
0548 CSGNode CSGNode::OldCone(float r1, float z1, float r2, float z2)
0549 {
0550 CSGNode nd = Cone(r1,z1,r2,z2);
0551 nd.setTypecode(CSG_OLDCONE) ;
0552 return nd ;
0553 }
0554
0555
0556 CSGNode CSGNode::Box3(float fullside)
0557 {
0558 return Box3(fullside, fullside, fullside);
0559 }
0560 CSGNode CSGNode::Box3(float fx, float fy, float fz )
0561 {
0562 assert( fx > 0.f );
0563 assert( fy > 0.f );
0564 assert( fz > 0.f );
0565
0566 CSGNode nd = {} ;
0567 nd.setParam( fx, fy, fz, 0.f, 0.f, 0.f );
0568 nd.setAABB( -fx*0.5f , -fy*0.5f, -fz*0.5f, fx*0.5f , fy*0.5f, fz*0.5f );
0569 nd.setTypecode(CSG_BOX3) ;
0570 return nd ;
0571 }
0572
0573 CSGNode CSGNode::Cylinder(float radius, float z1, float z2)
0574 {
0575 assert( z2 > z1 );
0576 CSGNode nd = {} ;
0577 nd.setParam( 0.f, 0.f, 0.f, radius, z1, z2) ;
0578 nd.setAABB( -radius, -radius, z1, +radius, +radius, z2 );
0579 nd.setTypecode(CSG_CYLINDER);
0580 return nd ;
0581 }
0582
0583 CSGNode CSGNode::OldCylinder(float radius, float z1, float z2)
0584 {
0585 float px = 0.f ;
0586 float py = 0.f ;
0587 CSGNode nd = {} ;
0588 nd.setParam( px, py, 0.f, radius, z1, z2) ;
0589 nd.setAABB( px-radius, py-radius, z1, px+radius, py+radius, z2 );
0590 nd.setTypecode(CSG_OLDCYLINDER);
0591 return nd ;
0592 }
0593
0594 CSGNode CSGNode::InfCylinder(float radius, float hz)
0595 {
0596 assert( hz > 0.f );
0597 CSGNode nd = {} ;
0598 nd.setParam( 0.f, 0.f, 0.f, radius, 0.f,0.f) ;
0599 nd.setAABB( -radius, -radius, -hz, radius, radius, hz );
0600 nd.setTypecode(CSG_INFCYLINDER);
0601 return nd ;
0602 }
0603
0604 CSGNode CSGNode::InfPhiCut(float startPhi_pi, float deltaPhi_pi )
0605 {
0606 CSGNode nd = {} ;
0607 SPhiCut::PrepareParam( nd.q0 , startPhi_pi, deltaPhi_pi );
0608 nd.setAABB( -100.f,-100.f,-100.f, 100.f, 100.f, 100.f );
0609 nd.setTypecode(CSG_PHICUT);
0610 return nd ;
0611 }
0612
0613 CSGNode CSGNode::InfThetaCut(float startTheta_pi, float deltaTheta_pi )
0614 {
0615 CSGNode nd = {} ;
0616 SThetaCut::PrepareParam( nd.q0, nd.q1, startTheta_pi, deltaTheta_pi );
0617 nd.setAABB( -100.f,-100.f,-100.f, 100.f, 100.f, 100.f );
0618 nd.setTypecode(CSG_THETACUT);
0619 return nd ;
0620 }
0621
0622
0623 CSGNode CSGNode::Disc(float px, float py, float ir, float r, float z1, float z2)
0624 {
0625 CSGNode nd = {} ;
0626 nd.setParam( px, py, ir, r, z1, z2 );
0627 nd.setAABB( px - r , py - r , z1, px + r, py + r, z2 );
0628 nd.setTypecode(CSG_DISC);
0629 return nd ;
0630 }
0631
0632 CSGNode CSGNode::Hyperboloid(float r0, float zf, float z1, float z2)
0633 {
0634 assert( z1 < z2 );
0635 const float rr0 = r0*r0 ;
0636 const float z1s = z1/zf ;
0637 const float z2s = z2/zf ;
0638
0639 const float rr1 = rr0 * ( z1s*z1s + 1.f ) ;
0640 const float rr2 = rr0 * ( z2s*z2s + 1.f ) ;
0641 const float rmx = sqrtf(fmaxf( rr1, rr2 )) ;
0642
0643 CSGNode nd = {} ;
0644 nd.setParam(r0, zf, z1, z2, 0.f, 0.f ) ;
0645 nd.setAABB( -rmx, -rmx, z1, rmx, rmx, z2 );
0646 nd.setTypecode(CSG_HYPERBOLOID) ;
0647 return nd ;
0648 }
0649
0650
0651 CSGNode CSGNode::Plane(float nx, float ny, float nz, float d)
0652 {
0653 CSGNode nd = {} ;
0654 nd.setParam(nx, ny, nz, d, 0.f, 0.f ) ;
0655 nd.setTypecode(CSG_PLANE) ;
0656 nd.setAABB( UNBOUNDED_DEFAULT_EXTENT );
0657 return nd ;
0658 }
0659
0660 CSGNode CSGNode::Slab(float nx, float ny, float nz, float d1, float d2 )
0661 {
0662 CSGNode nd = {} ;
0663 nd.setParam( nx, ny, nz, 0.f, d1, d2 );
0664 nd.setTypecode(CSG_SLAB) ;
0665 nd.setAABB( UNBOUNDED_DEFAULT_EXTENT );
0666 return nd ;
0667 }
0668
0669 CSGNode CSGNode::HalfSpace(float nx, float ny, float nz, float nw )
0670 {
0671 CSGNode nd = {} ;
0672 nd.setParam( nx, ny, nz, nw, 0, 0 );
0673 nd.setTypecode(CSG_HALFSPACE ) ;
0674 nd.setAABB( 0.f );
0675 return nd ;
0676 }
0677
0678 CSGNode* CSGNode::HalfCylinder(float nx, float ny, float nz, float nw, float radius, float z0, float z1 )
0679 {
0680 int subNum = 3 ;
0681 CSGNode* nd = new CSGNode[subNum] ;
0682 nd[0] = CSGNode::Intersection() ;
0683 nd[1] = CSGNode::HalfSpace(nx,ny,nz,nw);
0684 nd[2] = CSGNode::Cylinder(radius,z0,z1);
0685 nd[0].setSubNum(subNum);
0686 return nd ;
0687 }
0688 CSGNode* CSGNode::HalfCylinder()
0689 {
0690 float v = 1.f/sqrtf(2.f);
0691 return HalfCylinder(v,v,0.f,0.f, 100.f, -50.f, 50.f);
0692 }
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705 CSGNode CSGNode::MakeDemo(const char* name)
0706 {
0707 if(strncmp(name, "sphe", 4) == 0) return CSGNode::Sphere(100.f) ;
0708 if(strncmp(name, "zsph", 4) == 0) return CSGNode::ZSphere(100.f, -50.f, 50.f) ;
0709 if(strncmp(name, "cone", 4) == 0) return CSGNode::Cone(150.f, -150.f, 50.f, -50.f) ;
0710 if(strncmp(name, "hype", 4) == 0) return CSGNode::Hyperboloid(100.f, 50.f, -50.f, 50.f) ;
0711 if(strncmp(name, "box3", 4) == 0) return CSGNode::Box3(100.f, 100.f, 100.f) ;
0712 if(strncmp(name, "plan", 4) == 0) return CSGNode::Plane(1.f, 0.f, 0.f, 0.f) ;
0713 if(strncmp(name, "slab", 4) == 0) return CSGNode::Slab(1.f, 0.f, 0.f, -10.f, 10.f ) ;
0714 if(strncmp(name, "cyli", 4) == 0) return CSGNode::Cylinder( 100.f, -50.f, 50.f ) ;
0715 if(strncmp(name, "ocyl", 4) == 0) return CSGNode::OldCylinder(100.f, -50.f, 50.f ) ;
0716 if(strncmp(name, "disc", 4) == 0) return CSGNode::Disc( 0.f, 0.f, 50.f, 100.f, -2.f, 2.f ) ;
0717 if(strncmp(name, "iphi", 4) == 0) return CSGNode::InfPhiCut(0.25f, 0.10f) ;
0718 if(strncmp(name, "ithe", 4) == 0) return CSGNode::InfThetaCut(0.25f, 0.10f ) ;
0719 LOG(fatal) << " not implemented for name " << name ;
0720 assert(0);
0721 return CSGNode::Sphere(1.0);
0722 }
0723
0724
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734 CSGNode CSGNode::Make(unsigned typecode )
0735 {
0736 CSGNode nd = {} ;
0737 nd.setTypecode(typecode) ;
0738 return nd ;
0739 }
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753 CSGNode CSGNode::Make(unsigned typecode, const float* param6, const float* aabb )
0754 {
0755 CSGNode nd = {} ;
0756 nd.setTypecode(typecode) ;
0757 if(CSG::IsPrimitive(typecode))
0758 {
0759 if(param6) nd.setParam( param6 );
0760 if(aabb) nd.setAABB( aabb );
0761 }
0762 return nd ;
0763 }
0764 CSGNode CSGNode::MakeNarrow(unsigned typecode, const double* param6, const double* aabb )
0765 {
0766 CSGNode nd = {} ;
0767 nd.setTypecode(typecode) ;
0768 if(param6) nd.setParam_Narrow( param6 );
0769 if(aabb) nd.setAABB_Narrow( aabb );
0770 return nd ;
0771 }
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782 #endif
0783