Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:48:52

0001 // name=CSGClassifyTest ; gcc $name.cc -std=c++11 -I.. -I$OPTICKS_PREFIX/include/sysrap -lstdc++ -o /tmp/$name && /tmp/$name
0002 
0003 #include <iostream>
0004 #include "OpticksCSG.h"
0005 #include "scanvas.h"
0006 
0007 #define DEBUG 1
0008 #include "csg_classify.h"
0009 
0010 void print_LUT( const LUT& lut, OpticksCSG_t typecode, const char* notes )
0011 {
0012     int width = 4+1 ;
0013     int height = 4+1 ;
0014     int xscale = 18 ;
0015     int yscale = 6 ;
0016 
0017     int mx = 2 ;
0018     int my = 2 ;
0019 
0020     scanvas canvas(width, height, xscale, yscale );
0021 
0022     canvas.draw(   0,0, mx, my, CSG::Name(typecode) );
0023 
0024     for(int ix=0 ; ix < width-1  ; ix++)
0025     for(int iy=0 ; iy < height-1 ; iy++)
0026     {
0027         canvas.drawch( ix,iy,    0,              0, '+' );
0028         canvas.drawch( ix,iy,    0,       yscale-1, '+' );
0029 
0030         for(int ixx=1 ; ixx < xscale ; ixx++ ) canvas.drawch( ix,iy,    ixx,   0, '-' );
0031         for(int iyy=1 ; iyy < yscale ; iyy++ ) canvas.drawch( ix,iy,      0, iyy, '|' );
0032     }
0033 
0034     // rhs vertical
0035     int ix = width-1 ;
0036     for(int iy=0 ; iy < height-1 ; iy++)
0037     {
0038         canvas.drawch( ix,iy,    0,              0, '+' );
0039         for(int iyy=1 ; iyy < yscale ; iyy++ ) canvas.drawch( ix,iy,      0, iyy, '|' );
0040     }
0041 
0042     int iy = height-1 ;
0043     for(int ix=0 ; ix < width-1 ; ix++)
0044     {
0045         canvas.drawch( ix,iy,    0,              0, '+' );
0046         for(int ixx=1 ; ixx < xscale ; ixx++ ) canvas.drawch( ix,iy,     ixx,  0, '-' );
0047     }
0048     canvas.drawch( width-1,height-1,   0,0, '+' );
0049 
0050 
0051     for(int a=0 ; a < 3 ; a++)
0052     {
0053         IntersectionState_t A_state = (IntersectionState_t)a  ;
0054         canvas.drawch( 0,a+1, mx+0,my+0, 'A' );
0055         canvas.draw(   0,a+1, mx+2,my+0, IntersectionState::Name(A_state) );
0056     }
0057 
0058     for(int b=0 ; b < 3 ; b++)
0059     {
0060         IntersectionState_t B_state = (IntersectionState_t)b  ;
0061         canvas.drawch( b+1,0,  mx+0,my+0, 'B' );
0062         canvas.draw(   b+1,0,  mx+2,my+0, IntersectionState::Name(B_state) );
0063     }
0064 
0065     for(int c=1 ; c < 3 ; c++)
0066     {
0067         bool A_closer = c == 1 ;
0068         canvas.drawch( 0,0, mx+0, my+c,  A_closer ? 'A' : 'B' );
0069         canvas.draw(   0,0, mx+2, my+c, "Closer" );
0070     }
0071 
0072     for(int c=0 ; c < 2 ; c++)
0073     for(int b=0 ; b < 3 ; b++)
0074     for(int a=0 ; a < 3 ; a++)
0075     {
0076         bool A_closer = c == 0 ;
0077         IntersectionState_t A_state = (IntersectionState_t)a  ;
0078         IntersectionState_t B_state = (IntersectionState_t)b  ;
0079         int ictrl = lut.lookup( typecode , A_state, B_state, A_closer ) ;
0080         const char* ctrl = CTRL::Name(ictrl) ;
0081         assert( strlen(ctrl) < unsigned(xscale) );
0082 
0083         canvas.draw( b+1, a+1, mx+0, my+c+1,  ctrl );
0084     }
0085     canvas.print();
0086     printf("%s\n", notes);
0087 }
0088 
0089 
0090 const char* REFERENCE = R"LITERAL(
0091 
0092 http://xrt.wikidot.com/doc:csg
0093 
0094 http://xrt.wdfiles.com/local--files/doc%3Acsg/CSG.pdf
0095 
0096 A ray is shot at each sub-object to find the nearest intersection, then the
0097 intersection with the sub-object is classified as one of entering, exiting or
0098 missing it. Based upon the combination of the two classifications, one of
0099 several actions is taken:
0100 
0101 1. returning a hit
0102 2. returning a miss
0103 3. changing the starting point of the ray for one of the objects and then
0104    shooting this ray, classifying the intersection. In this case, the state
0105    machine enters a new loop.
0106 
0107 
0108 Note that when there is a MISS on either side, the LUT results
0109 are the same no matter what leftIsCloser is set to for all
0110 operations : UNION, INTERSECTION, DIFFERENCE.
0111 
0112 )LITERAL" ;
0113 
0114 const char* UNION = R"LITERAL(
0115 +-----------------+-----------------+-----------------+-----------------+
0116 |                 |                 |                 |                 |
0117 | union           | B Enter         | B Exit          | B Miss          |
0118 | A Closer        |                 |                 |                 |
0119 | B Closer        |                 |                 |                 |
0120 |                 |                 |                 |                 |
0121 +-----------------+-----------------+-----------------+-----------------+
0122 |                 |                 |                 |                 |
0123 | A Enter         |                 |                 |                 |
0124 |                 | RETURN_A        | LOOP_A          | RETURN_A        |
0125 |                 | RETURN_B        | RETURN_B        | RETURN_A        |
0126 |                 |                 |                 |                 |
0127 +-----------------+-----------------+-----------------+-----------------+
0128 |                 |                 |                 |                 |
0129 | A Exit          |                 |                 |                 |
0130 |                 | RETURN_A        | RETURN_B        | RETURN_A        |
0131 |                 | LOOP_B          | RETURN_A        | RETURN_A        |
0132 |                 |                 |                 |                 |
0133 +-----------------+-----------------+-----------------+-----------------+
0134 |                 |                 |                 |                 |
0135 | A Miss          |                 |                 |                 |
0136 |                 | RETURN_B        | RETURN_B        | RETURN_MISS     |
0137 |                 | RETURN_B        | RETURN_B        | RETURN_MISS     |
0138 |                 |                 |                 |                 |
0139 +-----------------+-----------------+-----------------+-----------------+
0140 
0141 (A Enter, B Enter)
0142     origin outside both -> return closest
0143 
0144 (A Exit, B Exit)
0145     origin inside both  -> return furthest
0146 
0147 (A Exit, B Enter)
0148     origin inside A
0149 
0150     * if A closer return A (means disjoint)
0151     * if B closer loop B (to find the otherside of it, and then compare again)
0152 
0153 
0154 
0155 
0156      UX1 : UNION FROM INSIDE ONE                           UX2 : UNION FROM OUTSIDE 0,1,2
0157                                                            UX3 : UNION FROM INSIDE BOTH 3,4,5
0158 
0159                   +-----------------------+                           +-----------------------+
0160                   |                     B |                           |                     B |
0161        +------------------+               |                +------------------+               |
0162        | A        |       |               |                | A        |       |               |
0163        |          |       |               |                |          |       |               |
0164        |          |       |               |                |          |       |               |
0165        |   0- - - 1 - - - 2 - - - - - - -[3]           0 -[1]- - - -  2       |               |
0166        |          E       X               X                E          E   3 - 4 - - - - - - -[5]
0167        |          |       |               |                |          |       X               X
0168        |          +-------|---------------+                |          +-------|---------------+
0169        |                  |                                |                  |
0170        |                  |                                |                  |
0171        +------------------+                                +------------------+
0172 
0173 
0174      0: origin                                           0: origin
0175      1: B Enter                                          1: A Enter
0176      2: A Exit                                           2: B Enter
0177      1,2: B Closer        ==> LOOP_B                     1,2: A Closer        ==> RETURN_A
0178      3: B Exit
0179      2,3: A closer        ==> RETURN_B                   3: origin
0180                                                          4: A Exit
0181                                                          5: B Exit
0182                                                          4,5 A Closer         ==> RETURN_B
0183 
0184 
0185       UX4 : DISJOINT UNION  0,[1],2
0186 
0187 
0188         +---------------------+                +---------------------+
0189         | A                   |                |                   B |
0190         |                     |                |                     |
0191         |                     |                |                     |
0192         |                     |                |                     |
0193         |                     |                |                     |
0194         |         0- - - - - [1] -  - - - - - -2                     |
0195         |                     X                E                     |
0196         |                     |                |                     |
0197         |                     |                |                     |
0198         |                     |                |                     |
0199         +---------------------+                +---------------------+
0200 
0201 
0202     0: origin
0203     1: A Exit
0204     2: B Enter
0205     1,2: A Closer        ==> RETURN_A [1]
0206 
0207 )LITERAL" ;
0208 
0209 
0210 const char* INTERSECTION = R"LITERAL(
0211 +-----------------+-----------------+-----------------+-----------------+
0212 |                 |                 |                 |                 |
0213 | intersection    | B Enter         | B Exit          | B Miss          |
0214 | A Closer        |                 |                 |                 |
0215 | B Closer        |                 |                 |                 |
0216 |                 |                 |                 |                 |
0217 +-----------------+-----------------+-----------------+-----------------+
0218 |                 |                 |                 |                 |
0219 | A Enter         |                 |                 |                 |
0220 |                 | LOOP_A          | RETURN_A        | RETURN_MISS     |
0221 |                 | LOOP_B          | LOOP_B          | RETURN_MISS     |
0222 |                 |                 |                 |                 |
0223 +-----------------+-----------------+-----------------+-----------------+
0224 |                 |                 |                 |                 |
0225 | A Exit          |                 |                 |                 |
0226 |                 | LOOP_A          | RETURN_A        | RETURN_MISS     |
0227 |                 | RETURN_B        | RETURN_B        | RETURN_MISS     |
0228 |                 |                 |                 |                 |
0229 +-----------------+-----------------+-----------------+-----------------+
0230 |                 |                 |                 |                 |
0231 | A Miss          |                 |                 |                 |
0232 |                 | RETURN_MISS     | RETURN_MISS     | RETURN_MISS     |
0233 |                 | RETURN_MISS     | RETURN_MISS     | RETURN_MISS     |
0234 |                 |                 |                 |                 |
0235 +-----------------+-----------------+-----------------+-----------------+
0236 
0237 
0238 Ordering states (Closer,Further)
0239 
0240 
0241 (Enter, Enter) -> Loop Closer
0242     Find otherside of Closer Enter (by advancing t_min and intersecting that constituent again and then comparing again)
0243 
0244     ::
0245 
0246             +-------------+
0247             | A           |
0248             |      +------|-------+      0:Origin
0249             |      |      |     B |      1:A_Enter
0250       0- - -1 - - [2]- - -3       |      2:B_Enter
0251             E      E      X       |      (1:A_Enter,2:B_Enter) => A_Closer => LOOP_A : Closer one => 3
0252             |      |      |       |      3:A Exit
0253             +------|------+       |      (2:B Enter,3:A Exit) => RETURN_B 2:B_Enter
0254                    |              |
0255                    +--------------+
0256 
0257 (Enter, Exit) -> Return Closer One : the Enter
0258 
0259 
0260 
0261 (Exit, Enter) -> Loop Closer (the Exit)
0262     One might first imagine that having just exited so there will be no otherside ?
0263     But that assumes simple convex constituent shapes whereas the alg needs to
0264     handle less simple shapes like torus or annulus
0265 
0266 
0267 (Exit, Exit) -> Return Closer Exit
0268     Both isect classified as Exit means origin is inside both,
0269     hence the closer isect is needed as it is the nature of
0270     CSG_INTERSECTION to pick the shape formed from the overlap
0271     of the constituents
0272 
0273 
0274 
0275 Thinking of ROTH diagrams for intersection
0276 
0277 
0278                        |--------------|
0279 
0280                             |------------------|
0281 
0282                                   |-----------------|
0283 
0284            Enters:     |    |     |
0285 
0286            Exits:                     |        |    |
0287 
0288 
0289                   farthest enter  |   |
0290                                   |   |    nearest exit
0291 
0292 For an overlap need::
0293 
0294                       farthest_enter < nearest_exit
0295 
0296 
0297                           |-----------|
0298 
0299                                            |------------|
0300 
0301             Enters:       |                |
0302 
0303             Exits:                    |                 |
0304 
0305 
0306                          nearest exit |    | farthest enter
0307 
0308 No overlap as::
0309 
0310                          nearest_exit   < farthest_enter
0311 
0312 
0313 
0314 
0315 
0316 
0317 
0318 Consider INTERSECTION between an ordinary bounded A and an unbounded B (eg phicut or thetacut)
0319 
0320 * assume that find a way to special case reclassify "B Miss" into "B Exit"
0321   for rays going in the appropriate range of directions
0322 
0323   * currently complement miss flips the signbits of isect.xyz
0324     but only signbit of isect.x is read as the signal for complemented miss
0325 
0326   * rationalize the signalling (note that are re-using isect when there is miss
0327     and hence no intersection to pass info up the tree)
0328 
0329     1. isect.x signbit for complement miss
0330     2. isect.y signbit for unbounded miss that can be promoted to unbounded exit
0331 
0332   * hmm this is only applicable when start "inside" B as can only EXIT_B when start inside
0333   * how to check are inside an infinite phicut ?  check (o.x,o.y) ? signed distances ?
0334   * think about a very thin wedge phicut and pure-z (eg orthographic view looking directly
0335     down on the cake) most of the time will miss the phicut hence do not want to
0336     promote that miss : as the phicut is effectively not there.
0337 
0338 * as the "otherside" of B is at infinity the comparison will always be "A Closer"
0339 
0340 
0341 ::
0342 
0343               .
0344                            => MISS         /
0345                              2:B_MISS     /
0346                                2         /  B : unbounded
0347                               /         /
0348                              /         /
0349                             /         /
0350                            /         /
0351                           /         /
0352               +----------1-A_EXIT--/-------------+
0353               | A       /         / . . . . . . .|
0354               |        /         / . . . . . . . |
0355               |       0         / . . .  0--->---1----------- 2:B_MISS
0356               |                / . . . . . . . . A_EXIT
0357               |               + . 0 . . . . . . .|       (A_EXIT, B_MISS) => RETURN_MISS
0358               |                \ / . . . . . . . |
0359               |                 1 . . . . . . . .|       (A_EXIT, B_EXIT) => A_Closer => RETURN_A
0360               |                / \ . . . . . . . |
0361               +---------------2---\--------------+
0362                                    \
0363                        1:B_EXIT     \
0364                        2:A_EXIT      \
0365                        1,2:B_Closer   \
0366                        => RETURN_B
0367 
0368 
0369 
0370 
0371 
0372 
0373      IX1 : INTERSECTION FROM INSIDE ONE 0,[1],2            IX2 : INTERSECTION FROM OUTSIDE 0,1,[2],3
0374                                                            IX3 : INTERSECTION FROM INSIDE BOTH 4,[5],6
0375 
0376                   +-----------------------+                           +-----------------------+
0377                   |                     B |                           |                     B |
0378        +------------------+               |                +------------------+               |
0379        | A        |       |               |                | A        |       |               |
0380        |          |       |               |                |          |   4 -[5]- - - - - - - 6
0381        |          |       |               |                |          |       |               |
0382        |   0- - -[1]- - - 2               |            0 - 1 - - - - [2] - - -3               |
0383        |          |       |               |                |          |       |               |
0384        |          |       |               |                |          |       |               |
0385        |          +-------|---------------+                |          +-------|---------------+
0386        |                  |                                |                  |
0387        |                  |                                |                  |
0388        +------------------+                                +------------------+
0389 
0390 
0391      0: origin                                           0: origin
0392      1: B Enter                                          1: A Enter
0393      2: A Exit                                           2: B Enter
0394      1,2: B Closer    ==> RETURN_B => [1]                1,2: A Closer   => LOOP_A  1->3
0395                                                          3: A Exit
0396                                                          3,2: B Closer   => RETURN_B => [2]
0397 
0398 
0399                                                          4: origin
0400                                                          5: A Exit
0401                                                          6: B Exit
0402                                                          5,6: A Closer   ==> RETURN_A   [5]
0403 
0404 
0405 
0406 
0407 
0408 
0409 
0410 
0411 The below shapes are not permissable as there is no common overlap
0412 giving such a shape to a MULTI_INTERSECT may abort and will give incorrect intersects.
0413 
0414 
0415              +------+
0416          +---|------|-----+
0417          |   |      |     |
0418          |   |      |     |
0419          |   +------+     |
0420          |           +----|-----+
0421          +-----------|----+     |
0422                      +----------+
0423 
0424       +----+      +-----+      +-----+
0425       |    |      |     |      |     |
0426    - -E - - - - - E- - - - - - E- - - - - -
0427       |    |      |     |      |     |
0428       +----+      +-----+      +-----+
0429 
0430 
0431 )LITERAL" ;
0432 
0433 const char* DIFFERENCE = R"LITERAL(
0434 +-----------------+-----------------+-----------------+-----------------+
0435 |                 |                 |                 |                 |
0436 | difference      | B Enter         | B Exit          | B Miss          |
0437 | A Closer        |                 |                 |                 |
0438 | B Closer        |                 |                 |                 |
0439 |                 |                 |                 |                 |
0440 +-----------------+-----------------+-----------------+-----------------+
0441 |                 |                 |                 |                 |
0442 | A Enter         |                 |                 |                 |
0443 |                 | RETURN_A        | LOOP_A          | RETURN_A        |
0444 |                 | LOOP_B          | LOOP_B          | RETURN_A        |
0445 |                 |                 |                 |                 |
0446 +-----------------+-----------------+-----------------+-----------------+
0447 |                 |                 |                 |                 |
0448 | A Exit          |                 |                 |                 |
0449 |                 | RETURN_A        | LOOP_A          | RETURN_A        |
0450 |                 | RETURN_FLIP_B   | RETURN_FLIP_B   | RETURN_A        |
0451 |                 |                 |                 |                 |
0452 +-----------------+-----------------+-----------------+-----------------+
0453 |                 |                 |                 |                 |
0454 | A Miss          |                 |                 |                 |
0455 |                 | RETURN_MISS     | RETURN_MISS     | RETURN_MISS     |
0456 |                 | RETURN_MISS     | RETURN_MISS     | RETURN_MISS     |
0457 |                 |                 |                 |                 |
0458 +-----------------+-----------------+-----------------+-----------------+
0459 
0460 
0461 
0462      DX1 : DIFFERENCE FROM INSIDE ONE 0,[1],2              DX2 : DIFFERENCE FROM OUTSIDE 0,[1],2
0463                                                            DX3 : DIFFERENCE FROM INSIDE BOTH 4,5,6
0464 
0465                   +-----------------------+                           +-----------------------+
0466                   |                     B |                           |                     B |
0467        +------------------+               |                +------------------+               |
0468        | A        |       |               |                | A        |       |               |
0469        |          |       |               |                |          |   4 - 5 - - - - - - - 6
0470        |          |       |               |                |          |       |               |
0471        |   0- - -[1]> - - 2               |          0 - <[1] - - - - 2       |               |
0472        |          |       |               |                |          |       |               |
0473        |          |       |               |                |          |       |               |
0474        |          +-------|---------------+                |          +-------|---------------+
0475        |                  |                                |                  |
0476        |                  |                                |                  |
0477        +------------------+                                +------------------+
0478 
0479 
0480      0: origin                                           0: origin
0481      1: B Enter                                          1: A Enter
0482      2: A Exit                                           2: B Enter
0483      1,2: B Closer  =>   RETURN_FLIP_B   [1]>            1,2: A Closer   => RETURN_A [1]
0484 
0485 
0486                                                          4: origin
0487                                                          5: A Exit
0488                                                          6: B Exit
0489                                                          5,6: A Closer    => LOOP_A  => A MISS
0490                                                          ==> RETURN_MISS
0491 
0492 )LITERAL" ;
0493 
0494 int main(int argc, char** argv)
0495 {
0496     printf("%s\b", REFERENCE);
0497     LUT lut ;
0498     switch( argc > 1 ? argv[1][0] : 'A' )
0499     {
0500         case 'U': print_LUT(lut, CSG_UNION        , UNION );        break ;
0501         case 'I': print_LUT(lut, CSG_INTERSECTION , INTERSECTION ); break ;
0502         case 'D': print_LUT(lut, CSG_DIFFERENCE   , DIFFERENCE );   break ;
0503         default:
0504                   print_LUT(lut, CSG_UNION        , UNION );
0505                   print_LUT(lut, CSG_INTERSECTION , INTERSECTION );
0506                   print_LUT(lut, CSG_DIFFERENCE   , DIFFERENCE );
0507     }
0508     return 0 ;
0509 }
0510