Polygonization Zippering Boundaries ====================================== Zippering Realizations for CSG union of box and sphere --------------------------------------------------------- * left and right mesh frontier "ribbons" of tris, each ribbon having inner/outer boundary edge loops * outer loop from leftmesh needs to be zippered with the outer loop of the rightmesh frontier ribbon equivalent * inner loops can be discarded, tris can be discarded, * hmm NO : can bisect frontier crossing edges to get verts on the frontier "ring" * ONLY NEED TO RETAIN outer loop vertices from left and right * only the verts from one side of the ribbons need to be :: . . . . . .*. . . . . . . . . . . * . . . . (rightmesh inner loop, can be discarded) / \ / \ --------/-----\-------------+-----------+--- leftmesh outer loop / \ \ / - - /- - - \- - - - -\ - - / - - - - - / \ \ / ----+-------------+-------------\---/-------- rightmesh outer loop \ / . . . . . . . . . . . . . . . . * . . . . (left mesh inner loop, can be discarded) OpenFlipper Boundary Snap ---------------------------- OpenFlipper does something similar, * /usr/local/opticks/externals/openflipper/OpenFlipper-3.1/Plugin-MeshRepair/BoundarySnappingT.cc An un-obfuscated version using typedefs * /Users/blyth/opticks/opticksnpy/tests/BoundarySnappingT.cc Mesh zippering ----------------- * boils down to adding faces that join the * problem is they are not 1-1, will be more vertices * constraint : cannot add vertices to the loops :: ----------+-----------------+-----------+--- leftmesh outer loop - - - - - - - - - - - - - - actual analytic interface between sub-objects ----+-------------+--------------+------------ rightmesh outer loop * for each vert find the nearest one on the other side * find the nearest vert on o * hmm the halfedge loop should give the correct ordering of each loop, its just a registration issue of lining them up and using triangle fans to deal with too many verts * another possibility is approximate the analytic boundary and add a line of vertices along it could do sdf evaluation, actually this * would be helpful as are free to put as many verts as like along the analytic curve, can help with vertex count mismatch ... then have a :: ----------+-----------------+-----------+--- leftmesh outer loop - + + + + + + + + analytic interface verts added flexibly ----+-------------+--------------+------------ rightmesh outer loop Investigate boundary loops with modded combine_hybrid ------------------------------------------------------- * modification just copies frontier faces from leftmesh :: tboolean-;tboolean-hybrid ## visualization shows "pixelated" ring of tris ## approximating the box-sphere intersection circle :: 133 template 134 void NOpenMesh::build_csg() 135 { 226 template 227 void NOpenMesh::combine_hybrid( ) 228 { 300 301 if(node->type == CSG_UNION) 302 { 303 //NOpenMeshPropType prop = PROP_OUTSIDE_OTHER ; 304 NOpenMeshPropType prop = PROP_FRONTIER ; 305 306 build.copy_faces( leftmesh, prop, epsilon ); 307 //build.copy_faces( rightmesh, prop, epsilon ); 308 309 //subdiv.sqrt3_refine( FIND_ALL_FACE , -1 ); // test refining copied over frontier tris 310 311 } ... 326 int nloop = find.find_boundary_loops() ; 327 // hmm expecting 2, but thats geometry specific 328 329 find.dump_boundary_loops("find.dump_boundary_loops", true ); 330 Leftmesh frontier "ribbon" with outer and inner boundary edge loops ------------------------------------------------------------------------ * the outer loop is the one that needs to be zippered with the outer boundary loop of the rightmesh frontier ribbon equivalent :: 2017-06-09 19:14:21.233 INFO [6274680] [>::combine_hybrid@247] combine_hybrid leftmesh 0x7fa0d5adedc0 rightmesh 0x7fa0d5adf900 2017-06-09 19:14:21.239 INFO [6274680] [>::mark_faces@401] mark_faces 0: 2728|1: 14|2: 14|3: 12|4: 28|5: 12|6: 12|7: 252| 2017-06-09 19:14:21.239 INFO [6274680] [>::mark_faces@401] mark_faces 0: 68|1: 10|2: 10|3: 8|4: 4|5: 12|6: 12|7: 356| 2017-06-09 19:14:21.242 INFO [6274680] [>::dump_boundary_loops@528] find.dump_boundary_loops nloop 2 NOpenMeshBoundary::desc halfedge boundary loop index 1 start 1 num_heh 56 : 1 9 67 75 91 99 115 123 141 161 173 193 205 225 237 239 261 263 285 287... NOpenMeshBoundary::desc halfedge boundary loop index 2 start 15 num_heh 36 : 15 25 31 41 47 57 81 105 129 153 165 185 197 217 229 249 273 297 355 347... 2017-06-09 19:14:21.242 INFO [6274680] [>::dump@78] NOpenMeshBoundary::dump halfedge boundary loop index 1 start 1 num_heh 56 : 1 9 67 75 91 99 115 123 141 161 173 193 205 225 237 239 261 263 285 287... // // dumping the "to" vertices around 1st heh loop // // all verts are on the wall of the box (left sub-object) ... hence sdf_C and sdf_L are zero (on- isosurface) // // sdf_R all small positive // boundary is fully outside the right sub-object sphere // // THIS OUTER BOUNDARY IS THE ONE THAT NEEDS TO BE ZIPPERED ONTO THE OTHER MESH // // i 0 heh 1 eh 0 tv 0 ( 201.000, -100.500, -175.875) sdf_C 0.00 sdf_L 0.00 sdf_R 26.35 i 1 heh 9 eh 4 tv 3 ( 201.000, -100.500, -150.750) sdf_C 0.00 sdf_L 0.00 sdf_R 7.43 i 2 heh 67 eh 33 tv 18 ( 201.000, -125.625, -150.750) sdf_C 0.00 sdf_L 0.00 sdf_R 20.70 i 3 heh 75 eh 37 tv 20 ( 201.000, -125.625, -125.625) sdf_C 0.00 sdf_L 0.00 sdf_R 4.36 i 4 heh 91 eh 45 tv 24 ( 201.000, -150.750, -125.625) sdf_C 0.00 sdf_L 0.00 sdf_R 20.70 i 5 heh 99 eh 49 tv 26 ( 201.000, -150.750, -100.500) sdf_C 0.00 sdf_L 0.00 sdf_R 7.43 i 6 heh 115 eh 57 tv 30 ( 201.000, -175.875, -100.500) sdf_C 0.00 sdf_L 0.00 sdf_R 26.35 i 7 heh 123 eh 61 tv 32 ( 201.000, -175.875, -75.375) sdf_C 0.00 sdf_L 0.00 sdf_R 16.37 ... i 47 heh 83 eh 41 tv 17 ( 201.000, 100.500, -150.750) sdf_C 0.00 sdf_L 0.00 sdf_R 7.43 i 48 heh 65 eh 32 tv 16 ( 201.000, 100.500, -175.875) sdf_C 0.00 sdf_L 0.00 sdf_R 26.35 i 49 heh 59 eh 29 tv 14 ( 201.000, 75.375, -175.875) sdf_C 0.00 sdf_L 0.00 sdf_R 16.37 i 50 heh 51 eh 25 tv 12 ( 201.000, 50.250, -175.875) sdf_C 0.00 sdf_L 0.00 sdf_R 8.95 i 51 heh 43 eh 21 tv 10 ( 201.000, 25.125, -175.875) sdf_C 0.00 sdf_L 0.00 sdf_R 4.36 i 52 heh 35 eh 17 tv 8 ( 201.000, 0.000, -175.875) sdf_C 0.00 sdf_L 0.00 sdf_R 2.81 i 53 heh 27 eh 13 tv 6 ( 201.000, -25.125, -175.875) sdf_C 0.00 sdf_L 0.00 sdf_R 4.36 i 54 heh 19 eh 9 tv 4 ( 201.000, -50.250, -175.875) sdf_C 0.00 sdf_L 0.00 sdf_R 8.95 i 55 heh 11 eh 5 tv 1 ( 201.000, -75.375, -175.875) sdf_C 0.00 sdf_L 0.00 sdf_R 16.37 2017-06-09 19:14:21.243 INFO [6274680] [>::dump@78] NOpenMeshBoundary::dump halfedge boundary loop index 2 start 15 num_heh 36 : 15 25 31 41 47 57 81 105 129 153 165 185 197 217 229 249 273 297 355 347... /// boundary loop on other side of the ribbon /// again on /// /// /// sdf_R all negative /// boundary is fully inside the sphere /// /// sdf_C all negative (same as sdf_R) /// boundary is fully inside the union of sphere and box /// i 0 heh 15 eh 7 tv 5 ( 201.000, -50.250, -150.750) sdf_C -11.71 sdf_L 0.00 sdf_R -11.71 i 1 heh 25 eh 12 tv 7 ( 201.000, -25.125, -150.750) sdf_C -16.81 sdf_L 0.00 sdf_R -16.81 i 2 heh 31 eh 15 tv 9 ( 201.000, 0.000, -150.750) sdf_C -18.54 sdf_L 0.00 sdf_R -18.54 i 3 heh 41 eh 20 tv 11 ( 201.000, 25.125, -150.750) sdf_C -16.81 sdf_L 0.00 sdf_R -16.81 i 4 heh 47 eh 23 tv 13 ( 201.000, 50.250, -150.750) sdf_C -11.71 sdf_L 0.00 sdf_R -11.71 i 5 heh 57 eh 28 tv 15 ( 201.000, 75.375, -150.750) sdf_C -3.51 sdf_L 0.00 sdf_R -3.51 i 6 heh 81 eh 40 tv 21 ( 201.000, 100.500, -125.625) sdf_C -10.05 sdf_L 0.00 sdf_R -10.05 i 7 heh 105 eh 52 tv 27 ( 201.000, 125.625, -100.500) sdf_C -10.05 sdf_L 0.00 sdf_R -10.05 i 8 heh 129 eh 64 tv 33 ( 201.000, 150.750, -75.375) sdf_C -3.51 sdf_L 0.00 sdf_R -3.51 i 9 heh 153 eh 76 tv 39 ( 201.000, 150.750, -50.250) sdf_C -11.71 sdf_L 0.00 sdf_R -11.71 i 10 heh 165 eh 82 tv 42 ( 201.000, 150.750, -25.125) sdf_C -16.81 sdf_L 0.00 sdf_R -16.81 i 11 heh 185 eh 92 tv 47 ( 201.000, 150.750, 0.000) sdf_C -18.54 sdf_L 0.00 sdf_R -18.54 i 12 heh 197 eh 98 tv 50 ( 201.000, 150.750, 25.125) sdf_C -16.81 sdf_L 0.00 sdf_R -16.81 i 13 heh 217 eh 108 tv 55 ( 201.000, 150.750, 50.250) sdf_C -11.71 sdf_L 0.00 sdf_R -11.71 i 14 heh 229 eh 114 tv 58 ( 201.000, 150.750, 75.375) sdf_C -3.51 sdf_L 0.00 sdf_R -3.51 i 15 heh 249 eh 124 tv 64 ( 201.000, 125.625, 100.500) sdf_C -10.05 sdf_L 0.00 sdf_R -10.05 i 16 heh 273 eh 136 tv 70 ( 201.000, 100.500, 125.625) sdf_C -10.05 sdf_L 0.00 sdf_R -10.05 i 17 heh 297 eh 148 tv 76 ( 201.000, 75.375, 150.750) sdf_C -3.51 sdf_L 0.00 sdf_R -3.51 i 18 heh 355 eh 177 tv 88 ( 201.000, 50.250, 150.750) sdf_C -11.71 sdf_L 0.00 sdf_R -11.71 i 19 heh 347 eh 173 tv 86 ( 201.000, 25.125, 150.750) sdf_C -16.81 sdf_L 0.00 sdf_R -16.81 i 20 heh 339 eh 169 tv 84 ( 201.000, 0.000, 150.750) sdf_C -18.54 sdf_L 0.00 sdf_R -18.54 i 21 heh 331 eh 165 tv 82 ( 201.000, -25.125, 150.750) sdf_C -16.81 sdf_L 0.00 sdf_R -16.81 i 22 heh 323 eh 161 tv 80 ( 201.000, -50.250, 150.750) sdf_C -11.71 sdf_L 0.00 sdf_R -11.71 i 23 heh 315 eh 157 tv 74 ( 201.000, -75.375, 150.750) sdf_C -3.51 sdf_L 0.00 sdf_R -3.51 i 24 heh 293 eh 146 tv 68 ( 201.000, -100.500, 125.625) sdf_C -10.05 sdf_L 0.00 sdf_R -10.05 i 25 heh 269 eh 134 tv 62 ( 201.000, -125.625, 100.500) sdf_C -10.05 sdf_L 0.00 sdf_R -10.05 i 26 heh 245 eh 122 tv 56 ( 201.000, -150.750, 75.375) sdf_C -3.51 sdf_L 0.00 sdf_R -3.51 i 27 heh 219 eh 109 tv 53 ( 201.000, -150.750, 50.250) sdf_C -11.71 sdf_L 0.00 sdf_R -11.71 i 28 heh 209 eh 104 tv 48 ( 201.000, -150.750, 25.125) sdf_C -16.81 sdf_L 0.00 sdf_R -16.81 i 29 heh 187 eh 93 tv 45 ( 201.000, -150.750, 0.000) sdf_C -18.54 sdf_L 0.00 sdf_R -18.54 i 30 heh 177 eh 88 tv 40 ( 201.000, -150.750, -25.125) sdf_C -16.81 sdf_L 0.00 sdf_R -16.81 i 31 heh 155 eh 77 tv 37 ( 201.000, -150.750, -50.250) sdf_C -11.71 sdf_L 0.00 sdf_R -11.71 i 32 heh 145 eh 72 tv 31 ( 201.000, -150.750, -75.375) sdf_C -3.51 sdf_L 0.00 sdf_R -3.51 i 33 heh 125 eh 62 tv 25 ( 201.000, -125.625, -100.500) sdf_C -10.05 sdf_L 0.00 sdf_R -10.05 i 34 heh 101 eh 50 tv 19 ( 201.000, -100.500, -125.625) sdf_C -10.05 sdf_L 0.00 sdf_R -10.05 i 35 heh 77 eh 38 tv 2 ( 201.000, -75.375, -150.750) sdf_C -3.51 sdf_L 0.00 sdf_R -3.51 2017-06-09 19:14:21.244 INFO [6274680] [>::combine_hybrid@333] combine_hybrid boundary_loops 2 2017-06-09 19:14:21.244 INFO [6274680] [>::build_csg@205] NOpenMesh::build_csg DONE leftmesh V 1538 E 4608 F 3072 Euler [(V - E + F)] 2 rightmesh V 242 E 720 F 480 Euler [(V - E + F)] 2 combined V 92 E 184 F 92 Euler [(V - E + F)] 0