├── .gitignore ├── data ├── Figure15 │ ├── figure15.json │ ├── fig15.bat │ ├── fig15.sh │ └── grid_1.json ├── function_examples │ ├── 1-wave.json │ ├── 1-smile.json │ ├── 1-Gaussian.json │ ├── 1-cyclide.json │ ├── 1-teardrop.json │ ├── 1-sphere.json │ ├── 1-sphere-flat.json │ ├── 1-cylinder.json │ ├── 2-sphere.json │ ├── 2-concentric.json │ ├── 2-close-sphere.json │ ├── 2-cylSphere.json │ ├── 3-sphere.json │ ├── 3-cyl3.json │ └── 18-sphere.json ├── Figure19 │ ├── key.json │ ├── fig19.bat │ ├── fig19.sh │ └── grid_1.json ├── mesh │ ├── cube61.msh │ ├── tet.msh │ └── cube6.msh ├── Figure22 │ ├── doghead_800_int_tree.json │ ├── fig22a.bat │ ├── fig22a.sh │ ├── grid_1.json │ ├── fig22b.bat │ ├── doghead_800_tree.json │ ├── fig22b.sh │ ├── config.json │ └── doghead_800_shifted.xyz ├── Figure1 │ ├── fig1a.bat │ ├── fig1a.sh │ ├── fig1b.bat │ ├── fig1b.sh │ ├── 10-wikiBall-tree.json │ └── 10-wikiBall.json ├── Figure2 │ ├── fig2d.bat │ ├── fig2d.sh │ ├── grid_1.json │ └── figure2.json ├── Figure18 │ ├── fig18.bat │ ├── fig18.sh │ ├── grid_1.json │ └── config.json ├── Figure10 │ ├── fig10d.bat │ ├── fig10d.sh │ ├── grid_1.json │ └── 2-cylSphere.json ├── Figure11 │ ├── fig11b.bat │ ├── fig11b.sh │ ├── grid_1.json │ └── 3-cylinder.json ├── Figure13 │ ├── fig13b.bat │ ├── fig13b.sh │ ├── grid_1.json │ └── figure13.json ├── Figure20 │ ├── grid_1.json │ ├── fig20a.bat │ ├── fig20a.sh │ ├── csg_examples_1_tree.json │ └── csg_examples_1.json ├── Figure21 │ ├── grid_1.json │ ├── fig21a.bat │ ├── fig21a.sh │ ├── csg_examples_3_tree.json │ └── csg_examples_3.json ├── Figure14 │ ├── grid_1.json │ ├── fig14b.bat │ ├── fig14b.sh │ ├── trans_sphere.json │ ├── figure14_tree.json │ └── figure14.json └── config.json ├── cmake ├── cli11.cmake ├── mtet.cmake ├── convex_hull_membership.cmake ├── implicit_functions.cmake ├── unordered_dense.cmake ├── Eigen3.cmake ├── smallvector.cmake └── nlohmann-json.cmake ├── CMakeLists.txt ├── include ├── tet_quality.h ├── timer.h ├── grid_mesh.h └── subdivide_multi.h ├── README.md ├── LICENSE.txt └── app └── isosurfacing.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | build/* 2 | .DS_Store 3 | .idea -------------------------------------------------------------------------------- /data/Figure15/figure15.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "teardrop" 4 | } 5 | ] 6 | -------------------------------------------------------------------------------- /data/function_examples/1-wave.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "wave" 4 | } 5 | ] 6 | -------------------------------------------------------------------------------- /data/function_examples/1-smile.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "smile" 4 | } 5 | ] 6 | -------------------------------------------------------------------------------- /data/function_examples/1-Gaussian.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "Gaussian" 4 | } 5 | ] 6 | -------------------------------------------------------------------------------- /data/function_examples/1-cyclide.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "cyclide" 4 | } 5 | ] 6 | -------------------------------------------------------------------------------- /data/function_examples/1-teardrop.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "teardrop" 4 | } 5 | ] 6 | -------------------------------------------------------------------------------- /data/Figure19/key.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"shader", 4 | "name": "key", 5 | "delta": 1e-8 6 | } 7 | ] -------------------------------------------------------------------------------- /data/mesh/cube61.msh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jurwen/Adaptive-grid-generation/HEAD/data/mesh/cube61.msh -------------------------------------------------------------------------------- /data/Figure22/doghead_800_int_tree.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"Intersection", 4 | "elements":[ 5 | -1, 6 | -2 7 | ] 8 | } 9 | ] 10 | -------------------------------------------------------------------------------- /data/Figure1/fig1a.bat: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | isosurfacing.exe ../../data/mesh/cube6.msh ../../data/Figure1/10-wikiBall.json -t 0.0005 4 | 5 | pause -------------------------------------------------------------------------------- /data/Figure19/fig19.bat: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | isosurfacing.exe ../../data/Figure19/grid_1.json ../../data/Figure19/key.json -t 0.001 4 | 5 | pause -------------------------------------------------------------------------------- /data/Figure2/fig2d.bat: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | isosurfacing.exe ../../data/Figure2/grid_1.json ../../data/Figure2/figure2.json -t 0.01 4 | 5 | pause -------------------------------------------------------------------------------- /data/Figure15/fig15.bat: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | isosurfacing.exe ../../data/Figure15/grid_1.json ../../data/Figure15/figure15.json -t 0.005 4 | 5 | pause -------------------------------------------------------------------------------- /data/Figure18/fig18.bat: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | isosurfacing.exe ../../data/Figure18/grid_1.json ../../data/Figure18/config.json -t 0.005 4 | 5 | pause -------------------------------------------------------------------------------- /data/Figure22/fig22a.bat: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | isosurfacing.exe ../../data/Figure22/grid_1.json ../../data/Figure22/config.json -t 0.008 4 | 5 | pause -------------------------------------------------------------------------------- /data/Figure10/fig10d.bat: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | isosurfacing.exe ../../data/Figure10/grid_1.json ../../data/Figure10/2-cylSphere.json -t 0.01 4 | 5 | pause -------------------------------------------------------------------------------- /data/Figure11/fig11b.bat: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | isosurfacing.exe ../../data/Figure11/grid_1.json ../../data/Figure11/3-cylinder.json -t 0.005 4 | 5 | pause -------------------------------------------------------------------------------- /data/Figure13/fig13b.bat: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | isosurfacing.exe ../../data/Figure13/grid_1.json ../../data/Figure13/figure13.json -t 0.001 -o "MI" 4 | 5 | pause -------------------------------------------------------------------------------- /data/Figure1/fig1a.sh: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | chmod +x isosurfacing 4 | 5 | ./isosurfacing ../../data/mesh/cube6.msh ../../data/Figure1/10-wikiBall.json -t 0.0005 6 | -------------------------------------------------------------------------------- /data/Figure18/fig18.sh: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | chmod +x isosurfacing 4 | 5 | ./isosurfacing ../../data/Figure18/grid_1.json ../../data/Figure18/config.json -t 0.005 6 | -------------------------------------------------------------------------------- /data/Figure19/fig19.sh: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | chmod +x isosurfacing 4 | 5 | ./isosurfacing ../../data/Figure19/grid_1.json ../../data/Figure19/key.json -t 0.001 6 | -------------------------------------------------------------------------------- /data/Figure2/fig2d.sh: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | chmod +x isosurfacing 4 | 5 | ./isosurfacing ../../data/Figure2/grid_1.json ../../data/Figure2/figure2.json -t 0.01 6 | -------------------------------------------------------------------------------- /data/Figure22/fig22a.sh: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | chmod +x isosurfacing 4 | 5 | ./isosurfacing ../../data/Figure22/grid_1.json ../../data/Figure22/config.json -t 0.008 6 | -------------------------------------------------------------------------------- /data/Figure10/fig10d.sh: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | chmod +x isosurfacing 4 | 5 | ./isosurfacing ../../data/Figure10/grid_1.json ../../data/Figure10/2-cylSphere.json -t 0.01 6 | -------------------------------------------------------------------------------- /data/Figure11/fig11b.sh: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | chmod +x isosurfacing 4 | 5 | ./isosurfacing ../../data/Figure11/grid_1.json ../../data/Figure11/3-cylinder.json -t 0.005 6 | -------------------------------------------------------------------------------- /data/Figure15/fig15.sh: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | chmod +x isosurfacing 4 | 5 | ./isosurfacing ../../data/Figure15/grid_1.json ../../data/Figure15/figure15.json -t 0.005 6 | -------------------------------------------------------------------------------- /data/Figure13/fig13b.sh: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | chmod +x isosurfacing 4 | 5 | ./isosurfacing ../../data/Figure13/grid_1.json ../../data/Figure13/figure13.json -t 0.001 -o "MI" 6 | -------------------------------------------------------------------------------- /data/Figure11/grid_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution":[ 3 | 1 4 | ], 5 | "bbox_min":[ 6 | 0, 7 | 0, 8 | 0 9 | ], 10 | "bbox_max":[ 11 | 1, 12 | 1, 13 | 1 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /data/Figure15/grid_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution":[ 3 | 1 4 | ], 5 | "bbox_min":[ 6 | 0, 7 | 0, 8 | 0 9 | ], 10 | "bbox_max":[ 11 | 1, 12 | 1, 13 | 1 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /data/Figure20/grid_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution":[ 3 | 2 4 | ], 5 | "bbox_min":[ 6 | 0, 7 | 0, 8 | 0 9 | ], 10 | "bbox_max":[ 11 | 1, 12 | 1, 13 | 1 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /data/Figure21/grid_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution":[ 3 | 2 4 | ], 5 | "bbox_min":[ 6 | 0, 7 | 0, 8 | 0 9 | ], 10 | "bbox_max":[ 11 | 1, 12 | 1, 13 | 1 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /data/Figure10/grid_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution":[ 3 | 1 4 | ], 5 | "bbox_min":[ 6 | -2, 7 | -2, 8 | -2 9 | ], 10 | "bbox_max":[ 11 | 2, 12 | 2, 13 | 2 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /data/Figure13/grid_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution":[ 3 | 1 4 | ], 5 | "bbox_min":[ 6 | -2, 7 | -2, 8 | -2 9 | ], 10 | "bbox_max":[ 11 | 2, 12 | 2, 13 | 2 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /data/Figure14/grid_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution":[ 3 | 1 4 | ], 5 | "bbox_min":[ 6 | -2, 7 | -2, 8 | -2 9 | ], 10 | "bbox_max":[ 11 | 2, 12 | 2, 13 | 2 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /data/Figure19/grid_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution":[ 3 | 2 4 | ], 5 | "bbox_min":[ 6 | -1, 7 | -1, 8 | -1 9 | ], 10 | "bbox_max":[ 11 | 1, 12 | 1, 13 | 1 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /data/Figure2/grid_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution":[ 3 | 1 4 | ], 5 | "bbox_min":[ 6 | -1, 7 | -1, 8 | -1 9 | ], 10 | "bbox_max":[ 11 | 1, 12 | 1, 13 | 1 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /data/Figure18/grid_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution":[ 3 | 1 4 | ], 5 | "bbox_min":[ 6 | -2, 7 | -2, 8 | -1.5 9 | ], 10 | "bbox_max":[ 11 | 2, 12 | 2, 13 | 2.5 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /data/Figure22/grid_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution":[ 3 | 1 4 | ], 5 | "bbox_min":[ 6 | -1.5, 7 | -1.5, 8 | -1.5 9 | ], 10 | "bbox_max":[ 11 | 1, 12 | 1, 13 | 1 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /data/Figure1/fig1b.bat: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | isosurfacing.exe ../../data/mesh/cube6.msh ../../data/Figure1/10-wikiBall.json -t 0.0005 "-o" "CSG" "--tree" ../../data/Figure1/10-wikiBall-tree.json 4 | 5 | pause -------------------------------------------------------------------------------- /data/Figure14/fig14b.bat: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | isosurfacing.exe ../../data/Figure14/grid_1.json ../../data/Figure14/figure14.json -t 0.001 -o "CSG" --tree ../../data/Figure14/figure14_tree.json 4 | 5 | pause -------------------------------------------------------------------------------- /data/function_examples/1-sphere.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"sphere", 4 | "center":[ 5 | 0.5112321, 6 | 0.51412521, 7 | 0.51 8 | ], 9 | "radius":0.3, 10 | "squared": false 11 | } 12 | ] 13 | -------------------------------------------------------------------------------- /data/Figure22/fig22b.bat: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | isosurfacing.exe ../../data/Figure22/grid_1.json ../../data/Figure22/config.json -t 0.008 -o "CSG" --tree ../../data/Figure22/doghead_800_int_tree.json 4 | 5 | pause -------------------------------------------------------------------------------- /data/Figure20/fig20a.bat: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | isosurfacing.exe ../../data/Figure20/grid_1.json ../../data/Figure20/csg_examples_1.json -t 0.01 -o "CSG" --tree ../../data/Figure20/csg_examples_1_tree.json 4 | 5 | pause -------------------------------------------------------------------------------- /data/Figure21/fig21a.bat: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | isosurfacing.exe ../../data/Figure21/grid_1.json ../../data/Figure21/csg_examples_3.json -t 0.03 -o "CSG" --tree ../../data/Figure21/csg_examples_3_tree.json 4 | 5 | pause -------------------------------------------------------------------------------- /data/function_examples/1-sphere-flat.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"sphere", 4 | "center":[ 5 | 0, 6 | 0, 7 | 0 8 | ], 9 | "radius":0.8, 10 | "squared": true, 11 | "flat": true 12 | } 13 | ] 14 | -------------------------------------------------------------------------------- /data/Figure1/fig1b.sh: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | chmod +x isosurfacing 4 | 5 | ./isosurfacing ../../data/mesh/cube6.msh ../../data/Figure1/10-wikiBall.json -t 0.0005 "-o" "CSG" "--tree" ../../data/Figure1/10-wikiBall-tree.json 6 | -------------------------------------------------------------------------------- /data/Figure14/fig14b.sh: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | chmod +x isosurfacing 4 | 5 | ./isosurfacing ../../data/Figure14/grid_1.json ../../data/Figure14/figure14.json -t 0.001 -o "CSG" --tree ../../data/Figure14/figure14_tree.json 6 | -------------------------------------------------------------------------------- /data/Figure22/doghead_800_tree.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"Intersection", 4 | "elements":[ 5 | 2, 6 | -1 7 | ] 8 | }, 9 | { 10 | "type":"Negation", 11 | "elements":[ 12 | -2, 13 | 0 14 | ] 15 | } 16 | ] 17 | -------------------------------------------------------------------------------- /data/Figure22/fig22b.sh: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | chmod +x isosurfacing 4 | 5 | ./isosurfacing ../../data/Figure22/grid_1.json ../../data/Figure22/config.json -t 0.008 -o "CSG" --tree ../../data/Figure22/doghead_800_int_tree.json 6 | -------------------------------------------------------------------------------- /data/Figure20/fig20a.sh: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | chmod +x isosurfacing 4 | 5 | ./isosurfacing ../../data/Figure20/grid_1.json ../../data/Figure20/csg_examples_1.json -t 0.01 -o "CSG" --tree ../../data/Figure20/csg_examples_1_tree.json 6 | -------------------------------------------------------------------------------- /data/Figure21/fig21a.sh: -------------------------------------------------------------------------------- 1 | cd ../../build/Release 2 | 3 | chmod +x isosurfacing 4 | 5 | ./isosurfacing ../../data/Figure21/grid_1.json ../../data/Figure21/csg_examples_3.json -t 0.03 -o "CSG" --tree ../../data/Figure21/csg_examples_3_tree.json 6 | -------------------------------------------------------------------------------- /data/mesh/tet.msh: -------------------------------------------------------------------------------- 1 | $MeshFormat 2 | 4.1 0 8 3 | $EndMeshFormat 4 | $Nodes 5 | 1 4 1 4 6 | 3 1 0 4 7 | 1 8 | 2 9 | 3 10 | 4 11 | 0 0 0 12 | 1 0 0 13 | 0 1 0 14 | 0 0 1 15 | $EndNodes 16 | $Elements 17 | 1 1 1 1 18 | 3 1 4 1 19 | 1 1 2 3 4 20 | $EndElements 21 | -------------------------------------------------------------------------------- /data/Figure14/trans_sphere.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"sphere", 4 | "center":[ 5 | 0.12941, 6 | 0.5834, 7 | 0.2483 8 | ], 9 | "radius":0.7, 10 | "squared": true 11 | } 12 | ] 13 | -------------------------------------------------------------------------------- /cmake/cli11.cmake: -------------------------------------------------------------------------------- 1 | if(TARGET CLI11::CLI11) 2 | return() 3 | endif() 4 | 5 | include(FetchContent) 6 | FetchContent_Declare( 7 | cli11 8 | GIT_REPOSITORY https://github.com/CLIUtils/CLI11.git 9 | GIT_TAG v2.3.2 10 | ) 11 | FetchContent_MakeAvailable(cli11) 12 | -------------------------------------------------------------------------------- /cmake/mtet.cmake: -------------------------------------------------------------------------------- 1 | if (TARGET mtet::mtet) 2 | return() 3 | endif() 4 | 5 | include(FetchContent) 6 | FetchContent_Declare( 7 | mtet 8 | GIT_REPOSITORY https://github.com/qnzhou/mtet.git 9 | GIT_TAG main 10 | ) 11 | 12 | FetchContent_MakeAvailable(mtet) 13 | -------------------------------------------------------------------------------- /data/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "gridResolution": 21, 3 | "gridBbox": [[0, 0, 0], [1, 1, 1]], 4 | "tetMeshFile": "../build/Release/mesh.json", 5 | "funcFile":"../build/Release/function_value.json", 6 | "outputDir":"./", 7 | "useLookup":true, 8 | "useSecondaryLookup":true, 9 | "useTopoRayShooting":true 10 | } 11 | -------------------------------------------------------------------------------- /data/Figure2/figure2.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "figure2" 4 | }, 5 | { 6 | "type": "plane", 7 | "point": [ 8 | 0, 9 | 0, 10 | 0 11 | ], 12 | "normal": [ 13 | 0, 14 | 0, 15 | 1 16 | ] 17 | } 18 | ] 19 | -------------------------------------------------------------------------------- /cmake/convex_hull_membership.cmake: -------------------------------------------------------------------------------- 1 | if (TARGET convex_hull_membership) 2 | return() 3 | endif() 4 | 5 | include(FetchContent) 6 | FetchContent_Declare( 7 | convex_hull_membership 8 | GIT_REPOSITORY https://github.com/qnzhou/convex_hull_membership.git 9 | GIT_TAG main 10 | ) 11 | 12 | FetchContent_MakeAvailable(convex_hull_membership) 13 | -------------------------------------------------------------------------------- /data/function_examples/1-cylinder.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "cylinder", 4 | "axis_point": [ 5 | 0.5241, 6 | 0.5321, 7 | 0.4214 8 | ], 9 | "axis_vector": [ 10 | 0, 11 | 0, 12 | 1 13 | ], 14 | "radius": 0.2, 15 | "squared": false 16 | } 17 | ] 18 | -------------------------------------------------------------------------------- /data/Figure18/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "input":[ 3 | { 4 | "color": [ 5 | 0.49411764705882355, 6 | 0.1607843137254902, 7 | 0.5294117647058824, 8 | 1.0 9 | ], 10 | "type":"rbf", 11 | "points":"planck_1011.xyz", 12 | "rbf_coeffs":"planck_1011_coeff", 13 | "name":"1", 14 | "samples":"1_sample.xyz" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /data/function_examples/2-sphere.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"sphere", 4 | "center":[ 5 | 3.452838736234284e-4, 6 | -1.0786219471257356e-4, 7 | 4.89271203828984e-4 8 | ], 9 | "radius":0.49929624763308034 10 | }, 11 | { 12 | "type":"sphere", 13 | "center":[ 14 | 0.4994385856433444, 15 | 4.962172654549902e-4, 16 | 8.670986710973788e-4 17 | ], 18 | "radius":0.5008509450705404 19 | } 20 | ] -------------------------------------------------------------------------------- /data/Figure22/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "input":[ 3 | { 4 | "color": [ 5 | 0.49411764705882355, 6 | 0.1607843137254902, 7 | 0.5294117647058824, 8 | 1.0 9 | ], 10 | "type":"rbf", 11 | "points":"doghead_800_shifted.xyz", 12 | "rbf_coeffs":"doghead_800_shifted_coeff", 13 | "name":"1", 14 | "samples":"1_sample.xyz" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /data/function_examples/2-concentric.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"sphere", 4 | "center":[ 5 | -6.854902847734613e-5, 6 | -3.1899844922706616e-4, 7 | -9.483435437863527e-4 8 | ], 9 | "radius":0.19916763551648828 10 | }, 11 | { 12 | "type":"sphere", 13 | "center":[ 14 | 4.325005114584604e-4, 15 | 2.3380249054754916e-4, 16 | -6.797904195856162e-4 17 | ], 18 | "radius":0.2993018746666167 19 | } 20 | ] -------------------------------------------------------------------------------- /cmake/implicit_functions.cmake: -------------------------------------------------------------------------------- 1 | if (TARGET implicit_functions::implicit_functions) 2 | return() 3 | endif() 4 | 5 | include(FetchContent) 6 | FetchContent_Declare( 7 | implicit_functions 8 | GIT_REPOSITORY https://github.com/duxingyi-charles/implicit_functions.git 9 | #GIT_REPOSITORY https://github.com/Jurwen/implicit_functions.git 10 | GIT_TAG main 11 | ) 12 | 13 | FetchContent_MakeAvailable(implicit_functions) 14 | -------------------------------------------------------------------------------- /data/function_examples/2-close-sphere.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"sphere", 4 | "center":[ 5 | 0.5, 6 | 0.5, 7 | 0.5 8 | ], 9 | "radius":0.3, 10 | "squared": false 11 | }, 12 | { 13 | "type":"sphere", 14 | "center":[ 15 | 0.5025, 16 | 0.5, 17 | 0.5 18 | ], 19 | "radius":0.3, 20 | "squared": false 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /data/mesh/cube6.msh: -------------------------------------------------------------------------------- 1 | $MeshFormat 2 | 4.1 0 8 3 | $EndMeshFormat 4 | $Entities 5 | 0 0 0 1 6 | 1 0 0 0 1 1 1 0 0 7 | $EndEntities 8 | $Nodes 9 | 1 8 1 8 10 | 3 1 0 8 11 | 1 12 | 2 13 | 3 14 | 4 15 | 5 16 | 6 17 | 7 18 | 8 19 | 0 0 0 20 | 0 0 1 21 | 0 1 0 22 | 0 1 1 23 | 1 0 0 24 | 1 0 1 25 | 1 1 0 26 | 1 1 1 27 | $EndNodes 28 | $Elements 29 | 1 6 1 6 30 | 3 1 4 6 31 | 1 1 2 8 4 32 | 2 8 1 6 2 33 | 3 5 1 6 8 34 | 4 5 7 1 8 35 | 5 1 8 7 3 36 | 6 8 3 1 4 37 | $EndElements 38 | -------------------------------------------------------------------------------- /data/function_examples/2-cylSphere.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"cylinder", 4 | "axis_point":[ 5 | 0.49, 6 | 0.51, 7 | 0.51 8 | ], 9 | "axis_vector":[ 10 | 0, 11 | 0, 12 | 1 13 | ], 14 | "radius":0.25 15 | }, 16 | { 17 | "type":"sphere", 18 | "center":[ 19 | 0.6165, 20 | 0.51, 21 | 0.51 22 | ], 23 | "radius":0.375 24 | } 25 | ] 26 | -------------------------------------------------------------------------------- /cmake/unordered_dense.cmake: -------------------------------------------------------------------------------- 1 | if(TARGET unordered_dense::unordered_dense) 2 | return() 3 | endif() 4 | 5 | message(STATUS "Third-party (external): creating target 'unordered_dense::unordered_dense'") 6 | 7 | include(CPM) 8 | CPMAddPackage( 9 | NAME unordered_dense 10 | GITHUB_REPOSITORY martinus/unordered_dense 11 | GIT_TAG v4.1.2 12 | ) 13 | 14 | set_target_properties(unordered_dense PROPERTIES SYSTEM ON) 15 | set_target_properties(unordered_dense PROPERTIES FOLDER third_party) 16 | -------------------------------------------------------------------------------- /data/Figure10/2-cylSphere.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"cylinder", 4 | "axis_point":[ 5 | 0.08, 6 | 0.1, 7 | 0.0 8 | ], 9 | "axis_vector":[ 10 | 0, 11 | 0, 12 | 1 13 | ], 14 | "radius":1, 15 | "squared": false 16 | }, 17 | { 18 | "type":"sphere", 19 | "center":[ 20 | 0.381, 21 | 0.1, 22 | 0.1 23 | ], 24 | "radius":1.3, 25 | "squared": false 26 | } 27 | ] 28 | -------------------------------------------------------------------------------- /cmake/Eigen3.cmake: -------------------------------------------------------------------------------- 1 | include_guard() 2 | 3 | if (NOT TARGET Eigen3::Eigen) 4 | FetchContent_Declare( 5 | Eigen 6 | GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git 7 | GIT_TAG 3.4.0 8 | GIT_SHALLOW TRUE 9 | ) 10 | 11 | FetchContent_GetProperties(Eigen) 12 | if(NOT eigen_POPULATED) 13 | FetchContent_Populate(Eigen) 14 | add_library(Eigen3::Eigen INTERFACE IMPORTED) 15 | target_include_directories(Eigen3::Eigen SYSTEM INTERFACE 16 | ${eigen_SOURCE_DIR}) 17 | endif() 18 | endif() -------------------------------------------------------------------------------- /data/Figure20/csg_examples_1_tree.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "Intersection", 4 | "elements": [ 5 | 2, 6 | 3 7 | ] 8 | }, 9 | { 10 | "type": "Negation", 11 | "elements": [ 12 | -1, 13 | 0 14 | ] 15 | }, 16 | { 17 | "type": "Intersection", 18 | "elements": [ 19 | -2, 20 | 4 21 | ] 22 | }, 23 | { 24 | "type": "Intersection", 25 | "elements": [ 26 | -3, 27 | -4 28 | ] 29 | } 30 | ] 31 | -------------------------------------------------------------------------------- /data/function_examples/3-sphere.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"sphere", 4 | "center":[ 5 | 3.452838736234284e-4, 6 | -1.0786219471257356e-4, 7 | 4.89271203828984e-4 8 | ], 9 | "radius":0.49929624763308034 10 | }, 11 | { 12 | "type":"sphere", 13 | "center":[ 14 | 0.4994385856433444, 15 | 4.962172654549902e-4, 16 | 8.670986710973788e-4 17 | ], 18 | "radius":0.5008509450705404 19 | }, 20 | { 21 | "type":"sphere", 22 | "center":[ 23 | 4.3081557112254745e-4, 24 | 0.49939685582823945, 25 | -3.21743595981072e-5 26 | ], 27 | "radius":0.5006739673424041 28 | } 29 | ] -------------------------------------------------------------------------------- /data/Figure13/figure13.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"sphere", 4 | "center":[ 5 | -0.496, 6 | -1.516, 7 | 0.0 8 | ], 9 | "radius":2.0, 10 | "squared": false 11 | }, 12 | { 13 | "type":"sphere", 14 | "center":[ 15 | -0.63, 16 | 0.452, 17 | 0.0 18 | ], 19 | "radius":1.0, 20 | "squared": false 21 | }, 22 | { 23 | "type":"sphere", 24 | "center":[ 25 | 0.636, 26 | -0.64, 27 | 0.0 28 | ], 29 | "radius":1.348, 30 | "squared": false 31 | } 32 | ] 33 | -------------------------------------------------------------------------------- /cmake/smallvector.cmake: -------------------------------------------------------------------------------- 1 | if (TARGET smallvector::smallvector) 2 | return() 3 | endif() 4 | 5 | message(STATUS "Third-party (external): creating target 'smallvector::smallvector'") 6 | 7 | include(CPM) 8 | CPMAddPackage( 9 | NAME smallvector 10 | GITHUB_REPOSITORY thelink2012/SmallVector 11 | GIT_TAG febc8cb7b1a83d902b86dd1612feb7c86c690186 12 | DOWNLOAD_ONLY YES 13 | ) 14 | 15 | add_library(smallvector INTERFACE) 16 | target_include_directories(smallvector INTERFACE ${smallvector_SOURCE_DIR}) 17 | set_target_properties(smallvector PROPERTIES SYSTEM ON) 18 | set_target_properties(smallvector PROPERTIES FOLDER third_party) 19 | add_library(smallvector::smallvector ALIAS smallvector) 20 | -------------------------------------------------------------------------------- /data/function_examples/3-cyl3.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"cylinder", 4 | "axis_point":[ 5 | 0.71, 6 | 0.51, 7 | 0.71 8 | ], 9 | "axis_vector":[ 10 | 1, 11 | 1, 12 | 1 13 | ], 14 | "radius":0.455 15 | }, 16 | { 17 | "type":"cylinder", 18 | "axis_point":[ 19 | 1.57603, 20 | 0.51, 21 | 0.71 22 | ], 23 | "axis_vector":[ 24 | 1, 25 | 1, 26 | 1 27 | ], 28 | "radius":0.455 29 | }, 30 | { 31 | "type":"cylinder", 32 | "axis_point":[ 33 | 1.14301, 34 | 1.04033, 35 | 0.17967 36 | ], 37 | "axis_vector":[ 38 | 1, 39 | 1, 40 | 1 41 | ], 42 | "radius":0.465 43 | } 44 | ] 45 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | 3 | project(adaptive_mesh_refinement LANGUAGES CXX C) 4 | 5 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake) 6 | include(cli11) 7 | include(nlohmann-json) 8 | include(mtet) 9 | include(implicit_functions) 10 | include(convex_hull_membership) 11 | include(smallvector) 12 | include(unordered_dense) 13 | 14 | add_executable(isosurfacing "app/isosurfacing.cpp") 15 | 16 | if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) 17 | include(FeatureSummary) 18 | feature_summary(WHAT ALL) 19 | endif() 20 | 21 | target_compile_features(isosurfacing PRIVATE cxx_std_20) 22 | target_include_directories(isosurfacing PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) 23 | target_link_libraries(isosurfacing PRIVATE 24 | CLI11::CLI11 25 | mtet::mtet 26 | implicit_functions::implicit_functions 27 | convex_hull_membership 28 | unordered_dense::unordered_dense 29 | smallvector::smallvector 30 | ) -------------------------------------------------------------------------------- /data/Figure11/3-cylinder.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"cylinder", 4 | "axis_point":[ 5 | 0.326795, 6 | 0.6, 7 | 0.5 8 | ], 9 | "axis_vector":[ 10 | 0, 11 | 0, 12 | 1 13 | ], 14 | "radius":0.2, 15 | "squared": true 16 | }, 17 | { 18 | "type":"cylinder", 19 | "axis_point":[ 20 | 0.673205, 21 | 0.6, 22 | 0.5 23 | ], 24 | "axis_vector":[ 25 | 0.100335, 26 | 0, 27 | 1 28 | ], 29 | "radius":0.2, 30 | "squared": true 31 | }, 32 | { 33 | "type":"cylinder", 34 | "axis_point":[ 35 | 0.5, 36 | 0.5, 37 | 0.5 38 | ], 39 | "axis_vector":[ 40 | 0, 41 | -0.100335, 42 | 1 43 | ], 44 | "radius":0.2, 45 | "squared": true 46 | } 47 | ] 48 | -------------------------------------------------------------------------------- /data/Figure14/figure14_tree.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "Union", 4 | "elements": [ 5 | 2, 6 | 3 7 | ] 8 | }, 9 | { 10 | "type": "Intersection", 11 | "elements": [ 12 | 8, 13 | -8 14 | ] 15 | }, 16 | { 17 | "type": "Intersection", 18 | "elements": [ 19 | -1, 20 | 4 21 | ] 22 | }, 23 | { 24 | "type": "Intersection", 25 | "elements": [ 26 | -2, 27 | 5 28 | ] 29 | }, 30 | { 31 | "type": "Intersection", 32 | "elements": [ 33 | -3, 34 | 6 35 | ] 36 | }, 37 | { 38 | "type": "Intersection", 39 | "elements": [ 40 | -4, 41 | 7 42 | ] 43 | }, 44 | { 45 | "type": "Intersection", 46 | "elements": [ 47 | -5, 48 | -6 49 | ] 50 | }, 51 | { 52 | "type": "Negation", 53 | "elements": [ 54 | -7, 55 | 0 56 | ] 57 | } 58 | ] 59 | -------------------------------------------------------------------------------- /data/Figure20/csg_examples_1.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "torus", 4 | "center" :[ 5 | 0.51, 6 | 0.51, 7 | 0.51 8 | ], 9 | "axis_vector" :[ 10 | 0, 11 | 0, 12 | 1 13 | ], 14 | "major_radius" : 0.3, 15 | "minor_radius" : 0.1 16 | }, 17 | { 18 | "type": "cylinder", 19 | "axis_point" :[ 20 | 0.51, 21 | 0.51, 22 | 0.51 23 | ], 24 | "axis_vector" :[ 25 | 1, 26 | 0, 27 | 0 28 | ], 29 | "radius": 0.0999 30 | }, 31 | { 32 | "type": "cylinder", 33 | "axis_point" :[ 34 | 0.51, 35 | 0.51, 36 | 0.51 37 | ], 38 | "axis_vector" :[ 39 | 0.5, 40 | 0.866025, 41 | 0 42 | ], 43 | "radius": 0.0999 44 | }, 45 | { 46 | "type": "cylinder", 47 | "axis_point" :[ 48 | 0.51, 49 | 0.51, 50 | 0.51 51 | ], 52 | "axis_vector" :[ 53 | 0.5, 54 | -0.866025, 55 | 0 56 | ], 57 | "radius": 0.0999 58 | } 59 | ] 60 | -------------------------------------------------------------------------------- /data/Figure1/10-wikiBall-tree.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "Intersection", 4 | "elements": [ 5 | 2, 6 | 8 7 | ] 8 | }, 9 | { 10 | "type": "Intersection", 11 | "elements": [ 12 | 3, 13 | 14 14 | ] 15 | }, 16 | { 17 | "type": "Intersection", 18 | "elements": [ 19 | -1, 20 | 4 21 | ] 22 | }, 23 | { 24 | "type": "Intersection", 25 | "elements": [ 26 | -2, 27 | 5 28 | ] 29 | }, 30 | { 31 | "type": "Intersection", 32 | "elements": [ 33 | -3, 34 | 6 35 | ] 36 | }, 37 | { 38 | "type": "Intersection", 39 | "elements": [ 40 | -4, 41 | 7 42 | ] 43 | }, 44 | { 45 | "type": "Intersection", 46 | "elements": [ 47 | -5, 48 | -6 49 | ] 50 | }, 51 | { 52 | "type": "Negation", 53 | "elements": [ 54 | 9, 55 | 0 56 | ] 57 | }, 58 | { 59 | "type": "Union", 60 | "elements": [ 61 | 11, 62 | 10 63 | ] 64 | }, 65 | { 66 | "type": "Union", 67 | "elements": [ 68 | 12, 69 | 13 70 | ] 71 | }, 72 | { 73 | "type": "Negation", 74 | "elements": [ 75 | -7, 76 | 0 77 | ] 78 | }, 79 | { 80 | "type": "Negation", 81 | "elements": [ 82 | -8, 83 | 0 84 | ] 85 | }, 86 | { 87 | "type": "Negation", 88 | "elements": [ 89 | -9, 90 | 0 91 | ] 92 | }, 93 | { 94 | "type": "Negation", 95 | "elements": [ 96 | -10, 97 | 0 98 | ] 99 | } 100 | ] 101 | -------------------------------------------------------------------------------- /data/Figure14/figure14.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"plane", 4 | "point": [ 5 | 0, 6 | 1.3417, 7 | 0 8 | ], 9 | "normal": [ 10 | 0, 11 | 1, 12 | 0 13 | ] 14 | }, 15 | { 16 | "type":"plane", 17 | "point": [ 18 | 0, 19 | 0.667648, 20 | 0 21 | ], 22 | "normal": [ 23 | 0, 24 | -1, 25 | 0 26 | ] 27 | }, 28 | { 29 | "type":"plane", 30 | "point": [ 31 | 0.331145, 32 | 0, 33 | 0 34 | ], 35 | "normal": [ 36 | 1, 37 | 0, 38 | 0 39 | ] 40 | }, 41 | { 42 | "type":"plane", 43 | "point": [ 44 | -0.66229, 45 | 0, 46 | 0 47 | ], 48 | "normal": [ 49 | -1, 50 | 0, 51 | 0 52 | ] 53 | }, 54 | { 55 | "type":"plane", 56 | "point": [ 57 | 0, 58 | 0, 59 | 0.331145 60 | ], 61 | "normal": [ 62 | 0, 63 | 0, 64 | 1 65 | ] 66 | }, 67 | { 68 | "type":"plane", 69 | "point": [ 70 | 0, 71 | 0, 72 | -0.66229 73 | ], 74 | "normal": [ 75 | 0, 76 | 0, 77 | -1 78 | ] 79 | }, 80 | { 81 | "type":"sphere", 82 | "center":[ 83 | 0.12941, 84 | 0.5834, 85 | 0.2483 86 | ], 87 | "radius":0.7, 88 | "squared": true 89 | }, 90 | { 91 | "type":"plane", 92 | "point": [ 93 | 0, 94 | 0.2834, 95 | 0 96 | ], 97 | "normal": [ 98 | 0, 99 | 1, 100 | 0 101 | ] 102 | } 103 | ] 104 | -------------------------------------------------------------------------------- /data/Figure21/csg_examples_3_tree.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"Intersection", 4 | "elements":[ 5 | 3, 6 | 2 7 | ] 8 | }, 9 | { 10 | "type":"Negation", 11 | "elements":[ 12 | 12, 13 | 0 14 | ] 15 | }, 16 | { 17 | "type":"Intersection", 18 | "elements":[ 19 | -1, 20 | 4 21 | ] 22 | }, 23 | { 24 | "type":"Intersection", 25 | "elements":[ 26 | -2, 27 | 5 28 | ] 29 | }, 30 | { 31 | "type":"Intersection", 32 | "elements":[ 33 | -3, 34 | 6 35 | ] 36 | }, 37 | { 38 | "type":"Intersection", 39 | "elements":[ 40 | -4, 41 | 7 42 | ] 43 | }, 44 | { 45 | "type":"Intersection", 46 | "elements":[ 47 | -5, 48 | 8 49 | ] 50 | }, 51 | { 52 | "type":"Intersection", 53 | "elements":[ 54 | -6, 55 | 9 56 | ] 57 | }, 58 | { 59 | "type":"Intersection", 60 | "elements":[ 61 | -7, 62 | 10 63 | ] 64 | }, 65 | { 66 | "type":"Intersection", 67 | "elements":[ 68 | -8, 69 | 11 70 | ] 71 | }, 72 | { 73 | "type":"Intersection", 74 | "elements":[ 75 | -9, 76 | -10 77 | ] 78 | }, 79 | { 80 | "type":"Intersection", 81 | "elements":[ 82 | -11, 83 | 13 84 | ] 85 | }, 86 | { 87 | "type":"Intersection", 88 | "elements":[ 89 | -12, 90 | 14 91 | ] 92 | }, 93 | { 94 | "type":"Intersection", 95 | "elements":[ 96 | -13, 97 | 15 98 | ] 99 | }, 100 | { 101 | "type":"Intersection", 102 | "elements":[ 103 | -14, 104 | 16 105 | ] 106 | }, 107 | { 108 | "type":"Intersection", 109 | "elements":[ 110 | -15, 111 | 17 112 | ] 113 | }, 114 | { 115 | "type":"Intersection", 116 | "elements":[ 117 | -16, 118 | 18 119 | ] 120 | }, 121 | { 122 | "type":"Intersection", 123 | "elements":[ 124 | -17, 125 | 19 126 | ] 127 | }, 128 | { 129 | "type":"Intersection", 130 | "elements":[ 131 | -18, 132 | 20 133 | ] 134 | }, 135 | { 136 | "type":"Intersection", 137 | "elements":[ 138 | -19, 139 | -20 140 | ] 141 | } 142 | ] -------------------------------------------------------------------------------- /cmake/nlohmann-json.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020 Adobe. All rights reserved. 3 | # This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. You may obtain a copy 5 | # of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software distributed under 8 | # the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | # OF ANY KIND, either express or implied. See the License for the specific language 10 | # governing permissions and limitations under the License. 11 | # 12 | if(TARGET nlohmann_json::nlohmann_json) 13 | return() 14 | endif() 15 | 16 | message(STATUS "Third-party (external): creating target 'nlohmann_json::nlohmann_json'") 17 | 18 | # nlohmann_json is a big repo for a single header, so we just download the release archive 19 | set(NLOHMANNJSON_VERSION "v3.7.3") 20 | 21 | include(FetchContent) 22 | FetchContent_Declare( 23 | nlohmann_json 24 | URL "https://github.com/nlohmann/json/releases/download/${NLOHMANNJSON_VERSION}/include.zip" 25 | URL_HASH SHA256=87b5884741427220d3a33df1363ae0e8b898099fbc59f1c451113f6732891014 26 | ) 27 | FetchContent_MakeAvailable(nlohmann_json) 28 | 29 | add_library(nlohmann_json INTERFACE) 30 | add_library(nlohmann_json::nlohmann_json ALIAS nlohmann_json) 31 | 32 | include(GNUInstallDirs) 33 | target_include_directories(nlohmann_json INTERFACE 34 | "$/include" 35 | "$" 36 | ) 37 | 38 | # Let the code know that we have nlohmann json 39 | # TODO: This shouldn't be here (should be set by the caller) 40 | target_compile_definitions(nlohmann_json INTERFACE -DLA_WITH_NLOHMANNJSON) 41 | 42 | # Install rules 43 | set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME nlohmann_json) 44 | install(DIRECTORY ${nlohmann_json_SOURCE_DIR}/include/nlohmann DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) 45 | install(TARGETS nlohmann_json EXPORT NlohmannJson_Targets) 46 | install(EXPORT NlohmannJson_Targets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/nlohmann_json NAMESPACE nlohmann_json::) 47 | export(EXPORT NlohmannJson_Targets FILE "${CMAKE_CURRENT_BINARY_DIR}/NlohmannJsonTargets.cmake") 48 | 49 | -------------------------------------------------------------------------------- /data/Figure1/10-wikiBall.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "plane", 4 | "point": [ 5 | 0, 6 | 0.8125, 7 | 0 8 | ], 9 | "normal": [ 10 | 0, 11 | 1, 12 | 0 13 | ] 14 | }, 15 | { 16 | "type": "plane", 17 | "point": [ 18 | 0, 19 | 0.2125, 20 | 0 21 | ], 22 | "normal": [ 23 | 0, 24 | -1, 25 | 0 26 | ] 27 | }, 28 | { 29 | "type": "plane", 30 | "point": [ 31 | 0.8125, 32 | 0, 33 | 0 34 | ], 35 | "normal": [ 36 | 1, 37 | 0, 38 | 0 39 | ] 40 | }, 41 | { 42 | "type": "plane", 43 | "point": [ 44 | 0.2125, 45 | 0, 46 | 0 47 | ], 48 | "normal": [ 49 | -1, 50 | 0, 51 | 0 52 | ] 53 | }, 54 | { 55 | "type": "plane", 56 | "point": [ 57 | 0, 58 | 0, 59 | 0.8125 60 | ], 61 | "normal": [ 62 | 0, 63 | 0, 64 | 1 65 | ] 66 | }, 67 | { 68 | "type": "plane", 69 | "point": [ 70 | 0, 71 | 0, 72 | 0.2125 73 | ], 74 | "normal": [ 75 | 0, 76 | 0, 77 | -1 78 | ] 79 | }, 80 | { 81 | "type": "cylinder", 82 | "axis_point": [ 83 | 0.5125, 84 | 0.5125, 85 | 0 86 | ], 87 | "axis_vector": [ 88 | 0, 89 | 0, 90 | 1 91 | ], 92 | "radius": 0.2, 93 | "squared": true 94 | }, 95 | { 96 | "type": "cylinder", 97 | "axis_point": [ 98 | 0.5125, 99 | 0, 100 | 0.5125 101 | ], 102 | "axis_vector": [ 103 | 0, 104 | 1, 105 | 0 106 | ], 107 | "radius": 0.2, 108 | "squared": true 109 | }, 110 | { 111 | "type": "cylinder", 112 | "axis_point": [ 113 | 0, 114 | 0.5125, 115 | 0.5125 116 | ], 117 | "axis_vector": [ 118 | 1, 119 | 0, 120 | 0 121 | ], 122 | "radius": 0.2, 123 | "squared": true 124 | }, 125 | { 126 | "type": "sphere", 127 | "center": [ 128 | 0.5125, 129 | 0.5125, 130 | 0.5125 131 | ], 132 | "radius": 0.4, 133 | "squared": true 134 | } 135 | ] 136 | -------------------------------------------------------------------------------- /data/function_examples/18-sphere.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"sphere", 4 | "center":[ 5 | 0.5000863209684059, 6 | 0.49997303445132185, 7 | 0.5001223178009573 8 | ], 9 | "radius":0.12482406190827008 10 | }, 11 | { 12 | "type":"sphere", 13 | "center":[ 14 | 0.6248596464108361, 15 | 0.5001240543163638, 16 | 0.5002167746677744 17 | ], 18 | "radius":0.1252127362676351 19 | }, 20 | { 21 | "type":"sphere", 22 | "center":[ 23 | 0.5001077038927806, 24 | 0.6248492139570598, 25 | 0.49999195641010047 26 | ], 27 | "radius":0.12516849183560103 28 | }, 29 | { 30 | "type":"sphere", 31 | "center":[ 32 | 0.5001956839887345, 33 | 0.5000661294299564, 34 | 0.6250745908302835 35 | ], 36 | "radius":0.12496030063061711 37 | }, 38 | { 39 | "type":"sphere", 40 | "center":[ 41 | 0.39995610279854005, 42 | 0.39983256315600824, 43 | 0.3999683587195556 44 | ], 45 | "radius":0.12486945641551507 46 | }, 47 | { 48 | "type":"sphere", 49 | "center":[ 50 | 0.40002869362449317, 51 | 0.3999294231871348, 52 | 0.6001218828548991 53 | ], 54 | "radius":0.1251614682421524 55 | }, 56 | { 57 | "type":"sphere", 58 | "center":[ 59 | 0.4000584884858513, 60 | 0.6000994616355266, 61 | 0.40024367648110515 62 | ], 63 | "radius":0.12493324691120354 64 | }, 65 | { 66 | "type":"sphere", 67 | "center":[ 68 | 0.4000841145503839, 69 | 0.6002425085364351, 70 | 0.5998540751687793 71 | ], 72 | "radius":0.12480188582778477 73 | }, 74 | { 75 | "type":"sphere", 76 | "center":[ 77 | 0.600187868039394, 78 | 0.4001123587316094, 79 | 0.39996830040949233 80 | ], 81 | "radius":0.12478976752157843 82 | }, 83 | { 84 | "type":"sphere", 85 | "center":[ 86 | 0.5999368709855876, 87 | 0.39993098976148245, 88 | 0.6001439824718386 89 | ], 90 | "radius":0.12483125212280817 91 | }, 92 | { 93 | "type":"sphere", 94 | "center":[ 95 | 0.6001398822262679, 96 | 0.5999748862165071, 97 | 0.4000299330125938 98 | ], 99 | "radius":0.12523706294353007 100 | }, 101 | { 102 | "type":"sphere", 103 | "center":[ 104 | 0.5999093951497778, 105 | 0.59976466379739, 106 | 0.6001667765621918 107 | ], 108 | "radius":0.12504263622164033 109 | }, 110 | { 111 | "type":"sphere", 112 | "center":[ 113 | 0.3998177824747407, 114 | 0.5000468569409583, 115 | 0.49994900944619325 116 | ], 117 | "radius":0.1251669273073903 118 | }, 119 | { 120 | "type":"sphere", 121 | "center":[ 122 | 0.5999002801986768, 123 | 0.5002187593835816, 124 | 0.5000387209078968 125 | ], 126 | "radius":0.12518475726128367 127 | }, 128 | { 129 | "type":"sphere", 130 | "center":[ 131 | 0.5001708404105658, 132 | 0.4001889463065761, 133 | 0.4997507797085935 134 | ], 135 | "radius":0.12490621984070022 136 | }, 137 | { 138 | "type":"sphere", 139 | "center":[ 140 | 0.4999222819525587, 141 | 0.6001240829010057, 142 | 0.5002255891248177 143 | ], 144 | "radius":0.12492745435808132 145 | }, 146 | { 147 | "type":"sphere", 148 | "center":[ 149 | 0.5000494638167944, 150 | 0.49991802983983313, 151 | 0.40017103064450965 152 | ], 153 | "radius":0.12519277757631317 154 | }, 155 | { 156 | "type":"sphere", 157 | "center":[ 158 | 0.5002437005698794, 159 | 0.4997500680122914, 160 | 0.6002129867589107 161 | ], 162 | "radius":0.12494797432981974 163 | } 164 | ] -------------------------------------------------------------------------------- /include/tet_quality.h: -------------------------------------------------------------------------------- 1 | // 2 | // tet_quality.h 3 | // adaptive_mesh_refinement 4 | // 5 | // Created by Yiwen Ju on 12/28/23. 6 | 7 | #ifndef tet_quality_h 8 | #define tet_quality_h 9 | #include 10 | #include 11 | 12 | double dot(const valarray &a, const valarray &b) { 13 | return (a * b).sum(); 14 | } 15 | 16 | valarray normalize(const valarray &a) { 17 | return a / sqrt(dot(a, a)); 18 | } 19 | 20 | double norm(const valarray &a) { 21 | return sqrt(dot(a, a)); 22 | } 23 | 24 | valarray perp(const valarray &a){ 25 | return {-a[1], a[0]}; 26 | } 27 | 28 | valarray cross(const valarray &a, const valarray &b) { 29 | valarray c(3); 30 | c[0] = a[1] * b[2] - a[2] * b[1]; 31 | c[1] = a[2] * b[0] - a[0] * b[2]; 32 | c[2] = a[0] * b[1] - a[1] * b[0]; 33 | return c; 34 | } 35 | 36 | std::array tet_metric_labels = {"total tet number: ", 37 | "active tet number: ", 38 | "minimum radius ratio among all tets: ", 39 | "minimum radius ratio amond active tets: ", 40 | "two functions' gurobi: ", 41 | "three functions' gurobi: " 42 | }; 43 | 44 | std::valarray mult(const std::valarray& a, const std::valarray& b){ 45 | double xcross, ycross, zcross; 46 | xcross = a[1] * b[2] - a[2] * b[1]; 47 | ycross = a[2] * b[0] - a[0] * b[2]; 48 | zcross = a[0] * b[1] - a[1] * b[0]; 49 | 50 | return {xcross, ycross, zcross}; 51 | } 52 | 53 | double tet_radius_ratio(const std::array,4> &pts) 54 | { 55 | 56 | // Determine side vectors 57 | std::array, 6> side; 58 | for (int i = 0; i < 6; ++i) 59 | { 60 | side[i].resize(3); 61 | } 62 | side[0] = {pts[1][0] - pts[0][0], pts[1][1] - pts[0][1], 63 | pts[1][2] - pts[0][2]}; 64 | 65 | side[1]={pts[2][0] - pts[1][0], pts[2][1] - pts[1][1], 66 | pts[2][2] - pts[1][2]}; 67 | 68 | side[2] = {pts[0][0] - pts[2][0], pts[0][1] - pts[2][1], 69 | pts[0][2] - pts[2][2]}; 70 | 71 | side[3] = {pts[3][0] - pts[0][0], pts[3][1] - pts[0][1], 72 | pts[3][2] - pts[0][2]}; 73 | 74 | side[4] = {pts[3][0] - pts[1][0], pts[3][1] - pts[1][1], 75 | pts[3][2] - pts[1][2]}; 76 | 77 | side[5] = {pts[3][0] - pts[2][0], pts[3][1] - pts[2][1], 78 | pts[3][2] - pts[2][2]}; 79 | 80 | std::valarray numerator = dot(side[3], side[3]) * mult(side[2],side[0]) + 81 | dot(side[2], side[2]) * mult(side[3] ,side[0]) + dot(side[0], side[0]) * mult(side[3] , side[2]); 82 | 83 | double area_sum; 84 | area_sum = (norm(mult(side[2], side[0])) 85 | + norm(mult(side[3], side[0])) 86 | + norm(mult(side[4], side[1])) 87 | + norm(mult(side[3], side[2]))) * 88 | 0.5; 89 | 90 | double volume = dot(pts[0] - pts[3], cross(pts[1] - pts[3], pts[2] - pts[3]))/6; 91 | const double radius_ratio = (108 * volume * volume)/(norm(numerator) * area_sum) ; 92 | return radius_ratio; 93 | } 94 | 95 | bool save_metrics(const std::string& filename, 96 | const std::array& tet_metric_labels, 97 | const std::valarray& tet_metric) 98 | { 99 | // assert stats_labels.size() == stats.size() 100 | using json = nlohmann::json; 101 | std::ofstream fout(filename.c_str(),std::ios::app); 102 | //fout.open(filename.c_str(),std::ios::app); 103 | json jOut; 104 | for (size_t i = 0; i < tet_metric.size(); ++i) { 105 | jOut[tet_metric_labels[i]] = tet_metric[i]; 106 | } 107 | fout << jOut << std::endl; 108 | fout.close(); 109 | return true; 110 | } 111 | 112 | bool save_json_mesh(const std::string& filename, 113 | const std::array& tet_metric_labels, 114 | const std::valarray& tet_metric) 115 | { 116 | // assert stats_labels.size() == stats.size() 117 | using json = nlohmann::json; 118 | std::ofstream fout(filename.c_str(),std::ios::app); 119 | //fout.open(filename.c_str(),std::ios::app); 120 | json jOut; 121 | for (size_t i = 0; i < tet_metric.size(); ++i) { 122 | jOut[tet_metric_labels[i]] = tet_metric[i]; 123 | } 124 | fout << jOut << std::endl; 125 | fout.close(); 126 | return true; 127 | } 128 | #endif /* tet_quality_h */ 129 | -------------------------------------------------------------------------------- /include/timer.h: -------------------------------------------------------------------------------- 1 | // 2 | // Timer.h 3 | // adaptive_mesh_refinement 4 | // 5 | // Created by Yiwen Ju on 12/20/23. 6 | // 7 | #ifndef timer_h 8 | #define timer_h 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | //profiling the time of the entire subdivision process. 16 | //an array of 8 {total time,time spent on single function, time spent on double functions, time spent on triple functions 17 | //, time spent on double functions' zero crossing test, time spent on three functions' zero crossing test, total subdivision time, total splitting time} 18 | 19 | //currently, the zero crossing test is using linear programming based on Gurobi package. 20 | const int timer_amount = 10; 21 | 22 | std::array profileTimer = {0,0,0,0,0,0,0,0,0,0}; 23 | 24 | std::array time_label = {"total time: ", 25 | "get active multiples: ", 26 | "single func: ", 27 | "two func: ", 28 | "three func: ", 29 | "sub two func: ", 30 | "sub three func: ", 31 | "subdivision: ", 32 | "evaluations: ", 33 | "splitting: " 34 | }; 35 | enum timeProfileName{ 36 | total_time, 37 | getActiveMuti, 38 | singleFunc, 39 | twoFunc, 40 | threeFunc, 41 | sub_twoFunc, 42 | sub_threeFunc, 43 | subdivision, 44 | evaluation, 45 | splitting 46 | }; 47 | 48 | std::array combine_timer (const std::array &profile, const std::array &timer){ 49 | std::array ret; 50 | for (int i = 0; i < timer_amount; i++){ 51 | ret[i] = profile[i] + timer[i]; 52 | } 53 | return ret; 54 | } 55 | 56 | template 57 | class Timer 58 | { 59 | public: 60 | Timer(timeProfileName name, 61 | Fn&& func 62 | ) 63 | : m_Name(name), m_Func(func) 64 | { 65 | starterTime = std::chrono::high_resolution_clock::now(); 66 | } 67 | 68 | ~Timer(){} 69 | 70 | void Stop() 71 | { 72 | auto stopperTime = std::chrono::high_resolution_clock::now(); 73 | auto start = std::chrono::time_point_cast(starterTime).time_since_epoch().count(); 74 | auto end = std::chrono::time_point_cast(stopperTime).time_since_epoch().count(); 75 | auto duration = end - start; 76 | double ms = duration * 0.001; 77 | switch (m_Name){ 78 | case total_time: 79 | m_timeProfile[0] += ms; 80 | break; 81 | case getActiveMuti: 82 | m_timeProfile[1] += ms; 83 | break; 84 | case singleFunc: 85 | m_timeProfile[2] += ms; 86 | break; 87 | case twoFunc: 88 | m_timeProfile[3] += ms; 89 | break; 90 | case threeFunc: 91 | m_timeProfile[4] += ms; 92 | break; 93 | case sub_twoFunc: 94 | m_timeProfile[5] += ms; 95 | break; 96 | case sub_threeFunc: 97 | m_timeProfile[6] += ms; 98 | break; 99 | case subdivision: 100 | m_timeProfile[7] += ms; 101 | break; 102 | case evaluation: 103 | m_timeProfile[8] += ms; 104 | break; 105 | case splitting: 106 | m_timeProfile[9] += ms; 107 | break; 108 | default: 109 | std::cout << "no matching time profile identifier" << std::endl; 110 | } 111 | m_Func(m_timeProfile); 112 | } 113 | 114 | 115 | private: 116 | timeProfileName m_Name; 117 | Fn m_Func; 118 | std::array m_timeProfile = {0,0,0,0,0,0,0,0,0,0}; 119 | std::chrono::time_point starterTime; 120 | }; 121 | 122 | bool save_timings(const std::string& filename, 123 | const std::array& time_label, 124 | const std::array& timings) 125 | { 126 | using json = nlohmann::json; 127 | std::ofstream fout(filename.c_str(),std::ios::app); 128 | //fout.open(filename.c_str(),std::ios::app); 129 | json jOut; 130 | for (size_t i = 0; i < timings.size(); ++i) { 131 | jOut[time_label[i]] = timings[i]; 132 | } 133 | // 134 | fout << jOut << std::endl; 135 | fout.close(); 136 | return true; 137 | 138 | 139 | } 140 | 141 | #endif /*timer_h*/ 142 | 143 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Adaptive Grid Generation 2 | 3 | This code implements the ACM SIGGRAPH 2024 paper: [Adaptive grid generation for discretizing implicit complexes](https://dl.acm.org/doi/10.1145/3658215). Given one or multiple functions in 3D and desired type of implicit complex defined by these functions (e.g., implicit arrangement, material interface, CSG, or curve network), this algorithm generates an adaptive simplicial (tetrahedral) grid, which can then be used to discretize the implicit complex using [this robust method](https://github.com/duxingyi-charles/Robust-Implicit-Surface-Networks/tree/main). 4 | 5 | ## Build 6 | 7 | Use the following command to build: 8 | 9 | ```bash 10 | mkdir build 11 | cd build 12 | cmake -DCMAKE_BUILD_TYPE=Release .. 13 | make 14 | ``` 15 | The program `isosurfacing` will be generated in the build file. 16 | 17 | ### Dependency 18 | 19 | Currently, all the packages dependencies are available. These are currently in a release process and will be available shortly. 20 | 21 | ## Usage 22 | 23 | To use the `isosurfacing` tool, you must provide an initial mesh file and implicit function file as arguments, along with any desired options. 24 | 25 | ```bash 26 | ./isosurfacing [OPTIONS] 27 | ``` 28 | 29 | ### Positional Arguments 30 | 31 | - `mesh` : The path to the initial mesh file that will be used for isosurfacing. This file can either be a `.msh` or `.json` file. 32 | Examples of mesh files can be found in the `data/mesh` directory. 33 | - `function` : The path to the implicit function file that is used to evaluate the isosurface. 34 | 35 | ### Options 36 | 37 | - `-h, --help` : Show the help message and exit the program. 38 | - `-t, --threshold` : Set the threshold value for the isosurface generation. This is a `DOUBLE` value that defines the precision level of the isosurfacing. 39 | - `-o, --option` : Set the type of the implicit complexes from Implicit Arrangement(IA), Material Interface(MI), or Constructive Solid Geometry(CSG). This is a `STRING` value that takes input from "IA", "MI", and "CSG". The default type is "IA". 40 | - `--tree` : The path to the CSG tree file that defines the set of boolean operations on the functions. Only required if the option is set to be "CSG". 41 | - `-c, --curve_network` : Set the switch of extracting only the Curve Network. Notice that Curve Network of all the above implicit complexes are different given the same set of input functions. This is a `BOOLEAN` type that takes in 1 or 0. 42 | - `-m, --max-elements` : Set the maximum number of elements in the mesh after refinement. This is an `INT` value that limits the size of the generated mesh. If this value is a **negative** number, the mesh will be refined until the threshold value is reached. 43 | - `-s,--shortest-edge` : Set the shortest length of edges in the mesh after refinement. This is a `DOUBLE` value that defines the shortest edge length. 44 | 45 | ## Example 46 | 47 | The following is an example of how to use the `isosurfacing` tool with all available options: 48 | 49 | ```bash 50 | ./isosurfacing ../data/mesh/cube6.msh ../data/function_examples/1-sphere.json -t 0.01 -o "IA" -m 10000 -s 0.05 51 | ``` 52 | 53 | In this example, `cube6.msh` is the initial mesh file, `sphere.json` is the implicit function file, `0.01` is the threshold value, "IA" is the type of implicit complexes, `10000` is the maximum number of elements, and `0.05` is the shortest edge length. 54 | 55 | Examples from the paper can be found in the `data` folder, where each example contains a mesh file and a function file. If the example is a CSG, then it also includes a CSG tree file. Each figure folder also contains a `figure.sh` and a `figure.bat` file containing the exact commandline to produce the examples from the paper. 56 | 57 | ## Help 58 | 59 | You can always run `./isosurfacing -h` to display the help message which provides usage information and describes all the options available. 60 | 61 | ## Output and After Grid Generation 62 | 63 | The complete set of output files include data files (`tet_mesh.msh`, `active_tets.msh`, `mesh.json`, and `function_value.json`) and information files (`timings.json` and `stats.json`). The first two files can be viewed using [Gmsh](https://gmsh.info/) software showing the entire background grid or only the grid elements containing the surfaces. The last two files are for the later isosurfacing tool. 64 | 65 | We have an off-the-shelf algorithm that extracts the isosurfacs robustly from the grid for implicit complexes. First download and build [this isosurfacing method](https://github.com/duxingyi-charles/Robust-Implicit-Surface-Networks/tree/main) following its instructions. 66 | 67 | After generating the grid using our method, please use the above isosurfacing tool by replacing its `config_file` with `data/config.json` according its usage example: 68 | 69 | ```bash 70 | ./impl_arrangement [OPTIONS] config_file 71 | ``` 72 | 73 | Currently, this isosurfacing tool supports implicit arrangement, material interface, and CSG. For CSG, please specify the same path to the CSG tree file using the same command. 74 | 75 | ## Information Files 76 | 77 | timing.json: timing of different stages of our pipeline. Details can be found in the paper. 78 | 79 | stats.json: statistics of the background grid, e.g., the worst tetrahedral quality (radius ratio). 80 | -------------------------------------------------------------------------------- /data/Figure21/csg_examples_3.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"torus", 4 | "center":[ 5 | 0.3944690947422555, 6 | 0.4985105231739283, 7 | 0.4253404084051045 8 | ], 9 | "axis_vector":[ 10 | -0.9066909509543661, 11 | 1.0202939780893594e-2, 12 | -0.4279503188658209 13 | ], 14 | "minor_radius":0.125, 15 | "major_radius":0.25 16 | }, 17 | { 18 | "type":"torus", 19 | "center":[ 20 | 0.5217971523477399, 21 | 0.3851609110637389, 22 | 0.5009140348070102 23 | ], 24 | "axis_vector":[ 25 | 0.40372735157449036, 26 | -0.5073961327881329, 27 | 0.9556010005003674 28 | ], 29 | "minor_radius":0.125, 30 | "major_radius":0.25 31 | }, 32 | { 33 | "type":"torus", 34 | "center":[ 35 | 0.586820179847102, 36 | 0.5013694446128989, 37 | 0.40626187315149875 38 | ], 39 | "axis_vector":[ 40 | 0.9588383073665674, 41 | -0.28274985315412104, 42 | -0.26281529722992536 43 | ], 44 | "minor_radius":0.125, 45 | "major_radius":0.25 46 | }, 47 | { 48 | "type":"torus", 49 | "center":[ 50 | 0.5249231149764005, 51 | 0.4634178234866712, 52 | 0.38228201890243696 53 | ], 54 | "axis_vector":[ 55 | -0.8801794338656008, 56 | 0.7378675734440177, 57 | 0.44487374349558095 58 | ], 59 | "minor_radius":0.125, 60 | "major_radius":0.25 61 | }, 62 | { 63 | "type":"torus", 64 | "center":[ 65 | 0.5902318038387557, 66 | 0.571758741304487, 67 | 0.5837306879908405 68 | ], 69 | "axis_vector":[ 70 | 0.6568877801039661, 71 | -0.23933309048824336, 72 | 0.5830640306570856 73 | ], 74 | "minor_radius":0.125, 75 | "major_radius":0.25 76 | }, 77 | { 78 | "type":"torus", 79 | "center":[ 80 | 0.4863904660503069, 81 | 0.5951440168396865, 82 | 0.5401462637704655 83 | ], 84 | "axis_vector":[ 85 | -0.8673486492674547, 86 | 0.674692650501616, 87 | 0.11373262154837427 88 | ], 89 | "minor_radius":0.125, 90 | "major_radius":0.25 91 | }, 92 | { 93 | "type":"torus", 94 | "center":[ 95 | 0.6239340437220846, 96 | 0.575359331558047, 97 | 0.490217834537788 98 | ], 99 | "axis_vector":[ 100 | 0.31269951136386975, 101 | 0.5762794749756925, 102 | -6.314747444922464e-2 103 | ], 104 | "minor_radius":0.125, 105 | "major_radius":0.25 106 | }, 107 | { 108 | "type":"torus", 109 | "center":[ 110 | 0.4771777800396958, 111 | 0.44841833688382354, 112 | 0.5228251204743788 113 | ], 114 | "axis_vector":[ 115 | 0.6519493883685801, 116 | 0.660929718235844, 117 | -7.420305506578417e-2 118 | ], 119 | "minor_radius":0.125, 120 | "major_radius":0.25 121 | }, 122 | { 123 | "type":"torus", 124 | "center":[ 125 | 0.477625083873617, 126 | 0.49798090602776823, 127 | 0.46637920223507473 128 | ], 129 | "axis_vector":[ 130 | 0.6407569620591049, 131 | 0.6658250772940253, 132 | 0.569721396432826 133 | ], 134 | "minor_radius":0.125, 135 | "major_radius":0.25 136 | }, 137 | { 138 | "type":"torus", 139 | "center":[ 140 | 0.6002665404596963, 141 | 0.5566466430117982, 142 | 0.4363513413254947 143 | ], 144 | "axis_vector":[ 145 | -0.1220587032101843, 146 | -0.18141597809727017, 147 | 0.3307365696872595 148 | ], 149 | "minor_radius":0.125, 150 | "major_radius":0.25 151 | }, 152 | { 153 | "type":"torus", 154 | "center":[ 155 | 0.47315042620201453, 156 | 0.5306508165511561, 157 | 0.40813194383221857 158 | ], 159 | "axis_vector":[ 160 | -0.20122519415823703, 161 | 0.915199592646744, 162 | -0.15354047876828947 163 | ], 164 | "minor_radius":0.125, 165 | "major_radius":0.25 166 | }, 167 | { 168 | "type":"torus", 169 | "center":[ 170 | 0.47432940436424004, 171 | 0.5667540513450691, 172 | 0.42968532325227166 173 | ], 174 | "axis_vector":[ 175 | 6.6483644175461265e-3, 176 | -0.8685408677033002, 177 | 0.2723471697346347 178 | ], 179 | "minor_radius":0.125, 180 | "major_radius":0.25 181 | }, 182 | { 183 | "type":"torus", 184 | "center":[ 185 | 0.49792641469734567, 186 | 0.5767839860644265, 187 | 0.5815771366290632 188 | ], 189 | "axis_vector":[ 190 | -0.7062503425275684, 191 | 0.991947708950117, 192 | 0.431454402474968 193 | ], 194 | "minor_radius":0.125, 195 | "major_radius":0.25 196 | }, 197 | { 198 | "type":"torus", 199 | "center":[ 200 | 0.6200076899088895, 201 | 0.3787751498596115, 202 | 0.47191678926806707 203 | ], 204 | "axis_vector":[ 205 | 0.6525550136161389, 206 | 0.13781774714676231, 207 | 0.43654913698181064 208 | ], 209 | "minor_radius":0.125, 210 | "major_radius":0.25 211 | }, 212 | { 213 | "type":"torus", 214 | "center":[ 215 | 0.40842274406637774, 216 | 0.5394091910908533, 217 | 0.552865772844756 218 | ], 219 | "axis_vector":[ 220 | 0.5420954417617496, 221 | 0.6039734060875261, 222 | -0.5368538543660359 223 | ], 224 | "minor_radius":0.125, 225 | "major_radius":0.25 226 | }, 227 | { 228 | "type":"torus", 229 | "center":[ 230 | 0.579986976410116, 231 | 0.4678099315438843, 232 | 0.38401539807675167 233 | ], 234 | "axis_vector":[ 235 | -0.5655144222781336, 236 | 7.663601220102034e-2, 237 | -4.491385379254309e-2 238 | ], 239 | "minor_radius":0.125, 240 | "major_radius":0.25 241 | }, 242 | { 243 | "type":"torus", 244 | "center":[ 245 | 0.45155899990876003, 246 | 0.43541662873462594, 247 | 0.48937149329197493 248 | ], 249 | "axis_vector":[ 250 | 0.7783478503001531, 251 | -0.2265958993791215, 252 | -0.3426969277449463 253 | ], 254 | "minor_radius":0.125, 255 | "major_radius":0.25 256 | }, 257 | { 258 | "type":"torus", 259 | "center":[ 260 | 0.4803257101912998, 261 | 0.4495068767066738, 262 | 0.5589256051696899 263 | ], 264 | "axis_vector":[ 265 | -0.2473924606122364, 266 | -6.599164543916736e-4, 267 | 0.22364269062613396 268 | ], 269 | "minor_radius":0.125, 270 | "major_radius":0.25 271 | }, 272 | { 273 | "type":"torus", 274 | "center":[ 275 | 0.5939351594719806, 276 | 0.5344024671072287, 277 | 0.47893106448275446 278 | ], 279 | "axis_vector":[ 280 | -0.9513148280312156, 281 | 0.3774891129394127, 282 | 0.2862132363007879 283 | ], 284 | "minor_radius":0.125, 285 | "major_radius":0.25 286 | }, 287 | { 288 | "type":"torus", 289 | "center":[ 290 | 0.42812059606999164, 291 | 0.4929052627619586, 292 | 0.6055101553528306 293 | ], 294 | "axis_vector":[ 295 | 0.306895287958199, 296 | -0.5539015310664603, 297 | 5.5855589779317594e-2 298 | ], 299 | "minor_radius":0.125, 300 | "major_radius":0.25 301 | } 302 | ] -------------------------------------------------------------------------------- /include/grid_mesh.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Charles Du on 1/15/24. 3 | // 4 | 5 | #ifndef ADAPTIVE_MESH_REFINEMENT_GRID_MESH_H 6 | #define ADAPTIVE_MESH_REFINEMENT_GRID_MESH_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace grid_mesh { 15 | 16 | enum GridStyle { 17 | TET5, // 5 tetrahedrons per grid cell 18 | TET6 // 6 tetrahedrons per grid cell 19 | }; 20 | 21 | mtet::MTetMesh generate_tet_mesh(const std::array &resolution, 22 | const std::array &bbox_min, 23 | const std::array &bbox_max, 24 | GridStyle style = TET5) { 25 | assert(resolution[0] > 0 && resolution[1] > 0 && resolution[2] > 0); 26 | const size_t N0 = resolution[0] + 1; 27 | const size_t N1 = resolution[1] + 1; 28 | const size_t N2 = resolution[2] + 1; 29 | std::vector> pts(N0 * N1 * N2); 30 | auto compute_coordinate = [&](double t, size_t i) { 31 | return t * (bbox_max[i] - bbox_min[i]) + bbox_min[i]; 32 | }; 33 | // vertices 34 | for (size_t i = 0; i < N0; i++) { 35 | double x = compute_coordinate(double(i) / double(N0 - 1), 0); 36 | for (size_t j = 0; j < N1; j++) { 37 | double y = compute_coordinate(double(j) / double(N1 - 1), 1); 38 | for (size_t k = 0; k < N2; k++) { 39 | double z = compute_coordinate(double(k) / double(N2 - 1), 2); 40 | 41 | size_t idx = i * N1 * N2 + j * N2 + k; 42 | pts[idx] = {x, y, z}; 43 | } 44 | } 45 | } 46 | // tets 47 | std::vector> tets; 48 | size_t num_tet_per_cell = 0; 49 | if (style == TET5) { 50 | num_tet_per_cell = 5; 51 | } else if (style == TET6) { 52 | num_tet_per_cell = 6; 53 | } else { 54 | throw std::runtime_error("unknown grid style!"); 55 | } 56 | tets.resize(resolution[0] * resolution[1] * resolution[2] * num_tet_per_cell); 57 | for (size_t i = 0; i < resolution[0]; i++) { 58 | for (size_t j = 0; j < resolution[1]; j++) { 59 | for (size_t k = 0; k < resolution[2]; k++) { 60 | size_t idx = (i * resolution[1] * resolution[2] + j * resolution[2] + k) * num_tet_per_cell; 61 | size_t v0 = i * N1 * N2 + j * N2 + k; 62 | size_t v1 = (i + 1) * N1 * N2 + j * N2 + k; 63 | size_t v2 = (i + 1) * N1 * N2 + (j + 1) * N2 + k; 64 | size_t v3 = i * N1 * N2 + (j + 1) * N2 + k; 65 | size_t v4 = i * N1 * N2 + j * N2 + k + 1; 66 | size_t v5 = (i + 1) * N1 * N2 + j * N2 + k + 1; 67 | size_t v6 = (i + 1) * N1 * N2 + (j + 1) * N2 + k + 1; 68 | size_t v7 = i * N1 * N2 + (j + 1) * N2 + k + 1; 69 | switch (style) { 70 | case TET5: 71 | if ((i + j + k) % 2 == 0) { 72 | tets[idx] = {v4, v6, v1, v3}; 73 | tets[idx + 1] = {v6, v3, v4, v7}; 74 | tets[idx + 2] = {v1, v3, v0, v4}; 75 | tets[idx + 3] = {v3, v1, v2, v6}; 76 | tets[idx + 4] = {v4, v1, v6, v5}; 77 | } else { 78 | tets[idx] = {v7, v0, v2, v5}; 79 | tets[idx + 1] = {v2, v3, v0, v7}; 80 | tets[idx + 2] = {v5, v7, v0, v4}; 81 | tets[idx + 3] = {v7, v2, v6, v5}; 82 | tets[idx + 4] = {v0, v1, v2, v5}; 83 | } 84 | break; 85 | case TET6: 86 | //{{0, 4, 6, 7}, {6, 0, 5, 4}, {1, 0, 5, 6}, {1, 2, 0, 6}, {0, 6, 2, 3}, {6, 3, 0, 7}} 87 | tets[idx] = {v0, v4, v6, v7}; 88 | tets[idx + 1] = {v6, v0, v5, v4}; 89 | tets[idx + 2] = {v1, v0, v5, v6}; 90 | tets[idx + 3] = {v1, v2, v0, v6}; 91 | tets[idx + 4] = {v0, v6, v2, v3}; 92 | tets[idx + 5] = {v6, v3, v0, v7}; 93 | break; 94 | } 95 | } 96 | } 97 | } 98 | // build mesh 99 | mtet::MTetMesh mesh; 100 | std::vector vertex_ids; 101 | vertex_ids.reserve(pts.size()); 102 | for (auto &v: pts) { 103 | vertex_ids.push_back(mesh.add_vertex(v[0], v[1], v[2])); 104 | } 105 | for (auto &t: tets) { 106 | mesh.add_tet(vertex_ids[t[0]], vertex_ids[t[1]], vertex_ids[t[2]], vertex_ids[t[3]]); 107 | } 108 | return mesh; 109 | } 110 | 111 | // load tet mesh from json file 112 | mtet::MTetMesh load_tet_mesh(const std::string &filename) { 113 | using json = nlohmann::json; 114 | std::ifstream fin(filename.c_str()); 115 | if (!fin) { 116 | throw std::runtime_error("tet mesh file not exist!"); 117 | } 118 | json data; 119 | fin >> data; 120 | fin.close(); 121 | // if the tet grid is specified by resolution and bounding box 122 | if (data.contains("resolution")) { 123 | size_t num_resolution = data["resolution"].size(); 124 | assert(num_resolution <= 3 && num_resolution > 0); 125 | size_t res = data["resolution"][0].get(); 126 | std::array resolution = {res, res, res}; 127 | for (size_t i = 0; i < num_resolution; i++) { 128 | resolution[i] = data["resolution"][i].get(); 129 | } 130 | assert(data.contains("bbox_min")); 131 | assert(data["bbox_min"].size() == 3); 132 | std::array bbox_min{0, 0, 0}; 133 | for (size_t i = 0; i < 3; i++) { 134 | bbox_min[i] = data["bbox_min"][i].get(); 135 | } 136 | assert(data.contains("bbox_max")); 137 | assert(data["bbox_max"].size() == 3); 138 | std::array bbox_max{1, 1, 1}; 139 | for (size_t i = 0; i < 3; i++) { 140 | bbox_max[i] = data["bbox_max"][i].get(); 141 | } 142 | GridStyle style = TET6; 143 | if (data.contains("style")) { 144 | auto style_str = data["style"].get(); 145 | if (style_str == "TET5") { 146 | style = TET5; 147 | } else if (style_str == "TET6") { 148 | style = TET6; 149 | } else { 150 | throw std::runtime_error("unknown grid style!"); 151 | } 152 | } 153 | return generate_tet_mesh(resolution, bbox_min, bbox_max, style); 154 | } 155 | // vertices 156 | std::vector> pts; 157 | pts.resize(data[0].size()); 158 | for (size_t j = 0; j < pts.size(); j++) { 159 | for (size_t k = 0; k < 3; k++) { 160 | pts[j][k] = data[0][j][k].get(); 161 | } 162 | } 163 | // tets 164 | std::vector> tets; 165 | tets.resize(data[1].size()); 166 | for (size_t j = 0; j < tets.size(); j++) { 167 | for (size_t k = 0; k < 4; k++) { 168 | tets[j][k] = data[1][j][k].get(); 169 | } 170 | } 171 | // build mesh 172 | mtet::MTetMesh mesh; 173 | std::vector vertex_ids; 174 | vertex_ids.reserve(pts.size()); 175 | for (auto &v: pts) { 176 | vertex_ids.push_back(mesh.add_vertex(v[0], v[1], v[2])); 177 | } 178 | for (auto &t: tets) { 179 | mesh.add_tet(vertex_ids[t[0]], vertex_ids[t[1]], vertex_ids[t[2]], vertex_ids[t[3]]); 180 | } 181 | return mesh; 182 | } 183 | 184 | 185 | } // namespace grid_mesh 186 | 187 | #endif //ADAPTIVE_MESH_REFINEMENT_GRID_MESH_H 188 | 189 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /app/isosurfacing.cpp: -------------------------------------------------------------------------------- 1 | //#define Check_Flip_Tets 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | using namespace mtet; 19 | 20 | bool save_mesh_json(const std::string& filename, 21 | const mtet::MTetMesh mesh) 22 | { 23 | vector> vertices((int)mesh.get_num_vertices()); 24 | vector> tets((int)mesh.get_num_tets()); 25 | using IndexMap = ankerl::unordered_dense::map; 26 | IndexMap vertex_tag_map; 27 | vertex_tag_map.reserve(mesh.get_num_vertices()); 28 | int counter = 0; 29 | mesh.seq_foreach_vertex([&](VertexId vid, std::span data){ 30 | size_t vertex_tag = vertex_tag_map.size() + 1; 31 | vertex_tag_map[value_of(vid)] = vertex_tag; 32 | vertices[counter] = {data[0], data[1], data[2]}; 33 | counter ++; 34 | }); 35 | counter = 0; 36 | mesh.seq_foreach_tet([&](TetId, std::span data) { 37 | tets[counter] = {vertex_tag_map[value_of(data[0])] - 1, vertex_tag_map[value_of(data[1])] - 1, vertex_tag_map[value_of(data[2])] - 1, vertex_tag_map[value_of(data[3])] - 1}; 38 | counter ++; 39 | }); 40 | if (std::filesystem::exists(filename.c_str())){ 41 | std::filesystem::remove(filename.c_str()); 42 | } 43 | using json = nlohmann::json; 44 | std::ofstream fout(filename.c_str(),std::ios::app); 45 | json jOut; 46 | jOut.push_back(json(vertices)); 47 | jOut.push_back(json(tets)); 48 | fout << jOut.dump(4, ' ', true, json::error_handler_t::replace) << std::endl; 49 | fout.close(); 50 | return true; 51 | } 52 | 53 | bool save_function_json(const std::string& filename, 54 | const mtet::MTetMesh mesh, 55 | ankerl::unordered_dense::map, 20>> vertex_func_grad_map, 56 | const size_t funcNum) 57 | { 58 | vector> values(funcNum); 59 | for (size_t funcIter = 0; funcIter < funcNum; funcIter++){ 60 | values[funcIter].reserve(((int)mesh.get_num_vertices())); 61 | } 62 | mesh.seq_foreach_vertex([&](VertexId vid, std::span data){ 63 | llvm_vecsmall::SmallVector, 20> func_gradList(funcNum); 64 | func_gradList = vertex_func_grad_map[value_of(vid)]; 65 | for (size_t funcIter = 0; funcIter < funcNum; funcIter++){ 66 | cout << data[0] << " " << data[1] << " " << data[2] << ": " << func_gradList[funcIter][0] << ", " << func_gradList[funcIter][1] << ", " << func_gradList[funcIter][2] << ", " << func_gradList[funcIter][3] << endl; 67 | values[funcIter].push_back(func_gradList[funcIter][0]); 68 | } 69 | }); 70 | if (std::filesystem::exists(filename.c_str())){ 71 | std::filesystem::remove(filename.c_str()); 72 | } 73 | using json = nlohmann::json; 74 | std::ofstream fout(filename.c_str(),std::ios::app); 75 | json jOut; 76 | for (size_t funcIter = 0; funcIter < funcNum; funcIter++){ 77 | json jFunc; 78 | jFunc["type"] = "customized"; 79 | jFunc["value"] = values[funcIter]; 80 | jOut.push_back(jFunc); 81 | } 82 | fout << jOut.dump(4, ' ', true, json::error_handler_t::replace) << std::endl; 83 | fout.close(); 84 | return true; 85 | } 86 | //hash for mounting a boolean that represents the activeness to a tet 87 | //since the tetid isn't const during the process, mount the boolean using vertexids of 4 corners. 88 | uint64_t vertexHash(std::span& x) 89 | { 90 | ankerl::unordered_dense::hash hash_fn; 91 | return hash_fn(value_of(x[0])) + hash_fn(value_of(x[1])) + hash_fn(value_of(x[2])) + hash_fn(value_of(x[3])); 92 | } 93 | 94 | int main(int argc, const char *argv[]) 95 | { 96 | struct 97 | { 98 | string mesh_file; 99 | string function_file; 100 | double threshold = 0.0001; 101 | double alpha = std::numeric_limits::infinity(); 102 | int max_elements = -1; 103 | double smallest_edge_length = 0; 104 | string method = "IA"; 105 | string csg_file; 106 | bool bfs = false; 107 | bool dfs = false; 108 | bool curve_network = false; 109 | //bool analysis_mode = false; 110 | } args; 111 | CLI::App app{"Longest Edge Bisection Refinement"}; 112 | app.add_option("mesh", args.mesh_file, "Initial mesh file")->required(); 113 | app.add_option("function", args.function_file, "Implicit function file")->required(); 114 | app.add_option("-t,--threshold", args.threshold, "Threshold value"); 115 | app.add_option("-a,--alpha", args.alpha, "Alpha value"); 116 | app.add_option("-o,--option", args.method, "Options of implicit manifold"); 117 | app.add_option("--tree", args.csg_file, "CSG Tree file"); 118 | app.add_option("-m,--max-elements", args.max_elements, "Maximum number of elements"); 119 | app.add_option("-s,--shortest-edge", args.smallest_edge_length, "Shortest edge length"); 120 | app.add_option("-b, --bfs", args.bfs, "Toggle BFS Mode"); 121 | app.add_option("-d, --dfs", args.dfs, "Toggle DFS Mode"); 122 | app.add_option("-c, --curve_network", args.curve_network, "Generate Curve Network only"); 123 | CLI11_PARSE(app, argc, argv); 124 | // Read mesh 125 | mtet::MTetMesh mesh; 126 | if (args.mesh_file.find(".json") != std::string::npos){ 127 | mesh = grid_mesh::load_tet_mesh(args.mesh_file); 128 | mtet::save_mesh("init.msh", mesh); 129 | mesh = mtet::load_mesh("init.msh"); 130 | } else { 131 | mesh = mtet::load_mesh(args.mesh_file); 132 | } 133 | 134 | // Read implicit function 135 | vector>> functions; 136 | load_functions(args.function_file, functions); 137 | size_t funcNum = functions.size(); 138 | // Read options 139 | if (args.max_elements < 0) 140 | { 141 | args.max_elements = numeric_limits::max(); 142 | } 143 | double threshold = args.threshold; 144 | double alpha = args.alpha; 145 | double smallest_edge_length = args.smallest_edge_length; 146 | if (args.method == "IA"){ 147 | GLOBAL_METHOD = IA; 148 | } 149 | if (args.method == "CSG"){ 150 | GLOBAL_METHOD = CSG; 151 | load_csgTree(args.csg_file, GLOBAL_CSGTREE); 152 | } 153 | if (args.method == "MI"){ 154 | GLOBAL_METHOD = MI; 155 | } 156 | if (args.curve_network){ 157 | curve_network = true; 158 | } 159 | 160 | //precomputing active multiples' indices: 161 | multiple_indices.resize(funcNum); 162 | for (int funcIter = 0; funcIter < funcNum; funcIter++){ 163 | multiple_indices[funcIter].resize(3); 164 | int activeNum = funcIter + 1; 165 | int pairNum = activeNum * (activeNum-1)/2, triNum = activeNum * (activeNum-1) * (activeNum - 2)/ 6; 166 | int quadNum = activeNum * (activeNum - 1) * (activeNum - 2) * (activeNum - 3)/ 24; 167 | llvm_vecsmall::SmallVector,100> pair(pairNum); 168 | llvm_vecsmall::SmallVector, 100> triple(triNum); 169 | llvm_vecsmall::SmallVector, 100> quad(quadNum); 170 | int pairIt = 0, triIt = 0, quadIt = 0; 171 | for (int i = 0; i < activeNum - 1; i++){ 172 | for (int j = i + 1; j < activeNum; j++){ 173 | pair[pairIt] = {i, j, 0, 0}; 174 | pairIt ++; 175 | if (j < activeNum - 1){ 176 | for (int k = j + 1; k < activeNum; k++){ 177 | triple[triIt] = {i, j, k, 0}; 178 | triIt ++; 179 | if (GLOBAL_METHOD == MI){ 180 | if (k < activeNum - 1){ 181 | for (int m = k + 1; m < activeNum; m++){ 182 | quad[quadIt] = {i, j, k, m}; 183 | quadIt++; 184 | } 185 | } 186 | } 187 | } 188 | } 189 | } 190 | } 191 | if (GLOBAL_METHOD == MI){ 192 | multiple_indices[funcIter] = {pair, triple, quad}; 193 | }else{ 194 | multiple_indices[funcIter] = {pair, triple}; 195 | } 196 | } 197 | int search_counter; 198 | if (args.bfs || args.dfs){ 199 | search_counter = 0; 200 | } 201 | // initialize vertex map: vertex index -> {{f_i, gx, gy, gz} | for all f_i in the function} 202 | using IndexMap = ankerl::unordered_dense::map, 20>>; 203 | IndexMap vertex_func_grad_map; 204 | vertex_func_grad_map.reserve(mesh.get_num_vertices()); 205 | 206 | //initialize activeness map: four vertexids (v0, v1, v2, v3) -> hash(v0, v1, v2, v3) -> active boolean 207 | using activeMap = ankerl::unordered_dense::map; 208 | activeMap vertex_active_map; 209 | vertex_active_map.reserve(mesh.get_num_tets()); 210 | 211 | mesh.seq_foreach_vertex([&](VertexId vid, std::span data) 212 | { 213 | llvm_vecsmall::SmallVector, 20> func_gradList(funcNum); 214 | for(size_t funcIter = 0; funcIter < funcNum; funcIter++){ 215 | auto &func = functions[funcIter]; 216 | array func_grad; 217 | func_grad[0] = func->evaluate_gradient(data[0], data[1], data[2], func_grad[1], func_grad[2], func_grad[3]); 218 | func_gradList[funcIter] = func_grad; 219 | } 220 | vertex_func_grad_map[value_of(vid)] = func_gradList;}); 221 | auto comp = [](std::pair e0, 222 | std::pair e1) 223 | { return e0.first < e1.first; }; 224 | std::vector> Q; 225 | 226 | std::array, 4> pts; 227 | llvm_vecsmall::SmallVector, 20> vals(funcNum); 228 | llvm_vecsmall::SmallVector,4>, 20> grads(funcNum); 229 | double activeTet = 0; 230 | auto push_longest_edge = [&](mtet::TetId tid) 231 | { 232 | std::span vs = mesh.get_tet(tid); 233 | { 234 | Timer eval_timer(evaluation, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 235 | for (int i = 0; i < 4; ++i) 236 | { 237 | auto vid = vs[i]; 238 | auto coords = mesh.get_vertex(vid); 239 | pts[i][0] = coords[0]; 240 | pts[i][1] = coords[1]; 241 | pts[i][2] = coords[2]; 242 | llvm_vecsmall::SmallVector, 20> func_gradList(funcNum); 243 | std::array func_grad; 244 | if (!vertex_func_grad_map.contains(value_of(vid))) { 245 | for(size_t funcIter = 0; funcIter < funcNum; funcIter++){ 246 | auto &func = functions[funcIter]; 247 | array func_grad; 248 | func_grad[0] = func->evaluate_gradient(coords[0], coords[1], coords[2], func_grad[1], func_grad[2], 249 | func_grad[3]); 250 | func_gradList[funcIter] = func_grad; 251 | } 252 | vertex_func_grad_map[value_of(vid)] = func_gradList; 253 | } 254 | else { 255 | func_gradList = vertex_func_grad_map[value_of(vid)]; 256 | } 257 | for(size_t funcIter = 0; funcIter < funcNum; funcIter++){ 258 | vals[funcIter][i] = func_gradList[funcIter][0]; 259 | grads[funcIter][i][0] = func_gradList[funcIter][1]; 260 | grads[funcIter][i][1] = func_gradList[funcIter][2]; 261 | grads[funcIter][i][2] = func_gradList[funcIter][3]; 262 | } 263 | } 264 | eval_timer.Stop(); 265 | } 266 | bool isActive = 0; 267 | bool subResult; 268 | { 269 | Timer sub_timer(subdivision, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 270 | if (GLOBAL_METHOD != MI){ 271 | subResult = subTet(pts, vals, grads, threshold, isActive); 272 | }else{ 273 | subResult = subMI(pts, vals, grads, threshold, isActive); 274 | } 275 | sub_timer.Stop(); 276 | } 277 | vertex_active_map[vertexHash(vs)] = isActive; 278 | Timer eval_timer(evaluation, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 279 | if (subResult) 280 | { 281 | mtet::EdgeId longest_edge; 282 | mtet::Scalar longest_edge_length = 0; 283 | mesh.foreach_edge_in_tet(tid, [&](mtet::EdgeId eid, mtet::VertexId v0, mtet::VertexId v1) 284 | { 285 | auto p0 = mesh.get_vertex(v0); 286 | auto p1 = mesh.get_vertex(v1); 287 | mtet::Scalar l = (p0[0] - p1[0]) * (p0[0] - p1[0]) + (p0[1] - p1[1]) * (p0[1] - p1[1]) + 288 | (p0[2] - p1[2]) * (p0[2] - p1[2]); 289 | if (l > longest_edge_length) { 290 | longest_edge_length = l; 291 | longest_edge = eid; 292 | } }); 293 | if (args.bfs){ 294 | Q.emplace_back(search_counter, longest_edge); 295 | search_counter--; 296 | }else if(args.dfs){ 297 | Q.emplace_back(search_counter, longest_edge); 298 | search_counter++; 299 | } 300 | else{ 301 | Q.emplace_back(longest_edge_length, longest_edge); 302 | } 303 | eval_timer.Stop(); 304 | return true; 305 | } 306 | eval_timer.Stop(); 307 | return false; 308 | }; 309 | 310 | 311 | { 312 | Timer timer(total_time, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 313 | 314 | // Initialize priority queue. 315 | mesh.seq_foreach_tet([&](mtet::TetId tid, [[maybe_unused]] std::span vs) 316 | { push_longest_edge(tid); }); 317 | std::make_heap(Q.begin(), Q.end(), comp); 318 | 319 | // Keep splitting the longest edge 320 | while (!Q.empty()) 321 | { 322 | std::pop_heap(Q.begin(), Q.end(), comp); 323 | auto [edge_length, eid] = Q.back(); 324 | if (!mesh.has_edge(eid)){ 325 | Q.pop_back(); 326 | continue; 327 | } 328 | //implement alpha value: 329 | mtet::Scalar comp_edge_length = alpha * edge_length; 330 | bool addedActive = false; 331 | mesh.foreach_tet_around_edge(eid,[&](mtet::TetId tid){ 332 | std::span vs = mesh.get_tet(tid); 333 | if(vertex_active_map.contains(vertexHash(vs))){ 334 | if (vertex_active_map[vertexHash(vs)]){ 335 | mtet::EdgeId longest_edge; 336 | mtet::Scalar longest_edge_length = 0; 337 | mesh.foreach_edge_in_tet(tid, [&](mtet::EdgeId eid_active, mtet::VertexId v0, mtet::VertexId v1) 338 | { 339 | auto p0 = mesh.get_vertex(v0); 340 | auto p1 = mesh.get_vertex(v1); 341 | mtet::Scalar l = (p0[0] - p1[0]) * (p0[0] - p1[0]) + (p0[1] - p1[1]) * (p0[1] - p1[1]) + 342 | (p0[2] - p1[2]) * (p0[2] - p1[2]); 343 | if (l > longest_edge_length) { 344 | longest_edge_length = l; 345 | longest_edge = eid_active; 346 | } 347 | }); 348 | if (longest_edge_length > comp_edge_length) { 349 | Q.emplace_back(longest_edge_length, longest_edge); 350 | addedActive = true; 351 | } 352 | } 353 | } 354 | }); 355 | if(addedActive){ 356 | std::push_heap(Q.begin(), Q.end(), comp); 357 | continue; 358 | } 359 | Q.pop_back(); 360 | std::array vs_old = mesh.get_edge_vertices(eid); 361 | Timer split_timer(splitting, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 362 | auto [vid, eid0, eid1] = mesh.split_edge(eid); 363 | split_timer.Stop(); 364 | //std::cout << "Number of elements: " << mesh.get_num_tets() << std::endl; 365 | if (mesh.get_num_tets() > args.max_elements) { 366 | break; 367 | } 368 | mesh.foreach_tet_around_edge(eid0, [&](mtet::TetId tid) 369 | { 370 | if (push_longest_edge(tid)) { 371 | std::push_heap(Q.begin(), Q.end(), comp); 372 | } }); 373 | mesh.foreach_tet_around_edge(eid1, [&](mtet::TetId tid) 374 | { 375 | if (push_longest_edge(tid)) { 376 | std::push_heap(Q.begin(), Q.end(), comp); 377 | } }); 378 | #ifdef Check_Flip_Tets 379 | std::array vs_new = mesh.get_edge_vertices(eid0); 380 | mesh.foreach_tet_around_edge(eid0, [&](mtet::TetId tid) 381 | { 382 | std::span vs = mesh.get_tet(tid); 383 | std::vector parent(4); 384 | parent[0] = vs_old[0]; parent[1] = vs_old[1]; 385 | int parentIndex = 2; 386 | for (auto vIter : vs){ 387 | if (vIter != vs_new[0] && vIter != vs_new[1]){ 388 | parent[parentIndex] = vIter; 389 | parentIndex ++; 390 | } 391 | } 392 | std::span spanVec(parent); 393 | if (!vertex_active_map[vertexHash(spanVec)] && vertex_active_map[vertexHash(vs)]){ 394 | { 395 | using json = nlohmann::json; 396 | std::string filePath = "flip_tets.json"; 397 | // if (std::filesystem::exists(filePath)) { 398 | // std::filesystem::remove(filePath); 399 | // } 400 | std::ofstream fout(filePath,std::ios::app); 401 | json jOut; 402 | std::array, 4> pts; 403 | llvm_vecsmall::SmallVector, 20> vals(funcNum); 404 | llvm_vecsmall::SmallVector,4>, 20> grads(funcNum); 405 | for (size_t i = 0; i < 4; ++i) { 406 | auto coords = mesh.get_vertex(vs[i]); 407 | pts[i][0] = coords[0]; 408 | pts[i][1] = coords[1]; 409 | pts[i][2] = coords[2]; 410 | auto func_gradList = vertex_func_grad_map[value_of(vs[i])]; 411 | for(size_t funcIter = 0; funcIter < funcNum; funcIter++){ 412 | vals[funcIter][i] = func_gradList[funcIter][0]; 413 | grads[funcIter][i][0] = func_gradList[funcIter][1]; 414 | grads[funcIter][i][1] = func_gradList[funcIter][2]; 415 | grads[funcIter][i][2] = func_gradList[funcIter][3]; 416 | } 417 | } 418 | jOut["vertices: "] = pts; 419 | jOut["value: "] = vals; 420 | jOut["gradient: "] = grads; 421 | // 422 | fout << jOut << std::endl; 423 | fout.close(); 424 | } 425 | { 426 | using json = nlohmann::json; 427 | std::string filePath = "flip_tets_parent.json"; 428 | // if (std::filesystem::exists(filePath)) { 429 | // std::filesystem::remove(filePath); 430 | // } 431 | std::ofstream fout(filePath,std::ios::app); 432 | json jOut; 433 | std::array, 4> pts; 434 | llvm_vecsmall::SmallVector, 20> vals(funcNum); 435 | llvm_vecsmall::SmallVector,4>, 20> grads(funcNum); 436 | for (size_t i = 0; i < 4; ++i) { 437 | auto coords = mesh.get_vertex(spanVec[i]); 438 | pts[i][0] = coords[0]; 439 | pts[i][1] = coords[1]; 440 | pts[i][2] = coords[2]; 441 | auto func_gradList = vertex_func_grad_map[value_of(spanVec[i])]; 442 | for(size_t funcIter = 0; funcIter < funcNum; funcIter++){ 443 | vals[funcIter][i] = func_gradList[funcIter][0]; 444 | grads[funcIter][i][0] = func_gradList[funcIter][1]; 445 | grads[funcIter][i][1] = func_gradList[funcIter][2]; 446 | grads[funcIter][i][2] = func_gradList[funcIter][3]; 447 | } 448 | } 449 | jOut["vertices: "] = pts; 450 | jOut["value: "] = vals; 451 | jOut["gradient: "] = grads; 452 | // 453 | fout << jOut << std::endl; 454 | fout.close(); 455 | } 456 | } 457 | }); 458 | vs_new = mesh.get_edge_vertices(eid1); 459 | mesh.foreach_tet_around_edge(eid1, [&](mtet::TetId tid) 460 | { 461 | std::span vs = mesh.get_tet(tid); 462 | std::vector parent(4); 463 | parent[0] = vs_old[0]; parent[1] = vs_old[1]; 464 | int parentIndex = 2; 465 | for (auto vIter : vs){ 466 | if (vIter != vs_new[0] && vIter != vs_new[1]){ 467 | parent[parentIndex] = vIter; 468 | parentIndex ++; 469 | } 470 | } 471 | std::span spanVec(parent); 472 | if (!vertex_active_map[vertexHash(spanVec)] && vertex_active_map[vertexHash(vs)]){ 473 | { 474 | using json = nlohmann::json; 475 | std::string filePath = "flip_tets.json"; 476 | // if (std::filesystem::exists(filePath)) { 477 | // std::filesystem::remove(filePath); 478 | // } 479 | std::ofstream fout(filePath,std::ios::app); 480 | json jOut; 481 | std::array, 4> pts; 482 | llvm_vecsmall::SmallVector, 20> vals(funcNum); 483 | llvm_vecsmall::SmallVector,4>, 20> grads(funcNum); 484 | for (size_t i = 0; i < 4; ++i) { 485 | auto coords = mesh.get_vertex(vs[i]); 486 | pts[i][0] = coords[0]; 487 | pts[i][1] = coords[1]; 488 | pts[i][2] = coords[2]; 489 | auto func_gradList = vertex_func_grad_map[value_of(vs[i])]; 490 | for(size_t funcIter = 0; funcIter < funcNum; funcIter++){ 491 | vals[funcIter][i] = func_gradList[funcIter][0]; 492 | grads[funcIter][i][0] = func_gradList[funcIter][1]; 493 | grads[funcIter][i][1] = func_gradList[funcIter][2]; 494 | grads[funcIter][i][2] = func_gradList[funcIter][3]; 495 | } 496 | } 497 | jOut["vertices: "] = pts; 498 | jOut["value: "] = vals; 499 | jOut["gradient: "] = grads; 500 | // 501 | fout << jOut << std::endl; 502 | fout.close(); 503 | } 504 | { 505 | using json = nlohmann::json; 506 | std::string filePath = "flip_tets_parent.json"; 507 | // if (std::filesystem::exists(filePath)) { 508 | // std::filesystem::remove(filePath); 509 | // } 510 | std::ofstream fout(filePath,std::ios::app); 511 | json jOut; 512 | std::array, 4> pts; 513 | llvm_vecsmall::SmallVector, 20> vals(funcNum); 514 | llvm_vecsmall::SmallVector,4>, 20> grads(funcNum); 515 | for (size_t i = 0; i < 4; ++i) { 516 | auto coords = mesh.get_vertex(spanVec[i]); 517 | pts[i][0] = coords[0]; 518 | pts[i][1] = coords[1]; 519 | pts[i][2] = coords[2]; 520 | auto func_gradList = vertex_func_grad_map[value_of(spanVec[i])]; 521 | for(size_t funcIter = 0; funcIter < funcNum; funcIter++){ 522 | vals[funcIter][i] = func_gradList[funcIter][0]; 523 | grads[funcIter][i][0] = func_gradList[funcIter][1]; 524 | grads[funcIter][i][1] = func_gradList[funcIter][2]; 525 | grads[funcIter][i][2] = func_gradList[funcIter][3]; 526 | } 527 | } 528 | jOut["vertices: "] = pts; 529 | jOut["value: "] = vals; 530 | jOut["gradient: "] = grads; 531 | // 532 | fout << jOut << std::endl; 533 | fout.close(); 534 | } 535 | } 536 | }); 537 | #endif 538 | } 539 | timer.Stop(); 540 | } 541 | //profiled time(see details in time.h) and profiled number of calls to zero 542 | for (int i = 0; i < profileTimer.size(); i++){ 543 | timeProfileName time_type = static_cast(i); 544 | std::cout << time_label[i] << ": " << profileTimer[i] << std::endl; 545 | } 546 | // std::cout << profileTimer[0] << " "<< profileTimer[1] << " "<< profileTimer[2] << " "<< profileTimer[3] << " "<< profileTimer[4] << " "<< profileTimer[5] << " "<< profileTimer[6] << " "<< profileTimer[7] << " "<< profileTimer[8] << " "<< profileTimer[9] << " "<< sub_call_two << " "<< sub_call_three << std::endl; 547 | //std::cout << "sub two func calls: " << sub_call_two << std::endl; 548 | //std::cout << "sub three func calls: " << sub_call_three << std::endl; 549 | double min_rratio_all = 1; 550 | double min_rratio_active = 1; 551 | std::vector activeTetId; 552 | mesh.seq_foreach_tet([&](mtet::TetId tid, std::span data) { 553 | std::span vs = mesh.get_tet(tid); 554 | std::array,4> vallPoints; 555 | for (int i = 0; i < 4; i++){ 556 | vallPoints[i] = {0.0,0.0,0.0}; 557 | } 558 | for (int i = 0; i < 4; i++){ 559 | VertexId vid = vs[i]; 560 | std::span coords = mesh.get_vertex(vid); 561 | vallPoints[i][0] = coords[0]; 562 | vallPoints[i][1] = coords[1]; 563 | vallPoints[i][2] = coords[2]; 564 | } 565 | double ratio = tet_radius_ratio(vallPoints); 566 | if (ratio < min_rratio_all){ 567 | min_rratio_all = ratio; 568 | 569 | } 570 | if(vertex_active_map.contains(vertexHash(vs))){ 571 | if (vertex_active_map[vertexHash(vs)]){ 572 | activeTet++; 573 | activeTetId.push_back(tid); 574 | if (ratio < min_rratio_active){ 575 | min_rratio_active = ratio; 576 | } 577 | } 578 | } 579 | }); 580 | // save timing records 581 | save_timings("timings.json",time_label, profileTimer); 582 | // save statistics 583 | save_metrics("stats.json", tet_metric_labels, {(double)mesh.get_num_tets(), activeTet, min_rratio_all, min_rratio_active, (double)sub_call_two, (double) sub_call_three}); 584 | // save the mesh output for isosurfacing tool 585 | save_mesh_json("mesh.json", mesh); 586 | // save the mesh output for isosurfacing tool 587 | save_function_json("function_value.json", mesh, vertex_func_grad_map, funcNum); 588 | //write mesh and active tets 589 | mtet::save_mesh("tet_mesh.msh", mesh); 590 | mtet::save_mesh("active_tets.msh", mesh, std::span(activeTetId)); 591 | return 0; 592 | } 593 | -------------------------------------------------------------------------------- /data/Figure22/doghead_800_shifted.xyz: -------------------------------------------------------------------------------- 1 | 3 2 | -0.13450219999999996 0.26950300000000005 0.22637800000000005 3 | -0.41246079999999996 -0.221773 -1.08 4 | 0.74894 -0.30846299999999993 -0.08001209199999998 5 | -0.7035199999999999 -0.458575 -0.08001209199999998 6 | -0.41246079999999996 -0.31161099999999997 0.8549959999999999 7 | -0.41246079999999996 0.45636299999999996 -0.55993 8 | 0.18302200000000007 0.03580120000000002 -0.412022 9 | -0.7678459999999999 0.1645798 0.11148380000000005 10 | -0.41246079999999996 0.313045 0.788446 11 | -0.07464039999999994 -0.41947100000000004 -0.08001209199999998 12 | 0.40747600000000006 0.03580120000000002 0.26177000000000006 13 | -0.41246079999999996 -0.1376692 -0.504288 14 | -0.41246079999999996 -0.261285 0.32263200000000003 15 | -0.41246079999999996 0.24578719999999998 -0.989976 16 | -0.4355728 0.45689100000000005 -0.08001209199999998 17 | 0.649818 0.03580120000000002 -0.38734599999999997 18 | -0.725038 0.2068136 -0.33428199999999997 19 | 0.2476560000000001 -0.366105 0.19953200000000001 20 | 0.2476560000000001 -0.377483 -0.34907999999999995 21 | -0.08510439999999996 0.33786700000000003 -0.33570199999999994 22 | -0.531028 0.332071 0.398116 23 | 0.7584640000000001 0.03580120000000002 0.08089540000000002 24 | 0.31179200000000007 0.1542886 -0.08001209199999998 25 | -0.41246079999999996 -0.01617739999999998 0.625256 26 | -0.41246079999999996 -0.45068500000000006 -0.31574599999999997 27 | -0.804782 -0.1213114 -0.08001209199999998 28 | 0.43696 -0.45976100000000003 -0.08001209199999998 29 | -0.41246079999999996 -0.479647 0.06620720000000004 30 | -0.14121359999999994 0.03580120000000002 -0.4779 31 | 0.07860000000000006 0.03580120000000002 0.2729060000000001 32 | -0.41246079999999996 0.010125600000000012 -0.784832 33 | -0.560978 0.03580120000000002 0.309026 34 | 0.03503800000000007 0.26950300000000005 -0.024372199999999976 35 | -0.43729339999999994 0.16728540000000003 -0.48079399999999994 36 | -0.2804441999999999 0.402377 0.541128 37 | -0.26846123999999993 0.03580120000000002 0.335202 38 | -0.41246079999999996 -0.02937439999999998 0.9083159999999999 39 | -0.15474179999999993 0.48060900000000006 -0.08001209199999998 40 | -0.27453219999999995 0.39299700000000004 -0.7966820000000001 41 | 0.5882160000000001 0.1688788 -0.08001209199999998 42 | -0.41246079999999996 -0.27229899999999996 -0.815574 43 | -0.5368999999999999 0.339645 -0.773874 44 | -0.6730039999999999 0.318269 -0.08001209199999998 45 | -0.41246079999999996 0.41185700000000003 0.17253000000000004 46 | 0.17977600000000005 -0.45794700000000005 -0.08001209199999998 47 | 0.7792560000000001 0.03580120000000002 -0.16326639999999998 48 | -0.26579063999999997 0.11454000000000002 0.777976 49 | -0.26475293999999994 -0.07444519999999999 -0.954758 50 | -0.41246079999999996 0.418779 -0.32284999999999997 51 | 0.2476560000000001 -0.13600659999999998 0.2615660000000001 52 | 0.4246000000000001 0.03580120000000002 -0.4233659999999999 53 | -0.5411299999999999 -0.11011799999999998 -0.929308 54 | -0.6250899999999999 0.03580120000000002 -0.443604 55 | -0.540244 0.12968860000000001 0.7367779999999999 56 | -0.41246079999999996 -0.23840900000000004 0.634784 57 | -0.7996 0.08661940000000001 -0.15557199999999996 58 | -0.26462845999999995 -0.146847 0.79646 59 | 0.2476560000000001 0.1125846 0.13403400000000001 60 | 0.2476560000000001 -0.17178700000000002 -0.421744 61 | -0.5368999999999999 0.339645 0.613872 62 | -0.5411459999999999 -0.1276288 0.7698959999999999 63 | -0.41246079999999996 0.03871540000000001 -1.05718 64 | 0.6178380000000001 0.03580120000000002 0.24335000000000004 65 | -0.29231199999999996 0.31912300000000005 0.349314 66 | -0.26013309999999995 0.26950300000000005 -0.418894 67 | -0.632822 0.25033360000000004 0.23899000000000006 68 | -0.540318 0.11984580000000002 -0.8994900000000001 69 | -0.2660968799999999 -0.468999 -0.08001209199999998 70 | -0.2658917599999999 0.1259732 -0.936342 71 | -0.41246079999999996 0.16764 0.33637800000000007 72 | 0.2476560000000001 0.12682000000000002 -0.25450319999999993 73 | -0.41246079999999996 0.193123 0.6148899999999999 74 | -0.28097799999999995 -0.26662699999999995 -0.9550560000000001 75 | -0.41246079999999996 0.2031138 -0.7732860000000001 76 | -0.41246079999999996 -0.328079 -0.45375999999999994 77 | 0.807052 -0.1336504 -0.08001209199999998 78 | -0.530322 0.319767 -0.532106 79 | -0.51525 -0.504687 -0.08001209199999998 80 | -0.41246079999999996 0.46123500000000006 0.43516600000000005 81 | -0.31964639999999994 0.03580120000000002 -0.497502 82 | -0.41246079999999996 0.15071500000000002 0.870544 83 | -0.41246079999999996 -0.06548199999999998 0.34570200000000006 84 | -0.784184 -0.302007 -0.08001209199999998 85 | 0.6100840000000001 -0.41331699999999993 -0.08001209199999998 86 | -0.09080579999999992 0.03580120000000002 0.30903 87 | 0.020324000000000064 0.26950300000000005 -0.19608039999999996 88 | -0.41246079999999996 -0.405585 0.22890200000000002 89 | -0.745752 0.03580120000000002 -0.32093399999999994 90 | -0.709652 0.03580120000000002 0.20765200000000003 91 | -0.27080266 0.33877900000000005 0.6969699999999999 92 | -0.02672199999999994 0.20404460000000002 0.11580720000000003 93 | -0.7888099999999999 0.03580120000000002 0.00943860000000002 94 | -0.41246079999999996 0.32618900000000006 -0.663486 95 | -0.41246079999999996 -0.36981299999999995 -0.947808 96 | -0.41246079999999996 0.377563 -0.8832420000000001 97 | 0.02490600000000004 0.03580120000000002 -0.44525799999999993 98 | -0.28894819999999993 0.35186300000000004 -0.563682 99 | -0.41246079999999996 0.435601 0.625434 100 | 0.15757000000000004 0.18983440000000001 -0.08001209199999998 101 | -0.054812999999999945 0.18840220000000002 -0.30462599999999995 102 | -0.5303519999999999 -0.27252699999999996 -0.9320380000000001 103 | -0.41246079999999996 0.328345 0.5158039999999999 104 | 0.2476560000000001 -0.4454809999999999 0.07011240000000003 105 | -0.26849613999999994 0.27849900000000005 -0.8942540000000001 106 | -0.5940719999999999 0.259347 -0.4123939999999999 107 | -0.41246079999999996 0.447163 -0.748802 108 | 0.2476560000000001 -0.450841 -0.21049319999999996 109 | -0.41246079999999996 -0.17950500000000003 0.9182919999999999 110 | 0.2476560000000001 0.016300600000000012 0.24431000000000005 111 | -0.5303519999999999 -0.27252699999999996 0.772038 112 | -0.5001559999999999 0.32067500000000004 0.24080600000000005 113 | -0.04994799999999994 0.382877 -0.08001209199999998 114 | -0.29563219999999996 0.503227 -0.08001209199999998 115 | -0.7592739999999999 0.20498319999999998 -0.08001209199999998 116 | -0.047245999999999955 0.34076700000000004 0.136862 117 | -0.49262599999999995 0.03580120000000002 -0.48777399999999993 118 | -0.2919033999999999 -0.289585 0.7931439999999998 119 | -0.41246079999999996 -0.1390958 -0.7848580000000001 120 | 0.44619200000000003 0.17321040000000001 -0.08001209199999998 121 | -0.41246079999999996 -0.48701900000000004 -0.18602259999999995 122 | -0.41246079999999996 0.458283 0.049555800000000025 123 | -0.553728 0.40081900000000004 -0.08001209199999998 124 | -0.26495847999999994 -0.015385599999999985 0.791436 125 | -0.41246079999999996 -0.349951 0.73013 126 | 0.7112520000000001 0.1089978 -0.08001209199999998 127 | -0.41246079999999996 0.431223 0.309172 128 | -0.5391819999999999 0.24169960000000001 -0.857736 129 | 0.740716 0.03580120000000002 -0.285586 130 | -0.41246079999999996 -0.094816 -1.074596 131 | -0.491604 0.331785 -0.3950119999999999 132 | 0.311338 -0.47026700000000005 -0.08001209199999998 133 | 0.058214000000000043 -0.425045 -0.08001209199999998 134 | -0.540878 -0.0021427999999999864 0.760132 135 | -0.533588 0.36295299999999997 -0.6521540000000001 136 | -0.41246079999999996 0.42135500000000004 -0.4446859999999999 137 | -0.5390579999999999 0.24949300000000002 0.6931319999999999 138 | -0.41246079999999996 0.458283 -0.2095618 139 | 0.2476560000000001 -0.25544100000000003 0.252294 140 | -0.32736439999999994 0.330983 0.23543200000000006 141 | -0.26749734 0.23013440000000002 0.750394 142 | -0.28224059999999995 0.399655 -0.672094 143 | -0.41246079999999996 0.2542354 0.4171640000000001 144 | 0.300964 0.03580120000000002 -0.40868399999999994 145 | -0.41246079999999996 0.2435102 -0.5671080000000001 146 | -0.31706239999999997 -0.221773 0.7024299999999999 147 | -0.31963299999999994 0.21901779999999998 0.293818 148 | -0.34654199999999996 0.350013 -0.38550799999999996 149 | -0.540848 0.008207800000000015 -0.919006 150 | 0.2476560000000001 0.13980040000000002 0.02436180000000003 151 | 0.791176 0.03580120000000002 -0.052041199999999975 152 | -0.41246079999999996 0.055998680000000016 0.34053200000000006 153 | 0.2476560000000001 -0.06118979999999999 -0.41536399999999996 154 | 0.7065840000000001 0.03580120000000002 0.17875600000000005 155 | -0.5001559999999999 0.2183288 0.294176 156 | -0.38590979999999997 -0.49469900000000006 -0.08001209199999998 157 | -0.31757939999999996 -0.222539 -0.8619780000000001 158 | -0.41246079999999996 -0.1253188 0.624962 159 | -0.5338539999999999 0.363239 0.5019559999999998 160 | -0.33631939999999994 0.1979904 -0.4647819999999999 161 | -0.15674259999999995 0.26950300000000005 -0.39242599999999994 162 | 0.5487960000000001 0.03580120000000002 -0.421296 163 | 0.2476560000000001 -0.28597700000000004 -0.40369 164 | -0.49551799999999996 -0.221773 0.857972 165 | 0.5131060000000001 0.03580120000000002 0.26505600000000007 166 | -0.7745939999999999 0.15479140000000002 -0.2569342 167 | -0.765744 0.03580120000000002 0.11164860000000001 168 | -0.41246079999999996 0.13988860000000003 -1.034318 169 | -0.495416 -0.221773 -1.017974 170 | -0.8065939999999999 -0.012635599999999983 -0.08001209199999998 171 | -0.7148479999999999 0.21384219999999998 0.18473200000000004 172 | -0.41246079999999996 0.08632920000000002 0.62218 173 | -0.3290586 -0.221773 0.8601840000000001 174 | -0.41246079999999996 0.385367 0.7143059999999999 175 | -0.28649259999999993 0.374397 0.44337000000000015 176 | -0.495416 -0.221773 -0.846236 177 | -0.24084041999999994 0.26950300000000005 0.25427200000000005 178 | 0.2476560000000001 0.14221720000000002 -0.15501279999999998 179 | -0.49551799999999996 -0.221773 0.686234 180 | -0.5078659999999999 0.23031059999999998 -0.447928 181 | -0.41246079999999996 -0.04044639999999998 -0.5052939999999999 182 | 0.2476560000000001 0.08315140000000001 -0.34324599999999994 183 | -0.41246079999999996 0.45957899999999996 0.530098 184 | -0.41246079999999996 -0.160321 0.342542 185 | -0.2651563599999999 0.020194000000000017 -0.9482360000000001 186 | -0.6095439999999999 -0.49603500000000006 -0.08001209199999998 187 | -0.26462399999999997 -0.168607 -0.956836 188 | -0.09196099999999995 0.19811 0.18273400000000004 189 | -0.02076399999999995 0.321933 -0.2696978 190 | -0.32944199999999996 -0.22218300000000002 -1.0198500000000001 191 | -0.41246079999999996 -0.298867 -1.029372 192 | -0.7763399999999999 0.03580120000000002 -0.2288062 193 | -0.41246079999999996 0.11132320000000001 -0.781096 194 | -0.41246079999999996 -0.242649 -0.48803799999999997 195 | -0.41246079999999996 0.061532360000000015 0.893108 196 | -0.41246079999999996 0.463133 -0.6511899999999999 197 | -0.17755999999999994 -0.446515 -0.08001209199999998 198 | -0.643686 0.03580120000000002 0.271026 199 | -0.41246079999999996 0.23537760000000002 0.8347819999999999 200 | -0.41246079999999996 0.07619266000000002 -0.49794799999999995 201 | -0.41246079999999996 0.293679 -0.7474720000000001 202 | -0.17926199999999998 0.03580120000000002 0.324372 203 | -0.23012879999999997 0.03580120000000002 -0.49173 204 | -0.7970919999999999 -0.21365300000000004 -0.08001209199999998 205 | -0.27498359999999994 0.396243 0.6293839999999999 206 | -0.41246079999999996 0.278731 0.592794 207 | 0.7875060000000002 -0.229001 -0.08001209199999998 208 | -0.7537959999999999 -0.384717 -0.08001209199999998 209 | 0.526626 -0.43970299999999995 -0.08001209199999998 210 | 0.004686000000000079 0.278969 0.08358540000000002 211 | -0.41246079999999996 -0.45068500000000006 0.15574400000000002 212 | -0.41246079999999996 -0.405585 -0.38890199999999997 213 | 0.6858540000000001 -0.36659699999999995 -0.08001209199999998 214 | -0.5288979999999999 0.294663 0.31981400000000004 215 | 0.2476560000000001 -0.46381100000000003 -0.01310799999999998 216 | -0.00798799999999994 0.03580120000000002 0.29266400000000004 217 | 0.802334 -0.04300119999999999 -0.08001209199999998 218 | 0.16092400000000007 0.03580120000000002 0.2557900000000001 219 | -0.41246079999999996 -0.34278299999999995 0.2846620000000001 220 | -0.4833 -0.343797 0.772038 221 | -0.6937119999999999 0.03580120000000002 -0.384324 222 | 0.03938000000000008 0.26950300000000005 -0.11671699999999997 223 | -0.7902039999999999 0.11458480000000001 -0.08001209199999998 224 | -0.05407799999999996 0.03580120000000002 -0.46220399999999995 225 | -0.41246079999999996 0.321535 -0.9409460000000001 226 | -0.29315559999999996 0.31085700000000005 -0.49567799999999995 227 | 0.32893400000000006 0.03580120000000002 0.252428 228 | -0.793994 0.11096620000000001 0.03176180000000002 229 | -0.41246079999999996 -0.33950099999999994 -0.875626 230 | -0.32589159999999995 -0.33000299999999994 -0.9471940000000001 231 | 0.22939600000000004 0.15372800000000003 -0.08001209199999998 232 | 0.2476560000000001 -0.46751100000000007 -0.12477539999999998 233 | -0.669764 0.2373458 -0.3796799999999999 234 | -0.5411839999999999 -0.18759900000000002 -0.93129 235 | -0.4833 -0.343797 -0.9320380000000001 236 | 0.2476560000000001 -0.425079 -0.28248399999999996 237 | 0.09933600000000004 0.03580120000000002 -0.428218 238 | 0.0016140000000000598 0.324755 -0.08001209199999998 239 | -0.2669374199999999 0.2002298 -0.9194420000000001 240 | -0.06866159999999993 0.26950300000000005 0.17006400000000002 241 | -0.009953999999999935 0.2286394 -0.258609 242 | -0.3573589999999999 -0.35294899999999996 0.781684 243 | -0.10988839999999993 0.2195064 -0.36112599999999995 244 | -0.05820759999999994 0.26950300000000005 -0.319766 245 | 0.2476560000000001 -0.06118979999999999 0.25536400000000004 246 | -0.41246079999999996 -0.10545779999999998 0.9151579999999999 247 | 0.09185400000000005 0.2323766 -0.08001209199999998 248 | -0.41246079999999996 -0.253193 0.8995519999999999 249 | 0.2476560000000001 -0.41682699999999995 0.13774 250 | -0.26449767999999996 -0.221773 0.7979419999999999 251 | -0.48188400000000003 0.03580120000000002 0.3288960000000001 252 | -0.27115019999999995 0.344885 -0.8513539999999999 253 | -0.41246079999999996 0.42245299999999997 -0.8173920000000001 254 | -0.36801999999999996 0.483367 -0.08001209199999998 255 | 0.2476560000000001 0.07420708000000001 0.19503000000000006 256 | -0.6163239999999999 0.362587 -0.08001209199999998 257 | -0.44933739999999994 0.36568900000000004 0.21733400000000005 258 | -0.34391839999999996 0.03580120000000002 0.338272 259 | -0.72116 0.266045 -0.08001209199999998 260 | -0.41246079999999996 -0.30055299999999996 0.6791579999999999 261 | 0.5168200000000001 0.17710920000000002 -0.08001209199999998 262 | -0.43729339999999994 0.371719 -0.3741899999999999 263 | -0.22541379999999994 0.500461 -0.08001209199999998 264 | -0.5675859999999999 0.26378500000000005 0.258992 265 | -0.41246079999999996 -0.49279100000000003 -0.015859399999999968 266 | -0.09790739999999996 0.43248300000000006 -0.08001209199999998 267 | -0.41246079999999996 -0.20799300000000004 -0.7843260000000001 268 | -0.41246079999999996 -0.07031099999999998 -0.7853320000000001 269 | -0.09836559999999993 0.32840100000000005 0.18930600000000006 270 | -0.541194 -0.204685 0.7716639999999999 271 | -0.5613619999999999 0.03580120000000002 -0.469 272 | -0.41266639999999993 0.464943 -0.01772559999999998 273 | -0.41266639999999993 0.464943 -0.14228699999999997 274 | 0.37752600000000003 0.163892 -0.08001209199999998 275 | -0.41246079999999996 -0.02937439999999998 -1.068316 276 | -0.3839777999999999 0.371217 0.21445000000000006 277 | -0.528542 0.288373 -0.466734 278 | -0.805484 0.04861280000000001 -0.060960799999999975 279 | -0.2956869999999999 0.286045 0.29476800000000003 280 | -0.41246079999999996 -0.15836899999999998 -1.077436 281 | -0.011615999999999932 -0.414149 -0.08001209199999998 282 | 0.7065840000000001 0.03580120000000002 -0.338758 283 | -0.5406719999999999 0.059727976000000016 0.752518 284 | 0.6591 0.143134 -0.08001209199999998 285 | 0.3749340000000001 -0.465857 -0.08001209199999998 286 | -0.41246079999999996 0.44172900000000004 0.11809060000000002 287 | -0.538206 0.29202300000000003 -0.82185 288 | -0.541048 -0.06334499999999998 0.7663139999999999 289 | -0.5398559999999999 0.17858040000000003 -0.882506 290 | 0.12090800000000007 -0.44145899999999993 -0.08001209199999998 291 | -0.5397759999999999 0.1882318 0.7195179999999999 292 | 0.2476560000000001 -0.31469899999999995 0.23215200000000005 293 | -0.26872299999999993 0.287517 0.730586 294 | -0.41246079999999996 0.44943500000000003 0.366974 295 | -0.41246079999999996 -0.47512099999999996 -0.24543639999999997 296 | -0.4456165999999999 -0.501869 -0.08001209199999998 297 | -0.26475037999999995 -0.07538959999999999 0.794778 298 | -0.535334 0.35683699999999996 -0.716342 299 | -0.7902899999999999 0.12260860000000001 -0.2090832 300 | -0.26530291999999994 0.043928240000000014 0.7858639999999999 301 | -0.79801 0.03580120000000002 -0.12473679999999998 302 | -0.27814759999999994 0.403061 -0.738246 303 | -0.41246079999999996 0.40771900000000005 0.254722 304 | -0.28570979999999996 0.38083500000000003 -0.6160220000000001 305 | -0.41246079999999996 0.2001906 -0.526704 306 | -0.41246079999999996 0.21103880000000003 0.37681200000000004 307 | -0.5380579999999999 0.29880300000000004 0.65638 308 | -0.41246079999999996 -0.359533 0.80148 309 | 0.2476560000000001 -0.0031787999999999816 -0.40726799999999996 310 | -0.30725939999999996 0.2433496 -0.44112799999999996 311 | 0.358742 0.03580120000000002 -0.416234 312 | -0.2851565999999999 -0.224897 -0.914908 313 | -0.31299839999999995 0.308153 -0.4073359999999999 314 | -0.5320639999999999 0.34876300000000005 -0.5961720000000001 315 | -0.35798919999999995 0.1810238 0.3136300000000001 316 | -0.41246079999999996 0.285023 -0.6067800000000001 317 | -0.41246079999999996 0.19330799999999998 -1.013354 318 | -0.41246079999999996 0.446029 -0.2651622 319 | -0.5410219999999999 -0.05339059999999998 -0.9254120000000001 320 | -0.41246079999999996 0.302619 0.46533800000000014 321 | 0.7792560000000001 0.03580120000000002 0.0032492000000000215 322 | -0.029199999999999948 0.26950300000000005 0.127472 323 | -0.48692399999999997 0.43402700000000005 -0.08001209199999998 324 | 0.2476560000000001 0.1303416 0.08087440000000003 325 | -0.26642135999999994 0.16956680000000002 0.767782 326 | 0.791176 0.03580120000000002 -0.10798079999999997 327 | -0.41246079999999996 0.44086100000000006 -0.496684 328 | -0.41246079999999996 -0.180433 0.624538 329 | -0.46093 0.1802032 0.31405800000000006 330 | -0.535334 0.35683699999999996 0.5563400000000001 331 | 0.7660080000000001 0.03580120000000002 -0.21613979999999997 332 | -0.5323939999999999 0.35330300000000003 0.44829600000000014 333 | -0.36909359999999997 -0.22181100000000004 -0.8138940000000001 334 | -0.41246079999999996 -0.07031099999999998 0.6253299999999999 335 | 0.2476560000000001 -0.117686 -0.4207099999999999 336 | 0.6649700000000001 0.03580120000000002 0.21730400000000002 337 | 0.49522600000000006 0.03580120000000002 -0.4258759999999999 338 | -0.3551211999999999 -0.221773 0.6645719999999999 339 | 0.6010960000000001 0.03580120000000002 -0.40942 340 | 0.5664800000000001 0.03580120000000002 0.25826000000000005 341 | -0.11513399999999994 0.306271 -0.36650799999999994 342 | -0.3839777999999999 0.1677866 -0.48053199999999996 343 | 0.2476560000000001 -0.18923299999999998 0.261054 344 | -0.745752 0.03580120000000002 0.16093000000000005 345 | -0.41246079999999996 -0.336831 -0.9922140000000002 346 | -0.33449419999999996 -0.48399700000000007 -0.08001209199999998 347 | 0.4596340000000001 0.03580120000000002 0.26561200000000007 348 | -0.5406719999999999 0.059727976000000016 -0.9125179999999999 349 | 0.2476560000000001 0.045587740000000015 -0.38980399999999993 350 | -0.38030239999999993 0.03580120000000002 -0.500238 351 | 0.2476560000000001 -0.22312300000000002 -0.4179799999999999 352 | -0.41246079999999996 0.11653680000000002 0.332356 353 | -0.7524139999999999 0.1828306 -0.29862199999999994 354 | 0.020324000000000064 0.26950300000000005 0.03607080000000003 355 | 0.004686000000000079 0.278969 -0.24359 356 | -0.456498 -0.221773 0.8904939999999999 357 | -0.456498 -0.221773 0.6537219999999999 358 | -0.456478 -0.221773 -1.050496 359 | -0.456478 -0.221773 -0.8137220000000001 360 | -0.2835367999999999 0.394879 0.491144 361 | -0.41246079999999996 0.035865000000000015 0.62412 362 | -0.41246079999999996 -0.49533900000000003 -0.12287159999999997 363 | -0.41246079999999996 -0.015152999999999986 0.34465200000000007 364 | -0.36901539999999994 -0.221773 0.890736 365 | -0.41246079999999996 -0.36997899999999995 -0.4243659999999999 366 | -0.36909359999999997 -0.22181100000000004 -1.050666 367 | -0.41246079999999996 0.06120290000000002 -0.783204 368 | 0.7627560000000001 0.06614664000000002 -0.08001209199999998 369 | -0.41246079999999996 0.41543300000000005 0.671198 370 | -0.41246079999999996 0.13604500000000003 0.619896 371 | 0.2476560000000001 0.1436532 -0.034848399999999974 372 | -0.7438319999999999 0.19129420000000003 0.15120600000000003 373 | -0.41246079999999996 0.32320099999999996 0.5652159999999999 374 | -0.4409951999999999 0.03580120000000002 -0.4984259999999999 375 | 0.22908600000000007 -0.470211 -0.08001209199999998 376 | -0.805974 -0.061065599999999984 -0.08001209199999998 377 | -0.540866 0.267649 -0.42473399999999994 378 | -0.5234939999999999 -0.221773 0.8184480000000001 379 | -0.5233319999999999 -0.221773 -0.97845 380 | -0.5234939999999999 -0.221773 0.725714 381 | -0.5233319999999999 -0.221773 -0.885716 382 | 0.740716 0.03580120000000002 0.12558000000000005 383 | -0.6554819999999999 -0.48215100000000005 -0.08001209199999998 384 | -0.12117799999999994 -0.43080699999999994 -0.08001209199999998 385 | -0.28978539999999997 0.343789 0.39015 386 | -0.2851565999999999 -0.224897 -0.977792 387 | -0.2654544999999999 0.06764188000000002 -0.943414 388 | -0.521304 0.25612060000000003 0.27447 389 | -0.41246079999999996 -0.09012740000000001 -0.5057579999999999 390 | -0.5628279999999999 -0.503655 -0.08001209199999998 391 | -0.26490323999999993 -0.027214799999999983 -0.9523300000000001 392 | -0.28462299999999996 -0.221773 0.7553559999999999 393 | -0.26467963999999994 -0.12154179999999996 -0.95594 394 | -0.68157 0.2321262 0.21191800000000002 395 | -0.41246079999999996 0.353911 0.7486919999999999 396 | 0.8031480000000001 -0.179987 -0.08001209199999998 397 | -0.41246079999999996 0.08426540000000002 -1.048764 398 | -0.2956869999999999 0.286045 -0.454766 399 | -0.41246079999999996 0.32739300000000005 -0.70976 400 | 0.2476560000000001 -0.32835899999999996 -0.38526799999999994 401 | -0.41246079999999996 -0.11423579999999998 0.3453280000000001 402 | -0.41246079999999996 0.19330799999999998 0.8533519999999999 403 | -0.41246079999999996 0.10678880000000002 0.883796 404 | -0.41246079999999996 0.015897800000000017 0.90113 405 | -0.17869699999999994 0.26950300000000005 0.23833800000000002 406 | -0.801774 0.07407532000000001 -0.023096599999999974 407 | -0.7888099999999999 0.03580120000000002 -0.16945559999999996 408 | -0.8020679999999999 -0.168273 -0.08001209199999998 409 | -0.7795259999999999 0.03580120000000002 0.05404740000000004 410 | -0.015199999999999936 0.314489 0.10398580000000004 411 | -0.67753 0.03580120000000002 0.24065400000000006 412 | -0.48217799999999994 0.19711879999999998 -0.465236 413 | -0.41246079999999996 0.285859 -0.9685460000000001 414 | -0.11513399999999994 0.2286394 0.20650800000000005 415 | -0.41246079999999996 0.39978100000000005 -0.399238 416 | -0.41246079999999996 0.276185 0.8143819999999999 417 | 0.483036 -0.451069 -0.08001209199999998 418 | -0.41246079999999996 0.24686940000000002 -0.76264 419 | -0.6609959999999999 0.03580120000000002 -0.416442 420 | -0.6049559999999999 0.03580120000000002 0.293806 421 | -0.20012239999999998 0.26950300000000005 -0.4039919999999999 422 | -0.41246079999999996 -0.182135 -0.5000359999999999 423 | -0.3839777999999999 0.371217 -0.37444999999999995 424 | 0.20460800000000007 0.03580120000000002 0.24843600000000002 425 | -0.7911159999999999 -0.25831499999999996 -0.08001209199999998 426 | -0.765744 0.03580120000000002 -0.2716566 427 | 0.03573200000000004 0.03580120000000002 0.2827700000000001 428 | 0.2476560000000001 0.13807000000000003 -0.19879419999999998 429 | -0.731282 -0.424685 -0.08001209199999998 430 | -0.08510439999999996 0.19352419999999998 -0.33570199999999994 431 | -0.054812999999999945 0.34247700000000003 -0.30462599999999995 432 | -0.30725939999999996 0.295655 0.253854 433 | -0.029199999999999948 0.26950300000000005 -0.28747199999999995 434 | -0.06254419999999994 0.18777660000000002 0.152558 435 | -0.41246079999999996 0.16003920000000002 -0.778386 436 | 0.2476560000000001 0.10636300000000001 -0.306712 437 | -0.5299659999999999 0.31351300000000004 0.35904400000000003 438 | -0.29498099999999994 -0.221773 0.8286039999999999 439 | -0.41246079999999996 -0.20310500000000004 0.336766 440 | 0.5693940000000001 -0.427489 -0.08001209199999998 441 | -0.0049419999999999464 0.238398 0.09346200000000003 442 | 0.02904400000000007 0.29187700000000005 -0.08001209199999998 443 | -0.08951519999999995 0.26950300000000005 -0.348924 444 | 0.2476560000000001 -0.459879 -0.16869559999999997 445 | -0.27758439999999995 0.40292300000000003 0.587348 446 | -0.632822 0.25033360000000004 -0.398992 447 | -0.41246079999999996 0.23865740000000002 0.6049959999999999 448 | 0.2874380000000001 0.03580120000000002 0.24683200000000002 449 | -0.785844 0.1338108 0.06573180000000002 450 | 0.2476560000000001 -0.455601 0.02994320000000003 451 | 0.11891800000000008 0.03580120000000002 0.263946 452 | -0.27257385999999995 0.36846100000000004 0.668336 453 | -0.7735879999999999 -0.34183699999999995 -0.08001209199999998 454 | -0.09946459999999994 0.26950300000000005 0.19737600000000002 455 | -0.41246079999999996 -0.48701900000000004 0.02601000000000002 456 | -0.41246079999999996 0.11653680000000002 -0.492356 457 | -0.26768809999999993 0.240022 -0.9073120000000001 458 | 0.6458900000000001 -0.39455299999999993 -0.08001209199999998 459 | -0.41246079999999996 0.45628500000000005 -0.7097960000000001 460 | -0.5148519999999999 0.296025 -0.4136599999999999 461 | -0.41246079999999996 0.45209900000000003 0.5694459999999999 462 | 0.19309000000000004 0.1713668 -0.08001209199999998 463 | 0.7718220000000001 -0.265579 -0.08001209199999998 464 | -0.22741159999999994 -0.459713 -0.08001209199999998 465 | -0.41246079999999996 -0.029547799999999985 -0.785358 466 | 0.799648 -0.0036017999999999883 -0.08001209199999998 467 | 0.030424000000000062 0.26950300000000005 -0.15516499999999997 468 | 0.804938 -0.08233259999999996 -0.08001209199999998 469 | -0.3749491999999999 -0.36251500000000003 -0.938606 470 | -0.7798619999999999 0.15244100000000002 -0.08001209199999998 471 | -0.27889679999999994 0.26950300000000005 0.263262 472 | -0.41246079999999996 0.463133 0.49119 473 | -0.41246079999999996 -0.46996299999999996 0.1039922 474 | 0.2476560000000001 -0.02261099999999998 0.25014000000000003 475 | 0.12362800000000007 0.20996360000000003 -0.08001209199999998 476 | -0.41246079999999996 0.010290400000000012 -0.503876 477 | 0.7164640000000001 -0.342997 -0.08001209199999998 478 | -0.14121359999999994 0.03580120000000002 0.31790000000000007 479 | -0.17926199999999998 0.03580120000000002 -0.4843719999999999 480 | 0.06203800000000004 0.2568494 -0.08001209199999998 481 | -0.4503516 -0.363839 0.772038 482 | -0.4503516 -0.363839 -0.9320380000000001 483 | -0.21738919999999995 0.03580120000000002 0.33013400000000004 484 | -0.32617919999999995 -0.33096499999999995 0.7871440000000001 485 | -0.2684667399999999 0.03580120000000002 -0.495204 486 | -0.10332339999999994 0.03580120000000002 -0.4712639999999999 487 | 0.13688200000000006 0.03580120000000002 -0.42026399999999997 488 | -0.30065299999999995 -0.30148299999999995 -0.9516120000000001 489 | 0.27312800000000004 -0.472857 -0.08001209199999998 490 | -0.41246079999999996 -0.279169 -0.47652399999999995 491 | -0.41246079999999996 0.46270500000000003 -0.61347 492 | -0.524654 0.03580120000000002 0.3188580000000001 493 | -0.41246079999999996 -0.253989 -1.06064 494 | -0.41246079999999996 -0.27074699999999996 0.65635 495 | -0.41246079999999996 -0.221773 0.9199999999999999 496 | -0.41246079999999996 -0.302315 -0.8380080000000001 497 | -0.05407799999999996 0.03580120000000002 0.3022020000000001 498 | -0.41246079999999996 -0.296277 0.309694 499 | -0.2695112599999999 0.311975 -0.8778460000000001 500 | -0.02485399999999996 0.355409 -0.08001209199999998 501 | -0.5207059999999999 0.41793500000000006 -0.08001209199999998 502 | -0.30679259999999997 0.03580120000000002 0.33705000000000007 503 | 0.62382 0.15871100000000002 -0.08001209199999998 504 | 0.2476560000000001 -0.0990922 0.25936000000000003 505 | -0.11780299999999992 0.26950300000000005 -0.37256999999999996 506 | -0.41246079999999996 0.40071100000000004 -0.8547359999999999 507 | 0.2476560000000001 -0.439423 -0.24869899999999998 508 | 0.6795180000000001 0.03580120000000002 -0.365888 509 | -0.5856619999999999 0.382409 -0.08001209199999998 510 | 0.2476560000000001 0.1441648 -0.11014439999999998 511 | -0.18952219999999997 0.493819 -0.08001209199999998 512 | -0.41246079999999996 -0.283481 0.878174 513 | -0.41246079999999996 -0.46416300000000005 -0.2818919999999999 514 | -0.27655159999999995 -0.25683500000000004 0.7958319999999999 515 | -0.41246079999999996 -0.38043899999999997 0.772038 516 | -0.26456705999999997 -0.18278299999999997 0.797172 517 | -0.41246079999999996 -0.336931 0.8294239999999999 518 | -0.72508 0.03580120000000002 -0.350286 519 | -0.645554 0.34128500000000006 -0.08001209199999998 520 | -0.741606 0.23670180000000002 -0.08001209199999998 521 | 0.552486 0.1747666 -0.08001209199999998 522 | -0.40140879999999995 0.47089100000000006 -0.08001209199999998 523 | -0.019203999999999943 0.03580120000000002 -0.45509599999999995 524 | -0.6982659999999999 0.293229 -0.08001209199999998 525 | -0.508218 -0.318589 0.772038 526 | -0.508218 -0.318589 -0.9320380000000001 527 | -0.41246079999999996 0.39726300000000003 -0.35091799999999995 528 | 0.2476560000000001 -0.432623 0.10614780000000004 529 | -0.26553253999999993 0.07946760000000001 0.7821499999999999 530 | -0.26458311999999995 -0.203905 -0.9574940000000001 531 | 0.481352 0.1763418 -0.08001209199999998 532 | -0.5274639999999999 0.03580120000000002 -0.47863 533 | -0.41246079999999996 -0.43471499999999996 0.18707000000000004 534 | -0.41246079999999996 -0.43471499999999996 -0.34707 535 | -0.41246079999999996 0.38976299999999997 0.19984800000000005 536 | 0.4596340000000001 0.03580120000000002 -0.425612 537 | -0.41246079999999996 -0.32693300000000003 0.7037279999999999 538 | -0.34201539999999997 -0.22197500000000003 -0.835728 539 | -0.3832977999999999 -0.221773 0.643834 540 | -0.541158 -0.144847 -0.9303380000000001 541 | -0.41246079999999996 0.353911 -0.908692 542 | -0.12014659999999992 0.297491 0.21165000000000003 543 | -0.41246079999999996 -0.360507 -0.9032640000000001 544 | -0.48013599999999995 -0.503539 -0.08001209199999998 545 | -0.41246079999999996 0.435601 -0.785434 546 | -0.5381699999999999 -0.23888500000000001 -0.9320380000000001 547 | 0.21896000000000004 0.03580120000000002 -0.4060619999999999 548 | -0.02672199999999994 0.20404460000000002 -0.2758108 549 | -0.5411679999999999 -0.16196300000000002 0.770726 550 | -0.5381699999999999 -0.23888500000000001 0.772038 551 | 0.4115120000000001 0.1687674 -0.08001209199999998 552 | -0.41246079999999996 0.0045126000000000124 -1.063052 553 | -0.41246079999999996 -0.497775 -0.058553799999999975 554 | 0.26364200000000004 0.14732660000000003 -0.08001209199999998 555 | 0.022346000000000033 -0.417987 -0.08001209199999998 556 | 0.2476560000000001 -0.407917 -0.31199599999999994 557 | -0.44849759999999994 0.03580120000000002 0.33588400000000007 558 | -0.07408079999999995 0.408115 -0.08001209199999998 559 | -0.5943879999999999 0.03580120000000002 -0.45810799999999996 560 | -0.41246079999999996 -0.36997899999999995 0.264366 561 | -0.3852017999999999 0.03580120000000002 0.340222 562 | -0.41246079999999996 0.30986500000000006 -0.6339920000000001 563 | -0.41246079999999996 0.45636299999999996 0.39993 564 | -0.2662690999999999 0.159008 -0.930242 565 | -0.7990079999999999 0.07544760000000002 -0.08001209199999998 566 | -0.12183659999999995 0.455781 -0.08001209199999998 567 | -0.41246079999999996 -0.06251539999999998 0.91222 568 | -0.537598 0.318435 -0.7995160000000001 569 | 0.05728000000000005 0.03580120000000002 -0.43780399999999997 570 | 0.3744700000000001 0.03580120000000002 0.25813600000000003 571 | -0.33652519999999997 0.49384700000000004 -0.08001209199999998 572 | 0.2476560000000001 -0.398381 0.16529600000000003 573 | -0.07027559999999994 0.34247700000000003 0.16048800000000005 574 | -0.27257385999999995 0.36846100000000004 -0.828338 575 | 0.34433 0.15902940000000002 -0.08001209199999998 576 | -0.26283843999999995 0.504687 -0.08001209199999998 577 | 0.2476560000000001 -0.22312300000000002 0.25798 578 | 0.2476560000000001 0.045587740000000015 0.22980400000000004 579 | -0.41246079999999996 -0.23901300000000003 -0.794516 580 | -0.41246079999999996 -0.06251539999999998 -1.072222 581 | 0.3907360000000001 0.03580120000000002 -0.41999999999999993 582 | -0.704172 0.22038999999999997 -0.354468 583 | -0.29399939999999997 0.30258700000000005 0.32204200000000005 584 | -0.29146859999999997 0.327379 -0.522944 585 | -0.41246079999999996 -0.1372308 0.9165719999999999 586 | -0.41246079999999996 -0.1266542 -1.076128 587 | -0.41246079999999996 -0.190071 -1.0787200000000001 588 | 0.2476560000000001 -0.25544100000000003 -0.41229399999999994 589 | -0.043461999999999945 -0.414709 -0.08001209199999998 590 | -0.41246079999999996 0.44943500000000003 -0.526976 591 | -0.5148519999999999 0.296025 0.25366200000000005 592 | -0.807052 0.02369200000000001 -0.08001209199999998 593 | -0.26467927999999996 -0.11545299999999996 0.7958179999999999 594 | -0.2669374199999999 0.2002298 0.759442 595 | -0.5407839999999999 0.028893400000000014 0.756656 596 | -0.29737459999999993 0.26950300000000005 -0.4274899999999999 597 | 0.2476560000000001 -0.28597700000000004 0.24369000000000005 598 | -0.5405179999999999 0.09006640000000002 0.7468599999999999 599 | -0.5409379999999999 -0.02280539999999999 -0.922334 600 | -0.5405179999999999 0.09006640000000002 -0.90686 601 | -0.540092 0.14930980000000002 -0.89117 602 | 0.2476560000000001 -0.34150899999999995 0.21758000000000002 603 | 0.2476560000000001 -0.354105 -0.36902199999999996 604 | -0.794944 0.03580120000000002 -0.020374799999999978 605 | -0.540014 0.1590956 0.7283139999999999 606 | -0.5409679999999999 -0.03308319999999998 0.7634019999999999 607 | -0.7826479999999999 0.03580120000000002 -0.199228 608 | -0.28811739999999997 0.35974300000000003 0.4171100000000001 609 | -0.30725939999999996 0.2433496 0.28113 610 | -0.539604 0.2071286 -0.873192 611 | -0.3839777999999999 0.1677866 0.320534 612 | -0.35798919999999995 0.357981 0.22135400000000002 613 | -0.48217799999999994 0.341885 0.22974600000000003 614 | -0.26807869999999995 0.259583 0.7409999999999999 615 | -0.3063547999999999 -0.22309100000000004 -0.998578 616 | 0.2476560000000001 0.06488308000000001 -0.3666919999999999 617 | -0.5395099999999999 0.21625260000000002 0.709746 618 | -0.41246079999999996 0.1784904 -0.506486 619 | -0.41246079999999996 0.18934060000000003 0.3565940000000001 620 | -0.805484 0.04861280000000001 -0.09906105999999998 621 | -0.41246079999999996 0.22188219999999997 -0.546918 622 | -0.41246079999999996 0.2327126 0.3970180000000001 623 | 0.2476560000000001 0.14221720000000002 -0.0050001999999999686 624 | 0.2476560000000001 0.09157500000000002 0.17129200000000003 625 | -0.2804441999999999 0.402377 -0.701128 626 | -0.773034 0.03580120000000002 0.08338280000000002 627 | -0.471922 0.35089100000000006 -0.38505 628 | -0.41246079999999996 0.44086100000000006 0.33668200000000004 629 | 0.2476560000000001 -0.471077 -0.05758259999999997 630 | -0.2872971999999999 0.36730700000000005 -0.590366 631 | -0.5292539999999999 0.300953 -0.49289399999999994 632 | -0.5281859999999999 0.28208300000000003 0.2936540000000001 633 | -0.31963299999999994 0.21901779999999998 -0.453816 634 | 0.04351000000000005 0.26950300000000005 -0.06177969999999998 635 | -0.33631939999999994 0.1979904 0.304782 636 | -0.35798919999999995 0.1810238 -0.47363 637 | -0.6576839999999999 0.24213020000000002 0.22679400000000002 638 | -0.41246079999999996 0.275135 0.4370600000000001 639 | -0.531028 0.332071 -0.558118 640 | -0.32736439999999994 0.330983 -0.395432 641 | -0.5411039999999999 -0.09202619999999999 0.768424 642 | -0.41246079999999996 0.453043 0.07777140000000003 643 | -0.04804399999999995 0.26950300000000005 0.14908800000000003 644 | -0.41486159999999994 0.46524699999999997 -0.055338199999999976 645 | -0.41486159999999994 0.46524699999999997 -0.10468079999999998 646 | 0.7969579999999999 0.03580120000000002 -0.08001209199999998 647 | -0.48217799999999994 0.19711879999999998 0.305238 648 | -0.534362 0.36211099999999996 -0.680636 649 | 0.2476560000000001 0.1359344 0.05301660000000004 650 | -0.41246079999999996 0.453043 -0.23777639999999997 651 | 0.2476560000000001 0.1333666 -0.2270518 652 | 0.32893400000000006 0.03580120000000002 -0.4124279999999999 653 | -0.41246079999999996 0.264817 -0.5871660000000001 654 | 0.7853100000000001 0.03580120000000002 -0.024224399999999972 655 | 0.7853100000000001 0.03580120000000002 -0.13579519999999998 656 | -0.6071519999999999 0.2567302 0.24850200000000003 657 | 0.2476560000000001 0.12274100000000002 0.10791160000000002 658 | 0.2476560000000001 0.11802380000000001 -0.2810996 659 | -0.41246359999999993 0.46198700000000004 0.021808200000000028 660 | -0.41246359999999993 0.46198700000000004 -0.18181619999999996 661 | -0.14811259999999993 -0.438265 -0.08001209199999998 662 | -0.43729339999999994 0.16728540000000003 0.320794 663 | -0.46093 0.1802032 -0.474058 664 | 0.7728780000000001 0.03580120000000002 0.030134200000000028 665 | -0.5675859999999999 0.26378500000000005 -0.4189919999999999 666 | -0.2695112599999999 0.311975 0.717846 667 | -0.41246079999999996 -0.180433 -0.78454 668 | -0.41246079999999996 -0.20799300000000004 0.6243259999999999 669 | -0.41246079999999996 -0.15287499999999998 0.6247499999999999 670 | -0.41246079999999996 -0.11154499999999999 -0.785066 671 | -0.41246079999999996 0.15678960000000003 -0.4862679999999999 672 | -0.541088 -0.08268059999999998 -0.9278300000000002 673 | -0.41246079999999996 -0.09777960000000001 0.625164 674 | -0.41246079999999996 0.320507 0.48974000000000006 675 | 0.274092 0.03580120000000002 -0.404988 676 | -0.534608 0.361015 0.5296859999999999 677 | -0.27648779999999995 0.40181100000000003 -0.7650700000000001 678 | 0.7728780000000001 0.03580120000000002 -0.19014899999999998 679 | -0.41246079999999996 -0.043043999999999985 0.6253960000000001 680 | -0.5387879999999999 0.264249 -0.8432060000000001 681 | -0.41246079999999996 0.43684100000000003 -0.29034399999999994 682 | -0.538646 0.27133300000000005 0.677986 683 | -0.5360419999999999 0.35160500000000006 0.582352 684 | -0.5360419999999999 0.35160500000000006 -0.742354 685 | -0.41246079999999996 0.39253099999999996 0.226228 686 | -0.41246079999999996 0.316817 -0.7340500000000001 687 | -0.012603999999999949 0.26950300000000005 0.1068588 688 | -0.012603999999999949 0.26950300000000005 -0.26686279999999996 689 | -0.5317259999999999 0.343603 0.423706 690 | -0.41246079999999996 0.42135500000000004 0.28468400000000005 691 | -0.41246079999999996 0.431223 -0.4691719999999999 692 | -0.41246079999999996 0.38562300000000005 -0.374444 693 | -0.6811119999999999 -0.47222900000000007 -0.08001209199999998 694 | 0.09563400000000005 -0.434419 -0.08001209199999998 695 | -0.28422939999999997 0.39115500000000003 -0.6399520000000001 696 | -0.41246079999999996 0.431357 0.14186 697 | 0.7660080000000001 0.03580120000000002 0.056127400000000036 698 | 0.7584640000000001 0.03580120000000002 -0.24090579999999998 699 | -0.537598 0.318435 0.639516 700 | -0.35979099999999997 -0.489295 -0.08001209199999998 701 | -0.41246079999999996 0.010125600000000012 0.62483 702 | -0.20466739999999994 0.03580120000000002 -0.488352 703 | -0.7568659999999999 0.03580120000000002 0.13778800000000005 704 | -0.7568659999999999 0.03580120000000002 -0.29779199999999995 705 | 0.14558400000000005 -0.4485009999999999 -0.08001209199999998 706 | -0.24288769999999998 0.03580120000000002 0.33310800000000007 707 | -0.5411999999999999 -0.213229 -0.9318500000000001 708 | -0.2940942 0.03580120000000002 -0.49655799999999994 709 | 0.33680600000000005 -0.468535 -0.08001209199999998 710 | -0.41246079999999996 0.03580120000000002 -0.503038 711 | -0.11591499999999992 0.03580120000000002 0.31348600000000004 712 | -0.41246079999999996 0.010290400000000012 0.34387600000000007 713 | -0.467848 0.03580120000000002 -0.49338399999999993 714 | -0.41246079999999996 0.035865000000000015 -0.7841200000000002 715 | 0.806382 -0.1083116 -0.08001209199999998 716 | -0.41246079999999996 -0.015152999999999986 -0.504652 717 | 0.4001380000000001 -0.46384300000000006 -0.08001209199999998 718 | -0.532712 0.357067 -0.619998 719 | -0.3447801999999999 0.03580120000000002 -0.498382 720 | -0.41246079999999996 0.06120290000000002 0.6232039999999999 721 | -0.41246079999999996 -0.04044639999999998 0.345294 722 | -0.41246079999999996 0.08632920000000002 -0.7821800000000001 723 | -0.41246079999999996 0.40071100000000004 0.694736 724 | -0.41246079999999996 0.11132320000000001 0.6210959999999999 725 | -0.07839899999999993 0.03580120000000002 -0.46678 726 | -0.31032899999999997 -0.478841 -0.08001209199999998 727 | -0.540866 0.267649 0.2647360000000001 728 | -0.521304 0.25612060000000003 -0.43446799999999997 729 | -0.41246079999999996 -0.06548199999999998 -0.505702 730 | -0.28495419999999994 0.386459 0.468236 731 | -0.12500519999999998 0.2485696 0.21663400000000002 732 | -0.00008399999999997299 0.2485696 -0.24848219999999996 733 | -0.2648137199999999 -0.05104879999999999 0.7937719999999999 734 | -0.8062879999999999 -0.03685319999999999 -0.08001209199999998 735 | -0.8056199999999999 -0.08525019999999998 -0.08001209199999998 736 | -0.732402 0.03580120000000002 0.18108000000000005 737 | -0.41246079999999996 -0.09012740000000001 0.345758 738 | -0.41246079999999996 0.270913 -0.7553179999999999 739 | -0.41246079999999996 0.16003920000000002 0.6183859999999999 740 | -0.41246079999999996 0.13604500000000003 -0.7798940000000001 741 | -0.12014659999999992 0.238398 -0.3716499999999999 742 | -0.533018 0.359943 0.471214 743 | -0.27370099999999997 0.38451100000000005 0.6501159999999999 744 | -0.2651563599999999 0.020193800000000012 0.7882359999999999 745 | -0.26530291999999994 0.043928240000000014 -0.9458660000000001 746 | -0.26501993999999995 -0.0035271999999999873 -0.9504440000000001 747 | -0.26561335999999997 0.09124700000000002 -0.940844 748 | -0.2648142399999999 -0.05085399999999998 -0.953768 749 | -0.26471133999999996 -0.09800199999999996 -0.95543 750 | -0.2646513999999999 -0.145075 -0.956396 751 | -0.26455587999999997 -0.227437 -0.957932 752 | -0.27483599999999997 -0.226111 -0.9359999999999999 753 | -0.53593 -0.221773 0.787944 754 | -0.41246079999999996 -0.11423579999999998 -0.505328 755 | -0.53593 -0.221773 0.7561640000000001 756 | 0.7500760000000001 0.03580120000000002 0.10412460000000004 757 | 0.7500760000000001 0.03580120000000002 -0.26413319999999996 758 | -0.8037299999999999 -0.145005 -0.08001209199999998 759 | -0.41246079999999996 0.300545 0.5845579999999999 760 | -0.27450639999999993 -0.221773 0.77626 761 | -0.41246079999999996 0.03871540000000001 0.8971799999999999 762 | -0.41246079999999996 0.061532360000000015 -1.053108 763 | -0.03060799999999994 0.03580120000000002 0.29749800000000004 764 | 0.4604440000000001 -0.455895 -0.08001209199999998 765 | -0.0049419999999999464 0.297491 -0.2534666 766 | -0.41246079999999996 0.36970900000000007 0.731876 767 | -0.709652 0.03580120000000002 -0.367652 768 | -0.41246079999999996 0.10678880000000002 -1.043796 769 | -0.41246079999999996 0.08426540000000002 0.8887639999999999 770 | -0.41246079999999996 0.21439419999999998 -1.00416 771 | -0.6937119999999999 0.03580120000000002 0.22432400000000005 772 | -0.41246079999999996 0.1721176 -1.022262 773 | -0.5834839999999999 0.03580120000000002 0.30200800000000005 774 | -0.41246079999999996 0.21439419999999998 0.84416 775 | -0.8037019999999999 0.06138626000000001 -0.11805359999999998 776 | -0.41246079999999996 0.1721176 0.8622619999999999 777 | -0.26600429999999997 0.1372114 0.7745219999999999 778 | -0.41246079999999996 0.12896040000000003 0.877786 779 | -0.41246079999999996 0.337935 0.765128 780 | -0.41246079999999996 0.41203500000000004 -0.42375399999999996 781 | -0.41246079999999996 0.32834700000000006 0.5386979999999999 782 | -0.67753 0.03580120000000002 -0.40065399999999995 783 | 0.7798619999999999 0.05103578000000002 -0.08001209199999998 784 | -0.8037019999999999 0.06138626000000001 -0.041965999999999976 785 | -0.41246079999999996 -0.006839599999999987 0.904908 786 | -0.41246079999999996 0.337935 -0.92513 787 | -0.15674259999999995 0.26950300000000005 0.23242800000000005 788 | -0.41246079999999996 0.2560932 0.8250199999999999 789 | -0.41246079999999996 -0.1376692 0.34428800000000004 790 | -0.09679199999999992 -0.424485 -0.08001209199999998 791 | -0.799796 -0.19111500000000003 -0.08001209199999998 792 | 0.7456280000000001 0.08098260000000002 -0.08001209199999998 793 | -0.41246079999999996 0.266245 -0.979852 794 | -0.6609959999999999 0.03580120000000002 0.25644200000000006 795 | 0.2476560000000001 -0.471077 -0.10243939999999997 796 | -0.015199999999999936 0.2195064 0.10398580000000004 797 | -0.7996 0.08661940000000001 -0.004442999999999975 798 | -0.801774 0.07407532000000001 -0.13692059999999998 799 | -0.41246079999999996 0.295233 0.8022819999999999 800 | -0.41246079999999996 0.30428900000000003 -0.955576 801 | -0.7941619999999999 -0.236031 -0.08001209199999998 -------------------------------------------------------------------------------- /include/subdivide_multi.h: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // tet_subdivision 4 | // 5 | // Created by Yiwen Ju on 12/2/23. 6 | // 7 | 8 | #ifndef subdivide_multi_h 9 | #define subdivide_multi_h 10 | //#define Non_Robust_Test 11 | //#define No_Multi_Check 12 | //#define Only_ZeroX 13 | //#define Only_Geometry 14 | //#define No_Multi_Check_3 15 | //#define Only_ZeroX_3 16 | //#define Only_Geometry_3 17 | //#define CSG_Base 18 | //#define MI_Base 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | using namespace std; 28 | 29 | 30 | int sub_call_two = 0; 31 | int sub_call_three = 0; 32 | 33 | llvm_vecsmall::SmallVector, 100>, 3>, 20> multiple_indices; 34 | 35 | enum geo_obj { 36 | IA, 37 | CSG, 38 | MI 39 | }; 40 | 41 | int GLOBAL_METHOD = IA; 42 | bool curve_network = false; 43 | 44 | enum csg_operations{ 45 | Intersection, 46 | Union, 47 | Negation 48 | }; 49 | 50 | struct csg_unit{ 51 | int operation; 52 | std::array elements; 53 | }; 54 | 55 | bool load_csgTree(const std::string filename, llvm_vecsmall::SmallVector& tree){ 56 | using json = nlohmann::json; 57 | std::ifstream fin(filename.c_str()); 58 | //llvm_vecsmall::SmallVector tree = {}; 59 | if (!fin) 60 | { 61 | std::cout << "function file not exist!" << std::endl; 62 | return false; 63 | } 64 | json tree_data; 65 | fin >> tree_data; 66 | fin.close(); 67 | // 68 | size_t n_units = tree_data.size(); 69 | tree.resize(n_units); 70 | for (size_t j = 0 ; j < n_units; j++){ 71 | std::string type = tree_data[j]["type"].get(); 72 | std::array elements; 73 | for (int i = 0; i < 2; i ++){ 74 | elements[i] = tree_data[j]["elements"][i].get(); 75 | } 76 | if (type == "Intersection"){ 77 | tree[j] = {0, elements}; 78 | }else if (type == "Union"){ 79 | tree[j] = {1, elements}; 80 | }else if (type == "Negation"){ 81 | tree[j] = {2, elements}; 82 | } 83 | } 84 | return true; 85 | } 86 | 87 | llvm_vecsmall::SmallVector GLOBAL_CSGTREE ={{0, {2, 8}}, {1, {3, -9}}, {0,{-1,4}}, {0, {-2, 5}}, {0, {-3,6}}, {0, {-4, 7}}, {0, {-5, -6}},{2,{9, 0}}, {1, {-7, -8}}}; 88 | 89 | std::pair, llvm_vecsmall::SmallVector> iterTree(const llvm_vecsmall::SmallVectorcsgTree,const int curNode,const llvm_vecsmall::SmallVector, 20> funcInt){ 90 | csg_unit curUnit = csgTree[curNode - 1]; 91 | array interval, childInt1, childInt2; 92 | llvm_vecsmall::SmallVector af(funcInt.size(), 1), childAF1(funcInt.size(), 1), childAF2(funcInt.size(), 1); 93 | if (curUnit.elements[0] > 0){ 94 | std::pair, llvm_vecsmall::SmallVector> child1 = iterTree(csgTree, curUnit.elements[0], funcInt); 95 | childInt1 = child1.first; 96 | childAF1 = child1.second; 97 | }else{ 98 | childInt1 = funcInt[-curUnit.elements[0] - 1]; 99 | childAF1[-curUnit.elements[0] - 1] = 0; 100 | } 101 | if (childInt1[0] * childInt1[1]>0){ 102 | for (size_t i = 0; i < childAF1.size(); i++){ 103 | childAF1[i] = 1; 104 | } 105 | } 106 | if (curUnit.operation != Negation){ 107 | if (curUnit.elements[1] > 0){ 108 | std::pair, llvm_vecsmall::SmallVector> child2 = iterTree(csgTree, curUnit.elements[1], funcInt); 109 | childInt2 = child2.first; 110 | childAF2 = child2.second; 111 | }else{ 112 | childInt2 = funcInt[-curUnit.elements[1] - 1]; 113 | childAF2[-curUnit.elements[1] - 1] = 0; 114 | } 115 | } 116 | if (childInt2[0] * childInt2[1]>0){ 117 | for (size_t i = 0; i < childAF2.size(); i++){ 118 | childAF2[i] = 1; 119 | } 120 | } 121 | switch (curUnit.operation){ 122 | case Intersection: 123 | interval = {std::max(childInt1[0], childInt2[0]), std::max(childInt1[1], childInt2[1])}; 124 | if(interval[0]*interval[1] <= 0){ 125 | for (int i = 0; i < funcInt.size(); i++){ 126 | af[i] = childAF1[i] * childAF2[i]; 127 | } 128 | } 129 | break; 130 | case Union: 131 | interval = {std::min(childInt1[0], childInt2[0]), std::min(childInt1[1], childInt2[1])}; 132 | if(interval[0]*interval[1] <= 0){ 133 | for (int i = 0; i < funcInt.size(); i++){ 134 | af[i] = childAF1[i] * childAF2[i]; 135 | } 136 | } 137 | break; 138 | case Negation: 139 | interval = {std::min(-childInt1[0], -childInt1[1]), std::max(-childInt1[0], -childInt1[1])}; 140 | if(interval[0]*interval[1] <= 0) 141 | af = childAF1; 142 | break; 143 | default: 144 | std::cout << "not a valid CSG operation" << std::endl; 145 | } 146 | return std::pair(interval, af); 147 | } 148 | 149 | const std::array, 16> coeff = {{{2, 1, 0, 0}, {2, 0, 1, 0}, {2, 0, 0, 1}, {0, 2, 1, 0},{0, 2, 0, 1}, {1, 2, 0, 0}, {0, 0, 2, 1}, {1, 0, 2, 0},{0, 1, 2, 0}, {1, 0, 0, 2}, {0, 1, 0, 2}, {0, 0, 1, 2},{0, 1, 1, 1}, {1, 0, 1, 1}, {1, 1, 0, 1}, {1, 1, 1, 0}}}; 150 | // constant matrix to build linear values with 151 | 152 | int get_sign(double x) { 153 | return (x > 0) ? 1 : -1; 154 | } 155 | 156 | double dot(const std::array &a, const std::array &b) { 157 | return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; 158 | } 159 | 160 | double dot(const std::array &a, const std::array &b) { 161 | return a[0] * b[0] + a[1] * b[1]; 162 | } 163 | 164 | double dot(const llvm_vecsmall::SmallVector &a, llvm_vecsmall::SmallVector &b) { 165 | double ret = 0; 166 | for (int i = 0; i < a.size(); i++){ 167 | ret += a[i] * b[i]; 168 | } 169 | return ret; 170 | } 171 | 172 | double norm(const std::array &a) { 173 | return sqrt(dot(a, a)); 174 | } 175 | 176 | std::array getVec(const std::array &p1, const std::array &p2){ 177 | std::array vec; 178 | for (int i = 0; i < 3; i++){ 179 | vec[i] = p1[i] - p2[i]; 180 | } 181 | return vec; 182 | } 183 | 184 | std::array vecPlus(const std::array &v1, const std::array &v2){ 185 | std::array vec; 186 | for (int i = 0; i < 3; i++){ 187 | vec[i] = v1[i] + v2[i]; 188 | } 189 | return vec; 190 | } 191 | 192 | std::array perp(const std::array &a){ 193 | return {-a[1], a[0]}; 194 | } 195 | 196 | llvm_vecsmall::SmallVector cross(const std::array &a, const std::array &b) { 197 | llvm_vecsmall::SmallVector c(3); 198 | c[0] = a[1] * b[2] - a[2] * b[1]; 199 | c[1] = a[2] * b[0] - a[0] * b[2]; 200 | c[2] = a[0] * b[1] - a[1] * b[0]; 201 | return c; 202 | } 203 | // 204 | double det(const std::array& vec1, 205 | const std::array& vec2, 206 | const std::array& vec3) { 207 | return vec1[0] * vec2[1] * vec3[2] + 208 | vec1[1] * vec2[2] * vec3[0] + 209 | vec1[2] * vec2[0] * vec3[1] - 210 | vec1[2] * vec2[1] * vec3[0] - 211 | vec1[1] * vec2[0] * vec3[2] - 212 | vec1[0] * vec2[2] * vec3[1]; 213 | } 214 | // 215 | double det(const std::array& vec1, 216 | const std::array& vec2) { 217 | return vec1[0] * vec2[1] - vec1[1] * vec2[0]; 218 | } 219 | // 220 | std::array transpose2d(const std::array, 2>& matrix) { 221 | std::array transposed{}; 222 | for (size_t i = 0; i < 20; ++i) { 223 | for (size_t j = 0; j < 2; ++j) { 224 | transposed[i * 2 + j] = matrix[j][i]; 225 | } 226 | } 227 | return transposed; 228 | } 229 | 230 | std::array transpose3d(const std::array, 3>& matrix) { 231 | std::array transposed{}; 232 | for (size_t i = 0; i < 20; ++i) { 233 | for (size_t j = 0; j < 3; ++j) { 234 | transposed[i * 3 + j] = matrix[j][i]; 235 | } 236 | } 237 | return transposed; 238 | } 239 | 240 | llvm_vecsmall::SmallVector, 20> matrixMultiply(const llvm_vecsmall::SmallVector, 20> &matA, const llvm_vecsmall::SmallVector, 20> &matB) { 241 | size_t rowsA = matA.size(); 242 | size_t colsA = matA[0].size(); 243 | size_t colsB = matB[0].size(); 244 | llvm_vecsmall::SmallVector, 20> result(rowsA, llvm_vecsmall::SmallVector(colsB)); 245 | for (size_t i = 0; i < rowsA; ++i) { 246 | for (size_t j = 0; j < colsB; ++j) { 247 | for (size_t k = 0; k < colsA; ++k) { 248 | result[i][j] += matA[i][k] * matB[k][j]; 249 | } 250 | } 251 | } 252 | return result; 253 | } 254 | 255 | 256 | bool subTet(std::array,4> &pts, 257 | const llvm_vecsmall::SmallVector, 20> &vals, 258 | const llvm_vecsmall::SmallVector,4>, 20> &grads, const double threshold, bool& active) { 259 | std::array p0 = pts[0], p1 = pts[1], p2 = pts[2], p3 = pts[3]; 260 | std::array vec1 = getVec(p1, p0), vec2 = getVec(p2, p0), vec3 = getVec(p3, p0), 261 | vec4 = getVec(p2, p1), vec5 = getVec(p3, p1), vec6 = getVec(p3, p2); 262 | double D = det(vec1, vec2, vec3); 263 | double sqD = D*D; 264 | bool score = true; 265 | // double tetEdgeLen[] = {norm(getVec(p1, p0)),norm(getVec(p2,p0)), norm(getVec(p3,p0)), norm(getVec(p2,p1)), norm(getVec(p3,p1)), norm(getVec(p3,p2))}; 266 | // double score = *std::max_element(tetEdgeLen, tetEdgeLen + 6); // find the largest edge length using 6 edges. 267 | const size_t funcNum = vals.size(); 268 | llvm_vecsmall::SmallVector, 20> crossMatrix = {cross(vec2, vec3), cross(vec3, vec1), cross(vec1, vec2)}; 269 | llvm_vecsmall::SmallVector, 20> gradList(funcNum); 270 | llvm_vecsmall::SmallVector, 20> valList(funcNum); 271 | llvm_vecsmall::SmallVector, 20> diffList(funcNum); 272 | llvm_vecsmall::SmallVector errorList(funcNum); 273 | llvm_vecsmall::SmallVector activeTF(funcNum); 274 | llvm_vecsmall::SmallVector, 20> funcInt(funcNum); 275 | int activeNum = 0; 276 | llvm_vecsmall::SmallVector, 20> zeroXResult(funcNum, llvm_vecsmall::SmallVector(funcNum)); 277 | 278 | //single function linearity check: 279 | for (int funcIter = 0; funcIter < funcNum; funcIter++){ 280 | double v0 = vals[funcIter][0], v1 = vals[funcIter][1], v2 = vals[funcIter][2], v3 = vals[funcIter][3]; 281 | std::array g0 = grads[funcIter][0], g1 = grads[funcIter][1], g2 = grads[funcIter][2], g3 = grads[funcIter][3]; 282 | // Bezier control points 283 | std::array v0s = {v0 + dot(g0, vec1) / 3, v0 + dot(g0, vec2) / 3, v0 + dot(g0, vec3) / 3}; 284 | std::array v1s = {v1 + dot(g1, vec4) / 3, v1 + dot(g1, vec5) / 3, v1 - dot(g1, vec1) / 3}; 285 | std::array v2s = {v2 + dot(g2, vec6) / 3, v2 - dot(g2, vec2) / 3, v2 - dot(g2, vec4) / 3}; 286 | std::array v3s = {v3 - dot(g3, vec3) / 3, v3 - dot(g3, vec5) / 3, v3 - dot(g3, vec6) / 3}; 287 | //double e0 = (v1s[0] + v1s[1] + v2s[0] + v2s[2] + v3s[1] + v3s[2]) / 6; 288 | double vMid0 = (9 * (v1s[0] + v1s[1] + v2s[0] + v2s[2] + v3s[1] + v3s[2]) / 6 - v1 - v2 - v3)/ 6; 289 | //double e1 = (v0s[1] + v0s[2] + v2s[0] + v2s[1] + v3s[0] + v3s[2]) / 6; 290 | double vMid1 =(9 * (v0s[1] + v0s[2] + v2s[0] + v2s[1] + v3s[0] + v3s[2]) / 6 - v0 - v2 - v3)/ 6; 291 | //double e2 = (v0s[0] + v0s[2] + v1s[1] + v1s[2] + v3s[0] + v3s[1]) / 6; 292 | double vMid2 =(9 * (v0s[0] + v0s[2] + v1s[1] + v1s[2] + v3s[0] + v3s[1]) / 6 - v0 - v1 - v3)/ 6; 293 | //double e3 = (v0s[0] + v0s[1] + v1s[0] + v1s[2] + v2s[1] + v2s[2]) / 6; 294 | double vMid3 =(9 * (v0s[0] + v0s[1] + v1s[0] + v1s[2] + v2s[1] + v2s[2]) / 6 - v0 - v1 - v2)/ 6; 295 | 296 | //storing bezier and linear info for later linearity comparison 297 | valList[funcIter] = {v0, v1, v2, v3, v0s[0], v0s[1], v0s[2], v1s[0], v1s[1], v1s[2], v2s[0], v2s[1], v2s[2], 298 | v3s[0], v3s[1], v3s[2], vMid0, vMid1, vMid2, vMid3}; 299 | if(GLOBAL_METHOD == IA){ 300 | Timer single_timer(singleFunc, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 301 | activeTF[funcIter] = get_sign(*std::max_element(valList[funcIter].begin(), valList[funcIter].end())) == get_sign(*std::min_element(valList[funcIter].begin(), valList[funcIter].end())) ? false : true; 302 | single_timer.Stop(); 303 | if (activeTF[funcIter]){ 304 | if (GLOBAL_METHOD == IA){ 305 | if (!active){ 306 | active = true; 307 | } 308 | } 309 | activeNum++; 310 | double d1 = v1-v0, d2 = v2-v0, d3 = v3-v0; 311 | llvm_vecsmall::SmallVector unNormF = matrixMultiply(llvm_vecsmall::SmallVector, 20>({{d1, d2, d3}}), crossMatrix)[0]; 312 | gradList[funcIter] = {unNormF[0],unNormF[1],unNormF[2]}; 313 | for (int i = 0; i < 16; ++i) { 314 | diffList[funcIter][i] = valList[funcIter][i + 4] - 315 | (v0 * coeff[i][0] + v1 * coeff[i][1] + v2 * coeff[i][2] + v3 * coeff[i][3]) / 3.0; 316 | } 317 | errorList[funcIter] = std::max(*max_element(diffList[funcIter].begin(), diffList[funcIter].end()), std::abs(*min_element(diffList[funcIter].begin(), diffList[funcIter].end()))); 318 | Timer single2_timer(singleFunc, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 319 | double lhs = errorList[funcIter] * errorList[funcIter] * sqD; 320 | double rhs; 321 | if (!curve_network){ 322 | rhs = threshold * threshold * dot(gradList[funcIter], gradList[funcIter]); 323 | }else{ 324 | rhs = numeric_limits::infinity() * dot(gradList[funcIter], gradList[funcIter]); 325 | } 326 | #ifdef Non_Robust_Test 327 | std::cout << norm(gradList[funcIter])/std::abs(D) << std::endl; 328 | lhs = errorList[funcIter] / (norm(gradList[funcIter])/std::abs(D)); 329 | rhs = threshold; 330 | #endif 331 | if (lhs > rhs) { 332 | single2_timer.Stop(); 333 | return score; 334 | } 335 | single2_timer.Stop(); 336 | } 337 | }else{ 338 | funcInt[funcIter] = {*std::min_element(valList[funcIter].begin(), valList[funcIter].end()), *std::max_element(valList[funcIter].begin(), valList[funcIter].end())}; 339 | } 340 | } 341 | 342 | if (GLOBAL_METHOD == CSG){ 343 | //Timer csg_timer(csgtree, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 344 | std::pair, llvm_vecsmall::SmallVector> csgResult = iterTree(GLOBAL_CSGTREE, 1, funcInt); 345 | //csg_timer.Stop(); 346 | #ifdef CSG_Base 347 | csgResult.second.resize(funcNum); 348 | for (size_t funcIter = 0; funcIter < funcNum; funcIter++){ 349 | csgResult.second[funcIter] = get_sign(*std::max_element(valList[funcIter].begin(), valList[funcIter].end())) == get_sign(*std::min_element(valList[funcIter].begin(), valList[funcIter].end())) ? 1 : 0;; 350 | } 351 | #endif 352 | if(csgResult.first[0] * csgResult.first[1] > 0){ 353 | return false; 354 | }else{ 355 | for (size_t funcIter = 0; funcIter < funcNum; funcIter++){ 356 | Timer single_timer(singleFunc, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 357 | activeTF[funcIter] = !csgResult.second[funcIter]; 358 | single_timer.Stop(); 359 | if (activeTF[funcIter]){ 360 | if (!active){ 361 | active = true; 362 | } 363 | activeNum++; 364 | double v0 = vals[funcIter][0], v1 = vals[funcIter][1], v2 = vals[funcIter][2], v3 = vals[funcIter][3]; 365 | double d1 = v1-v0, d2 = v2-v0, d3 = v3-v0; 366 | llvm_vecsmall::SmallVector unNormF = matrixMultiply(llvm_vecsmall::SmallVector, 20>({{d1, d2, d3}}), crossMatrix)[0]; 367 | //std:: cout << unNormF[0] << ", " << unNormF[1] << ", " << unNormF[2] << std::endl; 368 | gradList[funcIter] = {unNormF[0],unNormF[1],unNormF[2]}; 369 | for (int i = 0; i < 16; ++i) { 370 | diffList[funcIter][i] = valList[funcIter][i + 4] - 371 | (v0 * coeff[i][0] + v1 * coeff[i][1] + v2 * coeff[i][2] + v3 * coeff[i][3]) / 3.0; 372 | } 373 | errorList[funcIter] = std::max(*max_element(diffList[funcIter].begin(), diffList[funcIter].end()), std::abs(*min_element(diffList[funcIter].begin(), diffList[funcIter].end()))); 374 | Timer single2_timer(singleFunc, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 375 | double lhs = errorList[funcIter] * errorList[funcIter] * sqD; 376 | double rhs; 377 | if (!curve_network){ 378 | rhs = threshold * threshold * dot(gradList[funcIter], gradList[funcIter]); 379 | }else{ 380 | rhs = numeric_limits::infinity() * dot(gradList[funcIter], gradList[funcIter]); 381 | } 382 | if (lhs > rhs) { 383 | single2_timer.Stop(); 384 | return score; 385 | } 386 | single2_timer.Stop(); 387 | } 388 | } 389 | } 390 | } 391 | Timer single_timer(singleFunc, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 392 | if(activeNum < 2){ 393 | single_timer.Stop(); 394 | return false; 395 | } 396 | llvm_vecsmall::SmallVector activeFunc(activeNum); 397 | int activeFuncIter = 0; 398 | for (int funcIter = 0; funcIter < funcNum; funcIter++){ 399 | if (activeTF[funcIter]){ 400 | activeFunc[activeFuncIter] = funcIter; 401 | activeFuncIter++; 402 | } 403 | } 404 | single_timer.Stop(); 405 | const int pairNum = activeNum * (activeNum-1)/2, triNum = activeNum * (activeNum-1) * (activeNum - 2)/ 6; 406 | llvm_vecsmall::SmallVector,40> pair(pairNum); 407 | llvm_vecsmall::SmallVector, 100> triple(triNum); 408 | llvm_vecsmall::SmallVector, 100>, 3> multiples = multiple_indices[activeNum - 1]; 409 | // int pairIt = 0, triIt = 0; 410 | // for (int i = 0; i < activeNum - 1; i++){ 411 | // for (int j = i + 1; j < activeNum; j++){ 412 | // pair[pairIt] = {activeFunc[i], activeFunc[j]}; 413 | // pairIt ++; 414 | // if (j < activeNum - 1){ 415 | // for (int k = j + 1; k < activeNum; k++){ 416 | // triple[triIt] = {activeFunc[i], activeFunc[j], activeFunc[k]}; 417 | // triIt ++; 418 | // } 419 | // } 420 | // } 421 | // } 422 | 423 | // 2-function checks 424 | int activeDouble_count = 0; 425 | { 426 | Timer timer(twoFunc, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 427 | bool zeroX; 428 | for (int pairIter = 0; pairIter < pairNum; pairIter ++){ 429 | array pairIndices = {multiples[0][pairIter][0],multiples[0][pairIter][1]}; 430 | pair[pairIter] = {activeFunc[pairIndices[0]], activeFunc[pairIndices[1]]}; 431 | std::array nPoints = transpose2d({valList[pair[pairIter][0]], valList[pair[pairIter][1]]});// X0, Y0, X1, Y1, ... 432 | std::array query = {0.0, 0.0}; // X, Y 433 | sub_call_two ++; 434 | Timer sub_timer(sub_twoFunc, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 435 | zeroX = convex_hull_membership::contains<2, double>(nPoints, query); 436 | sub_timer.Stop(); 437 | #ifdef No_Multi_Check 438 | zeroX = false; 439 | #endif 440 | #ifdef Only_Geometry 441 | zeroX = true; 442 | #endif 443 | #ifdef Only_ZeroX 444 | if (zeroX){ 445 | return score; 446 | }else{ 447 | return false; 448 | } 449 | #endif 450 | if (zeroX){ 451 | activeDouble_count++; 452 | zeroXResult[pair[pairIter][0]][pair[pairIter][1]] = true; 453 | zeroXResult[pair[pairIter][1]][pair[pairIter][0]] = true; 454 | 455 | // two function linearity test: 456 | std::array w1 = {dot(gradList[pair[pairIter][0]], gradList[pair[pairIter][0]]), dot(gradList[pair[pairIter][0]], gradList[pair[pairIter][1]])}; 457 | std::array w2 = {dot(gradList[pair[pairIter][0]], gradList[pair[pairIter][1]]), dot(gradList[pair[pairIter][1]], gradList[pair[pairIter][1]])}; 458 | double E = det(w1, w2); 459 | std::arrayinvPerp_w2 = perp(w2); 460 | for(int i = 0; i < 2; i++){ 461 | invPerp_w2[i] *= -1; 462 | } 463 | std::array perp_w1 = perp(w1); 464 | llvm_vecsmall::SmallVector, 20> H = matrixMultiply(llvm_vecsmall::SmallVector, 20>({llvm_vecsmall::SmallVector(std::begin(invPerp_w2), std::end(invPerp_w2)), llvm_vecsmall::SmallVector(std::begin(perp_w1), std::end(perp_w1))}), llvm_vecsmall::SmallVector, 20>({llvm_vecsmall::SmallVector(std::begin(gradList[pair[pairIter][0]]), std::end(gradList[pair[pairIter][0]])), llvm_vecsmall::SmallVector(std::begin(gradList[pair[pairIter][1]]), std::end(gradList[pair[pairIter][1]]))})); 465 | 466 | //find the largest max error (max squared gamma: the LHS of the equation) among all 16 bezier control points 467 | double maxGammaSq = 0; 468 | for (int i = 0; i < 16; i++){ 469 | //std::cout << diffList[pair[pairIter][0]][i] << " " << diffList[pair[pairIter][1]][i] << std::endl; 470 | llvm_vecsmall::SmallVector unNormDis = matrixMultiply(llvm_vecsmall::SmallVector, 20>({{diffList[pair[pairIter][0]][i], diffList[pair[pairIter][1]][i]}}), llvm_vecsmall::SmallVector, 20>(H))[0]; 471 | double currError = sqD * dot(unNormDis, unNormDis); 472 | if (maxGammaSq < currError) 473 | maxGammaSq = currError; 474 | } 475 | #ifdef Non_Robust_Test 476 | maxGammaSq = 0; 477 | for (int i = 0; i < 16; i++){ 478 | //std::cout << diffList[pair[pairIter][0]][i] << " " << diffList[pair[pairIter][1]][i] << std::endl; 479 | llvm_vecsmall::SmallVector unNormDis = matrixMultiply(llvm_vecsmall::SmallVector, 20>({{diffList[pair[pairIter][0]][i], diffList[pair[pairIter][1]][i]}}), llvm_vecsmall::SmallVector, 20>(H))[0]; 480 | double currError = sqD * dot(unNormDis, unNormDis); 481 | if (maxGammaSq < currError){ 482 | maxGammaSq = currError;} 483 | unNormDis = matrixMultiply(llvm_vecsmall::SmallVector, 20>({{-diffList[pair[pairIter][0]][i], diffList[pair[pairIter][1]][i]}}), llvm_vecsmall::SmallVector, 20>(H))[0]; 484 | currError = sqD * dot(unNormDis, unNormDis); 485 | if (maxGammaSq < currError){ 486 | maxGammaSq = currError;} 487 | } 488 | if (maxGammaSq/(E*E) > threshold*threshold){ 489 | timer.Stop(); 490 | return score; 491 | } 492 | #else 493 | if (maxGammaSq > threshold*threshold * E*E){ 494 | timer.Stop(); 495 | return score; 496 | } 497 | #endif 498 | } 499 | } 500 | timer.Stop(); 501 | } 502 | if(activeDouble_count < 3) 503 | return false; 504 | { 505 | Timer timer(threeFunc, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 506 | bool zeroX; 507 | for (int triIter = 0; triIter < triNum; triIter ++){ 508 | array tripleIndices = {multiples[1][triIter][0], multiples[1][triIter][1], multiples[1][triIter][2]}; 509 | triple[triIter] = {activeFunc[tripleIndices[0]], activeFunc[tripleIndices[1]], activeFunc[tripleIndices[2]]}; 510 | if(!(zeroXResult[triple[triIter][0]][triple[triIter][1]]&&zeroXResult[triple[triIter][0]][triple[triIter][2]]&&zeroXResult[triple[triIter][1]][triple[triIter][2]])) 511 | continue; 512 | std::array nPoints = transpose3d({valList[triple[triIter][0]], valList[triple[triIter][1]], valList[triple[triIter][2]]}); 513 | std::array query = {0.0, 0.0, 0.0}; // X, Y, Z 514 | sub_call_three ++; 515 | Timer sub_timer(sub_threeFunc, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 516 | zeroX = convex_hull_membership::contains<3, double>(nPoints, query); 517 | sub_timer.Stop(); 518 | #ifdef No_Multi_Check_3 519 | return false; 520 | #endif 521 | #ifdef Only_Geometry_3 522 | zeroX = true; 523 | #endif 524 | #ifdef Only_ZeroX_3 525 | if (zeroX){ 526 | return score; 527 | }else{ 528 | return false; 529 | } 530 | #endif 531 | if (zeroX){ 532 | std::array fi = gradList[triple[triIter][0]]; 533 | std::array fj = gradList[triple[triIter][1]]; 534 | std::array fk = gradList[triple[triIter][2]]; 535 | double E = det(fi, fj, fk); 536 | llvm_vecsmall::SmallVector, 20> H = {cross(fj, fk), cross(fk, fi), cross(fi, fj)}; 537 | double maxGammaSq = 0; 538 | for (int i = 0; i < 16; i++){ 539 | llvm_vecsmall::SmallVector unNormDis = matrixMultiply({{diffList[triple[triIter][0]][i], diffList[triple[triIter][1]][i], diffList[triple[triIter][2]][i]}}, H)[0]; 540 | double currError = sqD * dot(unNormDis, unNormDis); 541 | if (maxGammaSq < currError) 542 | maxGammaSq = currError; 543 | } 544 | if (maxGammaSq > threshold*threshold * E*E){ 545 | timer.Stop(); 546 | return score; 547 | } 548 | } 549 | } 550 | timer.Stop(); 551 | } 552 | return false; 553 | } 554 | 555 | bool subMI(std::array,4> &pts, 556 | const llvm_vecsmall::SmallVector, 20> &vals, 557 | const llvm_vecsmall::SmallVector,4>, 20> &grads, const double threshold, bool& active) 558 | { 559 | std::array p0 = pts[0], p1 = pts[1], p2 = pts[2], p3 = pts[3]; 560 | std::array vec1 = getVec(p1, p0), vec2 = getVec(p2, p0), vec3 = getVec(p3, p0), 561 | vec4 = getVec(p2, p1), vec5 = getVec(p3, p1), vec6 = getVec(p3, p2); 562 | double D = det(vec1, vec2, vec3); 563 | double sqD = D*D; 564 | bool score = true; 565 | // double tetEdgeLen[] = {norm(getVec(p1, p0)),norm(getVec(p2,p0)), norm(getVec(p3,p0)), norm(getVec(p2,p1)), norm(getVec(p3,p1)), norm(getVec(p3,p2))}; 566 | // double score = *std::max_element(tetEdgeLen, tetEdgeLen + 6); // find the largest edge length using 6 edges. 567 | const size_t funcNum = vals.size(); 568 | llvm_vecsmall::SmallVector, 20> crossMatrix = {cross(vec2, vec3), cross(vec3, vec1), cross(vec1, vec2)}; 569 | llvm_vecsmall::SmallVector, 20> gradList(funcNum); 570 | llvm_vecsmall::SmallVector, 20> valList(funcNum); 571 | llvm_vecsmall::SmallVector, 20> diffList(funcNum); 572 | llvm_vecsmall::SmallVector errorList(funcNum); 573 | llvm_vecsmall::SmallVector activeList(funcNum); 574 | llvm_vecsmall::SmallVector, 20> funcInt(funcNum); 575 | double maxLow = -1 * numeric_limits::infinity(); 576 | llvm_vecsmall::SmallVector, 20> activePair(funcNum, llvm_vecsmall::SmallVector(false, funcNum)); 577 | 578 | //single function linearity check: 579 | for (int funcIter = 0; funcIter < funcNum; funcIter++){ 580 | double v0 = vals[funcIter][0], v1 = vals[funcIter][1], v2 = vals[funcIter][2], v3 = vals[funcIter][3]; 581 | std::array g0 = grads[funcIter][0], g1 = grads[funcIter][1], g2 = grads[funcIter][2], g3 = grads[funcIter][3]; 582 | // Bezier control points 583 | std::array v0s = {v0 + dot(g0, vec1) / 3, v0 + dot(g0, vec2) / 3, v0 + dot(g0, vec3) / 3}; 584 | std::array v1s = {v1 + dot(g1, vec4) / 3, v1 + dot(g1, vec5) / 3, v1 - dot(g1, vec1) / 3}; 585 | std::array v2s = {v2 + dot(g2, vec6) / 3, v2 - dot(g2, vec2) / 3, v2 - dot(g2, vec4) / 3}; 586 | std::array v3s = {v3 - dot(g3, vec3) / 3, v3 - dot(g3, vec5) / 3, v3 - dot(g3, vec6) / 3}; 587 | //double e0 = (v1s[0] + v1s[1] + v2s[0] + v2s[2] + v3s[1] + v3s[2]) / 6; 588 | double vMid0 = (9 * (v1s[0] + v1s[1] + v2s[0] + v2s[2] + v3s[1] + v3s[2]) / 6 - v1 - v2 - v3)/ 6; 589 | //double e1 = (v0s[1] + v0s[2] + v2s[0] + v2s[1] + v3s[0] + v3s[2]) / 6; 590 | double vMid1 =(9 * (v0s[1] + v0s[2] + v2s[0] + v2s[1] + v3s[0] + v3s[2]) / 6 - v0 - v2 - v3)/ 6; 591 | //double e2 = (v0s[0] + v0s[2] + v1s[1] + v1s[2] + v3s[0] + v3s[1]) / 6; 592 | double vMid2 =(9 * (v0s[0] + v0s[2] + v1s[1] + v1s[2] + v3s[0] + v3s[1]) / 6 - v0 - v1 - v3)/ 6; 593 | //double e3 = (v0s[0] + v0s[1] + v1s[0] + v1s[2] + v2s[1] + v2s[2]) / 6; 594 | double vMid3 =(9 * (v0s[0] + v0s[1] + v1s[0] + v1s[2] + v2s[1] + v2s[2]) / 6 - v0 - v1 - v2)/ 6; 595 | 596 | //storing bezier and linear info for later linearity comparison 597 | valList[funcIter] = {v0, v1, v2, v3, v0s[0], v0s[1], v0s[2], v1s[0], v1s[1], v1s[2], v2s[0], v2s[1], v2s[2], 598 | v3s[0], v3s[1], v3s[2], vMid0, vMid1, vMid2, vMid3}; 599 | funcInt[funcIter] = {*std::min_element(valList[funcIter].begin(), valList[funcIter].end()), *std::max_element(valList[funcIter].begin(), valList[funcIter].end())}; 600 | //cout << funcInt[funcIter][0] << " " << funcInt[funcIter][1] << endl; 601 | if (maxLow < funcInt[funcIter][0]){ 602 | maxLow = funcInt[funcIter][0]; 603 | } 604 | } 605 | //llvm_vecsmall::SmallVector, 20> active_valList; 606 | llvm_vecsmall::SmallVector activeFunc; 607 | for (int funcIter = 0; funcIter < funcNum; funcIter++){ 608 | if(funcInt[funcIter][1] > maxLow){ 609 | activeFunc.push_back(funcIter); 610 | //active_valList.push_back(valList[funcIter]); 611 | } 612 | } 613 | #ifdef MI_Base 614 | activeFunc.resize(funcNum); 615 | for (size_t funcIter = 0; funcIter < funcNum; funcIter++){ 616 | activeFunc[funcIter] = funcIter; 617 | } 618 | #endif 619 | int activeNum = activeFunc.size(); 620 | if(activeNum < 2) 621 | return false; 622 | 623 | //Timer get_func_timer(getActiveMuti, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 624 | 625 | 626 | const int pairNum = activeNum * (activeNum-1)/2, triNum = activeNum * (activeNum-1) * (activeNum - 2)/ 6, quadNum = activeNum * (activeNum - 1) * (activeNum - 2) * (activeNum - 3)/ 24; 627 | llvm_vecsmall::SmallVector,40> pair(pairNum); 628 | llvm_vecsmall::SmallVector, 100> triple(triNum); 629 | llvm_vecsmall::SmallVector, 300> quad(quadNum); 630 | llvm_vecsmall::SmallVector, 100>, 3> multiples = multiple_indices[activeNum - 1]; 631 | // int pairIt = 0, triIt = 0, quadIt = 0; 632 | // for (int i = 0; i < activeNum - 1; i++){ 633 | // for (int j = i + 1; j < activeNum; j++){ 634 | // pair[pairIt] = {activeFunc[i], activeFunc[j]}; 635 | // pairIt ++; 636 | // if (j < activeNum - 1){ 637 | // for (int k = j + 1; k < activeNum; k++){ 638 | // triple[triIt] = {activeFunc[i], activeFunc[j], activeFunc[k]}; 639 | // triIt ++; 640 | // if (k < activeNum - 1){ 641 | // for (int m = k + 1; m < activeNum; m++){ 642 | // quad[quadIt] = {activeFunc[i], activeFunc[j], activeFunc[k], activeFunc[m]}; 643 | // quadIt++; 644 | // } 645 | // } 646 | // } 647 | // } 648 | // } 649 | // } 650 | // get_func_timer.Stop(); 651 | 652 | for (int pairIter = 0; pairIter < pairNum; pairIter ++){ 653 | Timer single_timer(singleFunc, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 654 | array pairIndices = {multiples[0][pairIter][0],multiples[0][pairIter][1]}; 655 | pair[pairIter] = {activeFunc[pairIndices[0]], activeFunc[pairIndices[1]]}; 656 | array diff_at_point; 657 | int funcIndex1 = pair[pairIter][0]; 658 | int funcIndex2 = pair[pairIter][1]; 659 | for (int i = 0; i < 20; i++){ 660 | diff_at_point[i] = valList[funcIndex1][i] - valList[funcIndex2][i]; 661 | } 662 | bool activeTF = get_sign(*std::max_element(diff_at_point.begin(), diff_at_point.end())) == get_sign(*std::min_element(diff_at_point.begin(), diff_at_point.end())) ? false : true; 663 | single_timer.Stop(); 664 | if (activeTF){ 665 | if (!active){ 666 | active = true; 667 | } 668 | activePair[pair[pairIter][0]][pair[pairIter][1]] = true; 669 | activePair[pair[pairIter][1]][pair[pairIter][0]] = true; 670 | if (!activeList[funcIndex1]){ 671 | activeList[funcIndex1] = true; 672 | double d1 = valList[funcIndex1][1]-valList[funcIndex1][0], d2 = valList[funcIndex1][2]-valList[funcIndex1][0], d3 = valList[funcIndex1][3]-valList[funcIndex1][0]; 673 | llvm_vecsmall::SmallVector unNormF = matrixMultiply(llvm_vecsmall::SmallVector, 20>({{d1, d2, d3}}), crossMatrix)[0]; 674 | gradList[funcIndex1] = {unNormF[0],unNormF[1],unNormF[2]}; 675 | 676 | for (int i = 0; i < 16; ++i) { 677 | diffList[funcIndex1][i] = valList[funcIndex1][i + 4] - 678 | (valList[funcIndex1][0] * coeff[i][0] + valList[funcIndex1][1] * coeff[i][1] + valList[funcIndex1][2] * coeff[i][2] + valList[funcIndex1][3] * coeff[i][3]) / 3.0; 679 | } 680 | //errorList[funcIndex1] = std::max(*max_element(diffList[funcIndex1].begin(), diffList[funcIndex1].end()), std::abs(*min_element(diffList[funcIndex1].begin(), diffList[funcIndex1].end()))); 681 | } 682 | if (!activeList[funcIndex2]){ 683 | activeList[funcIndex2] = true; 684 | double d1 = valList[funcIndex2][1]-valList[funcIndex2][0], d2 = valList[funcIndex2][2]-valList[funcIndex2][0], d3 = valList[funcIndex2][3]-valList[funcIndex2][0]; 685 | llvm_vecsmall::SmallVector unNormF = matrixMultiply(llvm_vecsmall::SmallVector, 20>({{d1, d2, d3}}), crossMatrix)[0]; 686 | gradList[funcIndex2] = {unNormF[0],unNormF[1],unNormF[2]}; 687 | 688 | for (int i = 0; i < 16; ++i) { 689 | diffList[funcIndex2][i] = valList[funcIndex2][i + 4] - 690 | (valList[funcIndex2][0] * coeff[i][0] + valList[funcIndex2][1] * coeff[i][1] + valList[funcIndex2][2] * coeff[i][2] + valList[funcIndex2][3] * coeff[i][3]) / 3.0; 691 | } 692 | //errorList[funcIndex1] = std::max(*max_element(diffList[funcIndex2].begin(), diffList[funcIndex2].end()), std::abs(*min_element(diffList[funcIndex2].begin(), diffList[funcIndex2].end()))); 693 | } 694 | array diff_twofunc; 695 | for (int i = 0; i < 16; ++i){ 696 | diff_twofunc[i] = diffList[funcIndex1][i] - diffList[funcIndex2][i]; 697 | } 698 | 699 | Timer single2_timer(singleFunc, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 700 | double error =std::max(*max_element(diff_twofunc.begin(), diff_twofunc.end()), std::abs(*min_element(diff_twofunc.begin(), diff_twofunc.end()))); 701 | array grad; 702 | for (int i = 0; i < 3; ++i){ 703 | grad[i] = gradList[funcIndex1][i] - gradList[funcIndex2][i]; 704 | } 705 | double lhs = error * error * sqD; 706 | double rhs; 707 | if (!curve_network){ 708 | rhs = threshold * threshold * dot(grad, grad); 709 | }else{ 710 | rhs = numeric_limits::infinity() * dot(grad, grad); 711 | } 712 | //cout << lhs << " " << rhs << endl; 713 | if (lhs > rhs) { 714 | single2_timer.Stop(); 715 | return score; 716 | } 717 | single2_timer.Stop(); 718 | 719 | } 720 | } 721 | 722 | // 2-function checks 723 | int activeTriple_count = 0; 724 | { 725 | Timer timer(twoFunc, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 726 | bool zeroX; 727 | for (int tripleIter = 0; tripleIter < triNum; tripleIter ++){ 728 | array tripleIndices = {multiples[1][tripleIter][0], multiples[1][tripleIter][1], multiples[1][tripleIter][2]}; 729 | triple[tripleIter] = {activeFunc[tripleIndices[0]], activeFunc[tripleIndices[1]], activeFunc[tripleIndices[2]]}; 730 | int funcIndex1 = triple[tripleIter][0]; 731 | int funcIndex2 = triple[tripleIter][1]; 732 | int funcIndex3 = triple[tripleIter][2]; 733 | if(!(activePair[funcIndex1][funcIndex2]&&activePair[funcIndex1][funcIndex3]&&activePair[funcIndex2][funcIndex3])) 734 | continue; 735 | array diffList1, diffList2; 736 | for (int i = 0; i < 20; ++i){ 737 | diffList1[i] = valList[funcIndex1][i] - valList[funcIndex2][i]; 738 | diffList2[i] = valList[funcIndex2][i] - valList[funcIndex3][i]; 739 | } 740 | std::array nPoints = transpose2d({diffList1, diffList2});// X0, Y0, X1, Y1, ... 741 | std::array query = {0.0, 0.0}; // X, Y 742 | sub_call_two ++; 743 | Timer sub_timer(sub_twoFunc, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 744 | zeroX = convex_hull_membership::contains<2, double>(nPoints, query); 745 | sub_timer.Stop(); 746 | #ifdef No_Multi_Check 747 | return false; 748 | #endif 749 | if (zeroX){ 750 | activeTriple_count++; 751 | array diff_twofunc1, diff_twofunc2; 752 | for (int i = 0; i < 16; ++i){ 753 | diff_twofunc1[i] = diffList[funcIndex1][i] - diffList[funcIndex2][i]; 754 | diff_twofunc2[i] = diffList[funcIndex2][i] - diffList[funcIndex3][i]; 755 | } 756 | array grad1, grad2; 757 | for (int i = 0; i < 3; ++i){ 758 | grad1[i] = gradList[funcIndex1][i] - gradList[funcIndex2][i]; 759 | grad2[i] = gradList[funcIndex2][i] - gradList[funcIndex3][i]; 760 | } 761 | 762 | // two function linearity test: 763 | std::array w1 = {dot(grad1, grad1), dot(grad1, grad2)}; 764 | std::array w2 = {dot(grad1, grad2), dot(grad2, grad2)}; 765 | double E = det(w1, w2); 766 | std::arrayinvPerp_w2 = perp(w2); 767 | for(int i = 0; i < 2; i++){ 768 | invPerp_w2[i] *= -1; 769 | } 770 | std::array perp_w1 = perp(w1); 771 | llvm_vecsmall::SmallVector, 20> H = matrixMultiply(llvm_vecsmall::SmallVector, 20>({llvm_vecsmall::SmallVector(std::begin(invPerp_w2), std::end(invPerp_w2)), llvm_vecsmall::SmallVector(std::begin(perp_w1), std::end(perp_w1))}), llvm_vecsmall::SmallVector, 20>({llvm_vecsmall::SmallVector(std::begin(grad1), std::end(grad1)), llvm_vecsmall::SmallVector(std::begin(grad2), std::end(grad2))})); 772 | 773 | //find the largest max error (max squared gamma: the LHS of the equation) among all 16 bezier control points 774 | double maxGammaSq = 0; 775 | for (int i = 0; i < 16; i++){ 776 | //std::cout << diffList[pair[pairIter][0]][i] << " " << diffList[pair[pairIter][1]][i] << std::endl; 777 | llvm_vecsmall::SmallVector unNormDis = matrixMultiply(llvm_vecsmall::SmallVector, 20>({{diff_twofunc1[i], diff_twofunc2[i]}}), llvm_vecsmall::SmallVector, 20>(H))[0]; 778 | double currError = sqD * dot(unNormDis, unNormDis); 779 | if (maxGammaSq < currError) 780 | maxGammaSq = currError; 781 | } 782 | if (maxGammaSq > threshold*threshold * E*E){ 783 | timer.Stop(); 784 | return score; 785 | } 786 | } 787 | } 788 | timer.Stop(); 789 | } 790 | if(activeTriple_count < 4) 791 | return false; 792 | { 793 | Timer timer(threeFunc, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 794 | bool zeroX; 795 | for (int quadIter = 0; quadIter < quadNum; quadIter ++){ 796 | array quadIndices = {multiples[2][quadIter][0], multiples[2][quadIter][1], multiples[2][quadIter][2],multiples[2][quadIter][3]}; 797 | quad[quadIter] = {activeFunc[quadIndices[0]], activeFunc[quadIndices[1]], activeFunc[quadIndices[2]],activeFunc[quadIndices[3]]}; 798 | int funcIndex1 = quad[quadIter][0]; 799 | int funcIndex2 = quad[quadIter][1]; 800 | int funcIndex3 = quad[quadIter][2]; 801 | int funcIndex4 = quad[quadIter][3]; 802 | if(!(activePair[funcIndex1][funcIndex2]&&activePair[funcIndex1][funcIndex3]&&activePair[funcIndex1][funcIndex4]&&activePair[funcIndex2][funcIndex3]&&activePair[funcIndex2][funcIndex4]&&activePair[funcIndex3][funcIndex4])) 803 | continue; 804 | array diffList1, diffList2, diffList3; 805 | for (int i = 0; i < 20; ++i){ 806 | diffList1[i] = valList[funcIndex1][i] - valList[funcIndex2][i]; 807 | diffList2[i] = valList[funcIndex2][i] - valList[funcIndex3][i]; 808 | diffList3[i] = valList[funcIndex3][i] - valList[funcIndex4][i]; 809 | } 810 | std::array nPoints = transpose3d({diffList1, diffList2, diffList3}); 811 | std::array query = {0.0, 0.0, 0.0}; // X, Y, Z 812 | sub_call_three ++; 813 | Timer sub_timer(sub_threeFunc, [&](auto profileResult){profileTimer = combine_timer(profileTimer, profileResult);}); 814 | zeroX = convex_hull_membership::contains<3, double>(nPoints, query); 815 | sub_timer.Stop(); 816 | #ifdef No_Multi_Check_3 817 | return false; 818 | #endif 819 | if (zeroX){ 820 | array diff_twofunc1, diff_twofunc2, diff_twofunc3; 821 | for (int i = 0; i < 16; ++i){ 822 | diff_twofunc1[i] = diffList[funcIndex1][i] - diffList[funcIndex2][i]; 823 | diff_twofunc2[i] = diffList[funcIndex2][i] - diffList[funcIndex3][i]; 824 | diff_twofunc3[i] = diffList[funcIndex3][i] - diffList[funcIndex4][i]; 825 | } 826 | array fi, fj, fk; 827 | for (int i = 0; i < 3; ++i){ 828 | fi[i] = gradList[funcIndex1][i] - gradList[funcIndex2][i]; 829 | fj[i] = gradList[funcIndex2][i] - gradList[funcIndex3][i]; 830 | fk[i] = gradList[funcIndex3][i] - gradList[funcIndex4][i]; 831 | } 832 | double E = det(fi, fj, fk); 833 | llvm_vecsmall::SmallVector, 20> H = {cross(fj, fk), cross(fk, fi), cross(fi, fj)}; 834 | double maxGammaSq = 0; 835 | for (int i = 0; i < 16; i++){ 836 | llvm_vecsmall::SmallVector unNormDis = matrixMultiply(llvm_vecsmall::SmallVector, 20>({{diff_twofunc1[i], diff_twofunc2[i], diff_twofunc3[i]}}), H)[0]; 837 | double currError = sqD * dot(unNormDis, unNormDis); 838 | if (maxGammaSq < currError) 839 | maxGammaSq = currError; 840 | } 841 | if (maxGammaSq > threshold*threshold * E*E){ 842 | timer.Stop(); 843 | return score; 844 | } 845 | } 846 | } 847 | timer.Stop(); 848 | } 849 | return false; 850 | } 851 | 852 | 853 | 854 | #endif /* subdivide_multi_h */ 855 | --------------------------------------------------------------------------------