summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErwin Coumans <erwin.coumans@gmail.com>2022-03-05 14:02:18 -0800
committerErwin Coumans <erwin.coumans@gmail.com>2022-03-05 14:02:18 -0800
commit90414a5074ea1e236dfc4b6bdd8b253137ad674e (patch)
tree7e9da27bda49aba6238888d5a98c7deb584ea2a6
parentdd93f73fc4c594e90adee28437335ef32f189302 (diff)
parentb74bdfbbcfb887c0d511adaa94eed3034f5ddaa1 (diff)
downloadbullet3-90414a5074ea1e236dfc4b6bdd8b253137ad674e.tar.gz
Merge remote-tracking branch 'bp/master' into master
-rw-r--r--.gitignore4
-rw-r--r--data/reduced_beam/K_r_diag_mat.binbin0 -> 628 bytes
-rw-r--r--data/reduced_beam/M_diag_mat.binbin0 -> 228 bytes
-rw-r--r--data/reduced_beam/M_r_diag_mat.binbin0 -> 628 bytes
-rw-r--r--data/reduced_beam/beam_mesh.vtk83
-rw-r--r--data/reduced_beam/beam_mesh_origin.vtk83
-rw-r--r--data/reduced_beam/eigenvalues.binbin0 -> 628 bytes
-rw-r--r--data/reduced_beam/modes.binbin0 -> 52420 bytes
-rw-r--r--data/reduced_beam/reduced_beam.urdf14
-rw-r--r--data/reduced_cube/K_r_diag_mat.binbin0 -> 644 bytes
-rw-r--r--data/reduced_cube/M_diag_mat.binbin0 -> 2020 bytes
-rw-r--r--data/reduced_cube/M_r_diag_mat.binbin0 -> 644 bytes
-rw-r--r--data/reduced_cube/cube_mesh.vtk1134
-rw-r--r--data/reduced_cube/deform_cube.urdf14
-rw-r--r--data/reduced_cube/eigenvalues.binbin0 -> 644 bytes
-rw-r--r--data/reduced_cube/modes.binbin0 -> 483844 bytes
-rw-r--r--data/reduced_cube/reduced_cube.urdf14
-rw-r--r--data/reduced_torus/K_r_diag_mat.binbin0 -> 324 bytes
-rw-r--r--data/reduced_torus/M_diag_mat.binbin0 -> 8292 bytes
-rw-r--r--data/reduced_torus/M_r_diag_mat.binbin0 -> 324 bytes
-rw-r--r--data/reduced_torus/eigenvalues.binbin0 -> 324 bytes
-rw-r--r--data/reduced_torus/modes.binbin0 -> 994564 bytes
-rw-r--r--data/reduced_torus/reduced_torus.urdf15
-rw-r--r--data/reduced_torus/torus_mesh.vtk9917
-rw-r--r--data/reduced_torus/torus_mesh_visual.vtk9917
-rw-r--r--data/reduced_torus/torus_textured.obj2270
-rw-r--r--examples/DeformableDemo/LoadDeformed.cpp261
-rw-r--r--examples/DeformableDemo/LoadDeformed.h19
-rw-r--r--examples/ExampleBrowser/CMakeLists.txt20
-rw-r--r--examples/ExampleBrowser/ExampleEntries.cpp23
-rw-r--r--examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp5
-rw-r--r--examples/Importers/ImportURDFDemo/BulletUrdfImporter.h1
-rw-r--r--examples/Importers/ImportURDFDemo/UrdfParser.cpp174
-rw-r--r--examples/Importers/ImportURDFDemo/UrdfParser.h39
-rw-r--r--examples/MultiBody/MultiDofDemo.cpp2
-rw-r--r--examples/OpenGLWindow/X11OpenGLWindow.cpp2
-rw-r--r--examples/ReducedDeformableDemo/ConservationTest.cpp316
-rw-r--r--examples/ReducedDeformableDemo/ConservationTest.h19
-rw-r--r--examples/ReducedDeformableDemo/FreeFall.cpp276
-rw-r--r--examples/ReducedDeformableDemo/FreeFall.h19
-rw-r--r--examples/ReducedDeformableDemo/FrictionSlope.cpp288
-rw-r--r--examples/ReducedDeformableDemo/FrictionSlope.h19
-rw-r--r--examples/ReducedDeformableDemo/ModeVisualizer.cpp227
-rw-r--r--examples/ReducedDeformableDemo/ModeVisualizer.h19
-rw-r--r--examples/ReducedDeformableDemo/ReducedBenchmark.cpp349
-rw-r--r--examples/ReducedDeformableDemo/ReducedBenchmark.h19
-rw-r--r--examples/ReducedDeformableDemo/ReducedCollide.cpp522
-rw-r--r--examples/ReducedDeformableDemo/ReducedCollide.h19
-rw-r--r--examples/ReducedDeformableDemo/ReducedGrasp.cpp457
-rw-r--r--examples/ReducedDeformableDemo/ReducedGrasp.h19
-rw-r--r--examples/ReducedDeformableDemo/ReducedMotorGrasp.cpp558
-rw-r--r--examples/ReducedDeformableDemo/ReducedMotorGrasp.h19
-rw-r--r--examples/ReducedDeformableDemo/Springboard.cpp264
-rw-r--r--examples/ReducedDeformableDemo/Springboard.h19
-rw-r--r--examples/SharedMemory/PhysicsClientC_API.cpp16
-rw-r--r--examples/SharedMemory/PhysicsClientC_API.h2
-rw-r--r--examples/SharedMemory/PhysicsServerCommandProcessor.cpp636
-rw-r--r--examples/SharedMemory/PhysicsServerCommandProcessor.h2
-rw-r--r--examples/SharedMemory/PosixSharedMemory.cpp5
-rw-r--r--examples/SharedMemory/SharedMemoryPublic.h9
-rw-r--r--examples/pybullet/examples/reduced_deformable_cube.py27
-rw-r--r--examples/pybullet/examples/reduced_deformable_torus.py32
-rw-r--r--examples/pybullet/gym/pybullet_utils/urdfEditor.py18
-rw-r--r--examples/pybullet/pybullet.c1
-rw-r--r--examples/pybullet/tensorflow/humanoid_running.py6
-rw-r--r--examples/pybullet/tensorflow/humanoid_running_vr_follow.py6
-rw-r--r--src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.cpp792
-rw-r--r--src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h257
-rw-r--r--src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.cpp215
-rw-r--r--src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.h25
-rw-r--r--src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.cpp325
-rw-r--r--src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.h61
-rw-r--r--src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableContactConstraint.cpp579
-rw-r--r--src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableContactConstraint.h194
-rw-r--r--src/BulletSoftBody/CMakeLists.txt10
-rw-r--r--src/BulletSoftBody/btDeformableBackwardEulerObjective.h8
-rw-r--r--src/BulletSoftBody/btDeformableBodySolver.cpp90
-rw-r--r--src/BulletSoftBody/btDeformableBodySolver.h74
-rw-r--r--src/BulletSoftBody/btDeformableMultiBodyConstraintSolver.cpp71
-rw-r--r--src/BulletSoftBody/btDeformableMultiBodyConstraintSolver.h3
-rw-r--r--src/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp111
-rw-r--r--src/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h4
-rw-r--r--src/BulletSoftBody/btSoftBody.cpp20
-rw-r--r--src/BulletSoftBody/btSoftBody.h31
-rw-r--r--src/BulletSoftBody/btSoftBodyHelpers.cpp163
-rw-r--r--src/BulletSoftBody/btSoftBodyHelpers.h5
-rw-r--r--src/BulletSoftBody/btSoftBodyInternals.h34
-rw-r--r--src/BulletSoftBody/btSoftBodySolvers.h3
88 files changed, 31133 insertions, 141 deletions
diff --git a/.gitignore b/.gitignore
index 636ce8302..baee1828b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,3 +36,7 @@ CTestTestFile.cmake
# vim temp files
*.swp
+
+.vscode/
+.idea/
+cmake-build-debug/
diff --git a/data/reduced_beam/K_r_diag_mat.bin b/data/reduced_beam/K_r_diag_mat.bin
new file mode 100644
index 000000000..fab13e564
--- /dev/null
+++ b/data/reduced_beam/K_r_diag_mat.bin
Binary files differ
diff --git a/data/reduced_beam/M_diag_mat.bin b/data/reduced_beam/M_diag_mat.bin
new file mode 100644
index 000000000..9e505c373
--- /dev/null
+++ b/data/reduced_beam/M_diag_mat.bin
Binary files differ
diff --git a/data/reduced_beam/M_r_diag_mat.bin b/data/reduced_beam/M_r_diag_mat.bin
new file mode 100644
index 000000000..bb80034a4
--- /dev/null
+++ b/data/reduced_beam/M_r_diag_mat.bin
Binary files differ
diff --git a/data/reduced_beam/beam_mesh.vtk b/data/reduced_beam/beam_mesh.vtk
new file mode 100644
index 000000000..cbab3e1a2
--- /dev/null
+++ b/data/reduced_beam/beam_mesh.vtk
@@ -0,0 +1,83 @@
+#vtk DataFile Version 2.0
+I don't think this matters
+ASCII
+DATASET UNSTRUCTURED_GRID
+POINTS 28 double
+-0.5000000000000000 -0.2500000000000000 -2.0000000000000000
+-0.5000000000000000 0.2500000000000000 -2.0000000000000000
+0.5000000000000000 -0.2500000000000000 -2.0000000000000000
+0.5000000000000000 0.2500000000000000 -2.0000000000000000
+-0.5000000000000000 -0.2500000000000000 2.0000000000000000
+-0.5000000000000000 0.2500000000000000 2.0000000000000000
+0.5000000000000000 -0.2500000000000000 2.0000000000000000
+0.5000000000000000 0.2500000000000000 2.0000000000000000
+-0.5000000000000000 -0.2500000000000000 1.0000000000000000
+-0.5000000000000000 -0.2500000000000000 0.0000000000000000
+-0.5000000000000000 -0.2500000000000000 -1.0000000000000000
+0.5000000000000000 -0.2500000000000000 -1.0000000000000000
+0.5000000000000000 -0.2500000000000000 0.0000000000000000
+0.5000000000000000 -0.2500000000000000 1.0000000000000000
+-0.5000000000000000 0.2500000000000000 1.0000000000000000
+-0.5000000000000000 0.2500000000000000 0.0000000000000000
+-0.5000000000000000 0.2500000000000000 -1.0000000000000000
+0.5000000000000000 0.2500000000000000 1.0000000000000000
+0.5000000000000000 0.2500000000000000 0.0000000000000000
+0.5000000000000000 0.2500000000000000 -1.0000000000000000
+0.0000000000000000 -0.2500000000000000 -1.5000000000000000
+0.0000000000000000 -0.2500000000000000 -0.5000000000000000
+0.0000000000000000 -0.2500000000000000 0.5000000000000000
+0.0000000000000000 -0.2500000000000000 1.5000000000000000
+0.0000000000000000 0.2500000000000000 1.5000000000000000
+0.0000000000000000 0.2500000000000000 0.5000000000000000
+0.0000000000000000 0.2500000000000000 -0.5000000000000000
+0.0000000000000000 0.2500000000000000 -1.5000000000000000
+CELLS 48 192
+4 22 12 17 13
+4 20 26 21 11
+4 23 8 5 24
+4 11 27 26 19
+4 27 11 26 20
+4 17 22 24 25
+4 7 23 13 6
+4 22 17 24 13
+4 9 25 21 15
+4 24 22 8 14
+4 24 8 22 23
+4 25 9 21 22
+4 23 7 13 24
+4 15 10 16 26
+4 14 25 9 15
+4 25 14 9 22
+4 24 23 22 13
+4 15 10 21 9
+4 15 21 10 26
+4 24 25 22 14
+4 2 11 27 20
+4 7 5 23 6
+4 11 21 12 26
+4 20 1 0 16
+4 18 25 12 17
+4 18 12 25 26
+4 5 7 23 24
+4 26 21 25 15
+4 20 16 27 1
+4 21 25 22 12
+4 20 16 10 26
+4 20 27 16 26
+4 20 10 16 0
+4 11 12 19 26
+4 14 22 8 9
+4 8 23 5 4
+4 24 14 8 5
+4 11 2 27 3
+4 2 27 1 20
+4 12 18 19 26
+4 27 2 1 3
+4 24 13 17 7
+4 20 2 0 1
+4 5 23 6 4
+4 20 10 21 26
+4 12 22 17 25
+4 3 27 11 19
+4 21 26 25 12
+CELL_TYPES 10
diff --git a/data/reduced_beam/beam_mesh_origin.vtk b/data/reduced_beam/beam_mesh_origin.vtk
new file mode 100644
index 000000000..95d579d95
--- /dev/null
+++ b/data/reduced_beam/beam_mesh_origin.vtk
@@ -0,0 +1,83 @@
+#vtk DataFile Version 2.0
+I don't think this matters
+ASCII
+DATASET UNSTRUCTURED_GRID
+POINTS 28 double
+0.0000000000000000 0.0000000000000000 0.0000000000000000
+0.0000000000000000 0.5000000000000000 0.0000000000000000
+1.0000000000000000 0.0000000000000000 0.0000000000000000
+1.0000000000000000 0.5000000000000000 0.0000000000000000
+0.0000000000000000 0.0000000000000000 4.0000000000000000
+0.0000000000000000 0.5000000000000000 4.0000000000000000
+1.0000000000000000 0.0000000000000000 4.0000000000000000
+1.0000000000000000 0.5000000000000000 4.0000000000000000
+0.0000000000000000 0.0000000000000000 3.0000000000000000
+0.0000000000000000 0.0000000000000000 2.0000000000000000
+0.0000000000000000 0.0000000000000000 1.0000000000000000
+1.0000000000000000 0.0000000000000000 1.0000000000000000
+1.0000000000000000 0.0000000000000000 2.0000000000000000
+1.0000000000000000 0.0000000000000000 3.0000000000000000
+0.0000000000000000 0.5000000000000000 3.0000000000000000
+0.0000000000000000 0.5000000000000000 2.0000000000000000
+0.0000000000000000 0.5000000000000000 1.0000000000000000
+1.0000000000000000 0.5000000000000000 3.0000000000000000
+1.0000000000000000 0.5000000000000000 2.0000000000000000
+1.0000000000000000 0.5000000000000000 1.0000000000000000
+0.5000000000000000 0.0000000000000000 0.5000000000000000
+0.5000000000000000 0.0000000000000000 1.5000000000000000
+0.5000000000000000 0.0000000000000000 2.5000000000000000
+0.5000000000000000 0.0000000000000000 3.5000000000000000
+0.5000000000000000 0.5000000000000000 3.5000000000000000
+0.5000000000000000 0.5000000000000000 2.5000000000000000
+0.5000000000000000 0.5000000000000000 1.5000000000000000
+0.5000000000000000 0.5000000000000000 0.5000000000000000
+CELLS 48 192
+4 22 12 17 13
+4 20 26 21 11
+4 23 8 5 24
+4 11 27 26 19
+4 27 11 26 20
+4 17 22 24 25
+4 7 23 13 6
+4 22 17 24 13
+4 9 25 21 15
+4 24 22 8 14
+4 24 8 22 23
+4 25 9 21 22
+4 23 7 13 24
+4 15 10 16 26
+4 14 25 9 15
+4 25 14 9 22
+4 24 23 22 13
+4 15 10 21 9
+4 15 21 10 26
+4 24 25 22 14
+4 2 11 27 20
+4 7 5 23 6
+4 11 21 12 26
+4 20 1 0 16
+4 18 25 12 17
+4 18 12 25 26
+4 5 7 23 24
+4 26 21 25 15
+4 20 16 27 1
+4 21 25 22 12
+4 20 16 10 26
+4 20 27 16 26
+4 20 10 16 0
+4 11 12 19 26
+4 14 22 8 9
+4 8 23 5 4
+4 24 14 8 5
+4 11 2 27 3
+4 2 27 1 20
+4 12 18 19 26
+4 27 2 1 3
+4 24 13 17 7
+4 20 2 0 1
+4 5 23 6 4
+4 20 10 21 26
+4 12 22 17 25
+4 3 27 11 19
+4 21 26 25 12
+CELL_TYPES 10
diff --git a/data/reduced_beam/eigenvalues.bin b/data/reduced_beam/eigenvalues.bin
new file mode 100644
index 000000000..81e43677a
--- /dev/null
+++ b/data/reduced_beam/eigenvalues.bin
Binary files differ
diff --git a/data/reduced_beam/modes.bin b/data/reduced_beam/modes.bin
new file mode 100644
index 000000000..6e8239b83
--- /dev/null
+++ b/data/reduced_beam/modes.bin
Binary files differ
diff --git a/data/reduced_beam/reduced_beam.urdf b/data/reduced_beam/reduced_beam.urdf
new file mode 100644
index 000000000..88381795e
--- /dev/null
+++ b/data/reduced_beam/reduced_beam.urdf
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<robot name="reduced_cube">
+ <reduced_deformable name="reduced_beam">
+ <num_modes value="20"/>
+ <mass value="1"/>
+ <stiffness_scale value="100"/>
+ <collision_margin value="0.01"/>
+ <erp value= "0.2"/>
+ <cfm value= "0.2"/>
+ <friction value= "0.5"/>
+ <damping_coefficient value="0.0"/>
+ <visual filename="beam_mesh_origin.vtk"/>
+ </reduced_deformable>
+</robot>
diff --git a/data/reduced_cube/K_r_diag_mat.bin b/data/reduced_cube/K_r_diag_mat.bin
new file mode 100644
index 000000000..3894184a9
--- /dev/null
+++ b/data/reduced_cube/K_r_diag_mat.bin
Binary files differ
diff --git a/data/reduced_cube/M_diag_mat.bin b/data/reduced_cube/M_diag_mat.bin
new file mode 100644
index 000000000..fb6c5ce37
--- /dev/null
+++ b/data/reduced_cube/M_diag_mat.bin
Binary files differ
diff --git a/data/reduced_cube/M_r_diag_mat.bin b/data/reduced_cube/M_r_diag_mat.bin
new file mode 100644
index 000000000..62f64ba7b
--- /dev/null
+++ b/data/reduced_cube/M_r_diag_mat.bin
Binary files differ
diff --git a/data/reduced_cube/cube_mesh.vtk b/data/reduced_cube/cube_mesh.vtk
new file mode 100644
index 000000000..ccec00b32
--- /dev/null
+++ b/data/reduced_cube/cube_mesh.vtk
@@ -0,0 +1,1134 @@
+#vtk DataFile Version 2.0
+I don't think this matters
+ASCII
+DATASET UNSTRUCTURED_GRID
+POINTS 252 double
+-0.5000000000000000 -0.5000000000000000 0.5000000000000000
+-0.5000000000000000 0.5000000000000000 0.5000000000000000
+-0.5000000000000000 -0.5000000000000000 -0.5000000000000000
+-0.5000000000000000 0.5000000000000000 -0.5000000000000000
+0.5000000000000000 -0.5000000000000000 0.5000000000000000
+0.5000000000000000 0.5000000000000000 0.5000000000000000
+0.5000000000000000 -0.5000000000000000 -0.5000000000000000
+0.5000000000000000 0.5000000000000000 -0.5000000000000000
+-0.5000000000000000 -0.5000000000000000 -0.3000000000000000
+-0.5000000000000000 -0.5000000000000000 -0.1000000000000000
+-0.5000000000000000 -0.5000000000000000 0.1000000000000000
+-0.5000000000000000 -0.5000000000000000 0.3000000000000000
+-0.5000000000000000 -0.3000000000000000 0.5000000000000000
+-0.5000000000000000 -0.1000000000000000 0.5000000000000000
+-0.5000000000000000 0.1000000000000000 0.5000000000000000
+-0.5000000000000000 0.3000000000000000 0.5000000000000000
+-0.5000000000000000 0.3000000000000000 -0.5000000000000000
+-0.5000000000000000 0.1000000000000000 -0.5000000000000000
+-0.5000000000000000 -0.1000000000000000 -0.5000000000000000
+-0.5000000000000000 -0.3000000000000000 -0.5000000000000000
+-0.5000000000000000 0.5000000000000000 0.3000000000000000
+-0.5000000000000000 0.5000000000000000 0.1000000000000000
+-0.5000000000000000 0.5000000000000000 -0.1000000000000000
+-0.5000000000000000 0.5000000000000000 -0.3000000000000000
+0.3000000000000000 -0.5000000000000000 0.5000000000000000
+0.1000000000000000 -0.5000000000000000 0.5000000000000000
+-0.1000000000000000 -0.5000000000000000 0.5000000000000000
+-0.3000000000000000 -0.5000000000000000 0.5000000000000000
+0.5000000000000000 -0.5000000000000000 -0.3000000000000000
+0.5000000000000000 -0.5000000000000000 -0.1000000000000000
+0.5000000000000000 -0.5000000000000000 0.1000000000000000
+0.5000000000000000 -0.5000000000000000 0.3000000000000000
+-0.3000000000000000 -0.5000000000000000 -0.5000000000000000
+-0.1000000000000000 -0.5000000000000000 -0.5000000000000000
+0.1000000000000000 -0.5000000000000000 -0.5000000000000000
+0.3000000000000000 -0.5000000000000000 -0.5000000000000000
+0.5000000000000000 -0.3000000000000000 0.5000000000000000
+0.5000000000000000 -0.1000000000000000 0.5000000000000000
+0.5000000000000000 0.1000000000000000 0.5000000000000000
+0.5000000000000000 0.3000000000000000 0.5000000000000000
+0.3000000000000000 0.5000000000000000 0.5000000000000000
+0.1000000000000000 0.5000000000000000 0.5000000000000000
+-0.1000000000000000 0.5000000000000000 0.5000000000000000
+-0.3000000000000000 0.5000000000000000 0.5000000000000000
+0.5000000000000000 0.5000000000000000 0.3000000000000000
+0.5000000000000000 0.5000000000000000 0.1000000000000000
+0.5000000000000000 0.5000000000000000 -0.1000000000000000
+0.5000000000000000 0.5000000000000000 -0.3000000000000000
+0.3000000000000000 0.5000000000000000 -0.5000000000000000
+0.1000000000000000 0.5000000000000000 -0.5000000000000000
+-0.1000000000000000 0.5000000000000000 -0.5000000000000000
+-0.3000000000000000 0.5000000000000000 -0.5000000000000000
+0.5000000000000000 0.3000000000000000 -0.5000000000000000
+0.5000000000000000 0.1000000000000000 -0.5000000000000000
+0.5000000000000000 -0.1000000000000000 -0.5000000000000000
+0.5000000000000000 -0.3000000000000000 -0.5000000000000000
+-0.5000000000000000 -0.1233898373531572 0.1147879907201578
+-0.5000000000000000 0.1699175259303953 -0.1169110168900799
+-0.5000000000000000 -0.1609852541997776 -0.1119512415914603
+-0.5000000000000000 0.0036232260706970 -0.0539116421628889
+-0.5000000000000000 0.3633974596215561 0.3633974596215561
+-0.5000000000000000 0.1972146310466483 0.3323735462620343
+-0.5000000000000000 0.3351775535204424 0.1959995364102994
+-0.5000000000000000 0.0009111869567501 0.3086957330017754
+-0.5000000000000000 0.3262569087497712 0.0008160651638339
+-0.5000000000000000 -0.1980771930184211 0.3323182589309750
+-0.5000000000000000 0.3446068576518957 -0.1982737367849547
+-0.5000000000000000 -0.3657517910712106 0.3648263488753503
+-0.5000000000000000 0.3649054207921165 -0.3637759244031666
+-0.5000000000000000 -0.3341056573166621 0.1957724518129504
+-0.5000000000000000 0.2000000000000000 -0.3267949192431122
+-0.5000000000000000 -0.3233285815726809 0.0018786863780455
+-0.5000000000000000 0.0008672949319745 -0.2819827071689306
+-0.5000000000000000 -0.3426912797901960 -0.1961635268793381
+-0.5000000000000000 -0.2000000000000000 -0.3267949192431122
+-0.5000000000000000 -0.3661968559397331 -0.3638898101702758
+-0.5000000000000000 0.1275763097302068 0.1124307778956443
+-0.1147879907201578 -0.5000000000000000 0.1233898373531572
+0.1169110168900799 -0.5000000000000000 -0.1699175259303953
+0.1119512415914604 -0.5000000000000000 0.1609852541997776
+0.0539116421628889 -0.5000000000000000 -0.0036232260706970
+-0.3633974596215561 -0.5000000000000000 -0.3633974596215561
+-0.3323735462620343 -0.5000000000000000 -0.1972146310466483
+-0.1959995364102994 -0.5000000000000000 -0.3351775535204424
+-0.3086957330017754 -0.5000000000000000 -0.0009111869567501
+-0.0008160651638339 -0.5000000000000000 -0.3262569087497712
+-0.3323182589309750 -0.5000000000000000 0.1980771930184211
+0.1982737367849547 -0.5000000000000000 -0.3446068576518957
+-0.3648263488753501 -0.5000000000000000 0.3657517910712106
+0.3637759244031666 -0.5000000000000000 -0.3649054207921165
+-0.1957724518129504 -0.5000000000000000 0.3341056573166621
+0.3267949192431122 -0.5000000000000000 -0.2000000000000000
+-0.0018758478474226 -0.5000000000000000 0.3233272280198534
+0.2819827071689306 -0.5000000000000000 -0.0008672949319745
+0.1961785071028203 -0.5000000000000000 0.3426823728259605
+0.3268794460048395 -0.5000000000000000 0.1999818870328346
+0.3639011502450333 -0.5000000000000000 0.3661923734849296
+-0.1124307778956443 -0.5000000000000000 -0.1275763097302068
+-0.1233898373531572 -0.1147879907201578 0.5000000000000000
+0.1699175259303954 0.1169110168900800 0.5000000000000000
+-0.1609852541997776 0.1119512415914604 0.5000000000000000
+0.0036232260706970 0.0539116421628889 0.5000000000000000
+0.3633974596215561 -0.3633974596215561 0.5000000000000000
+0.1972146310466483 -0.3323735462620343 0.5000000000000000
+0.3351775535204424 -0.1959995364102994 0.5000000000000000
+0.0009111869567501 -0.3086957330017754 0.5000000000000000
+0.3262569087497712 -0.0008160651638339 0.5000000000000000
+-0.1980771930184211 -0.3323182589309750 0.5000000000000000
+0.3446068576518958 0.1982737367849547 0.5000000000000000
+-0.3657517910712106 -0.3648263488753501 0.5000000000000000
+0.3649054207921165 0.3637759244031666 0.5000000000000000
+-0.3341056573166621 -0.1957724518129504 0.5000000000000000
+0.2000000000000000 0.3267949192431122 0.5000000000000000
+-0.3233285815726809 -0.0018786863780454 0.5000000000000000
+0.0008672949319745 0.2819827071689306 0.5000000000000000
+-0.3426912797901960 0.1961635268793381 0.5000000000000000
+-0.2000000000000000 0.3267949192431122 0.5000000000000000
+-0.3661968559397331 0.3638898101702758 0.5000000000000000
+0.1275763097302068 -0.1124307778956443 0.5000000000000000
+-0.1233898373531572 0.5000000000000000 0.1147879907201578
+0.1699175259303954 0.5000000000000000 -0.1169110168900800
+-0.1609852541997776 0.5000000000000000 -0.1119512415914604
+0.0036232260706970 0.5000000000000000 -0.0539116421628889
+0.3633974596215561 0.5000000000000000 0.3633974596215561
+0.1972146310466483 0.5000000000000000 0.3323735462620343
+0.3351775535204424 0.5000000000000000 0.1959995364102994
+0.0009111869567501 0.5000000000000000 0.3086957330017754
+0.3262569087497712 0.5000000000000000 0.0008160651638339
+-0.1980771930184211 0.5000000000000000 0.3323182589309750
+0.3446068576518958 0.5000000000000000 -0.1982737367849547
+-0.3657517910712106 0.5000000000000000 0.3648263488753501
+0.3649054207921165 0.5000000000000000 -0.3637759244031666
+-0.3341056573166621 0.5000000000000000 0.1957724518129504
+0.2000000000000000 0.5000000000000000 -0.3267949192431122
+-0.3233285815726809 0.5000000000000000 0.0018786863780454
+0.0008672949319745 0.5000000000000000 -0.2819827071689306
+-0.3426912797901960 0.5000000000000000 -0.1961635268793381
+-0.2000000000000000 0.5000000000000000 -0.3267949192431122
+-0.3661968559397331 0.5000000000000000 -0.3638898101702758
+0.1275763097302068 0.5000000000000000 0.1124307778956443
+-0.1138311189195117 -0.1243075122798897 -0.5000000000000000
+0.1173045715116234 0.1661636709959234 -0.5000000000000000
+0.1119512415914604 -0.1609852541997777 -0.5000000000000000
+0.0527346162230125 0.0027364735902232 -0.5000000000000000
+-0.3633974596215561 0.3633974596215561 -0.5000000000000000
+-0.3323735462620343 0.1972146310466483 -0.5000000000000000
+-0.1959995364102994 0.3351775535204424 -0.5000000000000000
+-0.3086957330017754 0.0009111869567501 -0.5000000000000000
+-0.0007542274019505 0.3253495282808382 -0.5000000000000000
+-0.3323182589309750 -0.1980771930184211 -0.5000000000000000
+0.1972226270493975 0.3438104141551133 -0.5000000000000000
+-0.3648263488753501 -0.3657517910712106 -0.5000000000000000
+0.3640218288382323 0.3663226743832327 -0.5000000000000000
+-0.1957724518129504 -0.3341056573166621 -0.5000000000000000
+0.3267949192431122 0.2000000000000000 -0.5000000000000000
+-0.0016907199308348 -0.3236034630559812 -0.5000000000000000
+0.2822074687491826 0.0003085898773192 -0.5000000000000000
+0.1961635268793381 -0.3426912797901960 -0.5000000000000000
+0.3267949192431122 -0.2000000000000000 -0.5000000000000000
+0.3638898101702758 -0.3661968559397331 -0.5000000000000000
+-0.1126789669148792 0.1272095300916097 -0.5000000000000000
+0.5000000000000000 -0.1139003205079960 0.1236507313930517
+0.5000000000000000 0.1167861473396358 -0.1659278929029387
+0.5000000000000000 0.1119512415914604 0.1609852541997777
+0.5000000000000000 0.0525585572466856 -0.0026243850848537
+0.5000000000000000 -0.3633974596215561 -0.3633974596215561
+0.5000000000000000 -0.3326790862784247 -0.1970059846231134
+0.5000000000000000 -0.1962590290145882 -0.3347329118508892
+0.5000000000000000 -0.3094203451101027 -0.0009282668723746
+0.5000000000000000 -0.0008653934835057 -0.3252183203264405
+0.5000000000000000 -0.3319093082592758 0.1979804700488778
+0.5000000000000000 0.1971373528951688 -0.3437573684866272
+0.5000000000000000 -0.3647262292593217 0.3657167096326812
+0.5000000000000000 0.3640111473291716 -0.3663164272760489
+0.5000000000000000 -0.1954590801389594 0.3339920118596611
+0.5000000000000000 0.3267949192431122 -0.2000000000000000
+0.5000000000000000 -0.0016637824689947 0.3234253790938798
+0.5000000000000000 0.2821248376810557 -0.0002668761634654
+0.5000000000000000 0.1961635268793381 0.3426912797901960
+0.5000000000000000 0.3267949192431123 0.1999999999999999
+0.5000000000000000 0.3638898101702758 0.3661968559397331
+0.5000000000000000 -0.1125328985516271 -0.1269696593914712
+0.1382161006918166 0.1242362213851269 -0.1754384624630511
+0.0997197578836812 0.1719573094130328 0.2775520930681395
+-0.1109334710852802 0.1349119090064003 0.1096673578607459
+0.0385721552658961 -0.1342162050602863 0.0533150428697447
+-0.1218031490541463 0.1568695976325767 -0.1030044327512579
+-0.1220289804783044 -0.0933664698044071 0.1318418169744446
+-0.0992671103244849 -0.1460961852037935 -0.1138579112600268
+0.0795841007920177 -0.2324819534027316 -0.3261923602303002
+-0.3335077095827807 -0.1419290156017691 -0.1598260213338275
+0.3039915020696688 -0.0995509361234168 -0.0086515577464560
+0.3504346373841197 0.1516048892959737 -0.0347752454949213
+0.3376719918667223 -0.0097530026136469 -0.2125913893187307
+0.3253375479255823 0.1621595614633253 -0.2608644811040547
+0.3315585643384217 0.2667739235888602 0.1358365409419564
+0.3406896237435342 0.3457288393401758 -0.1126253883076864
+0.3199687134698594 -0.0013173219110393 0.2030938940479531
+0.3185065175119062 -0.2146938719053335 0.2192986039402167
+0.3188397637230317 -0.2150224962550966 -0.2204206626692699
+0.3350589496880162 0.3356066942029327 0.3402595751673152
+0.3266822680905204 0.1401856736099840 0.3412663521519537
+0.3099124471191828 0.3158840305210436 -0.3564778090139548
+0.1965269818424884 0.3155890832661574 -0.0060347949936939
+0.3727624322222096 -0.3144880907542937 0.0993172478843531
+0.3659782083692454 -0.3464068788785741 -0.0830274513265623
+0.2945809361924115 -0.3346821456055408 0.3338028961229819
+0.3002905646476915 -0.3351501893564901 -0.3297713053823574
+0.1631184361652979 0.0635789827228238 -0.3485927886884206
+0.1439862239630384 0.3321548422129696 -0.2792031204214467
+0.0049547754845206 0.2967901390222065 0.0586175960001352
+0.1100295257214490 0.3153286796573214 0.2513658312359172
+0.2248701643720291 -0.0479164645692960 0.3324929755346976
+0.1633900326125509 -0.2943354256176448 -0.0922956584851249
+-0.0013545299020093 0.2163350488608967 -0.3311049427548864
+-0.0579251565371261 0.0018794971339811 -0.3156678034169808
+0.0611950705822844 -0.0262087018048493 0.2210692312484564
+-0.0669216512405002 0.3483795663398098 -0.1630484643777863
+-0.1091507646776734 0.3150812061341864 0.2526037532529465
+-0.2029263357734013 0.3196039150665015 0.0017014809960954
+-0.0404640132441894 0.0198675212666123 -0.0360672041461209
+0.0050160469263824 -0.1454638548823492 0.3251305830647260
+0.0995101598359466 -0.3829402311724771 0.3209847759375812
+-0.0017013101145269 -0.3195423268218793 0.2029258459693808
+-0.0577690421509711 -0.3153296844367551 -0.0026032328159155
+0.0011085880349744 -0.3195218604643649 -0.2082109046221309
+-0.1948355936891721 0.2283495754164206 -0.2575255295956453
+-0.2824523286219401 -0.1188911319221536 -0.3279855713205155
+-0.3246958163141473 0.3461421799214881 0.3245734458899297
+-0.0972256682889528 0.0148538171047589 0.3133605085864473
+-0.2614733128188890 -0.1043259062045388 0.3171009163602427
+-0.2734208990871634 -0.3210884520282516 0.1207541841196497
+-0.2139434257042606 -0.3204146055924667 -0.1682042572439628
+-0.3271078270417132 -0.3284404490254405 -0.3367061462316807
+-0.3191397360560487 0.3481345289809818 -0.0989522899886413
+-0.2783082017547144 0.1035956343822260 0.3190008621244552
+-0.3339231445418150 -0.3019814420075154 0.3329625934592976
+-0.3751021975870553 -0.3121776431093002 -0.1266789951840475
+-0.3283536532461477 0.3213501138270505 -0.2777764655425382
+-0.2943825974224472 0.1187693683365965 -0.3652663377460341
+-0.3189637252571256 0.1694228955816856 -0.0321596563161486
+-0.3019994021588921 0.0379394341803641 -0.1839744688540570
+-0.2974671434974731 0.0055818307524517 0.0530430199484020
+-0.3036065099585001 -0.1790458841322018 0.0119857102389410
+0.2760250241015013 -0.1301114837982048 -0.3569477927183523
+0.1664605357963639 -0.2171836390866614 0.3313149627029035
+0.1673424572039840 -0.2450637019678339 0.1466215058336045
+-0.1224207192968225 -0.2770080904201269 -0.3500102162329917
+-0.3295270239514344 0.3062256684599908 0.1358512568037255
+-0.1299734211964175 -0.2927430246944369 0.3483767967740041
+0.1346699996974801 -0.0996941426594149 -0.1506375345910397
+0.1601583419478076 0.0578069388713425 0.0722884124673341
+CELLS 875 3500
+4 135 148 50 49
+4 217 121 122 135
+4 225 85 78 97
+4 160 239 146 145
+4 197 163 161 164
+4 251 203 210 183
+4 51 238 146 137
+4 204 95 170 206
+4 206 96 24 94
+4 206 24 96 102
+4 217 135 120 209
+4 248 235 61 76
+4 211 126 41 124
+4 141 148 209 150
+4 203 127 120 139
+4 206 94 24 103
+4 169 156 53 54
+4 169 53 154 171
+4 229 101 98 221
+4 169 154 53 156
+4 190 72 74 58
+4 190 74 72 227
+4 71 231 56 69
+4 139 127 195 203
+4 238 51 146 144
+4 247 33 155 85
+4 246 93 80 213
+4 247 153 155 33
+4 64 76 248 62
+4 14 113 13 63
+4 248 134 219 234
+4 231 84 10 71
+4 227 18 147 149
+4 227 149 74 18
+4 243 56 59 58
+4 190 72 241 227
+4 237 58 74 73
+4 190 233 74 227
+4 207 55 167 165
+4 236 69 65 56
+4 198 174 104 206
+4 249 222 92 223
+4 249 98 111 107
+4 107 27 90 26
+4 3 23 68 138
+4 244 250 199 193
+4 244 193 208 250
+4 233 237 74 73
+4 251 246 212 216
+4 51 50 137 146
+4 127 139 195 125
+4 247 33 85 83
+4 33 153 32 83
+4 40 112 41 124
+4 202 52 173 171
+4 246 251 212 197
+4 40 110 123 5
+4 37 174 104 106
+4 251 183 197 195
+4 37 104 174 36
+4 236 111 109 107
+4 198 104 174 212
+4 235 61 115 228
+4 34 33 85 155
+4 220 215 182 250
+4 35 87 157 34
+4 206 103 24 102
+4 206 174 172 170
+4 220 182 215 186
+4 235 14 63 113
+4 251 182 191 250
+4 251 250 191 185
+4 207 189 213 199
+4 220 251 184 216
+4 219 121 119 122
+4 244 189 142 157
+4 206 96 94 95
+4 220 242 187 184
+4 220 186 242 184
+4 206 96 172 102
+4 206 102 104 103
+4 192 177 164 162
+4 1 60 130 117
+4 1 117 15 60
+4 1 20 130 60
+4 220 188 215 250
+4 216 183 101 212
+4 248 219 218 184
+4 248 235 240 184
+4 248 218 228 235
+4 246 80 79 223
+4 248 184 218 235
+4 30 95 31 170
+4 183 99 112 114
+4 167 207 244 158
+4 186 219 240 184
+4 225 78 80 97
+4 246 206 95 204
+4 218 128 42 126
+4 204 30 95 93
+4 248 76 240 235
+4 204 30 170 95
+4 204 168 170 30
+4 203 120 122 139
+4 196 129 202 209
+4 237 82 73 233
+4 243 56 58 71
+4 196 129 120 127
+4 186 242 240 241
+4 235 61 63 14
+4 211 41 112 124
+4 240 76 57 59
+4 195 178 179 200
+4 244 54 158 156
+4 244 169 54 156
+4 135 217 120 122
+4 235 248 61 228
+4 201 38 176 178
+4 234 226 219 240
+4 234 240 238 226
+4 192 164 163 197
+4 191 213 205 204
+4 244 189 157 207
+4 195 211 139 203
+4 239 160 147 145
+4 220 185 188 250
+4 109 0 88 27
+4 235 14 113 115
+4 191 197 164 192
+4 237 73 71 58
+4 190 59 58 243
+4 195 125 139 211
+4 241 72 57 70
+4 239 238 145 70
+4 241 70 57 238
+4 220 251 185 250
+4 191 164 193 192
+4 218 116 42 128
+4 217 209 214 135
+4 185 223 221 187
+4 189 142 140 143
+4 197 174 161 176
+4 244 207 199 189
+4 189 157 87 34
+4 189 87 85 34
+4 237 58 71 243
+4 225 97 80 224
+4 225 80 78 213
+4 225 224 80 213
+4 225 83 85 97
+4 247 83 153 33
+4 220 250 182 251
+4 216 229 183 184
+4 201 176 38 106
+4 201 178 108 38
+4 201 38 108 106
+4 229 235 100 218
+4 189 143 140 215
+4 189 142 157 155
+4 86 10 11 69
+4 242 241 59 240
+4 132 218 228 248
+4 191 205 213 199
+4 192 162 164 193
+4 192 194 162 193
+4 207 78 87 91
+4 217 122 121 219
+4 192 175 177 162
+4 195 201 197 163
+4 247 83 85 225
+4 192 177 163 164
+4 251 212 197 183
+4 184 218 235 229
+4 182 193 194 192
+4 185 221 223 246
+4 251 195 203 183
+4 244 199 167 193
+4 216 183 212 251
+4 190 232 243 237
+4 236 90 88 86
+4 231 10 84 86
+4 235 115 61 14
+4 189 215 140 247
+4 177 192 163 195
+4 195 125 45 127
+4 190 237 233 232
+4 238 23 68 66
+4 246 95 79 93
+4 189 87 78 85
+4 192 194 175 162
+4 214 160 148 141
+4 31 4 172 96
+4 239 70 72 241
+4 67 0 11 88
+4 195 200 125 211
+4 211 124 112 200
+4 92 77 249 223
+4 211 126 124 139
+4 93 246 80 79
+4 224 80 77 97
+4 231 56 69 236
+4 225 78 85 189
+4 215 160 147 239
+4 218 132 228 128
+4 212 99 118 106
+4 189 208 142 143
+4 218 228 116 128
+4 189 34 85 155
+4 242 63 76 56
+4 196 127 120 203
+4 212 201 99 106
+4 242 76 63 235
+4 235 100 115 113
+4 229 98 100 113
+4 235 230 113 63
+4 239 241 226 238
+4 215 239 147 227
+4 209 133 150 49
+4 250 191 199 193
+4 209 135 49 148
+4 196 46 129 127
+4 250 213 199 191
+4 209 133 49 135
+4 207 213 78 91
+4 242 230 63 56
+4 242 63 230 235
+4 242 240 76 235
+4 239 238 70 241
+4 217 210 122 219
+4 189 155 157 34
+4 132 119 218 248
+4 250 182 191 193
+4 222 246 221 245
+4 189 215 208 143
+4 242 230 56 243
+4 190 233 227 232
+4 222 94 25 92
+4 229 230 98 113
+4 186 240 242 184
+4 125 195 45 179
+4 212 201 106 176
+4 212 197 201 176
+4 238 138 68 23
+4 212 118 104 106
+4 204 213 205 93
+4 249 111 98 230
+4 77 92 249 90
+4 224 84 97 77
+4 231 77 90 86
+4 247 85 155 189
+4 182 191 193 192
+4 186 219 210 217
+4 249 77 231 223
+4 77 249 231 90
+4 186 210 219 184
+4 247 227 233 232
+4 238 145 144 146
+4 198 174 197 212
+4 109 88 0 67
+4 222 25 94 103
+4 198 161 174 170
+4 207 35 159 89
+4 249 107 111 236
+4 186 217 210 182
+4 209 150 148 49
+4 159 207 55 158
+4 198 204 161 170
+4 232 97 82 83
+4 198 170 174 206
+4 231 86 90 236
+4 231 86 84 77
+4 215 214 160 226
+4 215 226 160 239
+4 173 52 152 7
+4 232 83 82 233
+4 216 101 183 229
+4 237 243 71 231
+4 207 89 87 35
+4 165 6 159 55
+4 244 142 158 157
+4 237 71 84 231
+4 184 229 235 187
+4 144 238 16 145
+4 198 204 170 206
+4 209 120 133 135
+4 246 204 95 93
+4 215 143 140 160
+4 231 69 86 236
+4 248 61 62 76
+4 231 230 56 236
+4 231 56 230 243
+4 231 77 84 224
+4 232 97 83 225
+4 229 235 230 113
+4 222 79 94 92
+4 215 214 143 160
+4 247 155 153 140
+4 76 64 248 240
+4 249 236 111 230
+4 223 224 77 231
+4 109 0 12 67
+4 250 193 208 182
+4 247 233 153 83
+4 238 136 138 23
+4 244 142 156 158
+4 235 100 116 115
+4 232 82 97 84
+4 232 237 82 84
+4 232 233 82 237
+4 205 30 204 93
+4 215 241 226 239
+4 215 227 241 239
+4 247 232 233 83
+4 247 232 83 225
+4 232 84 97 224
+4 184 235 242 187
+4 187 230 235 242
+4 247 140 227 215
+4 200 123 125 124
+4 247 215 227 188
+4 194 154 208 202
+4 194 156 154 169
+4 194 193 156 169
+4 194 154 156 208
+4 228 115 116 117
+4 194 208 156 193
+4 194 154 171 169
+4 194 171 154 202
+4 194 171 162 169
+4 194 169 162 193
+4 221 246 212 245
+4 207 91 166 205
+4 207 205 166 199
+4 200 110 39 180
+4 207 35 157 159
+4 207 87 157 35
+4 218 211 126 114
+4 44 45 179 125
+4 200 108 39 110
+4 218 128 126 119
+4 218 119 126 210
+4 218 210 126 211
+4 238 23 66 136
+4 178 201 195 163
+4 235 115 116 228
+4 54 55 167 158
+4 218 210 219 119
+4 246 221 212 216
+4 214 137 148 146
+4 246 204 93 213
+4 249 26 90 92
+4 198 174 161 197
+4 229 113 100 235
+4 200 110 112 108
+4 191 204 161 198
+4 248 62 61 228
+4 191 161 197 198
+4 247 140 153 149
+4 73 8 82 9
+4 234 66 57 64
+4 246 213 80 224
+4 234 64 57 240
+4 247 225 85 189
+4 250 199 213 189
+4 119 132 218 128
+4 36 206 102 104
+4 214 226 137 146
+4 220 184 210 186
+4 201 195 197 183
+4 225 213 78 189
+4 183 101 99 114
+4 250 189 213 225
+4 246 224 80 223
+4 223 79 92 77
+4 112 183 201 99
+4 190 58 74 237
+4 188 227 241 215
+4 195 192 163 197
+4 189 142 208 244
+4 223 92 79 222
+4 186 226 219 217
+4 195 177 179 163
+4 246 222 221 223
+4 217 137 121 135
+4 217 121 137 238
+4 209 208 202 194
+4 183 114 100 101
+4 234 57 66 238
+4 165 89 159 6
+4 183 112 201 200
+4 183 100 114 218
+4 222 92 25 105
+4 154 202 52 152
+4 202 154 52 171
+4 214 148 137 135
+4 182 210 203 217
+4 196 195 203 192
+4 232 224 97 225
+4 207 213 91 205
+4 102 96 172 4
+4 232 231 84 224
+4 190 242 59 243
+4 222 105 25 103
+4 221 118 98 105
+4 182 203 209 217
+4 245 206 222 246
+4 226 137 146 238
+4 182 209 208 214
+4 182 217 209 214
+4 217 238 137 226
+4 222 103 94 206
+4 245 118 212 221
+4 249 105 222 221
+4 232 84 231 237
+4 182 215 214 208
+4 245 103 118 105
+4 102 4 172 36
+4 183 114 112 211
+4 183 211 112 200
+4 220 210 184 251
+4 245 105 118 221
+4 247 227 140 149
+4 215 208 143 214
+4 234 240 57 238
+4 182 194 208 209
+4 234 136 66 22
+4 217 226 137 214
+4 217 137 135 214
+4 234 66 64 22
+4 234 22 134 136
+4 202 175 171 173
+4 234 64 134 22
+4 234 238 136 121
+4 246 198 206 204
+4 79 206 94 95
+4 249 90 26 107
+4 249 92 105 26
+4 249 26 105 107
+4 195 45 179 177
+4 245 222 103 105
+4 206 36 102 172
+4 183 114 211 218
+4 201 99 108 112
+4 200 178 39 108
+4 251 183 184 216
+4 244 250 189 199
+4 138 238 51 137
+4 238 121 137 136
+4 207 199 213 205
+4 238 144 16 68
+4 220 242 241 188
+4 251 182 203 192
+4 189 225 188 247
+4 189 250 188 225
+4 210 119 126 139
+4 218 116 100 114
+4 245 221 222 105
+4 209 202 150 133
+4 185 187 224 223
+4 38 108 39 178
+4 195 127 45 177
+4 229 100 98 101
+4 189 188 215 247
+4 189 215 188 250
+4 249 105 98 107
+4 173 129 47 131
+4 187 235 230 229
+4 183 99 101 212
+4 186 241 226 215
+4 186 226 214 215
+4 246 79 222 223
+4 186 214 226 217
+4 188 232 243 190
+4 248 132 62 228
+4 246 191 198 204
+4 189 208 215 250
+4 188 213 224 225
+4 251 210 203 182
+4 207 159 157 158
+4 187 188 243 242
+4 196 129 46 175
+4 196 127 177 46
+4 16 238 70 145
+4 238 16 70 68
+4 207 87 89 91
+4 35 6 159 89
+4 218 100 116 235
+4 210 139 126 211
+4 245 198 206 246
+4 196 46 177 175
+4 218 116 228 235
+4 201 112 108 200
+4 196 175 177 192
+4 196 192 203 194
+4 206 79 94 222
+4 238 138 51 144
+4 165 207 28 166
+4 240 64 57 76
+4 207 165 28 89
+4 239 147 72 17
+4 79 246 206 95
+4 196 194 175 192
+4 3 68 144 138
+4 3 16 144 68
+4 182 194 203 192
+4 182 203 194 209
+4 217 203 122 210
+4 217 120 122 203
+4 237 84 71 9
+4 231 10 69 71
+4 217 209 120 203
+4 200 39 178 180
+4 200 44 179 125
+4 200 179 44 180
+4 200 125 123 44
+4 200 44 123 180
+4 207 165 89 159
+4 207 165 167 166
+4 183 251 184 210
+4 31 206 172 170
+4 209 135 148 214
+4 239 72 70 17
+4 248 219 119 218
+4 246 79 206 222
+4 232 188 243 224
+4 201 178 195 200
+4 242 76 59 56
+4 219 134 119 121
+4 207 166 167 199
+4 52 202 173 152
+4 207 159 55 165
+4 248 134 132 119
+4 232 224 243 231
+4 206 31 172 96
+4 207 87 78 189
+4 185 223 224 246
+4 232 231 243 237
+4 205 166 29 91
+4 205 29 166 168
+4 210 122 119 139
+4 196 192 177 195
+4 205 91 29 93
+4 110 200 40 123
+4 207 78 213 189
+4 187 224 243 188
+4 190 241 59 242
+4 190 243 58 237
+4 142 156 208 244
+4 210 119 122 219
+4 248 219 134 119
+4 185 224 213 246
+4 175 202 171 194
+4 189 244 208 250
+4 249 98 105 221
+4 209 141 150 202
+4 189 140 155 247
+4 249 236 90 107
+4 242 56 59 243
+4 211 124 125 139
+4 228 60 115 117
+4 187 231 224 223
+4 73 81 8 75
+4 246 204 213 191
+4 246 198 197 212
+4 187 231 243 224
+4 187 230 243 231
+4 114 42 41 126
+4 190 227 241 188
+4 190 188 241 242
+4 248 21 132 134
+4 248 134 64 21
+4 190 242 243 188
+4 188 225 224 232
+4 187 243 230 242
+4 250 225 213 188
+4 191 199 193 181
+4 205 168 166 181
+4 191 181 205 199
+4 204 168 161 170
+4 191 181 164 161
+4 171 154 52 53
+4 244 193 169 156
+4 202 152 131 173
+4 186 182 214 217
+4 151 75 19 2
+4 233 75 19 151
+4 233 19 149 151
+4 233 75 74 19
+4 233 19 74 149
+4 247 149 153 233
+4 213 80 78 93
+4 84 9 10 71
+4 190 72 59 241
+4 213 93 78 91
+4 238 138 144 68
+4 227 233 74 149
+4 183 201 99 212
+4 211 125 124 200
+4 251 197 192 195
+4 187 230 221 229
+4 183 197 201 212
+4 2 81 75 8
+4 233 149 153 151
+4 216 212 101 221
+4 249 236 230 231
+4 249 230 98 221
+4 249 187 223 231
+4 249 231 230 187
+4 202 154 150 152
+4 173 7 152 131
+4 173 131 47 7
+4 249 187 230 221
+4 213 205 93 91
+4 249 221 223 187
+4 245 104 103 206
+4 202 129 131 133
+4 202 131 129 173
+4 202 173 129 175
+4 28 207 91 166
+4 191 161 164 197
+4 246 197 198 191
+4 216 221 101 229
+4 251 192 203 195
+4 183 200 201 195
+4 211 114 41 126
+4 37 38 176 106
+4 102 4 24 96
+4 216 221 229 187
+4 216 185 221 187
+4 185 213 191 246
+4 202 48 131 152
+4 48 7 131 152
+4 202 152 150 48
+4 216 246 221 185
+4 202 48 150 133
+4 228 61 115 60
+4 193 162 181 169
+4 202 133 131 48
+4 218 114 42 116
+4 207 28 91 89
+4 215 241 220 186
+4 202 150 154 141
+4 202 141 154 208
+4 183 211 203 210
+4 26 105 25 92
+4 183 203 211 195
+4 185 213 224 188
+4 184 218 210 219
+4 65 13 12 111
+4 194 175 162 171
+4 185 250 213 188
+4 60 15 61 115
+4 60 117 15 115
+4 140 189 155 142
+4 251 191 197 246
+4 191 161 168 181
+4 244 157 158 207
+4 214 146 148 160
+4 231 69 10 86
+4 31 95 206 170
+4 230 113 13 111
+4 233 73 75 81
+4 233 81 82 73
+4 73 82 8 81
+4 208 143 141 156
+4 148 141 209 214
+4 208 141 154 156
+4 230 111 13 65
+4 227 18 74 72
+4 214 226 146 160
+4 95 31 206 96
+4 218 126 42 114
+4 241 215 220 188
+4 233 82 81 83
+4 193 181 167 169
+4 233 151 81 75
+4 196 177 127 195
+4 196 127 203 195
+4 209 120 129 133
+4 217 234 238 226
+4 196 203 120 209
+4 191 181 168 205
+4 193 181 162 164
+4 30 205 204 168
+4 196 120 129 209
+4 199 181 167 193
+4 186 215 214 182
+4 250 208 215 182
+4 217 121 238 234
+4 251 185 191 246
+4 209 133 129 202
+4 196 209 194 203
+4 209 202 208 141
+4 230 111 98 113
+4 14 15 115 61
+4 184 183 210 218
+4 229 100 101 183
+4 184 229 183 218
+4 185 188 224 187
+4 216 251 246 185
+4 49 133 150 48
+4 216 184 187 229
+4 205 29 30 93
+4 29 205 30 168
+4 207 157 87 189
+4 227 72 147 18
+4 234 66 136 238
+4 245 206 103 222
+4 211 112 41 114
+4 245 103 104 118
+4 201 108 178 200
+4 201 108 99 106
+4 18 72 147 17
+4 248 21 62 132
+4 214 160 141 143
+4 238 57 66 70
+4 238 137 138 136
+4 200 110 40 112
+4 214 143 141 208
+4 146 137 148 50
+4 183 211 210 218
+4 3 51 138 144
+4 237 233 74 190
+4 191 164 181 193
+4 227 149 147 140
+4 239 146 238 226
+4 146 239 238 145
+4 212 104 174 106
+4 230 111 65 236
+4 182 194 193 208
+4 249 222 223 221
+4 184 235 240 242
+4 109 236 27 88
+4 236 109 27 107
+4 236 109 12 67
+4 236 67 12 65
+4 236 12 109 111
+4 236 65 12 111
+4 233 73 74 75
+4 220 241 242 186
+4 227 188 232 247
+4 188 227 232 190
+4 220 210 182 186
+4 199 166 167 181
+4 103 25 94 24
+4 88 236 11 67
+4 209 141 208 214
+4 238 70 66 68
+4 40 200 124 123
+4 247 227 149 233
+4 200 40 124 112
+4 234 136 134 121
+4 151 2 32 81
+4 151 81 75 2
+4 248 64 62 21
+4 230 63 56 65
+4 207 167 244 199
+4 210 122 139 203
+4 36 174 206 104
+4 174 36 206 172
+4 231 71 56 243
+4 233 151 32 81
+4 237 9 82 84
+4 236 88 11 86
+4 230 65 56 236
+4 233 81 32 83
+4 237 73 9 71
+4 200 180 123 110
+4 5 123 44 180
+4 195 179 125 200
+4 195 163 179 178
+4 22 136 66 23
+4 234 121 134 219
+4 248 240 64 234
+4 22 64 134 21
+4 251 191 192 197
+4 220 182 210 251
+4 247 232 225 188
+4 245 198 104 206
+4 245 118 104 212
+4 55 207 167 158
+4 245 212 104 198
+4 220 187 188 185
+4 110 5 39 180
+4 110 180 123 5
+4 245 212 198 246
+4 239 17 70 145
+4 241 59 57 72
+4 233 153 32 151
+4 241 57 59 240
+4 227 147 72 239
+4 200 180 178 179
+4 212 174 176 106
+4 197 176 161 163
+4 210 203 139 211
+4 201 163 178 176
+4 199 205 166 181
+4 227 72 241 239
+4 244 167 158 54
+4 215 140 147 160
+4 11 236 69 67
+4 197 201 176 163
+4 249 90 236 231
+4 233 32 153 83
+4 37 176 174 106
+4 191 205 168 204
+4 215 147 140 227
+4 156 142 208 143
+4 212 176 174 197
+4 217 226 219 234
+4 221 101 98 118
+4 249 105 92 222
+4 220 187 242 188
+4 220 216 187 185
+4 220 184 187 216
+4 251 192 191 182
+4 236 65 69 67
+4 230 65 13 63
+4 230 13 113 63
+4 242 59 76 240
+4 248 64 134 234
+4 228 62 61 60
+4 228 130 132 20
+4 186 240 219 226
+4 236 11 69 86
+4 191 168 161 204
+4 241 238 57 240
+4 241 226 238 240
+4 27 236 90 88
+4 236 67 88 109
+4 237 82 9 73
+4 223 80 79 77
+4 212 118 99 101
+4 248 240 219 184
+4 223 224 80 77
+4 183 211 200 195
+4 239 145 147 17
+4 17 145 16 70
+4 228 132 62 20
+4 228 117 116 43
+4 228 43 116 128
+4 20 132 62 21
+4 228 130 117 43
+4 229 218 100 183
+4 220 216 185 251
+4 46 127 177 45
+4 175 129 47 173
+4 236 27 90 107
+4 185 191 213 250
+4 72 190 59 58
+4 128 43 116 42
+4 228 128 130 43
+4 228 60 117 130
+4 228 60 130 20
+4 228 20 62 60
+4 248 234 219 240
+4 175 47 129 46
+4 196 129 175 202
+4 196 202 175 194
+4 196 209 202 194
+4 228 128 132 130
+4 217 219 121 234
+4 244 193 167 169
+4 1 130 43 117
+4 235 63 61 76
+4 221 212 101 118
+4 186 241 240 226
+4 244 193 156 208
+4 18 149 74 19
+4 229 221 98 230
+4 28 29 166 91
+4 239 160 146 226
+4 28 6 89 165
+4 244 169 167 54
+4 135 137 50 148
+CELL_TYPES 10
diff --git a/data/reduced_cube/deform_cube.urdf b/data/reduced_cube/deform_cube.urdf
new file mode 100644
index 000000000..3faef357a
--- /dev/null
+++ b/data/reduced_cube/deform_cube.urdf
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<robot name="cube">
+ <deformable name="cube">
+ <inertial>
+ <mass value="10" />
+ <inertia ixx="0.0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0" />
+ </inertial>
+ <collision_margin value="0.006"/>
+ <repulsion_stiffness value="800.0"/>
+ <friction value= "0.5"/>
+ <neohookean mu= "180" lambda= "600" damping= "0.01" />
+ <visual filename="cube_mesh.vtk"/>
+ </deformable>
+</robot> \ No newline at end of file
diff --git a/data/reduced_cube/eigenvalues.bin b/data/reduced_cube/eigenvalues.bin
new file mode 100644
index 000000000..5c378ccde
--- /dev/null
+++ b/data/reduced_cube/eigenvalues.bin
Binary files differ
diff --git a/data/reduced_cube/modes.bin b/data/reduced_cube/modes.bin
new file mode 100644
index 000000000..d8fd6cea8
--- /dev/null
+++ b/data/reduced_cube/modes.bin
Binary files differ
diff --git a/data/reduced_cube/reduced_cube.urdf b/data/reduced_cube/reduced_cube.urdf
new file mode 100644
index 000000000..552cbd4a5
--- /dev/null
+++ b/data/reduced_cube/reduced_cube.urdf
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<robot name="reduced_cube">
+ <reduced_deformable name="reduced_cube">
+ <num_modes value="20"/>
+ <mass value="10"/>
+ <stiffness_scale value="100"/>
+ <collision_margin value="0.01"/>
+ <erp value= "0.2"/>
+ <cfm value= "0.2"/>
+ <friction value= "0.5"/>
+ <damping_coefficient value="0.0"/>
+ <visual filename="cube_mesh.vtk"/>
+ </reduced_deformable>
+</robot>
diff --git a/data/reduced_torus/K_r_diag_mat.bin b/data/reduced_torus/K_r_diag_mat.bin
new file mode 100644
index 000000000..baa768f51
--- /dev/null
+++ b/data/reduced_torus/K_r_diag_mat.bin
Binary files differ
diff --git a/data/reduced_torus/M_diag_mat.bin b/data/reduced_torus/M_diag_mat.bin
new file mode 100644
index 000000000..e35822c49
--- /dev/null
+++ b/data/reduced_torus/M_diag_mat.bin
Binary files differ
diff --git a/data/reduced_torus/M_r_diag_mat.bin b/data/reduced_torus/M_r_diag_mat.bin
new file mode 100644
index 000000000..ddf8e5003
--- /dev/null
+++ b/data/reduced_torus/M_r_diag_mat.bin
Binary files differ
diff --git a/data/reduced_torus/eigenvalues.bin b/data/reduced_torus/eigenvalues.bin
new file mode 100644
index 000000000..208f1cf3e
--- /dev/null
+++ b/data/reduced_torus/eigenvalues.bin
Binary files differ
diff --git a/data/reduced_torus/modes.bin b/data/reduced_torus/modes.bin
new file mode 100644
index 000000000..ae8b826db
--- /dev/null
+++ b/data/reduced_torus/modes.bin
Binary files differ
diff --git a/data/reduced_torus/reduced_torus.urdf b/data/reduced_torus/reduced_torus.urdf
new file mode 100644
index 000000000..16b23470a
--- /dev/null
+++ b/data/reduced_torus/reduced_torus.urdf
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<robot name="reduced_cube">
+ <reduced_deformable name="reduced_cube">
+ <num_modes value="20"/>
+ <mass value="10"/>
+ <stiffness_scale value="10"/>
+ <collision_margin value="0.01"/>
+ <erp value= "0.2"/>
+ <cfm value= "0.2"/>
+ <friction value= "0.5"/>
+ <damping_coefficient value="0.00001"/>
+ <visual filename="torus_textured.obj"/>
+ <collision filename="torus_mesh.vtk"/>
+ </reduced_deformable>
+</robot>
diff --git a/data/reduced_torus/torus_mesh.vtk b/data/reduced_torus/torus_mesh.vtk
new file mode 100644
index 000000000..a06ef2061
--- /dev/null
+++ b/data/reduced_torus/torus_mesh.vtk
@@ -0,0 +1,9917 @@
+# vtk DataFile Version 2.0
+torus_, Created by Gmsh
+ASCII
+DATASET UNSTRUCTURED_GRID
+POINTS 1036 double
+-0.75 -2.18556941e-08 1.13246855e-07
+-0.71031338 -0.135160238 1.07254337e-07
+-0.710313141 0.135160565 1.07254301e-07
+-0.692909718 -2.18556941e-08 -0.287012398
+-0.692909598 -2.18556941e-08 0.287012607
+-0.65624404 -0.135160238 -0.271825016
+-0.6562439799999999 -0.135160238 0.271825194
+-0.656243861 0.135160565 -0.271824926
+-0.656243742 0.135160565 0.271825105
+-0.603853762 -0.227407992 9.11793805e-08
+-0.603853405 0.227408156 9.11793308e-08
+-0.558141589621361 -0.2272469457790709 -0.2307452454467901
+-0.557888091 -0.227407992 0.231084868
+-0.557887852 0.227408156 -0.23108457
+-0.557887793 0.227408156 0.231084719
+-0.530330241 -2.18556941e-08 -0.530329943
+-0.50226754 -0.135160238 -0.5022673010000001
+-0.50226742 -0.135160238 0.50226742
+-0.50226742 0.135160565 -0.502267122
+-0.502267241 0.135160565 0.502267241
+-0.464421362 -0.247455373 7.01256795e-08
+-0.464420974 0.247455314 7.01256155e-08
+-0.42906943 -0.247455373 -0.177726254
+-0.4296712671318722 -0.247455373 0.1747004492923097
+-0.429069072 0.247455314 -0.17772612
+-0.429069012 0.247455314 0.177726239
+-0.426989228 -0.227407992 -0.426988989
+-0.426989079 -0.227407992 0.426989079
+-0.426988959 0.227408156 -0.426988721
+-0.42698884 0.227408156 0.42698884
+-0.336284906 -0.18893747 5.07776079e-08
+-0.336284608 0.188937217 5.07775653e-08
+-0.328395605 -0.247455373 -0.328395396
+-0.328395486 -0.247455373 0.328395486
+-0.328395337 0.247455314 -0.328395128
+-0.328395218 0.247455314 0.328395218
+-0.310686767 -0.18893747 -0.128690585
+-0.310686737 -0.18893747 0.128690675
+-0.310686499 0.188937217 -0.128690481
+-0.310686469 0.188937217 0.128690571
+-0.287012696 -2.18556941e-08 -0.692909598
+-0.287012637 -2.18556941e-08 0.692909598
+-0.271825254 -0.135160238 -0.6562439799999999
+-0.271825224 -0.135160238 0.6562439799999999
+-0.271825165 0.135160565 -0.656243742
+-0.271825135 0.135160565 0.656243742
+-0.260126799 -0.07043330370000001 3.92780564e-08
+-0.26012671 0.07043293120000001 3.92780422e-08
+-0.240325853 -0.07043330370000001 -0.09954615679999999
+-0.240325823 -0.07043330370000001 0.0995462313
+-0.240325764 0.07043293120000001 -0.099546127
+-0.240325734 0.07043293120000001 0.0995461941
+-0.237789407 -0.18893747 -0.237789273
+-0.237789333 -0.18893747 0.237789333
+-0.237789199 0.188937217 -0.237789065
+-0.237789124 0.188937217 0.237789124
+-0.231084913 -0.227407992 -0.557888091
+-0.231084883 -0.227407992 0.557888091
+-0.231084779 0.227408156 -0.557887793
+-0.231084749 0.227408156 0.557887793
+-0.18393749 -0.07043330370000001 -0.183937371
+-0.183937415 -0.07043330370000001 0.183937415
+-0.183937415 0.07043293120000001 -0.183937311
+-0.1826027894390168 0.07043797995747503 0.1848329123509294
+-0.177726433 -0.247455373 -0.42906937
+-0.177726403 -0.247455373 0.42906937
+-0.177726284 0.247455314 -0.429069012
+-0.177726254 0.247455314 0.429069012
+-0.128690705 -0.18893747 -0.310686737
+-0.12869069 -0.18893747 0.310686737
+-0.1286906 0.188937217 -0.310686469
+-0.128690571 0.188937217 0.310686469
+-0.0995462537 -0.07043330370000001 -0.240325823
+-0.09954623880000001 -0.07043330370000001 0.240325823
+-0.0995462164 0.07043293120000001 -0.240325734
+-0.0995462015 0.07043293120000001 0.240325734
+-3.27835394e-08 -2.18556941e-08 0.75
+-3.10487849e-08 -0.135160238 0.71031338
+-0.002247339125087955 0.135160565 0.7098661234313948
+-2.6395286e-08 -0.227407992 0.603853762
+-2.639527e-08 0.227408156 0.603853405
+0.005294134150853763 -0.247455373 0.4633682886880875
+-2.03004848e-08 0.247455314 0.464420974
+-1.46994799e-08 -0.18893747 0.336284906
+-1.46994674e-08 0.188937217 0.336284608
+-1.13705036e-08 -0.07043330370000001 0.260126799
+-1.13704992e-08 0.07043293120000001 0.26012671
+3.10198112e-09 -0.07043330370000001 -0.260126799
+3.10198001e-09 0.07043293120000001 -0.26012671
+4.01015754e-09 -0.18893747 -0.336284906
+4.01015399e-09 0.188937217 -0.336284608
+5.53816948e-09 -0.247455373 -0.464421362
+5.53816459e-09 0.247455314 -0.464420974
+7.20088389e-09 -0.227407992 -0.603853762
+7.20087989e-09 0.227408156 -0.603853405
+8.470402160000001e-09 -0.135160238 -0.71031338
+8.470399489999999e-09 0.135160565 -0.710313141
+8.943660029999999e-09 -2.18556941e-08 -0.75
+0.0995461792 0.07043293120000001 0.240325734
+0.0995462164 -0.07043330370000001 0.240325823
+0.09954622389999999 0.07043293120000001 -0.240325719
+0.09954626110000001 -0.07043330370000001 -0.240325809
+0.128690541 0.188937217 0.310686469
+0.1286906 0.188937217 -0.310686439
+0.12869066 -0.18893747 0.310686737
+0.12869072 -0.18893747 -0.310686707
+0.177726209 0.247455314 0.429069012
+0.177726299 0.247455314 -0.429068983
+0.177726358 -0.247455373 0.42906937
+0.177726448 -0.247455373 -0.42906934
+0.183937356 0.07043293120000001 0.183937356
+0.183937415 -0.07043330370000001 0.183937415
+0.183937415 0.07043293120000001 -0.183937296
+0.18393749 -0.07043330370000001 -0.183937356
+0.231084689 0.227408156 0.557887793
+0.231084794 0.227408156 -0.5578877330000001
+0.231084824 -0.227407992 0.557888091
+0.231084928 -0.227407992 -0.557888091
+0.237789124 0.188937217 0.237789124
+0.237789199 0.188937217 -0.237789035
+0.237789333 -0.18893747 0.237789333
+0.237789407 -0.18893747 -0.237789258
+0.240325734 0.07043293120000001 0.0995461866
+0.240325794 0.07043293120000001 -0.09954606739999999
+0.2405965857521089 -0.07043330370000001 0.09818501000602463
+0.240325883 -0.07043330370000001 -0.0995460972
+0.26012671 0.07043293120000001 1.69520092e-07
+0.260126799 -0.07043330370000001 1.69520149e-07
+0.271825075 0.135160565 0.656243742
+0.271825165 -0.135160238 0.6562439799999999
+0.271825194 0.135160565 -0.6562436820000001
+0.271825284 -0.135160238 -0.65624392
+0.287012577 -2.18556941e-08 0.692909598
+0.287012696 -2.18556941e-08 -0.692909598
+0.310686469 0.188937217 0.128690556
+0.310686529 0.188937217 -0.128690392
+0.310686737 -0.18893747 0.128690675
+0.310686827 -0.18893747 -0.128690511
+0.328395218 0.247455314 0.328395218
+0.328395337 0.247455314 -0.328395098
+0.328395486 -0.247455373 0.328395486
+0.328395605 -0.247455373 -0.328395367
+0.336284608 0.188937217 2.19150877e-07
+0.336284906 -0.18893747 2.19151062e-07
+0.42698884 0.227408156 0.42698884
+0.426988959 0.227408156 -0.426988691
+0.426989079 -0.227407992 0.426989079
+0.426989228 -0.227407992 -0.42698893
+0.429069012 0.247455314 0.177726224
+0.429069132 0.247455314 -0.177726001
+0.4285832038493428 -0.2473905309719522 0.1782033175787506
+0.429069489 -0.247455373 -0.17772615
+0.464420974 0.247455314 3.02655138e-07
+0.464421362 -0.247455373 3.02655394e-07
+0.502267241 0.135160565 0.502267241
+0.50226742 -0.135160238 0.50226742
+0.50226742 0.135160565 -0.502267063
+0.50226754 -0.135160238 -0.502267241
+0.530330062 -2.18556941e-08 0.530330062
+0.530330241 -2.18556941e-08 -0.5303298829999999
+0.557887793 0.227408156 0.231084704
+0.557887912 0.227408156 -0.231084421
+0.557888091 -0.227407992 0.231084839
+0.557888269 -0.227407992 -0.231084555
+0.603853405 0.227408156 3.9352085e-07
+0.603853762 -0.227407992 3.93521077e-07
+0.656243742 0.135160565 0.271825075
+0.65624392 0.135160565 -0.271824747
+0.6562439799999999 -0.135160238 0.271825165
+0.656244159 -0.135160238 -0.271824837
+0.692909598 -2.18556941e-08 0.287012577
+0.692909837 -2.18556941e-08 -0.287012219
+0.710313141 0.135160565 4.62898811e-07
+0.71031338 -0.135160238 4.62898981e-07
+0.75 -2.18556941e-08 4.88762055e-07
+0.2148047599579061 0.05862636186789426 0.502491616306411
+0.08708371449759361 -0.07904678396405236 0.4544761890310727
+-0.146602316861926 -0.009632696391538147 -0.315119087525655
+0.1692244930490057 0.1812843605 0.623422415988969
+0.2079651687174781 0.1331645320914401 -0.5836410988931576
+0.1536632925775345 0.1239510807482383 0.4572738201945878
+-0.5671834958762344 -0.01939125278810325 -0.1175294783630399
+0.5569435355 0.06758027157215296 0.45546928025
+0.45546936975 -0.06758012992784704 0.5569436249999999
+-0.6446421632553362 -0.05976163801653798 -0.1092778761071423
+-0.6214703736046712 -0.0666511357727524 0.1250423258651282
+0.300758051598111 0.07172693423651585 0.4583027905022347
+-0.654305795925001 0.03357102801595683 0.001848341005699126
+-0.6258175216303261 0.05432506588159775 0.1162604558790866
+-0.442057131510203 0.03095741689814975 -0.2765487156973705
+0.30043105825 -0.181284115 0.5743412825
+0.6159713774510746 0.1837769934522046 -0.1922216808197105
+0.5322994338378045 0.008502274921264123 -0.3744977122371063
+0.04265738067802943 -0.1046145807176613 -0.4450745330079127
+0.1246996850352893 0.06574632593164867 -0.7058907283422399
+0.414704820039705 0.05850602124603817 -0.5873244043967869
+-0.5997874394191635 -0.06652994583433987 -0.3918934603056267
+0.4105207575547945 -0.02280618123261142 -0.4112567807811419
+0.1154383286484265 -0.0670131696695989 0.3444306649723132
+-0.5457887659485642 -0.1555429921777584 -0.2112258584708629
+-0.556036820477818 -0.1322847934326201 -0.08914487821102607
+-0.5287910658346734 -0.145964002948216 0.09942815883918801
+-0.5488808869220985 -0.1230845936541704 0.1994070919703603
+-0.5514166647614607 -0.06021660203561584 0.006754432547757371
+-0.5410083912396699 -0.04992438886868006 0.1097211985421525
+-0.5282477366216665 -0.0457190959344033 0.2285741534938628
+-0.5471074779992053 -0.03863338164943837 0.3383833878444414
+-0.5379197870483288 0.04712173579130802 -0.311524103556143
+-0.5444049150912931 0.04459180613937631 0.004718340344478199
+-0.5221095018638044 0.0369594492107734 0.119071275868263
+-0.5308799781628447 0.04747798722078263 0.3117821923412912
+0.4475426814502823 0.1489278561181345 -0.2688886257995359
+0.2996792148585254 0.1654024873724193 -0.4496521940991762
+0.0006848522370035207 -0.1023848032902419 0.5037054741521728
+-0.5278138632473582 0.1468044649733942 0.09245296480095991
+-0.5412677375001846 0.1432254272463678 0.2064531176041771
+-0.4231612307707837 -0.1037401749254241 -0.1337060640227804
+0.3305945547851408 0.01949853570690828 0.5514300148461841
+-0.4037618125828935 -0.1605445022397436 -0.336392455313646
+-0.4247760234915319 -0.1530323475734049 0.2024351829109144
+-0.4495954867690495 -0.1502396951148145 0.3301820862519624
+-0.4408269404029921 -0.07227179543752946 -0.0169300934674944
+-0.4374801290473587 -0.07174959795745348 0.1003803329881969
+-0.4416965121862891 -0.04176342978079188 0.3173556488626441
+-0.4210349730051253 -0.04504186570420775 0.4288698757126937
+-0.4469474911194326 0.05062181151367538 -0.4380625839577525
+-0.4208545034966771 0.02789523773719308 -0.124023188409767
+-0.4426622831200132 0.05234302201265242 -0.01514508992852398
+-0.4508707370426806 0.07401740893526983 0.235274710670023
+-0.4193989654820721 0.05283121747753344 0.3293365305174706
+-0.429259712191232 0.04147422157022783 0.4546009980040832
+-0.4365211327554736 0.1347201315161209 -0.3271173605683869
+-0.4285450353537538 0.1540513903482495 0.1047628151789162
+-0.4403871896259152 0.1709419521191819 0.210772629951794
+-0.4174665753576615 0.1439620252099086 0.3300534389646202
+0.2079223709471942 -0.1155629893027928 -0.3256443507170392
+0.4773776328763831 0.08791904828105823 -0.3315091410248636
+0.6109661671423812 -0.1312233317339073 -0.04826091956918894
+-0.3210912808149326 0.09886036457796581 -0.3443362945660071
+-0.5107203347875002 -0.0511037324690895 -0.2162246520966066
+-0.4274951252036663 -0.03507233851382638 -0.1978104046406515
+-0.3221922211749222 -0.1445975170440534 -0.4425145553301829
+-0.3286954227264652 -0.1434492302514711 0.2222906885168947
+-0.3285017090814557 -0.1265089069691785 0.308151421041821
+-0.3395649970840241 -0.1554064149526791 0.4225686128741589
+-0.3290190794293953 -0.05254108065203134 -0.5467141964176405
+-0.3159309151850979 -0.04120775039923903 -0.3224716358271946
+-0.3258398369406388 -0.03510117790117903 -0.1134249561622734
+-0.3376001506561476 -0.05717751503157612 0.102342810283574
+-0.3114520801316878 -0.03409065073118795 0.2177680683076604
+-0.328474165477487 -0.02648855206584399 0.3310258350020063
+-0.3225401600591715 0.05796838860563992 -0.5319520165267214
+0.2015107240799966 -0.0348512362201389 -0.4020904760206556
+-0.3346454802644096 0.05207433096846966 -0.01301303916511887
+-0.324625531231217 0.04835716156963638 0.1075824478319873
+-0.3479391062280647 -0.126665390258168 -0.2287931817071033
+-0.3339391802062537 0.08638104506876045 0.4153871716356871
+-0.3437931748730649 0.06799499691212332 0.5252200011202918
+0.2457413693967162 0.1472628478350848 0.429295858344446
+0.5295492770417918 0.1093862086104987 0.2733651267765829
+-0.3160302043757477 0.1364302962912125 -0.2386521499676249
+-0.3325980279608176 0.1444494011689514 0.2364387692234707
+-0.2930387724981217 0.1411993925395293 0.34719695896367
+-0.3437518688936977 0.1722947186730353 0.4268002410906342
+-0.3002781246773413 -0.05656847936871779 0.5773421353060838
+0.6116200389999999 -2.18556941e-08 -0.408671051
+0.4086714685 -2.18556941e-08 -0.6116197404999999
+-0.6116199795 -2.18556941e-08 -0.4086711705
+0.4086713195 -2.18556941e-08 0.61161983
+0.61161983 -2.18556941e-08 0.4086713195
+-0.3961672556480173 -6.155555294249769e-05 0.6199534874067836
+0.2898606410459698 0.09953935377376469 -0.5721343919035593
+0.1274258562189954 0.1820950256176694 -0.6308011075224357
+-0.2983307807445332 0.1419806263712661 -0.4269982341363224
+-0.01753325163574215 -0.1046126048589783 0.5737683073312927
+-0.1065471808270385 0.08839229482936621 -0.6047472533910651
+-0.5078357084441076 -0.1134888177294395 -0.3438187367651265
+0.07138585320850009 -0.05840339156309945 0.6482034465556364
+0.1875194341956316 -0.06385973718928681 0.6174557333286409
+-0.1940775370390703 0.1189988285552581 -0.5653164243045676
+0.210606074927093 -0.07955350966472875 -0.5157443637988349
+-0.2329323291013624 -0.1248761065775685 -0.5354600680477379
+0.4529133510639263 0.1027731533397032 0.4209756521472898
+-0.4260979781625683 -0.08344441861394807 -0.4140970192187416
+-0.2169229250232756 -0.139728824653224 0.3022348443465113
+-0.2198768006712144 -0.149968159355379 0.4321842579547452
+-0.2214114204232291 -0.1225220799957973 0.5409621791502991
+-0.1929736857355174 -0.03818610480938463 -0.5031431915557217
+0.2447988857322374 0.00381362611841892 0.5899237674964953
+-0.2253454435756435 -0.0510535612519891 0.3044597114244738
+-0.2040544704023095 -0.03176029619634726 0.427052550607548
+-0.2092215002784332 -0.02565337133532111 0.5411861284909295
+0.480989766979571 -0.08319996631774527 -0.4210647206063204
+0.6832787695 -0.135160238 -0.1359121870505095
+-0.1359126227647989 -0.135160238 -0.6832786799999999
+-0.2289056667134217 0.04663271431507766 -0.4255814967903377
+0.1359126012351997 0.135160565 -0.6832784115
+-0.2066628191114914 0.05480046826812753 0.3198049648384878
+-0.2243058615160185 0.07964437541474738 0.4247297184543852
+-0.208113090690223 0.06445928225980971 0.5231662485997532
+0.1359125669756076 -0.135160238 0.6832786799999999
+-0.1359126275243924 -0.135160238 0.6832786799999999
+0.387046307 0.135160565 -0.5792553725
+0.3870462925 -0.135160238 0.5792557
+-0.6832786799999999 -0.135160238 0.1359126506271685
+0.6832786799999999 -0.135160238 0.1359128139494905
+-0.2194004785644676 0.1475847545349244 -0.3469514787709857
+-0.5956393160156814 0.09490531950004515 -0.2042934565935917
+-0.2178745302422234 0.1453261132084583 0.3328986335035305
+-0.2418619683830102 0.1723327817400896 0.4269176136807822
+-0.1831818339704835 0.1484536604414157 0.5221446291367574
+0.03663870813279047 0.05005509956049407 -0.6414864284917617
+0.1942350135205994 0.05851852115451094 -0.6161295752759666
+-0.5420417635302861 0.1012002134691774 -0.1193827443122811
+-0.5756313767461709 0.1636057234662092 -0.06013303154197015
+-0.08651201916266667 -0.06865067701275893 -0.3321620682941319
+0.1027626229516373 -0.1314567021304453 0.3834698204860338
+-0.362428029410273 -0.1070244315800844 0.4886937738212236
+-0.1011488098433493 -0.1488108851409737 -0.5298702748774109
+0.1020647599765114 -0.07371707566437634 -0.366754583133816
+0.3903368429134106 0.101699745956457 -0.433818578133064
+-0.1074126412370914 -0.1526189193003277 0.4088007775076468
+-0.1151641662391919 -0.1438442203091108 0.5312796308049904
+0.2921648111109675 -0.07492673849593907 -0.2773684319721069
+-0.1285905486543048 -0.05647037586924304 -0.6133127505128496
+-0.1216163521409942 -0.03813129009229205 -0.4360208940675083
+-0.09905003496170785 -0.06196894632151512 0.3368756483460959
+-0.0990668004357604 -0.05903067457631835 0.4461241622524353
+-0.4776363609860341 0.1465133577617411 -0.2274197198236627
+-0.08773698924304667 -0.05184598555492647 0.6268363586823165
+-0.2267429148408685 0.1249132199309427 -0.4913909097447509
+-0.1121832809510704 0.04646092772441284 -0.5238551018576121
+0.2073757465014909 -0.0005490189447118193 -0.2818296401738018
+0.3574044012045842 0.1547702511617189 -0.2277470630249493
+-0.2354812082527474 -0.150851567101606 -0.3768350049973243
+-0.08743158532283671 0.05697845190875393 0.3357206925042919
+-0.1277896175209473 0.0578934535227305 0.440598521116173
+-0.1033125957436848 0.03928284369367165 0.5233789300229542
+-0.09304793425364484 0.05084289554029058 0.6380521403377361
+0.2386457396262456 0.1715816661461778 -0.3828757503815334
+0.423909910978836 0.1317032982272586 0.06356530576229823
+0.4097262710096638 0.1454523582378435 0.1438076249432514
+-0.0911470481544097 0.1452334358097956 -0.4158156824845399
+-0.1016133527545378 0.136860667934726 0.4330388861157719
+-0.4292389925744527 -0.1654781027874459 -0.07721888439167002
+0.2059596359472754 -0.0381533441888445 0.2457693811615254
+0.2680266045401745 -0.0409369721715605 -0.1942463155450726
+-0.5684009439817774 -0.181284115 0.3093214345483903
+0.156376008505201 -0.03237108451866057 0.2901862018655822
+0.4036041502130215 0.07115527728618469 0.4897612657744972
+0.4145351070767421 0.04784708682520229 -0.4968945110667345
+0.5250185200556235 0.04036754828805152 0.3708378603636437
+-0.3939857586234845 -0.0354399188984108 0.5159839140024425
+-0.5136737465592929 -0.02096928334744927 -0.3939635237507689
+-0.6094018716296354 0.002003007624447968 -0.202297769504363
+-0.3663963947652291 0.008372259341285189 -0.228274073560665
+0.3184424023319196 -0.02249886458617977 0.3579632423854461
+0.006561687502009625 0.05724662934245741 -0.5358999954437873
+-0.02114722495813348 0.04872463253946129 -0.3390579201943842
+0.3048686051070211 0.1840817211670154 -0.5675677732621035
+-0.01038008191495194 0.05798805100217008 0.4357427118599579
+0.0008467820919496345 0.03331469483369875 0.5521021583643705
+0.407017633 0.1812843605 -0.50312203175
+0.05776611603134262 0.1376535741227746 -0.2918362873837625
+0.0497730822502663 0.1296850741 0.288305171
+0.2457107185925527 0.135139000195845 0.1648979522399937
+0.1686676516 0.1296850741 0.239057429
+-0.5000568779581299 -0.1795990531282913 0.4150386052352156
+0.5014528792180527 -0.1816753454552545 -0.408719237110252
+-0.5029512339302212 0.1812843605 -0.4072733907773048
+0.5029512152035382 0.1812843605 -0.4072733664139633
+-0.3764123707272886 0.09879670488745546 -0.4095454500084148
+-0.4725332676819864 0.005642352703116546 0.2020216355148748
+-0.1496650072925399 -0.235647257655321 0.5167782537253931
+-0.5302451570783469 0.2365965943548609 -0.04876828145860426
+-0.002591613671415457 -0.1026208303124244 0.3928908007681053
+-0.0523451173707068 0.1302623922386563 0.4927621326423263
+0.05860755375353332 0.1257279774771141 0.4794596148821863
+0.08802430931468684 -0.1225325715056166 0.5603036431373815
+0.1032241182142573 -0.0340591879952308 -0.5533129910255919
+0.00745278544232821 -0.06582211103224113 0.630052478596229
+-0.01082466888663697 -0.03801533319731521 -0.6156480556982972
+0.4726120106138331 0.12484313881195 0.3448375643845454
+0.4814544006975456 -0.05513774069059533 -0.2986534077813469
+0.4732694108739305 -0.05522915948677016 -0.1778180843447857
+0.4909415760273616 -0.03837679976116375 -0.06661192117720928
+0.100095691090951 0.05093218150821434 -0.4304550833388545
+0.1239385805155771 0.044544506316063 -0.3352807243241612
+-0.2802087049206544 -0.08144478342526922 0.4785192195300021
+0.09580812999656925 0.05650133103318054 0.5018653908681395
+0.1112308163202565 0.150059329766388 -0.5249317956161899
+0.6459383261078916 0.06758027157215296 0.3222791452973603
+-0.1565518800075456 0.04876135164867082 -0.3722630768346345
+0.5560387821509727 -0.04441632956197366 -0.1490117451147615
+0.581792943649261 -0.04102538424861867 -0.06392366822802879
+-0.2582127270014075 0.02913406223927319 0.2684441064386298
+0.2927387924644004 -0.0149633208788464 -0.4491729904496716
+0.2013878265835575 -0.1266401577586878 0.3266978710424491
+0.443141937 -0.2374316825 -0.279739961
+0.5157281007889414 -0.2374270833779515 -0.09271138174935373
+0.2090559597555721 -0.04395774488034123 0.4278392112683149
+-0.4944336897194478 -0.09005668250886321 0.3978113830106517
+-0.432532593947051 -0.2375984594420146 -0.2935702535581112
+0.2277292536980891 0.0428303539450235 -0.5320631122757074
+0.2865164264133694 -0.2374651039703354 0.4383398348635704
+0.2056064164492523 0.04985412590180793 0.3127630284553709
+-0.2820232971018125 0.2372968610762593 -0.4427223751947126
+0.4395616904484677 -0.2384988760845237 0.2719947621906035
+-0.5081604390019669 -0.2378210470469928 0.1169813244873835
+0.4327316470501742 0.2384381322497851 -0.2829623286064294
+0.2877680748853014 0.2378403864535273 -0.4344245922410273
+0.2797399535 0.237431735 0.4431415055
+-0.4340564080289104 0.2378165773830367 0.2886114810717543
+-0.1828011762689302 0.05364457025045295 -0.6355453293052928
+0.6375438199914241 -0.02935637925234931 -0.152892417653076
+0.2602975085172395 -0.09745952344616611 0.5477608240078249
+0.2775263424353848 -0.1228377492099226 0.384791984454249
+0.3596151937197254 -0.141597768176489 -0.4231164447026335
+0.3208415581685442 -0.1349795480412619 -0.2171832530745286
+0.3109056466661628 -0.1388776022384641 0.1987929501681949
+0.3335612390022412 -0.04552068754656854 -0.5281548867660718
+-0.4531333533695962 0.07692855650042288 -0.555266519638251
+-0.4585715218401867 -0.07760329815977847 -0.5513992488579733
+0.3396141930387401 -0.05279514643595638 -0.0921131507041876
+0.3204727004155962 -0.06529806721664831 0.1046288254150648
+0.31306525603795 -0.06567965594681423 0.2046364937964013
+0.3159038841314221 0.02599107147295122 -0.3415755577703607
+0.3351976816345975 0.06128680549085182 -0.1479704239571715
+0.3388606878224936 0.0394365795661426 -0.03384902201879005
+0.3437417281098993 0.05703090942030965 0.107072764716187
+0.3220169919082694 0.05095046011482658 0.2177406215607413
+0.0689665525288998 -0.01163147790780546 -0.665821750833281
+0.4247853193968322 0.138055140745489 0.2498450206885172
+0.5666235297019543 -0.1721782523580675 -0.1155446617485881
+0.2372398230317664 -0.03167176195468971 -0.6080155472507058
+0.3357930029995391 0.1567136729231967 0.4253357575546892
+0.3540986515356748 -0.1424058629083627 0.3969252358031086
+-0.3414012713464936 -0.0621048952609243 0.002901790927666791
+-0.006352275712959725 -0.06508036243897163 -0.3374551632923645
+0.4077025720526192 0.04826923006195883 -0.2421012815042307
+0.1654412905940297 0.04562478981903653 0.4212167249231981
+0.4197084439871971 0.05192469954844516 0.1814469788058192
+-0.2208049830591295 0.06251985565641553 -0.6877215877450071
+0.426338398304634 -0.1434752602320325 -0.3367315691514332
+0.4326170457437952 -0.1411491565218985 -0.2188400560397645
+0.4237305177426459 -0.141661095432702 -0.08709124284118519
+0.404215024391447 -0.1399533434716075 0.2156067827615666
+0.4328630722823912 -0.1328013499737094 0.3308716072960298
+0.2248175293217677 -0.06758012992784704 0.6854376795667962
+0.4161155946855566 -0.05584439860466436 -0.002441013836284896
+0.4313140076389336 -0.05978578617486206 0.1088070022131595
+0.450918256819464 -0.03847381900589373 0.2359583877933817
+0.4457060890403761 -0.02620527055913056 0.413482502816888
+0.09835692228621801 0.06442805687023616 0.3643175222483206
+0.4369762376240091 0.04583458804269828 -0.1157588923316206
+0.4259958964602643 0.06108205071788198 -0.01539096574106599
+0.4162805245750874 0.04502838616233909 0.3078736604558807
+-0.2079118128565157 -0.04963516806072479 -0.3889561128873697
+-0.4299064880738119 0.135160565 0.5506171529961174
+0.5281180042296583 -0.1378503329927562 -0.2334815132298401
+0.5223484067072454 -0.1458065956801332 -0.02071680486975328
+0.5425252574054265 -0.1373263383845702 0.1072054410899196
+0.5350977120239054 -0.05103806950915329 0.3245688546285393
+0.5333863472702021 0.05046379975240864 -0.1975902518114613
+0.532455096746828 0.04560488532328932 -0.005699071116475381
+0.5419193981501835 0.0486765864019862 0.1239391687217768
+0.5355481056583311 0.1414417937687622 -0.09261594688985184
+-0.4967510892678877 0.04316175247488441 -0.1928494949928883
+-0.02348498660855512 -0.05726929540916417 -0.4929404584818559
+0.3389491987958484 0.1263167279134933 0.5054477140885989
+0.6274560120419712 -0.05198890175872962 0.1099921569861211
+0.4878419111093683 0.05875103888030383 0.2200223268103224
+0.6240885685723052 0.04492717659879997 -0.1054570120072385
+-0.6018963927443802 0.05107175258897927 0.2237810152843244
+0.641493437015596 0.04698768983416271 0.1038913003334417
+-0.2638401636369636 -0.05493290412767491 -0.4459854414188743
+-0.4048759839159633 -0.06931554420171929 0.2011181734596874
+-0.6013782642278841 -0.008670811585460226 0.05953811030783254
+0.236902116816932 0.07230934141622231 -0.4053013921960443
+0.1152841078827855 0.0709724499571117 -0.6207345739323095
+-0.2104418741655573 -0.06950722531256681 -0.2601247953068311
+-0.2245041950568541 -0.1051655974782383 -0.3165675198391922
+0.2110263114297359 0.1100623185224954 -0.31596710503771
+-0.3303083506116173 -0.02760598174876897 0.4317847611411088
+-0.3969790557273846 0.08278970153870198 -0.223719143864455
+0.3181074745640283 0.001246966633677706 -0.2511003853726549
+-0.001060707671683717 -0.1065111122750068 -0.5541061858275393
+0.650853451752721 0.009920080387569559 0.011665510543036
+-0.3574599974014963 0.09734137741098607 -0.09965203923949038
+-0.1436064464398353 0.08831529589285453 -0.3151052839264627
+-0.007506786969251721 -0.004105502730003744 -0.4243101107139098
+0.1065931068429387 -0.0001085366789827557 0.4135578084754778
+-0.3329912408681484 0.06421172716095264 0.3029882505886588
+-0.3375421951262143 0.006229202633078193 -0.4349069127969654
+-0.6985554476013591 -0.1024719621527603 0.1073642970980115
+0.5452928391102743 0.01608060722268402 0.2319397301056004
+0.1155424676004419 -0.227407992 -0.5808709265000001
+0.4924387485 -0.227407992 -0.3290367425
+0.5805699011497513 -0.227407992 -0.1170558901122047
+0.3290369515 -0.227407992 0.492438585
+0.492438585 -0.227407992 0.329036959
+0.11554240060044 0.227408156 -0.580870569
+0.4924384355 0.227408156 -0.329036556
+0.5808706585 0.227408156 -0.115542013739575
+-0.329036869 0.227408156 -0.492438257
+-0.5770880277546183 -0.227407992 -0.1345605514496855
+-0.492438585 -0.227407992 0.3290369735
+0.3290368765 0.227408156 -0.492438212
+0.3290367645 0.227408156 0.4924383165
+-0.4846991967808343 0.2275824300242007 0.3384793634329527
+-0.4924384055 0.227408156 -0.3290366455
+-0.5808706285 0.227408156 -0.1155422394103346
+0.5263242134816848 0.1427634180929979 0.04084918483631195
+-0.1523500837504407 0.1543677763815984 -0.5036055611948859
+0.502190705004582 0.1453440444158882 0.1545363581935308
+0.1381249001229966 -0.1411164872603262 -0.4731299872355259
+-0.6070921062993293 0.07694558145276738 0.3755620352998136
+0.1406031141985266 0.1429805795156574 -0.4029942841166447
+-0.5103359034007181 0.2364667903916487 0.1533976511473124
+0.1425452530490057 0.237431735 0.5057831616462883
+-0.3731252291502142 0.1294891353399314 -0.4883120817928434
+0.3723381797994571 -0.04828163511992769 -0.2021711263110909
+0.3764661100207322 -0.04326195962319036 -0.3110841143459703
+-0.5149001436269404 0.1817831010578217 0.3883744154118514
+-0.4075790725065548 -0.07011207976826006 -0.5880659568874272
+-0.5303300891969429 -5.833858670062555e-08 0.5303300379042957
+0.3692070733341348 0.05887650239374177 0.3977133352200331
+-0.4079152010050289 -0.1850652088177073 -0.4973754617889673
+0.3329196737418877 0.1396696471672832 -0.5128027077454528
+-0.06310352592163579 -0.05063790301029709 0.5320612101990535
+-0.4016297809554171 0.07665157112216678 -0.5897760485424426
+-0.3792981735569309 0.2069810069713509 0.4866624706549424
+0.3021500544248019 -0.07243349234632183 -0.3680829388445839
+-0.3032017640904151 0.0466666413092313 -0.2590452631690672
+-0.2390805197549287 0.05934859095666144 -0.3203443511140383
+-0.3843687658895464 0.0597781261690172 -0.320510805268692
+-0.297150850631037 0.04789404968614406 -0.1751198455174624
+-0.491150875371558 -0.02431634563507673 -0.1034359022115692
+-0.3426425664506795 0.06567166007506782 -0.6329930304230099
+0.622054807140332 -0.06919338799472372 0.2517012930533061
+-0.1703098257617832 -0.1826550824458945 -0.6216246471829776
+-0.2174347219811193 0.01272135947138664 -0.245695297556412
+0.4439378877973604 0.06758027157215296 0.5646485581078916
+0.04763992432268208 -0.01224661208412182 0.5024657892071374
+-0.1708675632617437 -0.1854258582415338 0.6183160665788725
+-0.1716332338339093 -0.07729741666714569 0.6931634498852716
+0.4859623908309793 -0.1751256506962191 -0.1293025462109802
+-0.1895947160490057 0.135160565 0.6726003965825593
+0.5863066585133995 -0.05325755980125289 -0.2416842667002071
+-0.6726003999896268 0.135160565 0.1895947010490057
+0.1895946860490058 0.135160565 0.6726003904889689
+-0.6705388748474567 0.135160565 -0.1999589308460862
+0.6726004757712991 0.135160565 -0.1895945220490057
+-0.5959268895394246 -0.08763387546571111 -0.193621137504829
+0.2024962576489122 0.1321155658524761 -0.4660263074064109
+0.4354731070692088 0.1354985673547656 -0.1637449946554581
+-0.1637739673863473 0.08397379746190908 0.6927663054735529
+0.3265732257357251 -0.1509614322112238 0.2884515197475907
+0.2732793647740832 0.1546584917298763 0.3314554491719456
+0.3352013350452636 0.1560501476469682 0.2713065059666275
+0.1855214459446696 0.1402342518748386 0.377939225620567
+0.5952374280764472 0.05149610372169009 0.2848800021155177
+0.309976557537971 0.02941156572264442 -0.5861860739822928
+-0.5819583326726456 -0.05848943025699382 -0.2922827175629795
+0.4478022466495745 0.1487306241748066 -0.05278736440785489
+-0.06061965019220951 -0.1546782628110873 -0.4451638315554993
+-0.4739719375085265 0.1595241468053785 -0.07235625997418475
+-0.4389376217620313 -0.1571890255726863 0.05923078313502133
+0.03523894539594524 0.1322226216130693 -0.4287150964234601
+0.4406472348063602 -0.1457053958490441 0.05768599293734747
+-0.6888037686428277 -0.07036105566768017 -0.2037901556721537
+-0.06229448528435831 0.03133867538934622 -0.6561603563492422
+0.6623351609753214 -0.05696093651650429 -0.04555963134792926
+0.7142163401685105 -0.06509681597650166 -0.08380314178483944
+0.08210689966282012 0.05937132490740349 0.7162348457707524
+0.08333145252853005 -0.06595830440988804 -0.7140572377641591
+0.06608137356851983 0.1491054590402661 0.4009851807085034
+-0.3611274408840614 -0.1077702581600939 -0.06242896573356903
+0.3796094865805174 0.1486590723480749 0.3447589131660058
+0.04712138799494611 -0.09589795714366683 -0.6301910061738919
+0.0659446078747277 0.09224666523738477 0.621360874667907
+0.181154043491014 -0.08994650355324102 -0.6200918491966262
+0.5771762656224043 0.09484020020585483 0.1912421960319913
+0.0226914655921382 0.02659887758775728 0.6516329293572531
+0.3075185328989046 0.07299906362394958 -0.4985846099332604
+0.07577543452462263 -0.1433929495342712 -0.5746623127656189
+0.1596925585545952 -0.1348942439547208 -0.561311843514139
+0.4452187262509794 0.04287656012943429 0.1108911178589169
+-0.646405235051362 0.1812843605 -0.0536821029593403
+-0.2904552754354776 -0.04991148299524247 -0.2135005964108463
+-0.2027902505473725 0.04060653507155906 -0.5494798040191847
+0.312554733939242 -0.1507221313137781 -0.3192189438369041
+0.532405183857342 0.02947761865663639 -0.102715572874153
+0.5275086031262067 -0.1055867242650335 -0.1088883244036733
+-0.4264568237336529 0.03087572834513268 0.1118487827067294
+0.5386311781670815 -0.1739261713797737 0.3688656825855084
+0.318987690826632 0.08094470550083935 0.3082873048685877
+-0.5247960083693182 0.05760442579045268 0.2134851504654077
+0.6158593372512614 -0.1874400435104712 0.1715324352895766
+0.4315624334526753 -0.02798427575426788 -0.5103779956811643
+-0.4123433473060267 -0.04764382775535243 -0.5032775626162018
+0.7173603882156612 0.07561188915947202 -0.05247448317129177
+-0.2713328395803039 0.1161625451622493 0.5697169244581305
+-0.1741215833851504 -0.1867567049684828 0.4804577250082678
+0.6976598577362255 -0.06827042213568386 0.1623536943023283
+-0.04610012519939551 0.1448809950000666 0.5674450728739088
+-0.06820624315971494 0.1391422404993094 -0.5422448272563861
+0.04976206459513634 0.1459319893446545 0.5648956198046813
+-0.4405659160829608 -0.05935747034583092 -0.2987452142975358
+0.7101340715369242 0.06931532101520638 0.09809893503159287
+-0.5233272589156744 0.1371867973524671 -0.006070351955850449
+0.003411548988928413 0.1576623979034729 0.5143549750367112
+-0.007709896184820183 0.1617475887412644 -0.4979439886996553
+-0.5015913141449097 -0.148026251126252 -0.0007504796998853022
+0.3156046534344432 -0.02657801295699586 0.456855152278661
+-0.7146314176639721 -2.18556941e-08 -0.1778099321739148
+-0.714631391435433 -2.18556941e-08 0.1778099059453759
+-0.6889572874750536 -0.135160238 -0.1073642970980114
+-0.0800325114130878 -0.2144714877278948 -0.376277204125747
+-0.2045620552658866 -0.2184651849984501 -0.3362589268787387
+-0.6889570651027241 0.135160565 -0.1073642970980114
+-0.6889570579792537 0.135160565 0.1073642970980115
+0.07462547832493387 -0.2197393122455355 0.3888876602281924
+0.3226232787263165 -0.2162282417004459 0.2163220611664897
+-0.382677138 -0.2181964215 0.08886321938880395
+0.3260948967187077 0.2168535096272338 -0.2135434742241258
+-0.08047208479996108 0.2175162374763322 -0.3828568457923386
+-0.5709528055146412 -0.1788981212378028 -0.3103633892284121
+0.2294042978034777 0.2168584666811915 -0.3155098213988843
+-0.5989670613063136 -0.135160238 -0.3575461347945523
+0.38267687 0.2181962655 -0.0888628909245615
+0.091470285862678 0.217038063599734 -0.379622106314556
+-0.07140032689038553 0.2154323042171401 0.3800981761532723
+0.221030943918663 0.2171582416863385 0.3218790327721636
+-0.3857783053634699 0.2178326861474558 -0.06926851353584285
+-0.2269041027428502 0.2188124539906703 0.322227403264663
+-0.3317374084906508 0.2173518025519454 0.207025087688183
+-0.5835519514615468 -0.2268300252085159 0.105417351210259
+-0.3827407025570413 0.217881574844037 0.08507772784439768
+-0.5824973265862685 0.227408156 0.1073642970980115
+0.3812711629175531 -0.2165997755367423 0.0783551961348893
+-0.1521653160164021 -0.1287108372045364 -0.4187192410115158
+-0.4859042057485281 -0.227407992 -0.3388164423898491
+-0.4257266172768689 0.1457644899011558 -0.1483052091300335
+0.02270542428141074 -0.01774936420632196 0.3414903994776349
+-0.3716315400264734 0.1944972016295138 -0.508779491398935
+-0.3048382051472016 -0.1745592467809746 0.5805511771905953
+-0.3135551595490744 -0.1851134063945669 -0.5603592340360726
+-0.4356442171131527 -2.18556941e-08 -0.5935971483996163
+-0.07717212950074337 -0.1785652289067969 -0.6448708338027288
+-0.06507398806140052 -0.1761046441822036 0.6501169839026913
+0.6453716043734744 -0.1791687299460072 0.07115349393080496
+0.3897301333485112 0.1893134174198639 0.5037431591401457
+-0.6887090665053673 -0.07379341498840072 0.1991994430700723
+-0.5935971383366712 -2.18556941e-08 0.4356441969872622
+-0.6117749063923518 0.01644354433148199 -0.2978603801681667
+-0.387558001269515 -0.135160238 -0.5789137973090235
+-0.5789137969635547 -0.135160238 0.3875580010967806
+-0.3875580048364737 -0.135160238 0.5789138044429412
+-0.5789135088604425 0.135160565 -0.3875580605546097
+-0.3875580495343058 0.135160565 -0.5789134868198349
+0.5644643984827786 -0.06495018187921164 -0.4455770106383233
+-0.578913471633707 0.135160565 0.3875580419412419
+0.23709719603894 0.1014150416760966 0.2680955908015779
+0.04018451750921416 -0.1349437665400113 0.6245923834942313
+-0.6051502767477215 -0.1339196929326989 0.04824931533981232
+0.06106294228067399 0.1185684120684981 -0.6226282579399706
+-0.6062220019205854 0.1293499032270441 0.03599799757209045
+-0.6078126614727571 0.08914747057635643 -0.04573977024164903
+0.5754370663803664 0.1269034291391263 -0.2020234705263327
+-0.3709021398994805 -0.00134424386124089 -0.6363908604690129
+-0.1778099073798559 -2.18556941e-08 -0.7146313928699131
+-0.1778099039496093 -2.18556941e-08 0.7146313894396665
+0.4347152300153192 -0.03845077592829239 0.3242724391810436
+-0.3575457461164083 0.135160565 -0.598967070476627
+0.5212411926782172 -0.05775566056478709 0.01756777546771002
+0.5259509822148767 -0.03592485772890536 0.09957469724955148
+-0.1073642970980114 0.135160565 -0.6889570487660757
+-0.3575457351476239 0.135160565 0.5989670649922347
+-0.1073642970980114 0.135160565 0.6889570511651186
+-0.3462750200225362 -0.227407992 -0.4809205082873176
+-0.1073642970980114 -0.227407992 -0.5824976636260482
+-0.33153474006408 -0.227407992 0.4907696355829997
+-0.1073642970980114 -0.227407992 0.5824976644313991
+-0.1073642970980114 0.227408156 -0.5824973216541982
+-0.3318778745421381 0.227663389878087 0.4884459660073816
+-0.1073642970980114 0.227408156 0.5824973224595431
+-0.09142014233927777 -0.04957767833824132 -0.5334365820416362
+-0.1411060818092554 -0.05316603507842676 0.5382820154556561
+0.07839309595428723 -0.03606997118258356 0.5627924560811802
+0.2228311347285496 -0.04566485180113804 0.3316338944249109
+0.1778098936435355 -2.18556941e-08 0.7146313791335925
+0.1119377679059749 0.135160565 0.688047318674596
+0.1073642970980115 -0.227407992 0.5824976533568385
+0.1107310237709541 0.2263410543301188 0.5830591323502694
+0.1073642970980115 -0.135160238 -0.6889572750606456
+0.1778099085090079 -2.18556941e-08 -0.7146313939990649
+-0.2867197080342601 0.06935592017993335 0.2082907636499682
+-0.1040286901134598 0.04955933054357604 -0.428733056122008
+0.1087667398617572 0.05680384432486649 -0.5469337818933063
+0.3462749938603848 -0.227407992 -0.4809204952062419
+0.3575457135947208 0.135160565 0.5989670542157832
+0.3575461221925426 -0.135160238 -0.5989670550053088
+0.1812223911135857 -0.1736821308172768 -0.6298093261526846
+-0.6193708249721932 -0.181284115 0.1895947455490057
+0.1905191600437536 -0.1743820496510929 0.62715234095378
+-0.1895947310490057 0.1812843605 -0.6193705318270991
+-0.6237485270845429 0.1807169479230611 0.1708771116222541
+0.6193705496990755 0.1812843605 0.1895946860490058
+-0.6285656566370914 0.1761324746024394 -0.1732584543457864
+0.394701284275205 -0.1042605866668516 -0.4997370861425395
+0.4699929441616674 0.227408156 0.3626286470636558
+-0.5084742133742602 0.06489101169978406 0.3985956981616894
+0.5085238562446177 -0.09862272073648808 0.3981796479379747
+-0.252784993881451 0.08889640338330405 -0.2133526125177653
+-0.053682158699257 -0.2374316825 0.5234595132156995
+0.5789137897334826 -0.135160238 0.3875579974817446
+0.5789134714070765 0.135160565 -0.3875580418279266
+-0.5234595159721932 -0.2374316825 0.05368218361184548
+0.5789137748970357 -0.135160238 -0.387557990063521
+0.4119679658371732 0.171320395173378 -0.3619113785125
+0.5824973573981509 0.227408156 0.1073642970980115
+0.5824976994624926 -0.227407992 0.1073642970980115
+0.5989670542157832 0.135160565 0.3575457135947208
+-0.1851208683566414 0.124208603344928 -0.4239884656902839
+0.6889570984230848 0.135160565 0.1073642970980115
+0.173734377190098 -0.1592113573896186 0.4569211512536634
+-0.28606352997408 0.1545826835379782 -0.5211144100507749
+0.6889570315425984 0.135160565 -0.1073642970980114
+0.5456779809973004 -0.1215914160305011 0.2584213678038438
+-0.558393685464368 -0.1146177080545493 0.2834043871933823
+0.6190017582884673 -0.07274211245430767 -0.3599170327319804
+0.0411829889215951 -0.01367151147718778 0.4358118977414294
+-0.426429427626163 0.143843426080977 0.002542584081843323
+0.7146314120566302 -2.18556941e-08 0.1778099265665732
+0.7143730345430807 -0.00140176429054186 -0.1770398293756113
+0.3739725842088806 0.1215769468470212 -0.08292337630397037
+-0.05485930368709809 -0.1053031201782086 -0.3871347894732904
+-0.3714078393416314 -0.1180642596737125 0.05878671147875928
+0.3598360547299361 -0.1098711723824991 0.05711255573169563
+-0.2229579979104957 -0.01042827856541734 -0.3327072361197876
+-0.6422801729477911 -0.03894346107858589 -0.3425982442479343
+0.6608410879144642 -0.08766114178271175 0.05095820244838246
+0.1426328224684481 -0.01999499921288682 -0.6425278445708872
+0.1451338818735528 0.04608510717745574 0.6124456115996282
+0.01809742601197574 -0.1721964576789065 -0.4967334593128879
+-0.246127712574023 0.04135798095259782 0.5983282486609528
+-0.3138521513056136 -0.1556622707844267 -0.3161040462964457
+0.323493049226149 0.1290001483902456 -0.3253386948631966
+0.2728508941316176 0.07549347174791185 -0.2372820664953083
+0.5562842649028102 -0.0485295044900356 0.1953580131414835
+-0.3673911643395928 -0.09103973029133546 0.3705530982467184
+0.4355860589542803 -0.06553550803975287 -0.5709373490885763
+0.5632559126388801 -0.06387772482078147 0.4479415235371896
+-0.5623988653662189 -0.05767263513801224 0.4524406607131942
+-0.5561151775794455 0.06810076880820351 -0.4564393132378073
+0.5660902677743312 0.06010819246444307 -0.4456534833601336
+-0.2548913804596937 0.06258836563347484 -0.609930088042597
+0.6241570345002212 0.002226028570825955 0.2002465762605789
+-0.649776531707054 -0.0725164334290863 0.001715429544915426
+-0.004389374735116239 0.1180139820763546 0.6205176565062831
+-0.02316628772584089 0.1114646632479806 -0.6235726113015037
+-0.1543271382898399 -0.09275660230181169 -0.3310827964762754
+-0.6484132865773928 0.03340105755634293 -0.112249268939819
+0.08134865638375682 -0.0668181207163879 0.7141991738988013
+-0.08165379287038785 -0.05609759458137611 -0.7172863175211743
+-0.08318554957996099 -0.0696514590344952 0.7130018514806905
+-0.0739077083046028 0.05868607434484126 0.7180669935902767
+0.05266965457730004 -0.1751399486361745 0.6536976595518434
+0.05368213302461863 0.1812843605 0.6464052261462883
+-0.05328394604293371 0.1784463116146165 -0.6497597270761811
+-0.0536821640733928 0.1812843605 0.6464052317297715
+-0.6464055249721932 -0.181284115 0.05368220217617423
+0.6467232799244399 0.1809402739390439 0.05407987922160953
+0.234169056917011 0.05670640816227374 0.4156758517070452
+-0.5089134388924373 -0.1923102973818645 0.05068212359475061
+0.1676413756067232 -0.06781041643326767 0.531558722267077
+0.5865201611484786 0.1316140442522556 0.1131982866086703
+-0.04196278628353433 0.08189709568967014 -0.4641796369398359
+-0.2423508878776404 0.001876770083158745 0.1933769569910977
+0.2800534084650199 -0.001419473771088816 0.1515067266544594
+-0.1560211292574079 -0.0006481472840781907 0.2851380005602722
+0.7123616063516282 -0.08049241694007397 0.07040161526726069
+-0.6278805340950337 0.105766568169776 0.1909343800546901
+0.6415084338809066 0.0798150248930703 0.1822983339745222
+-0.193204923899704 -0.05572412844052755 0.6224482061031797
+-0.6304617438564843 -0.1035122462338923 0.198036709796241
+0.6156512441366255 -0.1032623802693025 0.1753596888902071
+0.6334392450885363 0.06696755323160408 -0.1838983985512123
+0.3782062441392018 -0.12204988584297 0.133183390216391
+-0.3828751918786762 -0.1285998340989022 0.1330862319117084
+0.5072024770378601 0.02634700497318234 0.4506209427980654
+-0.7191544659780258 -0.06197279360122413 -0.06358919318901379
+0.5728575186449349 0.07727439263062541 -0.2980850278327078
+-0.7044764983498082 0.06248231541307675 0.1366278139779501
+0.2566443629179671 -0.1170930898586065 -0.57977294954992
+-0.2765169719865896 0.01562580963005574 0.4859752387090623
+-0.1753814023370256 -0.124284950943586 0.367624994491605
+0.4898723741986995 -0.09038045200736297 0.1732492806675991
+0.3766615163973158 -0.123978037291708 -0.1575263032116939
+0.4881935107812874 -0.0085710500253026 0.1662459875931393
+-0.56444933379114 -0.002316203731541758 0.1710273760706686
+-0.5614368059721748 0.0973977351253799 0.1566922547789323
+-0.3759252044357331 0.0156099603600098 0.3811072818299944
+0.05383705383083659 0.2145299440226167 0.3816158270208281
+-0.1619732726120931 0.1330765460643622 0.3981378604129159
+0.3740296575279978 0.2111397287358895 0.05465499176783607
+0.382604670169172 0.2201042797991723 0.1102298907106016
+-0.05959478828599387 0.005930859013459864 -0.5663805162004295
+-0.01717673474360292 -0.03153853481555432 0.4675011682325878
+0.1364068407452007 -0.007277509535040018 0.4931110900239976
+0.385242784587982 0.00493529360549544 0.0469820988995634
+-0.6153711266794439 -0.1812035918895354 -0.2101699509978979
+-0.4726629202983678 -0.003327897542008701 0.3806000630414419
+-0.2761035454032154 0.007953612206295075 -0.3797424360944924
+-0.3888636207135883 -0.007938706908226399 0.04178998606509782
+-0.383278176165127 0.002973667381423688 -0.3690494541521624
+-0.3951191553982251 -0.008625205350272521 0.167258353233485
+-0.3778274958314471 0.097823632437333 0.06631071941621698
+-0.3790763659663187 0.1397429760054126 0.166309023532448
+-0.07173407266451474 -0.01249665451441885 -0.3804837643958644
+0.2877288837036373 0.09196999960831206 0.3768515569196144
+-0.2638412931493026 -0.1036766116893414 0.2391878653767805
+0.5991487400768469 -0.08920454298047388 0.02674751036901173
+0.607540993752861 0.1001621139512669 -0.03389076552791264
+0.5998837187108649 0.08338905575378201 0.04540625595553115
+-0.4743685905329021 0.09628227912602481 0.1566870273403166
+-0.4899423282037244 -0.08777947848176004 0.0496655557590468
+-0.4872238388481392 -0.008111734031781198 0.05133027066828713
+-0.2690792112134239 0.1005271315784323 0.2846467055547287
+-0.1622708114648139 0.01555625283271768 0.5870885011921256
+-0.1696039443719094 0.08373059661137741 0.606094424742615
+-0.4727827962661386 0.08448025899041636 0.06102069089748234
+-0.0605344123561698 0.008905324522109764 -0.4866242428196116
+-0.3815748147572086 0.001616454738300511 0.2542510822105668
+-0.3829317236935794 0.09050305714296698 0.249640564453501
+0.2616995180087382 -0.0944119383604532 0.2673071635684744
+0.2822514647509506 -0.005850493949298635 0.2691987114193257
+0.5935218637257337 0.002482111530269636 -0.3213259738383724
+-0.505464412258112 -0.1833568021761748 -0.3992898990550236
+-0.280967206550657 -0.1069018532045351 -0.2712158017948815
+-0.1161557276237301 0.1330592507396156 0.5699473656025384
+0.1369649530693391 0.1316506868926868 0.5592349600599259
+-0.1563140975 -0.12968538685 -0.247312054
+0.2471092834451507 -0.1351991643392156 -0.1628731266204674
+0.05673806489688069 -0.1305484283378361 -0.2874745836492385
+0.1628260980373148 -0.1376422746858275 -0.2489927473513118
+0.285898666730311 -0.1265875515597322 -0.05186365307744811
+-0.05510728922311799 -0.1288880401778301 -0.2867319091516609
+-0.05504061217906892 -0.1306847878369744 0.287899872612026
+0.05682477422099689 -0.1333662801572196 0.2892682689746576
+0.1581282015648371 -0.1267552300700679 0.2438786222378669
+-0.247312076 -0.12968538685 0.156314045
+0.2422066962597056 -0.1302997933916133 0.164651855644622
+-0.1563140525 -0.12968538685 0.247312076
+-0.1630249122458465 0.1419671064563262 -0.2521384231743916
+-0.289625310045959 -0.1340672575029545 -0.05729459453291589
+-0.2879229197619732 -0.1301596644734891 0.05322815267895153
+0.2896188458856734 0.1357133639383724 -0.06264541548807114
+-0.0627561069358414 0.1340128003260848 -0.2885039532850485
+-0.06003912720029972 0.1284922867886495 0.2854965770306342
+-0.2526884136545073 0.1362608592798777 0.1557278784104276
+-0.1651630450343733 0.1414745578076895 0.2503363810445914
+-0.247311957 0.1296850741 -0.156313896
+-0.2854066045 0.1296850741 -0.06434522086097889
+-0.2821769618407176 0.1225299473665231 0.05746447519469901
+0.2874402478974803 -0.131064917060987 0.05857953496711188
+0.2854065895 0.1296850741 0.064345362760046
+0.09956721556483739 0.008900787700942986 0.3040684694373372
+0.141227164390001 -0.03915237319037788 -0.4606711437015398
+0.7323157185262316 -2.18556941e-08 -0.08890473140017549
+-0.732315708831986 -2.18556941e-08 -0.08890490946352991
+0.08890493042999804 -2.18556941e-08 0.7323156895667963
+-0.08890494921809791 -2.18556941e-08 -0.7323156964349565
+0.08890495872633397 -2.18556941e-08 -0.7323156969995325
+-0.08890496836657437 -2.18556941e-08 0.7323156947198333
+-0.7323156957177165 -2.18556941e-08 0.08890500959611544
+0.7323157060283151 -2.18556941e-08 0.08890520766431409
+0.08886322676908474 -0.247455373 -0.446745351
+-0.08886321373091526 -0.247455373 -0.446745366
+-0.253061019 -0.247455373 -0.378732383
+0.4467454255 -0.247455373 -0.088862923672303
+0.378732547 -0.247455373 -0.2530607585
+0.2530610265 -0.247455373 -0.3787323535
+-0.08886321165025131 -0.247455373 0.446745366
+0.08886316884974869 -0.247455373 0.446745366
+0.253060922 -0.247455373 0.378732428
+0.378732428 -0.247455373 0.2530609295
+-0.3787325175 -0.247455373 -0.253060825
+-0.378732428 -0.247455373 0.253060937
+-0.446745366 -0.247455373 0.08886322906283976
+-0.446745396 -0.247455373 -0.08886309193716024
+0.0888631522690823 0.247455314 -0.4467449785
+-0.08886313923091771 0.247455314 -0.446744993
+-0.2530608105 0.247455314 -0.37873207
+0.446745053 0.247455314 -0.08886284917243099
+0.2610196563250436 0.247455314 -0.3734141119799477
+0.3787322345 0.247455314 -0.2530605495
+-0.0888631371502424 0.247455314 0.446744993
+0.0888630943497576 0.247455314 0.446744993
+0.2530607135 0.247455314 0.378732115
+0.378732115 0.247455314 0.253060721
+-0.446745023 0.247455314 -0.08886302493719224
+-0.378732115 0.247455314 0.2530607285
+-0.446744993 0.247455314 0.08886315456280776
+-0.3787322045 0.247455314 -0.253060624
+-0.253060736 0.247455314 0.378732115
+0.446745366 -0.247455373 0.08886333782769699
+0.446744993 0.247455314 0.088863263327569
+0.6200791714077696 0.03064473749778887 -0.2440277489762376
+-0.2626299684804731 -0.01779926795500601 -0.599686805331662
+-0.6123164101680636 -0.04121299126851069 0.2479495684496193
+-0.6378744981290908 -0.08641631458216771 -0.3245838369211331
+0.3222791452973603 0.06758027157215296 0.6459383261078916
+-0.6432533681683356 -2.18556941e-08 0.3613284019936311
+-0.2395605239587259 0.1861935899383363 -0.4408444524343927
+-0.01815759320534445 -0.1340331295755921 -0.618553481301664
+-0.416173620953785 0.1334507751933589 0.4501201060061978
+-0.4299310368060829 -0.1311833513982786 0.4365280856573984
+0.4154314094009814 -0.1274728968155736 0.4504484112711975
+0.3741153953545832 -0.1242355469020759 -0.0241854340486779
+-0.5578965797509108 0.07758988814764095 0.4488543656622259
+0.066887528377056 0.1134054046445166 -0.3500728402253111
+-0.05292311315347678 0.1260431071072435 0.3580833601168914
+0.3551564114844889 0.1039168763322923 0.03884608765805646
+0.2530163933438245 0.1514527965299385 0.5046020668611034
+0.2170199306452358 0.07035957400422863 -0.6861725016313338
+-0.6886531840337877 0.06831837761274545 0.2075619354184494
+0.2146550888955935 0.06925477135835592 0.6869673050358971
+0.6856670468292471 0.07175132639315042 0.2175067344931936
+-0.6855026363122276 0.06738785333983141 -0.224774707991908
+0.210947856979893 -0.08000473670797401 -0.6845483310126054
+0.6855619969327065 0.07218350698739592 -0.2173972238496296
+0.6854377980262316 -0.06758012992784704 -0.224817394281203
+0.2474381341489587 0.1061938412000234 0.5766180351873803
+0.489503016304909 -0.1785221406910227 0.263169924743284
+0.3037402902914204 -0.1480370568980555 -0.5174410365166965
+-0.4864719094610887 0.1752779821252042 0.2794938371976077
+0.4313217303001755 0.135160565 0.5496715059782117
+-0.5506173006531567 -0.135160238 -0.4299067178972762
+0.1092678841352424 -0.08993497320759923 -0.6208877979904343
+0.3315483361717592 -0.1186488286544302 -0.101273559173753
+-0.05332356464008531 -0.003220860878376586 -0.2495200389000687
+-0.04525869337901792 -0.0002733267622190005 0.2511242429814381
+0.1406911262572085 0.00458300473952665 0.2128336142806865
+-0.212131627 -1.862499999991107e-07 -0.141741749
+0.2502262665 -1.862499999991107e-07 0.049773196710046
+-0.3038750919021984 -0.00420447504443615 0.04991694629414084
+0.3060295077376545 0.01098691065300924 0.05504694712444477
+0.1170500682120619 0.1810802133846133 0.4998806125319112
+0.4856608853215326 0.07434546177884246 -0.4322363107862517
+-0.458826067180756 -0.1539076895358543 -0.2411783655387011
+0.2414409659261295 -0.1395981122085382 -0.4286050346936315
+0.4102733319937368 -0.03911917457333562 0.5089220698446709
+0.6436677085590493 0.05276964120720886 -0.3333546024610379
+-0.6328982967916651 0.06338561222163799 -0.3439693233029654
+0.6393865205766276 -0.06783917936103923 0.3319505522899195
+-0.6254841434299707 -0.07086294435058846 0.3511895693749568
+-0.3416269174305976 -0.06356443637116133 -0.6344016122869763
+0.3434770270001724 -0.06692247982426226 -0.6320022943216725
+-0.3433089855389704 0.06847439970572868 0.631576980383792
+0.01187510501014911 0.09071444418817076 0.3552258624282731
+-0.09777969011320647 0.1858866393441107 0.4930423179985466
+-0.09000200204206606 0.1904619032906356 -0.4874776471335208
+-0.1425452905490057 0.237431735 -0.5057831668270991
+-0.1960150597271896 0.1899289804033522 0.3766604375387921
+0.6036653880207526 -0.1001926936403398 -0.1444334652759952
+-0.5402624007491028 0.1237898832495177 0.2844891380745601
+-0.05006475582362858 -0.01280714490476897 0.3921732275300897
+0.1790506689861273 0.09320743189656971 -0.5309763578678544
+0.6040451972022797 -0.01620572259224715 0.2810845165686729
+0.1895947905490057 -0.135160238 -0.6726005975303229
+0.6726004202115424 0.135160565 0.1895946860490058
+-0.6726006637375268 -0.135160238 -0.1895946565490057
+-0.02211429515907533 0.1594037691029022 0.4252731110919391
+-0.2178001310488206 -0.2187878848473082 0.3282470318331274
+-0.5592332994570895 0.1902521000391926 -0.3047708475982757
+-0.5620171585001306 0.1836874142745606 0.3139790672500916
+0.5719226547333054 -0.184839971894952 0.2968062977771854
+-0.6502893879669944 -0.1778044424086221 -0.05434518036839411
+0.05368215214944767 -0.181284115 -0.6464055185303228
+-0.2158743658231015 0.09526841972257911 -0.2647745309902759
+-0.2114200026182485 0.1010409781318316 0.2608651734868205
+-0.1982647250058633 -0.09896759786522454 0.2555716819455021
+-0.3129920331155432 0.1084669587386941 0.1627058173366869
+-0.1551685730867522 0.1080878068838509 0.3164997837178271
+0.3107971034315091 -0.09707599796195117 -0.154823053830057
+-0.1583120171750342 -0.1054586665971662 0.303083453438425
+0.1842856487044458 0.1328246243631194 0.3071171654625506
+0.3405021210770199 0.1414651450899855 0.1906460150110045
+0.1222497898060191 -0.01459653842951159 0.6716419314541555
+0.6187727551000032 -0.1822425903685795 -0.1870407695448417
+-0.5140658381072688 -0.1017583303142997 -0.1591315148082528
+0.1506872594387387 0.107011086778144 -0.5785905499054989
+-0.4543830012629956 0.02070776700615354 -0.3534233502059753
+0.05208701996476486 0.2369451377659843 0.5271608231354115
+-0.05035418058057255 0.236541723503403 -0.5303113484986198
+-0.0536821586992481 0.237431735 0.5234591482297716
+0.652264938 -2.18556941e-08 -0.347841635
+-0.65226484875 -2.18556941e-08 -0.34784178425
+0.34784194825 -2.18556941e-08 0.652264714
+0.570974946 -2.18556941e-08 0.46950069075
+0.05288088412692972 -0.1696738401445088 0.4812655001975786
+-0.03458365933052948 -0.1696053900123612 0.4469547003571025
+0.5253901567920133 0.01334285814744612 -0.2715949297219139
+0.5008552018403365 0.0008968449184086402 -0.4476622468363466
+-0.4679785893234675 -0.1720388775723341 0.1441529655658877
+0.4608469644229725 -0.1715736804020539 0.1526932380534281
+0.4712710999359984 0.1910190031111572 -0.1336326997259548
+-0.4922261458666373 -0.1795631286234275 -0.1535029704981328
+-0.04003071875929925 -0.01735235223485209 0.6844048178359888
+0.05786895306571511 0.04951594845714467 -0.7239498885560181
+0.2127057635028024 -0.0833398813849658 -0.2538144673578778
+-0.5133981546337892 0.03912537763871422 0.4644387356716861
+0.3773758525022843 -0.1145068351912803 -0.2694092044220085
+0.1576327673835248 -0.00174623569951705 0.3567090232373112
+0.06760794136056919 -0.03105061583133411 -0.4613535665477629
+-0.7234264959800163 -0.05601355432624411 0.0509091710031585
+0.3307809421322569 -0.06714567745126444 0.6404082325370969
+-0.2708684508911888 -0.1157463251588329 0.3750957971723319
+-0.2789744190406261 0.03582508947728972 0.3637404139816443
+0.4699139694816132 0.01791589074177289 0.04241381727681382
+-0.1542487939470152 0.03758487944378665 0.3777753383082115
+0.370206414436605 -0.02919216874927832 0.1646086345337974
+-0.3843560426382542 -0.01459984482335379 -0.05331358427969477
+-0.3756036815077443 0.0655473812595731 0.1739739322222879
+0.3624013269252122 -0.0545436899147785 0.2752232163131648
+-0.4804420812630442 -0.05407407237313248 0.1595268585124839
+-0.1649969073003941 0.07391696382954899 -0.4781800483207995
+0.172943408404652 0.03270492546648051 -0.4770234506938139
+-0.5131791762068501 0.2357481102122256 -0.1642331900472321
+0.4967968321015735 0.01720857935661327 0.2988126091935098
+-0.3058843387849141 -0.09545112865391527 0.1671091894972072
+-0.6105761183708176 -0.01727895628303047 -0.05109497939867216
+-0.1020149918114597 0.1002042812521527 -0.4793742608257536
+0.34784208225 -2.18556941e-08 -0.6522646692499999
+
+CELLS 4436 22180
+4 416 356 836 690
+4 0 759 1017 1
+4 0 1 792 759
+4 0 1017 187 876
+4 899 180 560 106
+4 1 665 759 494
+4 667 314 610 668
+4 543 176 732 810
+4 145 370 320 156
+4 10 314 667 588
+4 2 187 668 667
+4 3 563 570 5
+4 812 200 199 553
+4 136 419 424 853
+4 414 573 870 572
+4 193 585 486 379
+4 314 511 10 374
+4 204 477 209 828
+4 492 803 250 1020
+4 6 12 202 730
+4 473 210 597 967
+4 312 296 479 272
+4 6 202 704 786
+4 6 911 202 786
+4 6 202 911 730
+4 22 216 951 1009
+4 10 214 610 21
+4 418 986 799 521
+4 774 400 405 356
+4 808 468 357 833
+4 11 22 951 1009
+4 1025 232 819 818
+4 228 826 819 1025
+4 207 994 608 353
+4 499 146 436 919
+4 953 155 303 919
+4 84 974 632 923
+4 328 1030 643 24
+4 554 212 179 115
+4 735 932 171 909
+4 15 18 755 225
+4 15 18 225 421
+4 525 17 224 352
+4 712 206 210 813
+4 525 224 230 352
+4 352 257 264 796
+4 561 166 929 784
+4 295 392 698 724
+4 617 979 184 1
+4 1027 222 594 817
+4 17 224 401 754
+4 17 352 918 224
+4 483 352 388 796
+4 18 28 225 520
+4 697 829 261 492
+4 1033 668 208 181
+4 752 420 599 266
+4 966 293 991 933
+4 548 991 459 169
+4 19 917 230 712
+4 63 697 395 982
+4 19 917 458 230
+4 478 332 252 426
+4 258 821 558 435
+4 623 557 446 419
+4 21 904 214 232
+4 21 374 610 10
+4 21 733 214 610
+4 21 610 566 733
+4 21 214 733 232
+4 240 589 608 355
+4 23 37 624 219
+4 23 219 1006 12
+4 226 484 536 355
+4 231 34 260 238
+4 25 903 233 636
+4 25 819 232 39
+4 25 636 819 39
+4 826 232 233 819
+4 27 33 220 244
+4 28 371 231 225
+4 28 231 238 34
+4 30 577 856 36
+4 30 857 738 37
+4 30 46 856 577
+4 30 46 577 437
+4 30 46 437 857
+4 30 857 437 738
+4 31 865 253 47
+4 920 445 423 449
+4 127 423 449 920
+4 178 550 744 128
+4 178 694 842 692
+4 178 842 744 692
+4 33 243 889 220
+4 272 115 390 179
+4 33 243 244 1019
+4 179 969 993 312
+4 272 312 179 993
+4 35 262 261 55
+4 723 351 269 182
+4 35 308 262 55
+4 1001 791 158 182
+4 35 262 308 906
+4 953 183 268 303
+4 36 22 344 216
+4 657 401 206 754
+4 37 248 49 857
+4 37 248 1032 49
+4 499 919 303 146
+4 37 790 219 242
+4 37 790 242 1032
+4 303 499 190 415
+4 38 905 643 24
+4 499 116 190 415
+4 728 191 669 503
+4 503 191 669 161
+4 39 818 254 819
+4 40 324 910 42
+4 40 44 538 757
+4 41 43 264 785
+4 41 556 785 746
+4 42 281 647 56
+4 42 245 281 910
+4 42 324 910 281
+4 44 251 757 279
+4 45 310 602 59
+4 46 947 49 47
+4 46 47 253 947
+4 47 49 51 947
+4 47 254 253 947
+4 50 62 945 536
+4 51 697 779 63
+4 68 315 762 72
+4 68 315 641 762
+4 52 480 589 60
+4 72 942 177 74
+4 52 32 888 747
+4 53 61 822 983
+4 53 242 243 822
+4 119 135 427 333
+4 119 333 427 749
+4 584 271 562 403
+4 55 829 697 982
+4 55 829 262 261
+4 558 405 596 821
+4 558 578 138 435
+4 56 281 647 241
+4 57 65 285 603
+4 58 66 330 513
+4 59 310 309 67
+4 59 686 310 67
+4 60 541 945 62
+4 61 781 75 63
+4 61 63 779 781
+4 61 289 983 73
+4 288 132 1000 913
+4 62 541 74 60
+4 62 74 541 981
+4 114 694 949 842
+4 554 212 584 179
+4 179 584 403 271
+4 528 584 271 302
+4 63 297 781 75
+4 63 982 297 75
+4 179 212 584 528
+4 63 395 697 779
+4 55 982 697 63
+4 554 584 403 179
+4 313 511 314 566
+4 314 313 668 620
+4 313 511 620 314
+4 314 313 610 668
+4 566 313 610 314
+4 184 1033 181 763
+4 65 69 975 797
+4 187 763 668 1033
+4 65 69 797 321
+4 537 227 313 208
+4 354 207 307 467
+4 65 884 321 603
+4 960 257 264 270
+4 66 342 963 893
+4 960 264 257 746
+4 960 746 602 45
+4 67 805 965 71
+4 67 343 805 71
+4 67 962 343 898
+4 68 72 848 315
+4 68 64 334 641
+4 69 326 849 73
+4 69 73 987 326
+4 69 284 797 987
+4 404 726 116 415
+4 70 342 306 66
+4 70 342 489 306
+4 404 726 415 416
+4 732 176 644 491
+4 71 75 860 335
+4 71 335 985 75
+4 375 176 644 732
+4 71 923 860 84
+4 360 453 491 644
+4 71 308 985 805
+4 72 177 541 74
+4 72 87 848 438
+4 73 75 781 943
+4 73 849 85 326
+4 73 85 943 326
+4 73 326 289 987
+4 74 358 859 88
+4 74 541 489 177
+4 85 644 375 850
+4 850 198 644 375
+4 75 335 943 86
+4 75 335 985 297
+4 75 297 781 335
+4 76 77 1010 380
+4 76 77 380 277
+4 76 583 767 78
+4 76 1010 767 583
+4 6 347 730 657
+4 77 79 650 664
+4 77 650 329 380
+4 78 760 771 80
+4 78 769 760 80
+4 78 769 580 760
+4 81 83 884 1003
+4 81 83 1003 622
+4 82 995 949 899
+4 82 376 974 611
+4 82 611 974 377
+4 83 375 850 85
+4 83 85 849 375
+4 83 375 849 321
+4 84 86 364 961
+4 84 961 923 86
+4 207 231 328 189
+4 85 86 943 644
+4 86 453 644 868
+4 86 644 335 943
+4 86 335 644 961
+4 87 89 438 845
+4 88 90 363 922
+4 88 922 358 90
+4 88 100 101 387
+4 89 91 565 745
+4 359 528 271 302
+4 359 212 179 528
+4 302 130 271 359
+4 359 212 528 507
+4 302 320 156 362
+4 507 528 302 362
+4 528 320 302 362
+4 176 375 316 1002
+4 316 176 198 375
+4 88 363 100 922
+4 100 363 103 922
+4 112 119 482 103
+4 749 119 482 112
+4 364 86 98 453
+4 364 98 102 453
+4 145 720 320 370
+4 94 666 761 96
+4 365 118 989 134
+4 366 110 118 663
+4 954 171 909 838
+4 95 97 765 381
+4 95 97 381 431
+4 838 909 548 171
+4 102 366 118 988
+4 988 366 118 663
+4 95 324 916 381
+4 869 379 386 1029
+4 506 367 220 657
+4 869 252 1029 386
+4 368 157 292 719
+4 96 311 571 97
+4 368 292 443 719
+4 497 719 368 443
+4 737 490 468 325
+4 18 659 225 369
+4 96 761 311 666
+4 194 479 666 311
+4 950 717 156 370
+4 86 453 868 98
+4 98 405 944 110
+4 129 303 190 415
+4 99 345 111 944
+4 452 155 158 953
+4 100 332 113 101
+4 884 603 65 373
+4 100 101 387 332
+4 683 373 322 884
+4 101 113 1012 332
+4 566 902 374 21
+4 511 902 374 566
+4 98 348 868 99
+4 98 868 348 405
+4 102 576 560 899
+4 178 744 934 128
+4 178 842 934 744
+4 27 220 918 244
+4 105 109 515 952
+4 751 220 243 244
+4 105 319 101 235
+4 107 212 554 115
+4 107 103 339 628
+4 711 382 578 432
+4 711 259 382 432
+4 723 351 382 259
+4 382 282 351 723
+4 110 780 345 111
+4 110 780 111 122
+4 161 555 149 211
+4 110 837 405 345
+4 110 405 837 430
+4 111 836 851 120
+4 111 425 853 124
+4 107 339 554 212
+4 339 410 212 107
+4 112 113 332 346
+4 100 112 482 103
+4 302 320 350 156
+4 362 320 156 145
+4 1012 323 332 346
+4 113 1012 332 346
+4 113 112 123 346
+4 969 179 390 554
+4 213 529 327 322
+4 809 176 732 543
+4 1016 869 379 386
+4 278 691 744 990
+4 278 744 689 277
+4 278 990 744 277
+4 992 200 216 537
+4 166 723 561 391
+4 391 723 561 269
+4 200 537 221 216
+4 568 517 390 892
+4 517 568 631 892
+4 118 558 559 138
+4 119 482 103 628
+4 959 133 434 562
+4 959 562 434 420
+4 122 124 946 780
+4 122 126 867 429
+4 122 429 948 126
+4 436 452 614 919
+4 919 452 614 953
+4 123 428 858 126
+4 46 47 50 253
+4 124 424 127 946
+4 124 424 866 127
+4 124 136 866 424
+4 424 789 425 419
+4 125 127 847 423
+4 125 941 847 137
+4 125 137 986 941
+4 126 924 142 867
+4 126 428 858 142
+4 126 924 428 142
+4 126 948 428 429
+4 206 754 401 813
+4 754 224 401 813
+4 129 1018 278 132
+4 276 218 642 839
+4 614 953 452 349
+4 129 415 116 705
+4 129 303 415 1018
+4 839 26 218 642
+4 130 562 312 133
+4 452 953 158 349
+4 131 133 434 959
+4 547 679 831 841
+4 134 341 989 429
+4 134 989 341 148
+4 547 679 841 686
+4 135 142 858 736
+4 15 421 225 600
+4 135 119 625 333
+4 136 150 1007 446
+4 524 600 648 422
+4 648 600 15 422
+4 458 917 257 230
+4 136 789 424 419
+4 136 446 789 419
+4 678 458 263 257
+4 263 917 257 458
+4 137 151 882 799
+4 137 151 799 445
+4 137 986 941 799
+4 793 1004 463 236
+4 237 293 572 173
+4 141 147 417 443
+4 141 417 591 443
+4 731 548 459 169
+4 142 736 428 858
+4 142 455 924 428
+4 142 428 736 455
+4 719 731 459 169
+4 143 153 445 920
+4 156 320 350 950
+4 144 154 652 282
+4 144 578 435 138
+4 144 578 282 435
+4 231 484 535 238
+4 231 535 371 238
+4 966 459 593 393
+4 433 593 966 459
+4 85 644 850 99
+4 99 198 644 850
+4 40 442 413 671
+4 184 553 354 181
+4 239 207 354 467
+4 677 671 413 442
+4 448 132 278 691
+4 150 162 1007 935
+4 448 691 278 300
+4 150 935 1007 446
+4 151 546 445 881
+4 207 189 467 239
+4 240 355 484 226
+4 152 721 512 164
+4 61 779 63 51
+4 153 445 920 460
+4 155 753 452 158
+4 155 919 452 713
+4 156 950 350 159
+4 159 292 599 157
+4 159 599 292 1005
+4 280 396 403 1029
+4 113 123 125 346
+4 1029 396 403 478
+4 123 428 126 125
+4 52 255 589 840
+4 22 216 36 951
+4 255 52 48 36
+4 125 126 127 428
+4 36 216 255 951
+4 164 773 824 172
+4 165 173 237 651
+4 106 258 180 560
+4 774 821 405 560
+4 170 561 929 758
+4 140 416 404 436
+4 404 146 140 436
+4 166 582 561 259
+4 112 482 749 332
+4 735 414 788 909
+4 351 1031 456 259
+4 167 788 669 909
+4 878 515 193 319
+4 168 170 539 956
+4 878 319 193 89
+4 302 130 562 271
+4 508 701 469 652
+4 235 121 591 323
+4 701 349 469 652
+4 925 701 469 508
+4 105 235 121 883
+4 170 539 970 758
+4 621 876 2 188
+4 876 188 187 2
+4 354 763 930 615
+4 172 825 773 824
+4 538 44 251 757
+4 538 670 910 251
+4 173 237 651 823
+4 173 823 572 237
+4 170 561 970 269
+4 170 956 269 970
+4 270 458 960 257
+4 185 204 203 477
+4 187 477 203 208
+4 203 828 208 477
+4 296 272 96 666
+4 207 307 467 328
+4 154 791 282 182
+4 282 791 452 351
+4 349 282 791 452
+4 349 154 791 282
+4 28 231 371 238
+4 330 915 724 66
+4 330 915 66 58
+4 28 520 504 273
+4 77 650 380 664
+4 274 213 322 529
+4 933 991 548 169
+4 275 357 606 331
+4 966 991 548 933
+4 677 770 761 96
+4 939 283 839 16
+4 277 77 380 664
+4 378 300 278 277
+4 56 64 281 241
+4 241 334 64 281
+4 129 415 705 278
+4 281 318 641 64
+4 129 278 705 300
+4 58 66 513 964
+4 44 279 413 706
+4 279 606 331 275
+4 44 279 706 58
+4 795 131 581 434
+4 737 325 820 490
+4 869 386 1016 319
+4 722 150 162 1007
+4 282 578 526 435
+4 907 150 722 1007
+4 880 241 334 64
+4 64 680 880 241
+4 129 415 278 1018
+4 288 132 1018 1000
+4 288 1018 217 1000
+4 217 1018 268 1000
+4 573 173 572 293
+4 104 108 886 726
+4 649 294 324 95
+4 926 312 130 296
+4 681 879 318 64
+4 148 514 721 160
+4 148 721 514 908
+4 650 77 329 301
+4 639 904 518 214
+4 639 215 518 14
+4 639 214 518 215
+4 519 114 694 949
+4 899 694 949 519
+4 304 704 786 6
+4 651 305 173 742
+4 173 782 742 305
+4 184 181 354 763
+4 537 467 313 226
+4 467 313 226 643
+4 307 551 7 930
+4 314 511 374 566
+4 21 566 610 374
+4 311 357 379 699
+4 566 314 610 374
+4 479 311 379 699
+4 97 431 1011 311
+4 163 719 497 459
+4 743 479 379 312
+4 312 562 434 133
+4 312 403 699 379
+4 163 719 459 169
+4 312 479 379 699
+4 696 133 312 434
+4 459 719 497 443
+4 427 555 454 439
+4 736 427 555 454
+4 181 313 668 208
+4 763 307 620 313
+4 610 313 208 668
+4 315 942 177 72
+4 315 820 325 177
+4 315 72 848 438
+4 848 89 737 438
+4 596 578 526 456
+4 596 821 526 578
+4 478 426 252 396
+4 396 426 252 532
+4 179 528 584 271
+4 359 528 179 271
+4 359 528 302 507
+4 528 320 584 302
+4 353 196 276 563
+4 563 276 353 608
+4 682 317 27 658
+4 27 682 244 317
+4 319 869 386 252
+4 145 720 212 320
+4 720 236 748 320
+4 701 217 469 349
+4 701 934 925 217
+4 925 217 175 186
+4 925 934 175 217
+4 469 217 186 349
+4 346 121 1012 323
+4 113 121 1012 346
+4 123 427 428 125
+4 125 428 127 423
+4 13 976 510 328
+4 58 330 727 279
+4 320 950 236 197
+4 252 386 387 478
+4 72 177 480 541
+4 541 246 534 740
+4 139 720 212 145
+4 68 334 481 762
+4 32 241 747 334
+4 241 246 334 475
+4 52 334 481 68
+4 334 32 52 747
+4 339 103 482 628
+4 564 340 512 152
+4 340 429 811 587
+4 148 807 341 134
+4 989 441 430 429
+4 341 587 429 340
+4 148 908 514 341
+4 809 543 360 361
+4 361 689 543 389
+4 361 543 360 389
+4 213 689 543 361
+4 213 543 809 361
+4 200 216 221 344
+4 677 442 413 44
+4 677 44 413 706
+4 679 556 547 831
+4 621 927 783 549
+4 549 707 783 621
+4 178 692 744 550
+4 30 344 577 36
+4 692 744 550 928
+4 307 620 551 930
+4 82 377 974 576
+4 551 307 709 620
+4 360 389 453 377
+4 185 204 477 188
+4 185 801 204 188
+4 82 576 974 84
+4 552 932 728 788
+4 185 201 203 204
+4 728 552 669 191
+4 728 788 669 552
+4 5 973 812 553
+4 98 99 944 348
+4 98 405 348 944
+4 99 851 111 345
+4 345 836 851 111
+4 345 836 690 397
+4 184 200 553 181
+4 187 188 477 208
+4 112 123 346 749
+4 1033 763 668 181
+4 346 125 986 423
+4 203 828 477 204
+4 188 209 801 204
+4 188 208 209 477
+4 188 801 209 473
+4 137 418 986 799
+4 188 214 802 209
+4 188 209 208 214
+4 365 118 663 989
+4 348 851 198 99
+4 348 99 345 851
+4 348 690 397 345
+4 288 400 175 614
+4 415 400 776 288
+4 415 614 400 288
+4 288 776 810 400
+4 288 175 400 810
+4 212 720 748 320
+4 139 720 748 212
+4 349 953 158 542
+4 938 349 652 154
+4 542 154 158 349
+4 777 708 514 582
+4 584 396 420 350
+4 777 721 514 708
+4 350 562 420 584
+4 791 158 452 753
+4 1001 753 158 791
+4 270 352 257 264
+4 353 196 563 207
+4 5 553 199 563
+4 41 264 658 270
+4 41 960 264 270
+4 7 655 930 3
+4 850 316 198 375
+4 104 316 198 850
+4 40 44 757 413
+4 201 203 204 827
+4 201 222 827 204
+4 202 219 1027 205
+4 279 275 590 413
+4 188 209 204 477
+4 203 200 537 221
+4 204 1027 801 205
+4 477 208 209 828
+4 204 222 828 209
+4 205 801 597 372
+4 205 219 1027 476
+4 206 813 223 210
+4 206 220 223 401
+4 200 992 181 537
+4 209 208 214 832
+4 209 222 828 594
+4 8 215 967 473
+4 210 228 223 372
+4 210 229 813 223
+4 210 223 228 229
+4 210 813 229 712
+4 210 234 712 229
+4 92 390 612 94
+4 92 390 568 612
+4 92 568 390 892
+4 92 501 390 94
+4 501 390 892 92
+4 328 313 1030 13
+4 207 231 994 225
+4 826 215 228 233
+4 353 15 196 267
+4 353 15 939 196
+4 608 246 189 355
+4 189 231 484 535
+4 355 589 246 533
+4 22 216 1009 344
+4 175 400 774 614
+4 821 435 526 578
+4 186 526 821 435
+4 506 27 889 220
+4 218 888 32 747
+4 500 447 140 146
+4 407 447 140 500
+4 115 390 107 501
+4 501 390 107 892
+4 221 815 828 222
+4 221 226 227 1024
+4 221 815 1024 227
+4 895 152 466 503
+4 503 152 466 164
+4 223 243 476 834
+4 223 250 803 224
+4 223 224 751 250
+4 223 250 834 229
+4 224 813 230 803
+4 224 483 803 230
+4 224 244 751 483
+4 161 211 409 502
+4 643 328 24 905
+4 226 247 355 536
+4 508 144 435 411
+4 226 247 488 1024
+4 228 826 233 819
+4 228 817 594 1025
+4 228 229 834 835
+4 826 1025 594 232
+4 228 835 819 233
+4 228 1025 834 817
+4 534 306 238 260
+4 238 306 34 260
+4 279 413 590 757
+4 229 492 250 834
+4 230 256 483 803
+4 728 503 466 164
+4 230 917 257 256
+4 728 466 824 164
+4 728 824 172 164
+4 2 668 620 588
+4 588 314 668 620
+4 314 511 620 588
+4 444 459 384 546
+4 546 593 459 384
+4 364 86 453 961
+4 364 453 102 576
+4 32 241 334 880
+4 242 822 249 243
+4 243 1019 751 244
+4 244 285 388 682
+4 249 395 492 250
+4 249 289 243 822
+4 886 726 404 416
+4 726 397 416 886
+4 28 520 371 225
+4 28 371 520 273
+4 371 493 251 273
+4 493 246 475 814
+4 238 273 34 306
+4 256 492 262 1020
+4 256 796 1020 298
+4 251 475 287 295
+4 287 251 295 590
+4 287 590 910 251
+4 245 287 251 475
+4 910 287 251 245
+4 273 34 306 894
+4 205 801 372 1027
+4 205 476 1027 372
+4 209 1027 594 372
+4 378 278 689 277
+4 601 824 472 487
+4 870 728 472 601
+4 728 601 824 472
+4 870 472 487 601
+4 809 968 327 360
+4 82 376 962 974
+4 337 343 841 376
+4 337 361 376 605
+4 389 377 842 180
+4 82 995 377 949
+4 361 389 377 607
+4 870 487 174 601
+4 96 97 571 873
+4 96 873 571 677
+4 0 876 187 2
+4 284 289 797 987
+4 286 688 290 291
+4 602 310 309 59
+4 602 309 257 678
+4 602 310 299 309
+4 602 299 257 309
+4 57 603 285 286
+4 57 603 286 322
+4 475 457 814 246
+4 603 285 286 322
+4 287 325 1028 295
+4 287 687 325 318
+4 246 814 534 740
+4 257 309 299 796
+4 290 297 298 1022
+4 290 327 1022 336
+4 257 299 746 796
+4 291 337 290 299
+4 291 830 337 299
+4 722 153 460 165
+4 153 461 460 569
+4 907 153 569 461
+4 153 907 722 461
+4 724 342 66 306
+4 724 306 392 342
+4 724 330 66 513
+4 724 342 513 66
+4 295 325 1028 698
+4 306 342 489 392
+4 76 380 1010 583
+4 297 1022 308 298
+4 298 308 309 805
+4 299 336 337 290
+4 76 380 583 277
+4 329 274 322 529
+4 380 274 361 689
+4 381 97 765 571
+4 381 97 311 431
+4 324 486 687 318
+4 66 963 342 513
+4 656 281 245 241
+4 236 426 522 439
+4 439 384 383 1004
+4 384 393 593 459
+4 445 460 385 449
+4 445 460 593 385
+4 385 394 460 593
+4 449 460 385 675
+4 460 385 675 394
+4 184 1033 200 181
+4 203 181 537 200
+4 244 751 483 1019
+4 388 290 286 285
+4 810 732 389 491
+4 378 176 689 776
+4 936 795 420 702
+4 689 744 361 583
+4 583 580 744 361
+4 322 688 329 529
+4 322 529 327 688
+4 447 462 729 451
+4 215 937 233 14
+4 233 215 214 826
+4 325 331 698 833
+4 518 215 233 14
+4 518 214 233 215
+4 280 795 434 420
+4 177 820 325 392
+4 246 814 740 457
+4 795 959 434 420
+4 295 392 325 698
+4 392 698 820 325
+4 420 795 959 702
+4 324 808 275 331
+4 331 778 606 1034
+4 572 394 472 414
+4 700 952 936 117
+4 173 742 572 823
+4 414 393 394 472
+4 394 675 487 464
+4 335 360 343 336
+4 968 336 327 360
+4 336 360 343 337
+4 336 337 327 360
+4 337 361 605 338
+4 337 343 376 360
+4 337 361 360 376
+4 337 360 809 327
+4 698 490 820 325
+4 698 325 833 490
+4 63 781 395 779
+4 63 395 781 297
+4 347 12 730 220
+4 12 506 220 347
+4 952 417 396 532
+4 43 264 286 646
+4 646 286 682 264
+4 42 281 656 647
+4 647 281 656 241
+4 527 656 241 647
+4 117 131 795 702
+4 117 795 936 702
+4 236 211 439 463
+4 370 717 236 950
+4 236 463 439 1004
+4 8 662 967 977
+4 602 59 309 678
+4 45 59 602 678
+4 263 59 678 309
+4 263 59 531 678
+4 504 674 58 727
+4 44 674 727 58
+4 7 207 307 655
+4 655 7 207 955
+4 655 207 354 563
+4 196 563 207 655
+4 207 267 196 655
+4 267 207 955 655
+4 307 207 354 655
+4 399 153 165 460
+4 715 884 1003 81
+4 318 468 687 325
+4 888 402 22 951
+4 886 108 404 726
+4 915 406 66 58
+4 407 935 162 150
+4 64 879 318 565
+4 889 27 33 220
+4 149 503 1008 161
+4 64 565 318 641
+4 161 211 149 409
+4 366 110 663 405
+4 988 366 663 405
+4 339 896 410 107
+4 410 145 139 212
+4 900 258 411 106
+4 411 144 435 138
+4 110 663 405 430
+4 988 663 558 405
+4 663 405 430 596
+4 412 29 234 35
+4 28 510 231 34
+4 328 1030 24 13
+4 458 525 230 352
+4 325 833 490 468
+4 334 641 64 281
+4 334 475 641 281
+4 40 413 910 324
+4 176 732 810 491
+4 40 413 324 671
+4 571 671 324 413
+4 571 413 324 275
+4 354 763 615 184
+4 930 354 615 3
+4 3 354 615 570
+4 735 933 909 171
+4 167 788 909 932
+4 238 273 306 295
+4 915 306 724 66
+4 361 389 360 377
+4 86 868 644 99
+4 98 868 86 99
+4 583 580 760 78
+4 583 78 574 580
+4 689 744 389 361
+4 95 431 381 579
+4 431 379 479 311
+4 381 311 357 379
+4 575 579 431 95
+4 743 431 379 479
+4 138 711 578 901
+4 559 138 578 901
+4 387 101 319 332
+4 165 399 460 433
+4 386 252 1029 478
+4 399 151 546 163
+4 312 403 379 434
+4 743 434 312 379
+4 931 131 434 581
+4 170 166 929 561
+4 689 543 389 810
+4 693 726 116 108
+4 758 474 470 465
+4 784 561 582 758
+4 379 1029 699 386
+4 517 339 554 107
+4 517 103 339 107
+4 991 433 966 459
+4 146 436 919 447
+4 415 499 404 436
+4 436 447 356 452
+4 186 217 175 614
+4 186 175 774 614
+4 102 899 560 106
+4 437 46 947 248
+4 54 714 260 981
+4 714 981 533 260
+4 738 221 222 815
+4 437 815 1024 221
+4 738 248 815 222
+4 72 87 438 942
+4 714 536 260 533
+4 54 863 260 714
+4 863 714 536 260
+4 315 72 438 942
+4 315 737 325 820
+4 774 405 400 440
+4 405 560 440 774
+4 360 389 491 453
+4 365 663 430 989
+4 989 663 430 559
+4 341 587 441 429
+4 110 663 430 365
+4 429 441 450 587
+4 441 800 451 450
+4 663 596 430 559
+4 341 432 514 148
+4 89 845 319 438
+4 89 105 319 845
+4 89 193 438 319
+4 693 81 79 1002
+4 681 91 318 879
+4 683 884 322 715
+4 637 775 201 408
+4 637 9 201 775
+4 553 239 199 563
+4 84 961 364 576
+4 364 961 453 576
+4 218 241 283 246
+4 886 416 140 557
+4 218 32 241 747
+4 886 557 140 120
+4 416 557 436 140
+4 415 303 953 217
+4 415 953 614 217
+4 98 453 868 405
+4 1015 440 400 405
+4 440 453 560 405
+4 56 64 241 680
+4 7 655 307 930
+4 560 106 258 900
+4 558 578 559 138
+4 307 655 354 930
+4 405 821 356 596
+4 68 334 762 641
+4 287 325 295 457
+4 457 295 392 325
+4 457 177 325 392
+4 360 732 644 491
+4 968 732 644 360
+4 809 732 360 543
+4 543 732 360 389
+4 732 360 389 491
+4 968 360 809 732
+4 232 233 214 826
+4 518 904 232 214
+4 518 214 232 233
+4 152 512 466 164
+4 152 564 466 512
+4 895 152 564 466
+4 417 443 532 591
+4 419 446 789 425
+4 222 828 594 815
+4 222 248 815 594
+4 594 227 832 818
+4 370 950 320 156
+4 39 232 818 819
+4 594 248 815 254
+4 346 986 521 423
+4 418 521 1014 323
+4 418 444 882 1014
+4 423 384 445 799
+4 423 445 384 385
+4 423 385 449 445
+4 424 1023 780 425
+4 424 948 429 811
+4 424 450 811 429
+4 425 780 430 1023
+4 425 446 1023 451
+4 356 837 456 1026
+4 356 447 1026 673
+4 356 452 447 673
+4 302 195 562 1035
+4 960 746 257 602
+4 602 678 257 960
+4 746 299 257 602
+4 425 451 1023 430
+4 430 441 451 1023
+4 430 451 441 456
+4 425 451 430 1026
+4 1026 430 456 451
+4 428 449 423 455
+4 429 430 1023 441
+4 429 450 811 587
+4 603 884 321 322
+4 884 322 603 373
+4 373 322 603 57
+4 603 285 322 321
+4 20 30 613 567
+4 344 613 20 30
+4 613 30 221 567
+4 344 221 613 30
+4 17 224 918 401
+4 657 367 401 17
+4 989 432 341 148
+4 240 467 537 226
+4 467 484 226 240
+4 467 643 226 484
+4 505 200 1009 199
+4 5 812 199 553
+4 202 1027 204 205
+4 185 204 205 202
+4 318 486 687 468
+4 446 729 451 447
+4 446 450 451 798
+4 446 729 798 451
+4 196 563 655 741
+4 912 563 196 741
+4 1031 561 462 495
+4 655 267 196 741
+4 441 471 465 514
+4 441 451 800 471
+4 651 305 742 470
+4 1031 495 462 451
+4 742 782 470 305
+4 742 470 487 823
+4 439 454 384 463
+4 742 823 651 470
+4 742 487 470 782
+4 4 914 911 473
+4 473 205 801 597
+4 8 967 210 473
+4 454 592 385 384
+4 8 4 473 914
+4 449 1021 811 450
+4 967 215 228 597
+4 449 385 423 455
+4 450 451 798 800
+4 285 797 290 327
+4 285 327 322 321
+4 322 285 290 327
+4 285 797 327 321
+4 45 556 746 831
+4 451 750 729 798
+4 831 556 746 830
+4 447 462 451 673
+4 476 242 1032 249
+4 455 1021 464 512
+4 223 224 918 751
+4 224 751 244 918
+4 194 479 296 666
+4 117 936 280 952
+4 272 666 479 390
+4 194 479 312 296
+4 143 127 739 920
+4 847 127 143 920
+4 127 449 428 811
+4 739 127 811 449
+4 423 449 428 127
+4 507 212 528 362
+4 212 320 528 362
+4 346 521 485 427
+4 387 100 482 103
+4 480 740 246 541
+4 481 740 457 246
+4 52 334 747 481
+4 481 740 246 480
+4 119 748 628 139
+4 339 628 748 139
+4 40 757 538 910
+4 384 463 454 592
+4 460 823 675 461
+4 385 454 464 592
+4 460 823 394 675
+4 538 757 251 910
+4 40 757 910 413
+4 387 332 478 482
+4 224 352 483 230
+4 224 244 483 317
+4 230 256 257 483
+4 244 483 317 388
+4 707 639 667 621
+4 483 796 256 257
+4 707 667 188 621
+4 264 291 388 796
+4 454 592 466 464
+4 454 463 466 592
+4 464 465 487 825
+4 91 318 565 745
+4 879 91 318 565
+4 328 231 484 189
+4 723 259 382 711
+4 723 259 711 160
+4 346 323 521 418
+4 787 461 729 750
+4 598 787 461 729
+4 798 750 729 461
+4 598 729 461 162
+4 1007 162 461 729
+4 1007 729 461 798
+4 95 579 381 916
+4 381 379 357 468
+4 658 17 918 27
+4 658 17 352 918
+4 394 487 824 464
+4 658 918 317 27
+4 658 918 352 317
+4 38 260 488 643
+4 226 247 536 488
+4 50 863 488 38
+4 70 74 489 859
+4 70 342 859 489
+4 319 490 358 386
+4 319 1016 490 386
+4 568 386 358 490
+4 90 922 358 568
+4 491 810 176 400
+4 491 176 198 400
+4 689 176 543 810
+4 491 389 810 440
+4 491 1015 400 198
+4 491 440 400 1015
+4 701 217 925 469
+4 925 217 186 469
+4 925 469 186 435
+4 137 882 418 799
+4 799 882 418 444
+4 229 492 835 234
+4 492 395 829 1020
+4 250 395 492 1020
+4 492 261 262 829
+4 367 918 401 17
+4 367 220 401 918
+4 731 383 719 459
+4 292 383 443 719
+4 719 383 443 459
+4 292 383 719 731
+4 385 464 454 455
+4 385 464 455 1021
+4 385 1021 675 464
+4 746 299 310 831
+4 746 310 299 602
+4 225 493 251 371
+4 836 1026 425 837
+4 836 557 425 1026
+4 837 430 1026 425
+4 517 390 107 554
+4 892 517 390 107
+4 554 115 390 107
+4 718 775 637 408
+4 718 9 637 775
+4 9 775 613 201
+4 471 582 495 465
+4 471 465 495 800
+4 209 826 214 802
+4 802 214 215 826
+4 802 826 597 209
+4 802 597 826 215
+4 775 567 201 890
+4 775 567 613 201
+4 775 408 890 201
+4 537 226 313 227
+4 991 163 433 459
+4 566 226 227 313
+4 537 227 221 226
+4 572 394 414 966
+4 456 432 259 471
+4 496 703 586 117
+4 163 497 398 459
+4 165 399 433 498
+4 3 7 655 955
+4 4 653 911 6
+4 4 6 911 957
+4 293 498 165 433
+4 5 11 199 812
+4 499 146 404 436
+4 162 935 407 500
+4 162 978 935 500
+4 501 115 390 272
+4 10 639 214 21
+4 504 727 58 406
+4 493 251 475 245
+4 251 493 475 295
+4 506 27 220 367
+4 507 212 362 145
+4 507 145 410 212
+4 16 527 283 26
+4 17 367 918 27
+4 508 652 435 144
+4 18 369 225 28
+4 234 509 523 29
+4 19 531 917 29
+4 509 29 234 412
+4 510 28 231 369
+4 511 13 313 709
+4 511 13 1030 313
+4 239 354 181 467
+4 745 486 468 193
+4 745 93 486 585
+4 193 486 468 379
+4 878 109 496 515
+4 93 496 585 745
+4 455 340 1021 512
+4 279 513 331 606
+4 510 24 328 905
+4 295 306 392 724
+4 891 22 344 36
+4 1028 513 331 279
+4 513 606 1034 331
+4 514 340 587 341
+4 341 441 587 514
+4 35 906 308 635
+4 37 889 219 23
+4 514 512 465 340
+4 40 42 910 958
+4 40 294 324 42
+4 41 43 785 545
+4 42 540 281 56
+4 745 515 585 193
+4 585 515 379 193
+4 43 646 286 57
+4 43 544 57 286
+4 52 619 334 68
+4 759 203 187 477
+4 53 69 284 975
+4 54 38 260 863
+4 1017 187 477 759
+4 187 1017 477 876
+4 876 477 187 188
+4 59 67 309 906
+4 41 785 264 746
+4 746 785 264 291
+4 36 216 577 247
+4 76 766 1010 77
+4 36 247 255 216
+4 76 766 875 1010
+4 386 478 517 387
+4 387 103 482 517
+4 85 644 326 375
+4 82 804 576 84
+4 966 991 293 433
+4 991 498 293 433
+4 212 320 362 145
+4 93 95 916 980
+4 102 84 576 804
+4 127 811 948 424
+4 739 127 424 811
+4 127 811 428 948
+4 106 633 560 102
+4 18 520 225 421
+4 520 251 727 273
+4 520 251 371 225
+4 520 371 251 273
+4 660 421 520 18
+4 520 674 727 251
+4 465 777 582 474
+4 582 784 708 166
+4 117 280 936 795
+4 510 369 231 659
+4 225 659 231 369
+4 659 231 207 225
+4 659 976 207 231
+4 659 510 976 231
+4 120 136 419 623
+4 715 81 1003 1002
+4 715 1003 322 213
+4 129 132 278 448
+4 715 1002 1003 213
+4 300 277 77 764
+4 138 144 578 711
+4 44 279 757 413
+4 139 409 720 145
+4 279 275 331 590
+4 146 595 919 155
+4 147 417 292 157
+4 147 157 292 368
+4 195 350 159 156
+4 149 895 1008 503
+4 748 236 426 320
+4 130 1035 562 133
+4 130 302 562 1035
+4 157 159 292 661
+4 478 426 396 320
+4 478 426 320 748
+4 478 396 584 320
+4 212 478 584 320
+4 212 478 320 748
+4 384 459 383 548
+4 444 443 383 459
+4 166 391 561 170
+4 925 949 180 842
+4 106 925 949 180
+4 539 170 970 956
+4 168 604 539 170
+4 168 598 162 729
+4 269 351 791 182
+4 173 174 572 782
+4 351 791 452 753
+4 269 753 791 351
+4 174 487 877 609
+4 224 317 483 352
+4 483 257 352 796
+4 182 351 791 282
+4 1014 444 443 383
+4 726 316 622 1002
+4 1014 383 443 522
+4 30 221 738 437
+4 30 437 577 221
+4 521 444 383 384
+4 567 30 221 738
+4 521 439 383 522
+4 8 967 215 14
+4 30 344 221 577
+4 937 14 977 509
+4 43 264 785 286
+4 388 286 290 291
+4 2 187 620 668
+4 187 620 668 763
+4 323 485 522 426
+4 349 452 614 526
+4 282 456 452 526
+4 356 526 452 456
+4 614 452 356 526
+4 578 711 144 382
+4 423 521 384 799
+4 288 928 128 744
+4 128 132 288 913
+4 450 676 1021 587
+4 676 464 465 487
+4 132 928 128 288
+4 758 750 465 470
+4 451 800 750 798
+4 461 470 676 750
+4 800 465 495 750
+4 128 288 744 934
+4 758 750 495 465
+4 128 288 934 913
+4 203 537 208 221
+4 203 181 208 537
+4 283 816 225 994
+4 600 493 241 245
+4 283 493 246 241
+4 493 475 241 245
+4 381 324 687 808
+4 381 468 808 687
+4 324 331 687 808
+4 331 325 687 833
+4 687 468 833 325
+4 493 475 246 241
+4 213 809 327 529
+4 329 274 529 361
+4 529 809 327 337
+4 274 213 689 378
+4 380 274 689 378
+4 277 380 689 378
+4 213 378 176 689
+4 359 130 271 179
+4 302 350 195 156
+4 532 522 426 323
+4 62 945 536 541
+4 484 238 260 533
+4 534 306 295 238
+4 534 295 306 392
+4 534 489 392 306
+4 621 794 188 927
+4 876 188 621 794
+4 656 600 241 245
+4 656 527 241 600
+4 355 535 533 246
+4 225 816 535 994
+4 488 50 536 863
+4 484 536 533 260
+4 151 444 546 459
+4 398 151 163 459
+4 151 163 459 546
+4 151 459 398 444
+4 563 276 608 951
+4 608 218 276 283
+4 276 218 608 951
+4 280 795 581 434
+4 117 795 586 280
+4 586 795 581 280
+4 15 421 600 648
+4 648 421 600 251
+4 382 711 144 723
+4 382 144 282 723
+4 825 465 487 474
+4 229 835 492 834
+4 249 395 697 492
+4 168 539 729 956
+4 168 787 729 539
+4 112 332 749 346
+4 332 323 532 426
+4 485 332 426 323
+4 60 480 589 541
+4 541 589 533 246
+4 541 534 246 533
+4 217 268 542 701
+4 349 217 542 701
+4 938 154 542 349
+4 883 235 121 591
+4 328 307 467 313
+4 43 658 264 646
+4 646 264 682 658
+4 223 243 834 250
+4 834 243 249 250
+4 283 493 241 600
+4 546 460 445 153
+4 546 433 459 593
+4 399 546 460 433
+4 546 153 399 460
+4 548 171 909 933
+4 280 434 379 403
+4 723 561 259 166
+4 785 264 291 286
+4 56 318 281 64
+4 56 681 318 64
+4 540 318 281 56
+4 681 56 318 540
+4 115 212 179 359
+4 554 584 478 403
+4 386 390 554 1029
+4 386 478 1029 554
+4 179 115 390 554
+4 211 463 555 439
+4 555 454 463 466
+4 439 463 555 454
+4 281 318 287 641
+4 641 325 287 457
+4 641 325 318 287
+4 397 836 557 120
+4 419 446 425 557
+4 430 596 456 432
+4 989 901 432 148
+4 41 658 264 43
+4 560 405 558 821
+4 560 633 988 102
+4 8 215 473 783
+4 215 707 783 8
+4 430 432 441 989
+4 430 559 432 989
+4 561 970 758 170
+4 121 141 591 882
+4 561 462 495 970
+4 121 418 137 882
+4 121 882 591 418
+4 878 109 515 105
+4 878 515 319 105
+4 878 105 319 89
+4 3 655 354 563
+4 563 354 239 207
+4 741 563 655 3
+4 264 746 796 257
+4 142 455 736 564
+4 564 464 455 454
+4 630 736 564 142
+4 565 318 325 468
+4 565 737 468 325
+4 1003 83 321 375
+4 1003 321 322 327
+4 1003 213 327 322
+4 1003 327 213 375
+4 226 643 313 566
+4 24 643 634 902
+4 567 222 827 201
+4 922 568 90 631
+4 143 569 920 739
+4 569 449 450 675
+4 640 739 569 143
+4 319 387 386 358
+4 319 386 387 252
+4 571 808 275 324
+4 735 573 414 293
+4 572 487 472 394
+4 870 572 174 487
+4 82 899 576 804
+4 102 804 576 899
+4 901 118 559 138
+4 989 901 118 559
+4 989 134 118 901
+4 148 134 989 901
+4 735 728 472 870
+4 414 573 572 293
+4 870 573 174 572
+4 908 152 340 806
+4 76 574 872 583
+4 148 908 341 807
+4 743 379 431 940
+4 874 431 97 575
+4 908 806 340 807
+4 908 340 341 807
+4 577 344 221 216
+4 902 1030 24 643
+4 46 253 50 247
+4 437 46 247 253
+4 437 253 247 1024
+4 1024 247 488 253
+4 596 578 456 432
+4 579 431 381 379
+4 940 379 431 579
+4 93 916 486 585
+4 579 379 381 486
+4 93 916 585 980
+4 580 607 389 361
+4 361 580 744 389
+4 744 842 389 580
+4 105 515 319 952
+4 105 319 235 952
+4 319 515 252 952
+4 319 252 235 952
+4 796 299 291 290
+4 796 298 299 290
+4 943 75 781 335
+4 280 581 379 434
+4 943 335 781 326
+4 743 581 434 379
+4 940 743 379 581
+4 582 758 465 474
+4 939 283 16 15
+4 582 495 465 758
+4 283 16 15 600
+4 563 276 627 629
+4 292 197 443 383
+4 583 380 361 689
+4 197 522 443 383
+4 96 311 761 571
+4 381 571 324 808
+4 381 571 357 311
+4 197 236 383 192
+4 292 197 383 192
+4 197 236 522 383
+4 950 192 236 197
+4 705 776 726 378
+4 212 584 478 554
+4 590 275 331 324
+4 910 413 590 324
+4 287 324 910 590
+4 287 331 324 590
+4 413 275 590 324
+4 745 585 486 193
+4 585 579 486 379
+4 585 579 379 940
+4 238 493 273 295
+4 371 238 493 273
+4 181 354 313 467
+4 471 514 582 465
+4 465 512 514 777
+4 585 940 379 586
+4 515 586 379 280
+4 585 515 586 379
+4 586 581 379 280
+4 586 379 581 940
+4 838 548 731 171
+4 200 973 812 505
+4 572 742 487 823
+4 572 174 487 782
+4 572 487 742 782
+4 570 563 553 5
+4 514 465 587 340
+4 514 465 441 587
+4 587 450 811 1021
+4 52 589 48 60
+4 52 255 48 589
+4 240 589 247 255
+4 355 247 589 536
+4 590 1028 331 279
+4 287 590 295 1028
+4 121 591 323 418
+4 591 1014 323 418
+4 591 882 1014 418
+4 616 911 185 801
+4 616 473 911 801
+4 394 592 464 824
+4 592 463 466 472
+4 237 593 460 394
+4 433 460 237 593
+4 546 460 593 445
+4 546 433 593 460
+4 733 21 232 31
+4 172 824 487 825
+4 464 825 824 512
+4 427 423 428 125
+4 427 125 346 423
+4 465 777 514 582
+4 412 25 903 233
+4 209 826 832 214
+4 209 222 594 1027
+4 214 826 832 232
+4 217 303 953 268
+4 1018 303 415 217
+4 217 303 268 1018
+4 149 555 630 135
+4 135 427 555 736
+4 555 736 630 135
+4 135 333 149 555
+4 35 29 234 263
+4 126 428 948 127
+4 31 253 733 488
+4 436 919 614 415
+4 415 919 614 953
+4 614 356 452 436
+4 558 821 578 435
+4 596 356 837 456
+4 597 210 372 228
+4 372 834 223 476
+4 478 332 426 482
+4 35 906 263 262
+4 86 961 644 453
+4 252 319 235 332
+4 420 959 562 266
+4 752 157 599 710
+4 225 251 493 600
+4 648 600 524 245
+4 648 600 245 251
+4 525 458 230 19
+4 155 713 452 753
+4 269 351 462 753
+4 269 716 753 462
+4 525 230 1013 19
+4 525 230 224 754
+4 654 754 206 712
+4 921 1013 19 525
+4 525 17 754 224
+4 525 754 1013 230
+4 654 525 754 1013
+4 207 353 196 267
+4 353 207 659 267
+4 51 39 254 984
+4 45 41 746 556
+4 239 216 951 240
+4 114 178 934 128
+4 349 452 526 282
+4 349 791 158 452
+4 353 225 283 15
+4 225 283 15 600
+4 225 283 600 493
+4 952 591 417 532
+4 578 144 282 382
+4 80 611 997 82
+4 82 997 376 611
+4 337 605 376 841
+4 337 605 841 338
+4 92 612 996 94
+4 94 761 770 96
+4 80 995 611 82
+4 82 611 377 995
+4 607 389 377 842
+4 580 842 389 607
+4 584 320 396 350
+4 350 320 396 197
+4 227 313 208 610
+4 610 832 214 208
+4 610 313 566 227
+4 80 607 605 611
+4 611 376 360 361
+4 611 361 360 377
+4 611 605 376 361
+4 611 361 377 607
+4 612 778 342 606
+4 612 342 778 568
+4 612 390 568 357
+4 9 613 200 665
+4 9 613 665 201
+4 613 203 201 827
+4 613 200 203 221
+4 618 89 565 737
+4 45 746 310 831
+4 618 89 91 565
+4 151 137 881 445
+4 619 64 334 68
+4 880 32 619 334
+4 235 952 591 883
+4 310 45 831 547
+4 591 121 883 141
+4 235 105 952 883
+4 622 104 726 108
+4 885 1002 622 81
+4 888 52 255 36
+4 36 255 888 951
+4 104 120 397 886
+4 120 623 419 557
+4 37 53 242 889
+4 624 738 30 567
+4 624 567 30 20
+4 624 738 37 30
+4 254 47 51 947
+4 30 891 344 36
+4 891 344 20 30
+4 107 628 339 896
+4 894 70 306 66
+4 70 306 54 894
+4 149 555 1008 630
+4 149 1008 895 630
+4 568 92 631 892
+4 631 103 517 107
+4 106 900 560 633
+4 633 118 138 558
+4 899 949 576 180
+4 634 488 31 733
+4 634 733 31 21
+4 634 31 488 38
+4 905 54 260 34
+4 905 38 260 54
+4 635 67 965 71
+4 71 635 55 308
+4 636 35 261 55
+4 636 55 261 39
+4 638 31 232 21
+4 150 1007 640 136
+4 150 1007 907 640
+4 641 565 318 325
+4 624 37 790 219
+4 1006 201 202 1027
+4 1006 219 1027 202
+4 567 222 201 1006
+4 1006 222 790 567
+4 1006 790 219 624
+4 136 1007 789 446
+4 1007 450 446 798
+4 1007 450 569 789
+4 1007 789 640 136
+4 386 390 517 554
+4 386 478 554 517
+4 568 386 390 517
+4 386 568 922 517
+4 226 484 488 536
+4 333 555 427 439
+4 555 564 454 466
+4 555 454 564 736
+4 660 520 645 18
+4 645 674 504 520
+4 255 48 247 36
+4 48 255 247 589
+4 123 135 427 119
+4 123 119 427 749
+4 674 251 520 660
+4 674 520 645 660
+4 544 650 329 301
+4 785 544 329 301
+4 650 683 322 79
+4 787 305 651 470
+4 651 722 460 165
+4 787 461 470 651
+4 653 304 786 6
+4 616 653 494 185
+4 743 194 479 312
+4 431 479 194 311
+4 502 161 211 236
+4 717 161 502 236
+4 349 614 186 526
+4 186 614 356 526
+4 157 661 292 719
+4 661 192 731 265
+4 759 184 1033 200
+4 979 200 184 759
+4 979 9 200 665
+4 664 274 380 378
+4 277 664 380 378
+4 300 378 664 277
+4 664 693 378 300
+4 164 512 466 824
+4 728 824 466 472
+4 916 486 324 318
+4 649 916 324 318
+4 650 79 322 274
+4 650 274 322 329
+4 665 201 203 185
+4 665 9 201 637
+4 94 390 612 666
+4 296 666 479 272
+4 272 94 666 390
+4 667 214 610 10
+4 667 188 208 214
+4 667 639 214 10
+4 10 314 610 667
+4 763 313 620 668
+4 2 667 668 588
+4 324 281 318 287
+4 540 324 281 318
+4 785 688 322 286
+4 544 322 286 785
+4 12 201 637 704
+4 704 12 201 202
+4 705 278 378 300
+4 300 693 378 705
+4 973 200 553 184
+4 617 973 184 200
+4 272 115 179 130
+4 14 707 639 215
+4 802 214 188 707
+4 669 472 466 463
+4 728 472 466 669
+4 503 669 466 161
+4 441 471 514 432
+4 521 384 383 439
+4 423 385 384 454
+4 356 673 1026 456
+4 356 452 673 456
+4 423 454 521 427
+4 673 1031 451 456
+4 423 384 521 454
+4 521 384 439 454
+4 384 548 383 1004
+4 675 823 676 461
+4 675 385 464 394
+4 449 450 675 1021
+4 450 1021 676 675
+4 675 487 464 676
+4 676 470 465 750
+4 416 415 400 726
+4 149 1008 555 161
+4 555 466 669 161
+4 161 669 555 211
+4 1008 466 555 161
+4 920 127 739 449
+4 920 569 449 739
+4 979 665 200 759
+4 287 331 325 687
+4 979 665 759 1
+4 291 688 290 337
+4 688 529 327 337
+4 744 689 389 810
+4 543 810 732 389
+4 1015 405 400 690
+4 345 837 405 690
+4 348 1015 690 405
+4 348 405 690 345
+4 304 665 185 704
+4 304 704 637 665
+4 496 109 117 515
+4 496 515 117 586
+4 515 117 586 280
+4 218 241 246 747
+4 172 474 773 825
+4 172 825 487 474
+4 609 474 725 172
+4 725 172 474 773
+4 609 172 487 474
+4 975 53 243 284
+4 975 243 1019 284
+4 678 458 531 263
+4 531 917 263 458
+4 228 834 1025 835
+4 254 984 697 51
+4 698 342 1028 724
+4 698 331 1034 778
+4 295 698 1028 724
+4 57 682 285 65
+4 666 357 699 390
+4 479 666 699 390
+4 699 1029 390 386
+4 974 84 632 82
+4 847 423 127 920
+4 568 92 90 631
+4 90 103 922 631
+4 123 427 858 428
+4 966 393 394 414
+4 663 405 596 558
+4 663 558 596 559
+4 271 403 179 312
+4 271 403 312 562
+4 703 581 131 971
+4 677 706 275 684
+4 706 279 275 684
+4 706 279 684 58
+4 310 547 831 841
+4 547 59 686 310
+4 679 841 338 831
+4 114 694 842 178
+4 725 777 474 582
+4 7 307 709 551
+4 728 669 466 503
+4 731 383 459 548
+4 192 383 731 838
+4 838 548 383 731
+4 292 192 383 731
+4 421 520 225 251
+4 660 251 520 421
+4 600 421 225 251
+4 648 421 251 530
+4 660 530 251 421
+4 656 600 245 524
+4 234 523 210 712
+4 654 210 516 712
+4 713 716 462 753
+4 595 462 447 713
+4 657 220 206 401
+4 353 659 207 225
+4 483 1019 250 290
+4 1020 483 250 290
+4 658 352 264 317
+4 584 302 562 271
+4 302 562 195 350
+4 125 423 847 941
+4 125 941 986 423
+4 941 986 423 799
+4 941 445 423 920
+4 847 423 920 941
+4 941 799 423 445
+4 375 968 326 327
+4 634 488 733 566
+4 634 566 733 21
+4 110 430 780 122
+4 122 780 429 430
+4 122 365 430 989
+4 122 430 429 989
+4 122 110 430 365
+4 322 650 329 544
+4 785 322 329 544
+4 211 333 409 139
+4 211 748 333 139
+4 211 139 409 720
+4 211 748 139 720
+4 837 430 456 1026
+4 596 837 430 456
+4 405 837 430 596
+4 330 273 295 724
+4 724 392 698 342
+4 1028 330 724 513
+4 1028 342 513 724
+4 273 306 295 724
+4 726 397 400 416
+4 176 378 726 776
+4 207 307 328 976
+4 976 207 231 328
+4 7 207 976 307
+4 659 7 207 976
+4 251 273 330 727
+4 44 674 251 727
+4 44 251 279 727
+4 595 729 447 462
+4 716 168 729 956
+4 716 729 595 462
+4 730 202 205 220
+4 657 730 206 220
+4 42 281 245 656
+4 643 902 1030 566
+4 511 902 566 1030
+4 936 280 420 795
+4 920 445 449 460
+4 613 567 827 201
+4 221 200 344 613
+4 564 455 464 512
+4 455 340 512 564
+4 455 142 340 564
+4 733 832 214 610
+4 733 610 566 227
+4 733 214 832 232
+4 974 360 376 343
+4 974 376 360 611
+4 974 611 360 377
+4 974 377 360 576
+4 320 370 236 950
+4 502 370 236 720
+4 196 276 563 629
+4 912 563 741 3
+4 680 527 241 647
+4 117 700 702 936
+4 60 589 48 945
+4 945 247 536 589
+4 651 460 461 823
+4 165 237 460 651
+4 237 460 651 823
+4 736 454 428 427
+4 736 428 454 455
+4 736 455 454 564
+4 227 566 488 226
+4 488 1024 227 226
+4 643 226 488 566
+4 634 488 643 38
+4 922 358 386 387
+4 922 386 358 568
+4 922 517 387 386
+4 143 153 920 569
+4 153 920 569 460
+4 641 737 565 325
+4 375 327 326 321
+4 1003 375 321 327
+4 569 920 449 460
+4 738 248 790 37
+4 567 738 221 222
+4 790 222 738 567
+4 624 790 37 738
+4 136 739 424 789
+4 739 450 811 424
+4 739 569 449 450
+4 789 450 569 739
+4 640 789 739 136
+4 236 522 383 439
+4 445 593 384 385
+4 385 393 593 384
+4 740 295 534 392
+4 740 177 392 534
+4 740 295 392 457
+4 740 177 457 392
+4 656 422 600 524
+4 966 593 394 393
+4 140 407 557 447
+4 146 140 436 447
+4 140 447 557 436
+4 385 393 592 394
+4 385 592 464 394
+4 471 800 495 451
+4 451 800 495 750
+4 493 251 273 295
+4 251 273 295 330
+4 295 251 330 590
+4 696 194 743 312
+4 696 434 312 743
+4 695 743 696 575
+4 695 696 743 581
+4 300 691 278 990
+4 990 574 691 744
+4 928 744 691 574
+4 404 416 415 436
+4 0 187 1017 759
+4 0 759 871 187
+4 759 203 477 185
+4 745 318 565 468
+4 745 193 468 565
+4 745 318 468 486
+4 252 332 235 532
+4 441 432 514 341
+4 989 432 441 341
+4 52 747 255 840
+4 747 241 246 334
+4 481 747 52 840
+4 416 356 436 557
+4 557 447 356 436
+4 557 447 1026 356
+4 426 748 478 482
+4 119 333 749 748
+4 339 482 478 748
+4 288 614 175 217
+4 415 217 614 288
+4 570 553 973 5
+4 749 119 748 482
+4 482 426 749 332
+4 749 332 426 485
+4 52 840 589 480
+4 570 553 184 973
+4 481 52 480 840
+4 480 246 589 541
+4 199 200 812 505
+4 970 750 462 495
+4 539 750 462 970
+4 283 527 241 26
+4 527 283 241 600
+4 147 417 443 292
+4 147 700 417 157
+4 700 710 417 157
+4 919 447 452 713
+4 146 595 447 919
+4 595 713 447 919
+4 918 367 220 27
+4 657 220 401 367
+4 918 317 244 224
+4 27 317 244 918
+4 276 218 839 283
+4 283 26 218 839
+4 147 292 443 368
+4 917 234 230 712
+4 234 523 712 917
+4 234 523 917 29
+4 144 652 435 282
+4 539 604 758 170
+4 917 234 256 230
+4 917 531 263 29
+4 539 604 787 758
+4 225 369 231 28
+4 745 878 515 193
+4 702 710 752 420
+4 270 352 658 525
+4 485 749 427 439
+4 749 439 333 427
+4 521 454 439 427
+4 521 485 427 439
+4 723 351 182 282
+4 682 285 65 33
+4 755 353 659 267
+4 717 156 756 950
+4 717 265 192 756
+4 245 656 524 958
+4 211 555 149 333
+4 211 333 149 409
+4 355 189 484 535
+4 371 816 493 238
+4 225 816 493 371
+4 535 816 371 238
+4 225 816 371 535
+4 467 313 643 328
+4 89 193 737 438
+4 438 193 737 490
+4 672 338 329 785
+4 672 338 785 556
+4 911 653 786 6
+4 616 801 185 188
+4 616 911 653 185
+4 616 473 801 188
+4 473 8 783 927
+4 168 604 787 539
+4 604 474 470 758
+4 734 474 604 758
+4 166 561 582 784
+4 615 354 184 570
+4 735 414 472 788
+4 181 537 313 208
+4 181 467 313 537
+4 239 467 181 537
+4 759 665 203 185
+4 2 667 588 10
+4 667 208 188 187
+4 667 187 668 208
+4 760 607 605 80
+4 760 338 605 361
+4 760 607 580 361
+4 583 580 361 760
+4 583 361 338 760
+4 94 612 606 761
+4 94 666 612 761
+4 761 357 275 571
+4 761 357 311 666
+4 761 357 606 275
+4 761 311 357 571
+4 614 356 436 416
+4 132 691 928 288
+4 691 278 744 288
+4 132 278 691 288
+4 288 691 928 744
+4 240 355 247 589
+4 216 247 255 240
+4 240 226 247 355
+4 216 240 226 247
+4 22 36 888 951
+4 432 514 259 471
+4 139 119 333 625
+4 453 180 560 576
+4 139 119 748 333
+4 139 897 333 409
+4 139 625 333 897
+4 735 870 472 414
+4 554 339 478 212
+4 211 439 555 333
+4 762 315 177 72
+4 762 315 325 177
+4 762 177 480 72
+4 762 177 457 481
+4 762 177 325 457
+4 762 177 481 480
+4 538 530 251 674
+4 307 620 930 763
+4 620 763 615 930
+4 677 671 571 413
+4 677 413 571 275
+4 83 321 69 884
+4 1003 83 884 321
+4 990 764 300 691
+4 95 294 324 765
+4 765 324 671 294
+4 766 301 329 77
+4 766 545 672 329
+4 287 457 295 475
+4 641 457 287 475
+4 556 767 672 338
+4 768 79 664 693
+4 768 693 664 300
+4 769 694 607 80
+4 769 694 842 607
+4 692 694 842 769
+4 677 684 275 770
+4 94 606 684 770
+4 770 606 684 275
+4 771 605 686 80
+4 771 338 841 605
+4 679 771 338 841
+4 772 9 665 637
+4 772 304 637 665
+4 621 639 667 10
+4 164 721 512 773
+4 773 825 777 512
+4 725 773 474 777
+4 332 252 387 478
+4 175 774 400 440
+4 965 805 308 71
+4 635 965 308 71
+4 906 309 308 965
+4 355 536 589 533
+4 541 536 533 589
+4 906 965 308 635
+4 965 309 308 805
+4 532 522 323 591
+4 582 495 561 259
+4 582 561 495 758
+4 859 74 489 358
+4 47 31 864 253
+4 47 864 50 253
+4 667 214 208 610
+4 667 208 668 610
+4 605 607 361 611
+4 760 607 361 605
+4 612 390 357 666
+4 612 357 606 761
+4 612 666 357 761
+4 665 613 200 203
+4 665 613 203 201
+4 759 665 200 203
+4 745 515 496 585
+4 496 515 586 585
+4 564 142 340 152
+4 278 378 689 776
+4 705 776 378 278
+4 142 924 455 340
+4 415 776 278 288
+4 216 951 240 255
+4 515 952 280 252
+4 1033 203 200 181
+4 759 1033 203 200
+4 81 622 1003 1002
+4 316 375 622 1002
+4 1002 622 1003 375
+4 497 147 398 443
+4 398 147 141 443
+4 28 273 504 406
+4 28 273 406 34
+4 310 547 841 686
+4 771 841 686 605
+4 679 771 841 686
+4 465 825 512 777
+4 160 514 721 708
+4 725 721 777 708
+4 773 777 721 512
+4 725 773 777 721
+4 778 568 358 490
+4 778 490 357 568
+4 778 833 357 490
+4 681 93 318 91
+4 91 93 318 745
+4 649 93 318 681
+4 93 916 318 486
+4 916 93 318 649
+4 745 93 318 486
+4 49 254 779 51
+4 51 697 254 779
+4 779 395 697 249
+4 61 289 73 781
+4 61 781 779 289
+4 781 289 395 779
+4 781 395 289 297
+4 780 111 124 425
+4 780 425 345 111
+4 780 837 110 345
+4 780 110 837 430
+4 224 751 250 483
+4 243 1019 250 751
+4 751 250 483 1019
+4 780 124 424 425
+4 254 697 249 779
+4 73 781 289 326
+4 934 288 175 217
+4 934 288 744 175
+4 558 596 559 578
+4 782 604 470 305
+4 782 174 487 877
+4 644 968 335 326
+4 644 335 968 360
+4 375 644 326 968
+4 179 403 969 312
+4 403 179 969 554
+4 312 403 969 699
+4 1029 969 554 403
+4 699 403 969 1029
+4 831 746 299 830
+4 679 556 831 338
+4 783 802 473 188
+4 802 707 188 783
+4 473 927 188 616
+4 794 616 188 927
+4 783 707 188 621
+4 784 758 582 474
+4 758 784 734 474
+4 609 725 474 784
+4 725 582 474 784
+4 785 286 291 688
+4 545 672 329 785
+4 301 545 329 785
+4 304 704 185 786
+4 653 494 185 304
+4 911 653 185 786
+4 787 750 729 539
+4 787 470 750 758
+4 787 604 470 758
+4 384 459 548 393
+4 305 604 470 787
+4 384 393 548 463
+4 617 184 973 570
+4 570 354 184 553
+4 788 472 669 463
+4 788 735 728 472
+4 594 227 818 815
+4 594 254 815 818
+4 728 472 669 788
+4 389 180 453 377
+4 541 981 533 714
+4 440 389 180 453
+4 541 536 714 533
+4 584 320 350 302
+4 641 315 325 762
+4 641 762 325 457
+4 641 737 325 315
+4 789 1007 450 446
+4 789 739 424 450
+4 790 222 219 476
+4 790 222 476 248
+4 1006 790 222 219
+4 738 248 222 790
+4 135 333 555 427
+4 871 615 620 763
+4 620 763 187 871
+4 620 187 2 871
+4 677 571 671 873
+4 876 188 794 616
+4 717 236 192 793
+4 282 456 526 578
+4 596 526 356 456
+4 220 223 751 243
+4 223 751 243 250
+4 160 582 708 166
+4 1019 285 797 290
+4 244 1019 388 285
+4 1019 388 285 290
+4 1020 297 290 289
+4 250 395 1020 289
+4 395 1020 289 297
+4 796 388 290 291
+4 483 796 388 290
+4 256 298 1020 262
+4 262 308 298 297
+4 309 310 299 298
+4 286 285 290 322
+4 810 776 176 400
+4 415 400 726 776
+4 176 776 726 400
+4 731 169 171 548
+4 569 449 675 460
+4 569 461 460 675
+4 798 676 750 461
+4 553 992 200 199
+4 973 200 812 553
+4 704 202 201 185
+4 786 202 704 185
+4 789 424 425 1023
+4 789 446 1023 425
+4 418 799 444 521
+4 799 384 445 444
+4 521 799 444 384
+4 449 385 455 1021
+4 1021 676 464 465
+4 449 1021 675 385
+4 1021 464 676 675
+4 441 587 800 450
+4 441 800 465 471
+4 450 800 676 587
+4 800 465 750 676
+4 564 466 464 454
+4 564 464 466 512
+4 911 473 205 801
+4 215 214 802 707
+4 783 215 473 802
+4 215 707 802 783
+4 458 352 230 257
+4 352 257 483 230
+4 352 317 388 264
+4 352 317 483 388
+4 224 813 803 223
+4 224 483 250 803
+4 803 1020 483 250
+4 234 256 492 262
+4 234 256 262 263
+4 297 1022 781 335
+4 1022 968 327 326
+4 290 336 337 327
+4 298 308 805 1022
+4 298 336 1022 805
+4 805 343 336 335
+4 310 343 337 336
+4 808 357 275 331
+4 381 468 357 808
+4 808 331 687 833
+4 571 357 275 808
+4 381 571 808 357
+4 337 360 361 809
+4 529 361 809 337
+4 175 440 400 810
+4 491 810 400 440
+4 428 811 449 455
+4 429 1023 450 441
+4 1023 441 451 450
+4 712 206 813 754
+4 754 230 224 813
+4 206 401 223 813
+4 790 476 219 242
+4 790 476 242 1032
+4 814 493 238 295
+4 814 534 295 238
+4 493 814 475 295
+4 475 457 295 814
+4 814 295 534 740
+4 814 295 740 457
+4 437 248 947 815
+4 815 248 947 254
+4 536 260 484 488
+4 316 176 726 400
+4 316 726 397 400
+4 222 248 594 817
+4 817 248 594 254
+4 817 254 249 248
+4 222 248 817 476
+4 476 249 248 817
+4 815 227 818 253
+4 815 254 253 818
+4 31 253 818 733
+4 31 818 253 865
+4 826 228 594 1025
+4 228 835 1025 819
+4 319 438 358 490
+4 438 820 358 490
+4 315 438 820 358
+4 342 568 358 778
+4 90 568 358 342
+4 859 342 358 489
+4 90 342 358 859
+4 918 220 751 244
+4 220 223 918 751
+4 425 1026 446 451
+4 1026 451 447 446
+4 557 425 1026 446
+4 417 532 443 197
+4 417 396 532 197
+4 417 710 197 292
+4 417 197 443 292
+4 417 420 396 197
+4 417 420 197 710
+4 205 223 210 206
+4 205 223 372 210
+4 205 597 210 372
+4 473 205 597 210
+4 911 210 206 205
+4 911 210 205 473
+4 225 535 231 994
+4 225 535 371 231
+4 428 423 454 455
+4 423 385 454 455
+4 117 586 795 703
+4 586 581 795 703
+4 475 287 641 281
+4 891 200 1009 505
+4 344 200 1009 891
+4 186 435 821 258
+4 560 558 900 258
+4 258 558 900 435
+4 239 467 537 240
+4 53 822 284 983
+4 785 329 322 688
+4 722 153 461 460
+4 651 722 461 460
+4 68 89 737 848
+4 618 68 89 737
+4 68 737 641 315
+4 618 68 737 641
+4 173 823 651 742
+4 823 470 676 461
+4 651 823 461 470
+4 787 461 750 470
+4 487 465 470 474
+4 676 487 465 470
+4 823 470 487 676
+4 251 330 590 279
+4 251 279 590 757
+4 465 825 777 474
+4 727 330 251 279
+4 773 474 777 825
+4 209 372 826 597
+4 597 826 215 228
+4 209 372 594 826
+4 826 232 819 1025
+4 827 203 204 828
+4 827 222 828 204
+4 567 222 221 827
+4 613 203 827 221
+4 613 567 221 827
+4 201 222 204 1027
+4 1006 201 1027 222
+4 1006 219 222 1027
+4 208 828 221 227
+4 219 889 243 220
+4 243 242 476 249
+4 219 476 243 242
+4 493 251 245 600
+4 239 189 467 240
+4 981 306 534 260
+4 982 297 829 395
+4 55 829 982 308
+4 982 297 395 63
+4 291 688 337 830
+4 785 291 830 688
+4 785 338 329 830
+4 299 830 337 831
+4 831 841 338 337
+4 209 208 832 828
+4 209 594 828 832
+4 610 227 832 208
+4 733 227 832 610
+4 833 357 490 468
+4 808 331 833 357
+4 687 468 808 833
+4 329 337 338 361
+4 380 274 329 361
+4 529 337 329 361
+4 583 329 338 361
+4 583 380 329 361
+4 331 357 606 778
+4 612 357 778 606
+4 612 778 357 568
+4 833 331 778 357
+4 834 492 250 249
+4 834 697 492 249
+4 835 261 492 697
+4 179 969 390 993
+4 272 993 179 390
+4 993 272 479 390
+4 993 969 390 699
+4 993 479 699 390
+4 64 618 565 641
+4 64 618 879 565
+4 809 375 327 968
+4 375 732 644 968
+4 375 968 809 732
+4 226 484 643 488
+4 488 260 484 643
+4 280 403 396 420
+4 403 584 396 420
+4 871 187 2 0
+4 280 434 403 420
+4 584 420 403 562
+4 434 562 403 420
+4 735 414 909 933
+4 548 933 909 414
+4 616 4 911 473
+4 627 5 11 199
+4 967 597 228 210
+4 4 8 473 927
+4 664 79 274 378
+4 664 79 378 693
+4 79 213 274 378
+4 693 1002 79 378
+4 79 1002 213 378
+4 627 951 199 11
+4 627 642 951 11
+4 408 12 23 1006
+4 6 12 704 202
+4 14 412 233 25
+4 967 215 14 937
+4 473 967 597 215
+4 202 205 220 219
+4 210 234 229 228
+4 234 835 229 228
+4 655 999 741 3
+4 422 600 15 16
+4 563 608 207 239
+4 111 853 836 120
+4 120 836 419 853
+4 345 425 836 111
+4 345 425 837 836
+4 836 356 1026 837
+4 836 425 557 419
+4 836 557 1026 356
+4 211 236 439 748
+4 439 236 426 748
+4 780 425 837 345
+4 780 837 425 430
+4 333 439 749 748
+4 654 712 206 210
+4 211 439 333 748
+4 426 439 748 749
+4 16 26 283 839
+4 793 909 463 1004
+4 1004 463 548 909
+4 527 16 283 600
+4 717 838 192 265
+4 265 192 731 838
+4 717 838 793 192
+4 839 629 627 276
+4 645 520 28 18
+4 353 283 939 15
+4 749 748 426 482
+4 840 255 589 246
+4 917 523 712 19
+4 840 747 255 246
+4 917 523 19 29
+4 481 747 840 246
+4 840 246 589 480
+4 481 840 480 246
+4 160 582 514 708
+4 512 721 514 777
+4 841 343 962 376
+4 841 605 376 962
+4 279 684 606 275
+4 279 513 606 684
+4 513 963 342 606
+4 842 377 607 949
+4 890 567 624 20
+4 607 842 949 694
+4 307 763 930 354
+4 520 727 504 273
+4 520 674 504 727
+4 902 566 634 21
+4 68 843 762 481
+4 68 52 843 481
+4 68 843 72 762
+4 904 638 232 21
+4 137 418 121 844
+4 137 844 125 986
+4 87 845 438 101
+4 846 101 113 1012
+4 846 113 121 1012
+4 847 920 143 137
+4 848 87 89 438
+4 852 1032 61 49
+4 852 53 61 822
+4 136 853 120 419
+4 124 424 425 853
+4 69 284 854 53
+4 69 987 73 854
+4 70 306 855 54
+4 70 489 74 855
+4 856 247 48 36
+4 906 29 35 263
+4 856 46 48 247
+4 857 248 49 46
+4 23 1006 219 624
+4 954 998 838 265
+4 265 838 731 998
+4 864 31 38 488
+4 363 90 103 922
+4 864 38 50 488
+4 24 634 643 38
+4 123 427 135 858
+4 865 39 254 51
+4 25 39 232 638
+4 655 267 741 999
+4 267 655 955 999
+4 859 358 90 88
+4 119 749 123 112
+4 860 75 86 335
+4 860 923 86 84
+4 15 353 755 267
+4 84 364 102 576
+4 861 51 63 697
+4 861 697 63 55
+4 71 55 862 308
+4 71 862 75 985
+4 269 791 1001 182
+4 269 753 1001 791
+4 253 31 864 488
+4 253 864 50 488
+4 47 865 254 51
+4 953 183 158 268
+4 953 268 158 542
+4 866 739 143 127
+4 866 136 143 739
+4 122 867 134 429
+4 867 924 142 134
+4 496 695 585 703
+4 868 198 644 99
+4 868 348 198 99
+4 868 1015 348 405
+4 868 198 453 644
+4 868 453 1015 405
+4 280 379 1029 403
+4 280 1029 379 869
+4 515 379 869 280
+4 635 35 55 308
+4 515 252 280 869
+4 478 482 517 387
+4 478 339 554 517
+4 334 641 475 457
+4 295 330 724 1028
+4 330 513 1028 279
+4 295 590 330 1028
+4 590 330 1028 279
+4 870 572 472 414
+4 735 573 870 414
+4 871 615 763 184
+4 792 871 184 615
+4 872 574 691 990
+4 990 872 764 691
+4 571 765 671 873
+4 875 766 672 329
+4 338 672 329 875
+4 767 875 672 338
+4 188 876 185 616
+4 494 616 185 876
+4 877 474 734 609
+4 470 877 474 604
+4 474 734 604 877
+4 974 376 962 343
+4 898 962 343 974
+4 898 974 343 632
+4 482 103 339 517
+4 670 40 910 958
+4 207 189 239 608
+4 478 339 517 482
+4 467 643 484 328
+4 608 189 239 240
+4 879 618 91 565
+4 64 880 619 334
+4 881 546 445 153
+4 672 556 785 41
+4 881 153 399 546
+4 540 42 281 324
+4 882 151 398 444
+4 544 785 286 43
+4 417 591 883 141
+4 122 365 989 134
+4 122 989 429 134
+4 700 883 141 417
+4 885 108 726 693
+4 108 726 622 885
+4 148 432 514 160
+4 140 886 404 416
+4 432 711 160 148
+4 432 160 259 514
+4 711 259 432 160
+4 887 150 446 407
+4 623 887 150 446
+4 49 249 1032 61
+4 49 249 248 1032
+4 49 61 779 249
+4 49 254 248 249
+4 49 249 779 254
+4 32 402 888 218
+4 890 408 23 1006
+4 37 1032 852 49
+4 23 1006 624 890
+4 952 396 417 420
+4 936 952 417 420
+4 891 1009 22 505
+4 344 1009 22 891
+4 33 65 975 285
+4 37 53 852 242
+4 854 983 61 53
+4 915 894 306 66
+4 915 894 66 406
+4 895 564 152 630
+4 680 647 241 56
+4 896 628 339 139
+4 897 149 333 409
+4 897 625 333 149
+4 898 962 974 82
+4 373 603 65 57
+4 898 82 974 632
+4 138 435 411 900
+4 900 558 138 435
+4 273 34 894 406
+4 900 138 558 633
+4 901 711 432 148
+4 78 338 771 760
+4 583 760 338 78
+4 767 78 338 679
+4 679 78 338 771
+4 767 583 338 78
+4 903 35 234 261
+4 412 35 234 903
+4 903 35 261 636
+4 854 983 73 61
+4 25 638 232 904
+4 905 34 260 231
+4 510 905 231 34
+4 906 309 965 67
+4 906 67 965 635
+4 907 569 153 640
+4 908 721 512 152
+4 908 152 512 340
+4 64 68 618 641
+4 65 321 884 69
+4 66 70 342 626
+4 67 632 343 71
+4 76 78 574 583
+4 767 875 1010 76
+4 277 872 583 76
+4 277 76 764 872
+4 381 431 311 379
+4 381 571 311 97
+4 67 898 343 632
+4 314 511 588 10
+4 322 884 1003 715
+4 66 626 342 893
+4 272 94 96 666
+4 194 96 311 666
+4 134 341 429 340
+4 807 806 340 134
+4 134 340 924 142
+4 782 877 470 604
+4 807 340 341 134
+4 793 909 1004 838
+4 838 1004 548 909
+4 806 142 340 134
+4 134 340 429 924
+4 105 101 846 235
+4 312 403 434 562
+4 746 291 299 830
+4 315 848 737 438
+4 68 848 737 315
+4 212 410 115 107
+4 81 1002 693 885
+4 404 108 116 726
+4 1019 285 244 33
+4 1019 975 797 285
+4 140 887 623 557
+4 557 407 446 447
+4 262 309 308 906
+4 262 906 263 309
+4 903 234 233 261
+4 700 109 883 952
+4 883 105 952 109
+4 104 397 120 851
+4 629 563 196 912
+4 629 5 563 912
+4 128 913 934 701
+4 217 913 268 701
+4 105 846 121 235
+4 914 210 516 654
+4 844 346 121 113
+4 654 206 957 914
+4 210 914 206 654
+4 844 113 125 346
+4 774 356 405 821
+4 349 282 652 154
+4 555 466 463 669
+4 669 463 555 211
+4 236 669 211 463
+4 793 669 909 167
+4 793 669 236 463
+4 439 384 1004 463
+4 384 548 1004 463
+4 908 340 514 341
+4 908 512 514 340
+4 33 53 242 243
+4 53 889 33 242
+4 33 243 242 889
+4 743 940 431 575
+4 695 940 743 575
+4 575 940 431 579
+4 695 940 575 579
+4 583 580 574 744
+4 692 744 574 580
+4 330 273 724 915
+4 330 727 915 58
+4 727 406 915 58
+4 273 306 724 915
+4 273 894 306 915
+4 273 894 915 406
+4 757 413 590 910
+4 332 323 235 532
+4 251 757 590 910
+4 218 246 608 255
+4 218 246 283 608
+4 246 747 255 218
+4 335 336 968 360
+4 1022 335 968 326
+4 1022 968 335 336
+4 1002 726 176 378
+4 726 176 316 1002
+4 237 966 572 293
+4 966 293 414 572
+4 360 377 453 576
+4 377 180 453 576
+4 717 669 793 167
+4 717 669 236 793
+4 334 457 475 246
+4 481 334 246 457
+4 87 101 358 88
+4 88 387 101 358
+4 319 101 387 358
+4 87 438 358 101
+4 438 101 319 358
+4 942 74 88 358
+4 942 358 88 87
+4 942 87 438 358
+4 315 942 438 358
+4 747 334 246 481
+4 381 486 687 324
+4 916 486 381 324
+4 650 274 329 380
+4 217 268 953 542
+4 349 217 953 542
+4 916 579 381 486
+4 195 599 420 266
+4 195 420 599 350
+4 630 736 142 135
+4 919 436 452 447
+4 235 591 532 323
+4 640 739 143 136
+4 270 264 658 352
+4 170 391 561 269
+4 269 723 561 351
+4 293 433 165 237
+4 677 413 275 706
+4 413 279 275 706
+4 654 1013 921 525
+4 654 712 516 921
+4 137 445 941 920
+4 847 941 920 137
+4 577 247 856 36
+4 577 46 856 247
+4 577 46 247 437
+4 577 437 1024 221
+4 69 326 321 849
+4 849 85 326 375
+4 849 375 326 321
+4 136 623 150 446
+4 857 248 738 37
+4 857 46 437 248
+4 857 248 437 738
+4 135 858 427 736
+4 858 736 428 427
+4 866 424 739 127
+4 866 136 739 424
+4 88 922 100 387
+4 88 387 358 922
+4 922 103 387 517
+4 100 922 103 387
+4 71 335 860 923
+4 923 961 335 86
+4 71 343 335 923
+4 923 360 343 335
+4 860 335 86 923
+4 865 254 253 47
+4 700 141 147 417
+4 594 254 818 1025
+4 865 39 818 254
+4 865 818 253 254
+4 126 429 924 867
+4 126 429 428 924
+4 924 811 429 428
+4 924 429 811 340
+4 867 429 924 134
+4 762 334 481 457
+4 762 334 457 641
+4 504 273 727 406
+4 330 273 915 727
+4 273 406 915 727
+4 484 231 260 238
+4 905 231 260 484
+4 630 564 152 142
+4 806 152 340 142
+4 881 143 153 445
+4 1013 230 712 19
+4 921 712 19 1013
+4 1013 754 712 230
+4 640 569 153 143
+4 654 1013 754 712
+4 654 712 921 1013
+4 502 211 409 720
+4 502 717 236 370
+4 925 175 258 186
+4 186 435 258 925
+4 696 194 312 926
+4 696 133 926 312
+4 40 44 413 442
+4 473 927 783 188
+4 4 927 473 616
+4 621 188 783 927
+4 758 929 734 784
+4 170 929 734 758
+4 609 725 784 929
+4 140 557 407 887
+4 696 931 133 434
+4 695 696 581 931
+4 932 735 728 788
+4 167 932 909 171
+4 40 671 324 294
+4 41 545 785 672
+4 735 293 414 933
+4 555 736 564 630
+4 141 882 398 443
+4 634 643 488 566
+4 922 568 631 517
+4 618 737 565 641
+4 1006 790 624 567
+4 624 790 738 567
+4 1007 789 569 640
+4 640 789 569 739
+4 151 881 399 546
+4 258 180 774 175
+4 258 175 774 186
+4 774 180 440 175
+4 114 842 925 934
+4 175 842 744 934
+4 276 283 839 939
+4 939 629 839 276
+4 353 283 276 939
+4 939 629 276 196
+4 282 154 182 723
+4 277 744 689 583
+4 282 144 154 723
+4 583 380 689 277
+4 237 823 394 460
+4 164 773 512 824
+4 756 156 159 950
+4 824 825 773 512
+4 608 239 951 240
+4 199 1009 992 200
+4 992 200 1009 216
+4 288 278 744 776
+4 278 689 744 776
+4 459 497 398 443
+4 276 642 218 951
+4 642 951 402 218
+4 510 976 231 328
+4 13 510 24 328
+4 150 935 446 407
+4 935 446 447 729
+4 935 447 407 500
+4 935 595 447 500
+4 595 935 447 729
+4 12 23 219 889
+4 12 202 730 220
+4 12 220 219 202
+4 657 347 730 220
+4 12 506 889 220
+4 347 506 220 657
+4 411 258 925 106
+4 925 508 435 411
+4 109 117 515 952
+4 700 952 117 109
+4 234 937 523 509
+4 233 412 14 937
+4 215 228 233 937
+4 967 215 937 228
+4 937 509 234 412
+4 643 260 484 905
+4 535 484 533 238
+4 355 535 484 533
+4 508 469 435 652
+4 469 349 435 652
+4 925 469 435 508
+4 701 349 652 938
+4 701 938 542 349
+4 353 939 276 196
+4 198 176 316 400
+4 104 886 397 726
+4 991 459 169 163
+4 695 743 940 581
+4 585 579 940 695
+4 585 695 940 703
+4 703 940 581 695
+4 692 842 744 580
+4 745 878 496 515
+4 908 721 514 512
+4 758 561 929 784
+4 929 972 784 166
+4 954 909 171 167
+4 644 176 198 491
+4 375 176 198 644
+4 58 513 330 279
+4 58 513 279 684
+4 598 168 787 729
+4 991 163 498 433
+4 936 420 417 710
+4 702 710 420 936
+4 936 700 702 710
+4 700 936 417 710
+4 933 293 991 169
+4 237 433 165 460
+4 169 171 548 933
+4 60 541 74 72
+4 60 480 541 72
+4 734 758 604 170
+4 756 265 1005 159
+4 100 332 112 113
+4 85 644 99 86
+4 609 172 174 487
+4 944 345 111 110
+4 111 780 124 122
+4 49 779 61 51
+4 61 781 73 75
+4 122 946 126 948
+4 946 948 127 126
+4 471 259 495 582
+4 471 514 259 582
+4 46 50 48 247
+4 85 943 326 644
+4 943 644 335 326
+4 46 248 49 947
+4 947 49 51 254
+4 122 429 780 948
+4 122 946 948 780
+4 946 424 127 948
+4 549 927 783 8
+4 899 949 180 106
+4 82 949 576 899
+4 377 949 180 576
+4 82 949 377 576
+4 576 180 560 899
+4 653 185 786 304
+4 129 116 415 190
+4 717 950 192 236
+4 350 1005 599 159
+4 717 950 756 192
+4 756 950 159 1005
+4 484 231 328 905
+4 510 328 231 905
+4 882 398 443 444
+4 398 459 443 444
+4 900 435 411 258
+4 411 435 925 258
+4 234 412 903 233
+4 233 234 412 937
+4 888 402 951 218
+4 218 747 255 888
+4 887 407 446 557
+4 407 935 446 447
+4 12 889 219 220
+4 682 244 285 33
+4 417 591 952 883
+4 700 952 883 417
+4 700 417 936 952
+4 953 155 158 183
+4 599 292 710 157
+4 415 499 436 919
+4 953 155 919 452
+4 499 919 415 303
+4 60 541 589 945
+4 945 589 536 541
+4 598 305 651 787
+4 598 461 787 651
+4 540 294 324 649
+4 540 649 324 318
+4 717 954 838 265
+4 717 954 793 838
+4 717 793 954 167
+4 955 7 207 659
+4 267 207 659 955
+4 956 716 269 462
+4 729 956 462 716
+4 914 516 210 8
+4 670 958 245 524
+4 538 674 251 44
+4 966 433 293 237
+4 560 900 558 633
+4 989 559 432 901
+4 84 974 923 961
+4 961 335 644 360
+4 84 961 576 974
+4 961 360 644 453
+4 961 453 576 360
+4 923 360 335 961
+4 382 456 578 432
+4 382 259 456 432
+4 382 351 456 259
+4 456 282 351 382
+4 456 578 282 382
+4 759 792 0 871
+4 67 686 962 898
+4 67 310 962 686
+4 82 376 997 962
+4 841 962 686 605
+4 310 841 962 686
+4 898 997 962 82
+4 66 963 964 893
+4 66 964 963 513
+4 92 612 963 996
+4 513 684 963 606
+4 893 963 996 92
+4 350 396 420 197
+4 350 197 420 599
+4 1 9 665 772
+4 58 964 513 684
+4 617 200 184 979
+4 964 963 684 893
+4 964 684 963 513
+4 979 9 665 1
+4 518 904 25 232
+4 518 233 25 14
+4 106 114 519 949
+4 899 519 949 106
+4 244 483 388 1019
+4 483 388 1019 290
+4 621 10 667 2
+4 395 829 1020 297
+4 616 4 653 911
+4 776 176 689 810
+4 912 5 563 3
+4 200 505 9 979
+4 1 665 494 304
+4 1 304 772 665
+4 657 957 730 6
+4 8 707 783 549
+4 662 8 210 516
+4 177 358 392 489
+4 177 358 820 392
+4 392 698 358 820
+4 489 342 358 392
+4 392 342 358 698
+4 394 823 487 675
+4 505 1009 22 11
+4 11 22 402 951
+4 627 563 629 5
+4 637 408 201 12
+4 8 977 967 14
+4 662 967 210 8
+4 215 14 707 8
+4 977 967 14 937
+4 523 967 234 210
+4 523 967 937 234
+4 15 755 353 225
+4 999 655 955 3
+4 525 17 352 658
+4 1018 217 415 288
+4 754 206 957 654
+4 74 177 489 358
+4 315 358 820 177
+4 942 358 177 74
+4 315 358 177 942
+4 656 16 600 422
+4 656 527 600 16
+4 754 657 957 206
+4 657 401 754 17
+4 225 755 659 18
+4 712 210 516 662
+4 712 523 210 662
+4 712 662 921 19
+4 712 19 523 662
+4 531 917 458 19
+4 639 21 904 214
+4 880 26 32 241
+4 682 244 33 27
+4 14 509 937 412
+4 541 740 534 177
+4 685 263 531 29
+4 685 906 263 29
+4 480 177 740 541
+4 481 177 457 740
+4 619 32 52 334
+4 481 177 740 480
+4 245 656 958 42
+4 649 95 324 916
+4 540 42 324 294
+4 544 301 785 43
+4 301 545 785 43
+4 44 727 279 58
+4 45 678 602 960
+4 45 59 547 310
+4 193 490 468 737
+4 319 193 438 490
+4 565 193 468 737
+4 353 225 994 283
+4 918 352 317 224
+4 547 556 45 831
+4 39 51 861 984
+4 843 52 60 480
+4 438 737 820 490
+4 855 981 62 54
+4 39 261 861 55
+4 862 55 63 982
+4 28 645 504 520
+4 263 59 309 906
+4 263 59 906 685
+4 843 60 72 480
+4 855 981 74 62
+4 349 435 652 282
+4 862 63 75 982
+4 560 821 558 258
+4 264 317 682 658
+4 682 264 388 317
+4 57 286 682 646
+4 682 57 285 286
+4 346 332 485 323
+4 749 332 485 346
+4 764 277 77 76
+4 77 79 664 768
+4 729 956 539 462
+4 970 561 462 269
+4 970 956 269 462
+4 539 970 462 956
+4 911 6 730 957
+4 914 206 957 911
+4 210 911 206 914
+4 914 210 911 473
+4 692 580 574 78
+4 692 769 580 78
+4 8 914 473 210
+4 41 264 960 746
+4 910 42 245 958
+4 670 910 245 958
+4 910 670 245 251
+4 131 959 434 795
+4 752 710 599 420
+4 878 745 91 89
+4 703 581 971 695
+4 695 931 581 971
+4 95 93 916 649
+4 929 725 784 972
+4 725 708 784 972
+4 575 431 97 95
+4 167 932 552 788
+4 552 167 669 191
+4 552 788 669 167
+4 695 579 575 95
+4 426 332 252 532
+4 97 311 1011 96
+4 677 761 571 96
+4 874 97 431 1011
+4 280 396 952 420
+4 936 280 952 420
+4 411 925 114 106
+4 523 967 210 662
+4 91 878 496 745
+4 227 566 733 488
+4 733 253 227 488
+4 733 818 832 227
+4 733 253 818 227
+4 974 360 343 923
+4 974 360 923 961
+4 974 961 576 360
+4 94 501 390 272
+4 186 774 356 614
+4 934 913 217 701
+4 934 288 217 913
+4 93 496 745 91
+4 93 980 585 496
+4 550 744 128 928
+4 258 180 560 774
+4 560 180 440 774
+4 440 453 180 560
+4 114 949 925 842
+4 842 377 949 180
+4 106 114 949 925
+4 77 768 664 300
+4 220 33 243 244
+4 35 234 262 263
+4 931 131 133 434
+4 971 931 581 131
+4 561 970 495 758
+4 758 750 970 495
+4 539 750 970 758
+4 195 266 562 1035
+4 953 155 183 303
+4 117 795 131 703
+4 795 131 959 702
+4 926 133 130 312
+4 309 678 263 257
+4 263 685 531 59
+4 114 508 925 411
+4 115 507 410 212
+4 79 81 715 1002
+4 79 213 322 274
+4 375 327 213 809
+4 375 176 809 213
+4 937 977 523 509
+4 523 967 977 937
+4 662 523 967 977
+4 978 595 935 500
+4 595 978 935 729
+4 716 978 595 729
+4 200 505 979 617
+4 349 154 158 791
+4 182 791 158 154
+4 980 95 579 695
+4 980 579 585 695
+4 980 695 585 496
+4 595 713 919 155
+4 713 462 716 595
+4 713 155 595 716
+4 752 157 159 599
+4 288 776 744 810
+4 288 175 810 744
+4 417 710 292 157
+4 119 748 482 628
+4 339 482 748 628
+4 702 752 710 157
+4 702 157 710 700
+4 748 139 212 339
+4 339 139 212 410
+4 339 139 410 896
+4 981 74 541 489
+4 981 489 534 306
+4 855 306 981 54
+4 855 489 74 981
+4 55 829 261 697
+4 697 395 829 492
+4 861 51 697 984
+4 861 261 697 55
+4 982 985 297 75
+4 862 55 982 308
+4 862 982 75 985
+4 54 62 714 981
+4 50 62 536 863
+4 54 863 714 62
+4 61 249 1032 822
+4 852 1032 822 61
+4 852 53 822 242
+4 851 836 397 120
+4 345 836 397 851
+4 236 161 211 669
+4 983 289 987 73
+4 854 284 983 53
+4 854 987 73 983
+4 346 121 323 418
+4 844 418 121 346
+4 844 346 125 986
+4 863 260 488 38
+4 488 863 536 260
+4 863 62 536 714
+4 978 162 935 729
+4 39 984 861 261
+4 861 984 697 261
+4 71 862 985 308
+4 982 308 297 985
+4 862 982 985 308
+4 722 162 598 461
+4 70 306 489 855
+4 855 306 489 981
+4 346 986 418 521
+4 986 423 799 521
+4 137 844 986 418
+4 844 346 986 418
+4 348 851 345 397
+4 124 424 853 136
+4 37 242 852 1032
+4 1032 249 242 822
+4 852 242 822 1032
+4 69 284 987 854
+4 983 289 284 987
+4 854 284 987 983
+4 723 351 259 561
+4 129 448 278 300
+4 983 61 822 289
+4 983 822 284 289
+4 111 425 836 853
+4 853 836 419 425
+4 972 708 784 166
+4 982 697 395 829
+4 982 829 297 308
+4 735 932 909 788
+4 102 118 633 988
+4 98 110 366 405
+4 102 98 366 988
+4 989 118 663 559
+4 717 161 669 167
+4 191 167 669 161
+4 598 168 305 787
+4 978 168 162 729
+4 305 604 787 168
+4 541 981 534 533
+4 933 293 414 966
+4 541 981 714 62
+4 541 536 62 714
+4 159 1005 661 265
+4 159 1005 292 661
+4 98 988 453 405
+4 988 453 405 560
+4 560 558 405 988
+4 988 118 558 663
+4 988 98 366 405
+4 110 118 663 365
+4 601 487 174 172
+4 181 354 763 313
+4 1033 187 203 208
+4 181 313 763 668
+4 573 173 174 572
+4 146 919 303 155
+4 953 919 303 415
+4 951 218 255 888
+4 914 911 957 4
+4 300 990 278 277
+4 277 990 744 583
+4 277 764 300 990
+4 277 990 583 872
+4 277 872 764 990
+4 642 11 402 951
+4 402 218 32 26
+4 670 524 245 648
+4 648 538 530 251
+4 186 526 356 821
+4 596 821 356 526
+4 26 241 880 680
+4 26 527 241 680
+4 660 251 530 674
+4 571 765 873 97
+4 541 534 489 177
+4 534 177 392 489
+4 355 536 533 484
+4 716 168 978 729
+4 6 12 730 347
+4 116 499 404 415
+4 114 128 934 701
+4 114 934 925 701
+4 114 701 925 508
+4 199 951 239 992
+4 239 992 951 216
+4 199 1009 951 992
+4 951 992 1009 216
+4 627 276 563 951
+4 627 642 276 951
+4 469 349 186 435
+4 359 130 179 115
+4 186 821 774 258
+4 186 356 774 821
+4 901 711 578 432
+4 559 901 578 432
+4 497 368 147 443
+4 500 595 447 146
+4 502 720 409 145
+4 502 370 720 145
+4 240 355 189 484
+4 467 189 484 240
+4 717 161 236 669
+4 207 231 189 994
+4 994 535 231 189
+4 608 816 994 189
+4 994 816 535 189
+4 389 440 491 453
+4 40 670 910 538
+4 1035 959 562 133
+4 430 456 441 432
+4 441 456 471 432
+4 441 451 471 456
+4 995 694 949 899
+4 995 607 377 949
+4 80 694 607 995
+4 995 607 949 694
+4 996 606 684 94
+4 996 606 963 684
+4 893 963 684 996
+4 80 605 686 997
+4 997 962 376 605
+4 997 605 686 962
+4 898 686 962 997
+4 648 251 245 670
+4 648 670 538 251
+4 718 20 775 408
+4 718 9 775 20
+4 930 655 354 3
+4 3 354 570 563
+4 570 354 553 563
+4 563 553 239 354
+4 349 217 186 614
+4 300 664 77 277
+4 767 679 338 556
+4 766 545 329 301
+4 9 20 200 613
+4 613 200 344 20
+4 20 200 891 505
+4 344 200 891 20
+4 1002 378 176 213
+4 884 1003 321 322
+4 683 322 79 715
+4 79 715 322 213
+4 9 20 613 775
+4 20 567 775 890
+4 20 567 613 775
+4 20 408 890 775
+4 769 607 760 80
+4 769 607 580 760
+4 94 606 770 761
+4 761 606 770 275
+4 771 760 605 80
+4 771 338 605 760
+4 793 236 192 1004
+4 838 1004 383 548
+4 192 236 383 1004
+4 793 838 1004 192
+4 192 1004 383 838
+4 1005 197 292 192
+4 756 265 192 1005
+4 950 192 197 1005
+4 756 950 1005 192
+4 1005 192 661 265
+4 1005 192 292 661
+4 12 1006 201 202
+4 408 12 1006 201
+4 890 567 201 1006
+4 890 408 1006 201
+4 1007 907 569 461
+4 1007 729 798 446
+4 722 1007 162 461
+4 907 1007 722 461
+4 1008 895 564 466
+4 1008 503 466 161
+4 1008 895 466 503
+4 1008 564 555 466
+4 705 726 116 693
+4 1002 693 726 378
+4 200 216 344 1009
+4 505 199 1009 11
+4 515 117 280 952
+4 416 436 614 415
+4 193 515 379 1016
+4 515 1016 193 319
+4 193 1016 379 468
+4 193 1016 468 490
+4 319 193 490 1016
+4 135 625 149 333
+4 1006 567 624 890
+4 517 892 631 107
+4 1007 569 907 640
+4 643 1030 313 566
+4 902 643 634 566
+4 1008 555 564 630
+4 1008 564 895 630
+4 48 589 247 945
+4 870 572 487 472
+4 871 1033 184 763
+4 763 1033 187 871
+4 871 759 184 1033
+4 95 765 324 381
+4 381 765 324 571
+4 571 324 671 765
+4 1010 77 329 380
+4 1010 329 338 583
+4 1010 380 329 583
+4 1010 766 329 77
+4 1010 766 875 329
+4 338 875 329 1010
+4 767 1010 338 583
+4 338 875 1010 767
+4 1017 759 494 1
+4 1017 477 185 759
+4 477 1017 185 876
+4 494 876 185 1017
+4 876 185 477 188
+4 173 572 742 782
+4 782 487 470 877
+4 470 487 474 877
+4 487 474 877 609
+4 416 415 614 400
+4 1011 431 194 311
+4 1011 311 194 96
+4 874 1011 431 194
+4 194 312 926 296
+4 195 159 599 266
+4 195 599 159 350
+4 101 1012 235 332
+4 846 101 1012 235
+4 649 681 318 540
+4 650 544 322 683
+4 651 598 461 722
+4 532 426 522 197
+4 532 396 426 197
+4 599 292 197 710
+4 123 346 749 427
+4 749 346 485 427
+4 521 439 522 485
+4 323 521 522 485
+4 444 383 384 459
+4 244 682 388 317
+4 1014 521 522 323
+4 591 522 323 1014
+4 591 443 522 1014
+4 418 444 1014 521
+4 521 444 1014 383
+4 521 383 1014 522
+4 443 532 522 197
+4 443 522 532 591
+4 444 546 384 445
+4 198 316 397 400
+4 198 690 400 397
+4 348 198 397 690
+4 348 397 198 851
+4 198 1015 400 690
+4 348 198 690 1015
+4 868 198 348 1015
+4 868 453 198 1015
+4 533 534 238 260
+4 981 534 533 260
+4 644 453 491 198
+4 453 440 1015 405
+4 491 453 1015 198
+4 491 440 1015 453
+4 240 608 189 355
+4 189 246 535 355
+4 608 255 246 589
+4 608 246 816 189
+4 816 246 535 189
+4 207 328 467 189
+4 467 328 484 189
+4 456 259 1031 471
+4 471 259 1031 495
+4 471 495 1031 451
+4 456 471 1031 451
+4 468 357 1016 379
+4 490 357 1016 468
+4 188 802 473 209
+4 473 802 597 209
+4 473 597 802 215
+4 403 478 396 584
+4 563 951 239 199
+4 563 951 608 239
+4 537 208 221 227
+4 225 493 816 283
+4 207 225 994 353
+4 608 276 353 283
+4 207 563 353 608
+4 207 994 189 608
+4 316 375 83 622
+4 910 324 287 281
+4 911 185 202 786
+4 909 788 669 463
+4 793 669 463 909
+4 130 271 179 312
+4 130 271 312 562
+4 349 526 186 435
+4 349 526 435 282
+4 341 441 989 429
+4 114 842 934 178
+4 118 558 663 559
+4 752 959 420 266
+4 702 959 420 752
+4 712 662 516 921
+4 678 458 257 960
+4 155 716 713 753
+4 353 659 225 755
+4 725 777 582 708
+4 725 708 582 784
+4 572 823 394 237
+4 572 823 487 394
+4 667 314 668 588
+4 374 314 610 10
+4 762 843 480 481
+4 762 843 72 480
+4 387 332 482 100
+4 642 218 402 26
+4 496 703 585 586
+4 585 703 940 586
+4 586 940 581 703
+4 734 609 474 784
+4 734 609 784 929
+4 692 744 928 574
+4 615 570 184 617
+4 617 792 184 615
+4 41 746 960 45
+4 730 202 911 205
+4 657 957 206 730
+4 911 730 206 957
+4 104 316 397 198
+4 622 104 316 726
+4 104 726 397 316
+4 850 198 104 99
+4 83 104 316 622
+4 211 236 748 720
+4 478 748 212 339
+4 83 316 850 375
+4 99 851 198 104
+4 851 397 198 104
+4 98 102 453 988
+4 102 453 988 560
+4 102 453 560 576
+4 599 420 710 197
+4 548 393 966 414
+4 548 459 966 393
+4 80 995 607 611
+4 611 607 377 995
+4 612 606 996 94
+4 612 606 342 963
+4 612 606 963 996
+4 80 605 997 611
+4 611 997 376 605
+4 511 1030 566 313
+4 950 320 350 197
+4 950 1005 350 159
+4 274 213 361 689
+4 213 689 176 543
+4 274 213 529 361
+4 213 361 809 529
+4 213 176 809 543
+4 1002 1003 213 375
+4 79 1002 715 213
+4 1016 515 379 869
+4 515 869 1016 319
+4 319 515 869 252
+4 216 1024 226 221
+4 240 537 216 226
+4 537 226 221 216
+4 556 338 785 830
+4 746 291 830 785
+4 746 556 785 830
+4 195 420 562 266
+4 195 562 420 350
+4 707 639 214 667
+4 707 214 188 667
+4 922 103 517 631
+4 89 565 737 193
+4 89 745 565 193
+4 878 193 745 89
+4 451 495 462 750
+4 346 427 423 521
+4 346 323 485 521
+4 381 379 468 486
+4 381 486 468 687
+4 283 816 246 493
+4 677 770 275 761
+4 677 275 571 761
+4 296 96 194 666
+4 557 447 446 1026
+4 28 238 273 34
+4 28 238 371 273
+4 288 1000 217 913
+4 217 1000 268 913
+4 614 217 953 349
+4 774 400 356 614
+4 430 559 596 432
+4 559 578 596 432
+4 776 689 744 810
+4 351 452 456 1031
+4 447 462 673 452
+4 351 753 452 462
+4 673 1031 456 452
+4 713 447 452 462
+4 713 462 452 753
+4 243 289 250 1019
+4 553 239 354 181
+4 553 200 992 181
+4 682 286 388 264
+4 1020 796 256 483
+4 250 1019 289 290
+4 1020 250 289 290
+4 1020 492 262 829
+4 1020 290 297 298
+4 1020 298 297 262
+4 256 257 796 309
+4 796 299 298 309
+4 262 298 308 309
+4 882 444 443 1014
+4 141 591 882 443
+4 591 443 1014 882
+4 485 426 749 439
+4 485 439 522 426
+4 151 444 445 546
+4 445 593 546 384
+4 512 464 465 1021
+4 1021 340 465 512
+4 340 587 1021 465
+4 911 202 185 205
+4 185 205 204 801
+4 911 185 801 205
+4 229 230 803 256
+4 229 250 492 803
+4 229 256 234 230
+4 229 256 492 234
+4 29 917 234 263
+4 69 797 321 326
+4 65 285 603 321
+4 797 321 326 327
+4 287 318 324 687
+4 287 687 324 331
+4 289 781 297 290
+4 289 290 797 326
+4 290 797 326 327
+4 290 297 1022 781
+4 290 327 326 1022
+4 298 336 299 290
+4 290 322 327 688
+4 290 688 327 337
+4 297 985 308 1022
+4 1022 327 968 336
+4 1022 308 805 985
+4 1022 336 335 805
+4 298 805 309 310
+4 298 310 299 336
+4 310 336 337 299
+4 71 805 335 343
+4 67 343 310 805
+4 67 310 343 962
+4 310 337 343 841
+4 310 841 343 962
+4 137 799 941 445
+4 739 450 449 811
+4 424 450 429 1023
+4 1023 446 450 451
+4 789 424 1023 450
+4 789 446 450 1023
+4 340 811 1021 587
+4 924 455 811 428
+4 924 811 455 340
+4 450 800 798 676
+4 800 676 750 798
+4 981 306 260 54
+4 218 255 608 951
+4 608 255 589 240
+4 608 589 246 355
+4 577 247 216 1024
+4 577 437 247 1024
+4 216 247 226 1024
+4 401 220 223 918
+4 712 754 813 230
+4 401 224 223 813
+4 488 253 227 1024
+4 712 813 229 230
+4 712 234 230 229
+4 39 819 254 984
+4 594 1025 818 232
+4 1025 817 594 254
+4 1025 254 249 817
+4 1025 249 254 697
+4 1025 697 254 984
+4 1025 818 819 254
+4 1025 984 254 819
+4 778 490 358 698
+4 698 490 358 820
+4 342 778 358 698
+4 26 241 283 218
+4 26 32 241 218
+4 400 356 614 416
+4 1026 447 451 673
+4 241 475 334 281
+4 394 487 472 824
+4 394 592 824 472
+4 592 472 466 824
+4 675 823 487 676
+4 203 221 208 828
+4 827 203 828 221
+4 827 222 221 828
+4 204 222 209 1027
+4 1027 219 222 476
+4 1027 476 817 372
+4 1027 476 222 817
+4 778 698 833 490
+4 698 331 778 833
+4 372 1027 594 817
+4 372 228 826 597
+4 372 228 594 826
+4 53 822 243 284
+4 249 250 243 289
+4 249 289 395 250
+4 61 779 249 289
+4 779 289 395 249
+4 822 61 249 289
+4 55 308 262 829
+4 785 688 830 329
+4 287 325 331 1028
+4 1028 325 331 698
+4 1028 1034 331 513
+4 287 590 1028 331
+4 1028 698 331 1034
+4 831 556 830 338
+4 830 338 337 831
+4 357 386 379 699
+4 1016 357 386 379
+4 490 357 386 1016
+4 568 490 357 386
+4 568 390 386 357
+4 357 386 699 390
+4 828 208 832 227
+4 828 594 227 832
+4 379 403 699 1029
+4 1029 478 403 554
+4 234 492 261 262
+4 262 261 234 35
+4 835 233 234 261
+4 835 492 261 234
+4 1025 835 834 697
+4 835 697 492 834
+4 834 243 476 249
+4 219 242 243 889
+4 967 228 234 210
+4 228 234 233 937
+4 967 228 937 234
+4 205 206 220 223
+4 205 219 476 220
+4 205 223 476 372
+4 476 220 219 243
+4 228 834 223 372
+4 228 223 834 229
+4 345 837 690 836
+4 836 356 837 690
+4 120 557 140 623
+4 120 836 557 419
+4 270 458 352 525
+4 270 257 352 458
+4 269 351 561 462
+4 252 235 952 532
+4 172 824 601 487
+4 728 172 824 601
+4 1 617 792 184
+4 979 759 184 1
+4 792 1 184 759
+4 759 792 871 184
+4 621 2 667 188
+4 2 188 187 667
+4 494 665 759 185
+4 494 665 185 304
+4 1017 759 185 494
+4 925 180 258 175
+4 925 842 180 175
+4 925 842 175 934
+4 25 233 232 819
+4 25 636 233 819
+4 67 309 965 805
+4 67 310 309 805
+4 799 151 882 444
+4 799 151 444 445
+4 65 797 975 285
+4 65 797 285 321
+4 696 434 743 581
+4 696 434 581 931
+4 165 293 237 173
+4 311 357 699 666
+4 479 311 699 666
+4 769 842 580 607
+4 692 842 580 769
+4 643 484 328 905
+4 665 201 185 704
+4 665 704 637 201
+4 839 627 642 276
+4 1002 176 375 213
+4 944 405 345 110
+4 944 99 345 348
+4 944 405 348 345
+4 239 537 216 240
+4 239 992 216 537
+4 1002 885 726 693
+4 885 726 622 1002
+4 622 83 1003 375
+4 375 732 809 176
+4 272 312 130 179
+4 272 296 130 312
+4 312 272 479 993
+4 312 969 993 699
+4 312 479 699 993
+4 440 180 389 175
+4 180 842 389 175
+4 175 842 389 744
+4 92 342 612 568
+4 793 954 909 838
+4 793 909 954 167
+4 845 101 319 438
+4 845 105 319 101
+4 202 1006 219 12
+4 236 439 383 1004
+4 197 426 522 236
+4 320 236 426 197
+4 320 426 396 197
+4 599 197 292 1005
+4 350 1005 197 599
+4 950 197 350 1005
+4 246 534 238 533
+4 246 493 238 814
+4 246 534 814 238
+4 816 246 493 238
+4 535 533 246 238
+4 535 246 816 238
+4 560 558 988 633
+4 633 118 558 988
+4 414 472 463 393
+4 548 414 463 393
+4 414 788 463 472
+4 414 909 463 788
+4 548 909 463 414
+4 981 541 534 489
+4 933 548 966 414
+4 966 991 459 548
+4 966 593 237 394
+4 433 237 966 593
+4 175 440 810 389
+4 744 175 810 389
+4 787 750 539 758
+4 282 452 456 351
+4 415 726 116 705
+4 415 776 726 705
+4 415 776 705 278
+4 104 316 850 83
+4 498 399 433 163
+4 9 505 200 20
+4 328 313 643 1030
+4 935 162 1007 729
+4 935 729 1007 446
+4 11 951 199 1009
+4 720 236 320 370
+4 33 53 243 975
+4 33 243 1019 975
+4 397 416 886 557
+4 397 557 886 120
+4 894 306 54 34
+4 260 306 34 54
+4 315 438 737 820
+4 437 221 738 815
+4 437 248 815 738
+4 401 918 223 224
+4 450 676 461 675
+4 569 461 675 450
+4 1007 569 450 461
+4 450 798 461 676
+4 1007 450 798 461
+4 592 393 385 384
+4 384 393 463 592
+4 1019 289 797 284
+4 1019 797 289 290
+4 223 250 229 803
+4 813 229 230 803
+4 813 229 803 223
+4 587 676 1021 465
+4 441 465 800 587
+4 587 800 676 465
+4 351 462 1031 561
+4 673 462 451 1031
+4 351 452 1031 462
+4 673 462 1031 452
+4 803 256 483 1020
+4 229 803 492 256
+4 492 803 1020 256
+4 558 596 578 821
+4 822 289 243 284
+4 243 284 289 1019
+4 245 475 281 287
+4 910 245 281 287
+4 245 241 281 475
+4 354 307 313 467
+4 354 307 763 313
+4 992 239 181 537
+4 553 239 992 199
+4 553 992 239 181
+4 69 987 797 326
+4 987 289 797 326
+4 424 419 425 853
+4 201 1027 204 202
+4 185 204 202 201
+4 352 264 388 796
+4 746 299 291 796
+4 746 264 796 291
+4 286 322 290 688
+4 829 262 297 308
+4 1020 829 262 297
+4 45 310 746 602
+4 37 790 1032 248
+4 476 1032 248 249
+4 790 476 1032 248
+4 256 298 262 309
+4 263 256 262 309
+4 256 298 309 796
+4 256 309 263 257
+4 796 290 1020 298
+4 1020 290 796 483
+4 951 255 608 240
+4 393 463 592 472
+4 385 393 394 593
+4 283 816 994 608
+4 283 246 816 608
+4 353 994 608 283
+4 805 310 336 343
+4 298 336 805 310
+4 781 1022 326 335
+4 289 326 781 290
+4 290 781 1022 326
+4 424 1023 429 780
+4 780 429 430 1023
+4 423 427 428 454
+4 1033 208 203 181
+4 187 668 208 1033
+4 759 1033 187 203
+4 871 759 1033 187
+4 437 46 253 947
+4 437 947 253 815
+4 815 947 253 254
+4 71 985 335 805
+4 297 335 985 1022
+4 1022 985 805 335
+4 815 253 1024 227
+4 437 253 1024 815
+4 948 428 429 811
+4 465 825 464 512
+4 372 228 834 817
+4 372 817 594 228
+4 464 824 466 512
+4 464 592 466 824
+4 834 1025 249 817
+4 834 249 1025 697
+4 476 249 817 834
+4 204 1027 209 801
+4 801 209 597 372
+4 801 209 372 1027
+4 473 801 209 597
+4 221 815 227 828
+4 828 227 594 815
+4 835 261 819 233
+4 835 697 1025 261
+4 835 261 1025 819
+4 1029 390 554 969
+4 699 969 390 1029
+4 290 336 1022 298
+4 39 819 984 261
+4 1025 697 984 261
+4 1025 261 984 819
+4 299 337 310 831
+4 831 337 310 841
+4 594 832 232 818
+4 733 818 232 832
+4 449 1021 455 811
+4 340 811 455 1021
+4 917 263 257 256
+4 917 263 256 234
+4 280 952 396 252
+4 252 952 396 532
+4 252 387 319 332
+4 101 235 319 332
+4 1034 778 606 342
+4 513 606 342 1034
+4 698 1034 342 778
+4 1028 342 1034 513
+4 1028 698 1034 342
+4 209 826 594 832
+4 832 826 594 232
+4 393 472 592 394
+4 280 396 1029 252
+4 252 396 1029 478
+4 280 252 1029 869
+4 688 337 329 529
+4 830 329 337 338
+4 688 329 337 830
+4 464 825 487 824
+4 397 557 836 416
+4 416 557 836 356
+4 397 400 416 690
+4 690 400 416 356
+4 397 416 836 690
+4 730 205 206 220
+4 730 205 911 206
+4 205 220 476 223
+4 476 220 243 223
+4 451 750 462 729
+4 539 729 462 750
+4 234 233 835 228
+4 372 817 834 476
+4 1026 673 451 456
+4 405 356 837 596
+4 690 356 837 405
+4 690 356 405 400
+4 52 888 255 747
+4 650 79 274 664
+4 650 274 380 664
+4 623 887 446 557
+4 136 623 446 419
+4 37 889 242 219
+4 975 69 284 797
+4 33 975 1019 285
+4 975 797 284 1019
+4 38 260 643 905
+4 636 903 233 261
+4 636 261 819 39
+4 636 261 233 819
+4 774 821 560 258
+4 258 106 180 925
+4 200 973 505 617
+4 199 812 11 505
+4 92 612 342 963
+4 893 342 963 92
+4 893 626 342 92
+4 100 482 112 332
+4 843 52 480 481
+4 502 236 211 720
+4 237 394 572 966
+4 166 582 259 160
+4 582 514 259 160
+4 723 259 160 166
+4 1031 259 561 495
+4 351 561 1031 259
+4 627 5 199 563
+4 627 951 563 199
+4 682 286 285 388
+4 235 591 952 532
+4 1012 121 235 323
+4 1012 323 235 332
+4 846 1012 121 235
+4 137 445 920 143
+4 881 137 143 445
+4 626 70 342 90
+4 90 342 859 70
+4 568 92 342 90
+4 626 90 342 92
+4 632 923 343 71
+4 632 84 923 71
+4 632 974 343 923
+4 31 39 232 818
+4 31 818 232 733
+4 31 39 818 865
+4 638 39 232 31
+4 69 849 321 83
+4 1018 288 278 132
+4 1018 415 278 288
+4 36 216 344 577
+4 221 577 216 1024
+4 780 124 946 424
+4 780 429 424 948
+4 780 946 948 424
+4 947 49 254 248
+4 73 943 781 326
+4 48 50 945 247
+4 488 50 247 536
+4 253 50 247 488
+4 50 945 247 536
+4 123 125 346 427
+4 954 171 838 998
+4 998 838 731 171
+4 266 959 562 1035
+4 159 752 599 266
+4 661 192 292 731
+4 719 661 292 731
+4 291 264 388 286
+4 976 307 328 13
+4 307 709 313 13
+4 7 307 13 709
+4 7 976 13 307
+4 328 307 313 13
+4 544 57 286 322
+4 683 57 322 373
+4 683 57 544 322
+4 378 726 705 693
+4 215 707 639 214
+4 518 232 25 233
+4 916 95 579 980
+4 916 579 486 585
+4 916 579 585 980
+4 115 212 359 507
+4 212 320 584 528
+4 350 302 562 584
+4 307 620 313 709
+4 511 709 313 620
+4 795 581 131 703
+4 163 433 459 546
+4 399 163 546 433
+4 743 431 479 194
+4 696 431 743 194
+4 696 743 431 575
+4 696 431 874 575
+4 696 874 431 194
+4 583 574 990 744
+4 872 574 990 583
+
+CELL_TYPES 4436
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
diff --git a/data/reduced_torus/torus_mesh_visual.vtk b/data/reduced_torus/torus_mesh_visual.vtk
new file mode 100644
index 000000000..a06ef2061
--- /dev/null
+++ b/data/reduced_torus/torus_mesh_visual.vtk
@@ -0,0 +1,9917 @@
+# vtk DataFile Version 2.0
+torus_, Created by Gmsh
+ASCII
+DATASET UNSTRUCTURED_GRID
+POINTS 1036 double
+-0.75 -2.18556941e-08 1.13246855e-07
+-0.71031338 -0.135160238 1.07254337e-07
+-0.710313141 0.135160565 1.07254301e-07
+-0.692909718 -2.18556941e-08 -0.287012398
+-0.692909598 -2.18556941e-08 0.287012607
+-0.65624404 -0.135160238 -0.271825016
+-0.6562439799999999 -0.135160238 0.271825194
+-0.656243861 0.135160565 -0.271824926
+-0.656243742 0.135160565 0.271825105
+-0.603853762 -0.227407992 9.11793805e-08
+-0.603853405 0.227408156 9.11793308e-08
+-0.558141589621361 -0.2272469457790709 -0.2307452454467901
+-0.557888091 -0.227407992 0.231084868
+-0.557887852 0.227408156 -0.23108457
+-0.557887793 0.227408156 0.231084719
+-0.530330241 -2.18556941e-08 -0.530329943
+-0.50226754 -0.135160238 -0.5022673010000001
+-0.50226742 -0.135160238 0.50226742
+-0.50226742 0.135160565 -0.502267122
+-0.502267241 0.135160565 0.502267241
+-0.464421362 -0.247455373 7.01256795e-08
+-0.464420974 0.247455314 7.01256155e-08
+-0.42906943 -0.247455373 -0.177726254
+-0.4296712671318722 -0.247455373 0.1747004492923097
+-0.429069072 0.247455314 -0.17772612
+-0.429069012 0.247455314 0.177726239
+-0.426989228 -0.227407992 -0.426988989
+-0.426989079 -0.227407992 0.426989079
+-0.426988959 0.227408156 -0.426988721
+-0.42698884 0.227408156 0.42698884
+-0.336284906 -0.18893747 5.07776079e-08
+-0.336284608 0.188937217 5.07775653e-08
+-0.328395605 -0.247455373 -0.328395396
+-0.328395486 -0.247455373 0.328395486
+-0.328395337 0.247455314 -0.328395128
+-0.328395218 0.247455314 0.328395218
+-0.310686767 -0.18893747 -0.128690585
+-0.310686737 -0.18893747 0.128690675
+-0.310686499 0.188937217 -0.128690481
+-0.310686469 0.188937217 0.128690571
+-0.287012696 -2.18556941e-08 -0.692909598
+-0.287012637 -2.18556941e-08 0.692909598
+-0.271825254 -0.135160238 -0.6562439799999999
+-0.271825224 -0.135160238 0.6562439799999999
+-0.271825165 0.135160565 -0.656243742
+-0.271825135 0.135160565 0.656243742
+-0.260126799 -0.07043330370000001 3.92780564e-08
+-0.26012671 0.07043293120000001 3.92780422e-08
+-0.240325853 -0.07043330370000001 -0.09954615679999999
+-0.240325823 -0.07043330370000001 0.0995462313
+-0.240325764 0.07043293120000001 -0.099546127
+-0.240325734 0.07043293120000001 0.0995461941
+-0.237789407 -0.18893747 -0.237789273
+-0.237789333 -0.18893747 0.237789333
+-0.237789199 0.188937217 -0.237789065
+-0.237789124 0.188937217 0.237789124
+-0.231084913 -0.227407992 -0.557888091
+-0.231084883 -0.227407992 0.557888091
+-0.231084779 0.227408156 -0.557887793
+-0.231084749 0.227408156 0.557887793
+-0.18393749 -0.07043330370000001 -0.183937371
+-0.183937415 -0.07043330370000001 0.183937415
+-0.183937415 0.07043293120000001 -0.183937311
+-0.1826027894390168 0.07043797995747503 0.1848329123509294
+-0.177726433 -0.247455373 -0.42906937
+-0.177726403 -0.247455373 0.42906937
+-0.177726284 0.247455314 -0.429069012
+-0.177726254 0.247455314 0.429069012
+-0.128690705 -0.18893747 -0.310686737
+-0.12869069 -0.18893747 0.310686737
+-0.1286906 0.188937217 -0.310686469
+-0.128690571 0.188937217 0.310686469
+-0.0995462537 -0.07043330370000001 -0.240325823
+-0.09954623880000001 -0.07043330370000001 0.240325823
+-0.0995462164 0.07043293120000001 -0.240325734
+-0.0995462015 0.07043293120000001 0.240325734
+-3.27835394e-08 -2.18556941e-08 0.75
+-3.10487849e-08 -0.135160238 0.71031338
+-0.002247339125087955 0.135160565 0.7098661234313948
+-2.6395286e-08 -0.227407992 0.603853762
+-2.639527e-08 0.227408156 0.603853405
+0.005294134150853763 -0.247455373 0.4633682886880875
+-2.03004848e-08 0.247455314 0.464420974
+-1.46994799e-08 -0.18893747 0.336284906
+-1.46994674e-08 0.188937217 0.336284608
+-1.13705036e-08 -0.07043330370000001 0.260126799
+-1.13704992e-08 0.07043293120000001 0.26012671
+3.10198112e-09 -0.07043330370000001 -0.260126799
+3.10198001e-09 0.07043293120000001 -0.26012671
+4.01015754e-09 -0.18893747 -0.336284906
+4.01015399e-09 0.188937217 -0.336284608
+5.53816948e-09 -0.247455373 -0.464421362
+5.53816459e-09 0.247455314 -0.464420974
+7.20088389e-09 -0.227407992 -0.603853762
+7.20087989e-09 0.227408156 -0.603853405
+8.470402160000001e-09 -0.135160238 -0.71031338
+8.470399489999999e-09 0.135160565 -0.710313141
+8.943660029999999e-09 -2.18556941e-08 -0.75
+0.0995461792 0.07043293120000001 0.240325734
+0.0995462164 -0.07043330370000001 0.240325823
+0.09954622389999999 0.07043293120000001 -0.240325719
+0.09954626110000001 -0.07043330370000001 -0.240325809
+0.128690541 0.188937217 0.310686469
+0.1286906 0.188937217 -0.310686439
+0.12869066 -0.18893747 0.310686737
+0.12869072 -0.18893747 -0.310686707
+0.177726209 0.247455314 0.429069012
+0.177726299 0.247455314 -0.429068983
+0.177726358 -0.247455373 0.42906937
+0.177726448 -0.247455373 -0.42906934
+0.183937356 0.07043293120000001 0.183937356
+0.183937415 -0.07043330370000001 0.183937415
+0.183937415 0.07043293120000001 -0.183937296
+0.18393749 -0.07043330370000001 -0.183937356
+0.231084689 0.227408156 0.557887793
+0.231084794 0.227408156 -0.5578877330000001
+0.231084824 -0.227407992 0.557888091
+0.231084928 -0.227407992 -0.557888091
+0.237789124 0.188937217 0.237789124
+0.237789199 0.188937217 -0.237789035
+0.237789333 -0.18893747 0.237789333
+0.237789407 -0.18893747 -0.237789258
+0.240325734 0.07043293120000001 0.0995461866
+0.240325794 0.07043293120000001 -0.09954606739999999
+0.2405965857521089 -0.07043330370000001 0.09818501000602463
+0.240325883 -0.07043330370000001 -0.0995460972
+0.26012671 0.07043293120000001 1.69520092e-07
+0.260126799 -0.07043330370000001 1.69520149e-07
+0.271825075 0.135160565 0.656243742
+0.271825165 -0.135160238 0.6562439799999999
+0.271825194 0.135160565 -0.6562436820000001
+0.271825284 -0.135160238 -0.65624392
+0.287012577 -2.18556941e-08 0.692909598
+0.287012696 -2.18556941e-08 -0.692909598
+0.310686469 0.188937217 0.128690556
+0.310686529 0.188937217 -0.128690392
+0.310686737 -0.18893747 0.128690675
+0.310686827 -0.18893747 -0.128690511
+0.328395218 0.247455314 0.328395218
+0.328395337 0.247455314 -0.328395098
+0.328395486 -0.247455373 0.328395486
+0.328395605 -0.247455373 -0.328395367
+0.336284608 0.188937217 2.19150877e-07
+0.336284906 -0.18893747 2.19151062e-07
+0.42698884 0.227408156 0.42698884
+0.426988959 0.227408156 -0.426988691
+0.426989079 -0.227407992 0.426989079
+0.426989228 -0.227407992 -0.42698893
+0.429069012 0.247455314 0.177726224
+0.429069132 0.247455314 -0.177726001
+0.4285832038493428 -0.2473905309719522 0.1782033175787506
+0.429069489 -0.247455373 -0.17772615
+0.464420974 0.247455314 3.02655138e-07
+0.464421362 -0.247455373 3.02655394e-07
+0.502267241 0.135160565 0.502267241
+0.50226742 -0.135160238 0.50226742
+0.50226742 0.135160565 -0.502267063
+0.50226754 -0.135160238 -0.502267241
+0.530330062 -2.18556941e-08 0.530330062
+0.530330241 -2.18556941e-08 -0.5303298829999999
+0.557887793 0.227408156 0.231084704
+0.557887912 0.227408156 -0.231084421
+0.557888091 -0.227407992 0.231084839
+0.557888269 -0.227407992 -0.231084555
+0.603853405 0.227408156 3.9352085e-07
+0.603853762 -0.227407992 3.93521077e-07
+0.656243742 0.135160565 0.271825075
+0.65624392 0.135160565 -0.271824747
+0.6562439799999999 -0.135160238 0.271825165
+0.656244159 -0.135160238 -0.271824837
+0.692909598 -2.18556941e-08 0.287012577
+0.692909837 -2.18556941e-08 -0.287012219
+0.710313141 0.135160565 4.62898811e-07
+0.71031338 -0.135160238 4.62898981e-07
+0.75 -2.18556941e-08 4.88762055e-07
+0.2148047599579061 0.05862636186789426 0.502491616306411
+0.08708371449759361 -0.07904678396405236 0.4544761890310727
+-0.146602316861926 -0.009632696391538147 -0.315119087525655
+0.1692244930490057 0.1812843605 0.623422415988969
+0.2079651687174781 0.1331645320914401 -0.5836410988931576
+0.1536632925775345 0.1239510807482383 0.4572738201945878
+-0.5671834958762344 -0.01939125278810325 -0.1175294783630399
+0.5569435355 0.06758027157215296 0.45546928025
+0.45546936975 -0.06758012992784704 0.5569436249999999
+-0.6446421632553362 -0.05976163801653798 -0.1092778761071423
+-0.6214703736046712 -0.0666511357727524 0.1250423258651282
+0.300758051598111 0.07172693423651585 0.4583027905022347
+-0.654305795925001 0.03357102801595683 0.001848341005699126
+-0.6258175216303261 0.05432506588159775 0.1162604558790866
+-0.442057131510203 0.03095741689814975 -0.2765487156973705
+0.30043105825 -0.181284115 0.5743412825
+0.6159713774510746 0.1837769934522046 -0.1922216808197105
+0.5322994338378045 0.008502274921264123 -0.3744977122371063
+0.04265738067802943 -0.1046145807176613 -0.4450745330079127
+0.1246996850352893 0.06574632593164867 -0.7058907283422399
+0.414704820039705 0.05850602124603817 -0.5873244043967869
+-0.5997874394191635 -0.06652994583433987 -0.3918934603056267
+0.4105207575547945 -0.02280618123261142 -0.4112567807811419
+0.1154383286484265 -0.0670131696695989 0.3444306649723132
+-0.5457887659485642 -0.1555429921777584 -0.2112258584708629
+-0.556036820477818 -0.1322847934326201 -0.08914487821102607
+-0.5287910658346734 -0.145964002948216 0.09942815883918801
+-0.5488808869220985 -0.1230845936541704 0.1994070919703603
+-0.5514166647614607 -0.06021660203561584 0.006754432547757371
+-0.5410083912396699 -0.04992438886868006 0.1097211985421525
+-0.5282477366216665 -0.0457190959344033 0.2285741534938628
+-0.5471074779992053 -0.03863338164943837 0.3383833878444414
+-0.5379197870483288 0.04712173579130802 -0.311524103556143
+-0.5444049150912931 0.04459180613937631 0.004718340344478199
+-0.5221095018638044 0.0369594492107734 0.119071275868263
+-0.5308799781628447 0.04747798722078263 0.3117821923412912
+0.4475426814502823 0.1489278561181345 -0.2688886257995359
+0.2996792148585254 0.1654024873724193 -0.4496521940991762
+0.0006848522370035207 -0.1023848032902419 0.5037054741521728
+-0.5278138632473582 0.1468044649733942 0.09245296480095991
+-0.5412677375001846 0.1432254272463678 0.2064531176041771
+-0.4231612307707837 -0.1037401749254241 -0.1337060640227804
+0.3305945547851408 0.01949853570690828 0.5514300148461841
+-0.4037618125828935 -0.1605445022397436 -0.336392455313646
+-0.4247760234915319 -0.1530323475734049 0.2024351829109144
+-0.4495954867690495 -0.1502396951148145 0.3301820862519624
+-0.4408269404029921 -0.07227179543752946 -0.0169300934674944
+-0.4374801290473587 -0.07174959795745348 0.1003803329881969
+-0.4416965121862891 -0.04176342978079188 0.3173556488626441
+-0.4210349730051253 -0.04504186570420775 0.4288698757126937
+-0.4469474911194326 0.05062181151367538 -0.4380625839577525
+-0.4208545034966771 0.02789523773719308 -0.124023188409767
+-0.4426622831200132 0.05234302201265242 -0.01514508992852398
+-0.4508707370426806 0.07401740893526983 0.235274710670023
+-0.4193989654820721 0.05283121747753344 0.3293365305174706
+-0.429259712191232 0.04147422157022783 0.4546009980040832
+-0.4365211327554736 0.1347201315161209 -0.3271173605683869
+-0.4285450353537538 0.1540513903482495 0.1047628151789162
+-0.4403871896259152 0.1709419521191819 0.210772629951794
+-0.4174665753576615 0.1439620252099086 0.3300534389646202
+0.2079223709471942 -0.1155629893027928 -0.3256443507170392
+0.4773776328763831 0.08791904828105823 -0.3315091410248636
+0.6109661671423812 -0.1312233317339073 -0.04826091956918894
+-0.3210912808149326 0.09886036457796581 -0.3443362945660071
+-0.5107203347875002 -0.0511037324690895 -0.2162246520966066
+-0.4274951252036663 -0.03507233851382638 -0.1978104046406515
+-0.3221922211749222 -0.1445975170440534 -0.4425145553301829
+-0.3286954227264652 -0.1434492302514711 0.2222906885168947
+-0.3285017090814557 -0.1265089069691785 0.308151421041821
+-0.3395649970840241 -0.1554064149526791 0.4225686128741589
+-0.3290190794293953 -0.05254108065203134 -0.5467141964176405
+-0.3159309151850979 -0.04120775039923903 -0.3224716358271946
+-0.3258398369406388 -0.03510117790117903 -0.1134249561622734
+-0.3376001506561476 -0.05717751503157612 0.102342810283574
+-0.3114520801316878 -0.03409065073118795 0.2177680683076604
+-0.328474165477487 -0.02648855206584399 0.3310258350020063
+-0.3225401600591715 0.05796838860563992 -0.5319520165267214
+0.2015107240799966 -0.0348512362201389 -0.4020904760206556
+-0.3346454802644096 0.05207433096846966 -0.01301303916511887
+-0.324625531231217 0.04835716156963638 0.1075824478319873
+-0.3479391062280647 -0.126665390258168 -0.2287931817071033
+-0.3339391802062537 0.08638104506876045 0.4153871716356871
+-0.3437931748730649 0.06799499691212332 0.5252200011202918
+0.2457413693967162 0.1472628478350848 0.429295858344446
+0.5295492770417918 0.1093862086104987 0.2733651267765829
+-0.3160302043757477 0.1364302962912125 -0.2386521499676249
+-0.3325980279608176 0.1444494011689514 0.2364387692234707
+-0.2930387724981217 0.1411993925395293 0.34719695896367
+-0.3437518688936977 0.1722947186730353 0.4268002410906342
+-0.3002781246773413 -0.05656847936871779 0.5773421353060838
+0.6116200389999999 -2.18556941e-08 -0.408671051
+0.4086714685 -2.18556941e-08 -0.6116197404999999
+-0.6116199795 -2.18556941e-08 -0.4086711705
+0.4086713195 -2.18556941e-08 0.61161983
+0.61161983 -2.18556941e-08 0.4086713195
+-0.3961672556480173 -6.155555294249769e-05 0.6199534874067836
+0.2898606410459698 0.09953935377376469 -0.5721343919035593
+0.1274258562189954 0.1820950256176694 -0.6308011075224357
+-0.2983307807445332 0.1419806263712661 -0.4269982341363224
+-0.01753325163574215 -0.1046126048589783 0.5737683073312927
+-0.1065471808270385 0.08839229482936621 -0.6047472533910651
+-0.5078357084441076 -0.1134888177294395 -0.3438187367651265
+0.07138585320850009 -0.05840339156309945 0.6482034465556364
+0.1875194341956316 -0.06385973718928681 0.6174557333286409
+-0.1940775370390703 0.1189988285552581 -0.5653164243045676
+0.210606074927093 -0.07955350966472875 -0.5157443637988349
+-0.2329323291013624 -0.1248761065775685 -0.5354600680477379
+0.4529133510639263 0.1027731533397032 0.4209756521472898
+-0.4260979781625683 -0.08344441861394807 -0.4140970192187416
+-0.2169229250232756 -0.139728824653224 0.3022348443465113
+-0.2198768006712144 -0.149968159355379 0.4321842579547452
+-0.2214114204232291 -0.1225220799957973 0.5409621791502991
+-0.1929736857355174 -0.03818610480938463 -0.5031431915557217
+0.2447988857322374 0.00381362611841892 0.5899237674964953
+-0.2253454435756435 -0.0510535612519891 0.3044597114244738
+-0.2040544704023095 -0.03176029619634726 0.427052550607548
+-0.2092215002784332 -0.02565337133532111 0.5411861284909295
+0.480989766979571 -0.08319996631774527 -0.4210647206063204
+0.6832787695 -0.135160238 -0.1359121870505095
+-0.1359126227647989 -0.135160238 -0.6832786799999999
+-0.2289056667134217 0.04663271431507766 -0.4255814967903377
+0.1359126012351997 0.135160565 -0.6832784115
+-0.2066628191114914 0.05480046826812753 0.3198049648384878
+-0.2243058615160185 0.07964437541474738 0.4247297184543852
+-0.208113090690223 0.06445928225980971 0.5231662485997532
+0.1359125669756076 -0.135160238 0.6832786799999999
+-0.1359126275243924 -0.135160238 0.6832786799999999
+0.387046307 0.135160565 -0.5792553725
+0.3870462925 -0.135160238 0.5792557
+-0.6832786799999999 -0.135160238 0.1359126506271685
+0.6832786799999999 -0.135160238 0.1359128139494905
+-0.2194004785644676 0.1475847545349244 -0.3469514787709857
+-0.5956393160156814 0.09490531950004515 -0.2042934565935917
+-0.2178745302422234 0.1453261132084583 0.3328986335035305
+-0.2418619683830102 0.1723327817400896 0.4269176136807822
+-0.1831818339704835 0.1484536604414157 0.5221446291367574
+0.03663870813279047 0.05005509956049407 -0.6414864284917617
+0.1942350135205994 0.05851852115451094 -0.6161295752759666
+-0.5420417635302861 0.1012002134691774 -0.1193827443122811
+-0.5756313767461709 0.1636057234662092 -0.06013303154197015
+-0.08651201916266667 -0.06865067701275893 -0.3321620682941319
+0.1027626229516373 -0.1314567021304453 0.3834698204860338
+-0.362428029410273 -0.1070244315800844 0.4886937738212236
+-0.1011488098433493 -0.1488108851409737 -0.5298702748774109
+0.1020647599765114 -0.07371707566437634 -0.366754583133816
+0.3903368429134106 0.101699745956457 -0.433818578133064
+-0.1074126412370914 -0.1526189193003277 0.4088007775076468
+-0.1151641662391919 -0.1438442203091108 0.5312796308049904
+0.2921648111109675 -0.07492673849593907 -0.2773684319721069
+-0.1285905486543048 -0.05647037586924304 -0.6133127505128496
+-0.1216163521409942 -0.03813129009229205 -0.4360208940675083
+-0.09905003496170785 -0.06196894632151512 0.3368756483460959
+-0.0990668004357604 -0.05903067457631835 0.4461241622524353
+-0.4776363609860341 0.1465133577617411 -0.2274197198236627
+-0.08773698924304667 -0.05184598555492647 0.6268363586823165
+-0.2267429148408685 0.1249132199309427 -0.4913909097447509
+-0.1121832809510704 0.04646092772441284 -0.5238551018576121
+0.2073757465014909 -0.0005490189447118193 -0.2818296401738018
+0.3574044012045842 0.1547702511617189 -0.2277470630249493
+-0.2354812082527474 -0.150851567101606 -0.3768350049973243
+-0.08743158532283671 0.05697845190875393 0.3357206925042919
+-0.1277896175209473 0.0578934535227305 0.440598521116173
+-0.1033125957436848 0.03928284369367165 0.5233789300229542
+-0.09304793425364484 0.05084289554029058 0.6380521403377361
+0.2386457396262456 0.1715816661461778 -0.3828757503815334
+0.423909910978836 0.1317032982272586 0.06356530576229823
+0.4097262710096638 0.1454523582378435 0.1438076249432514
+-0.0911470481544097 0.1452334358097956 -0.4158156824845399
+-0.1016133527545378 0.136860667934726 0.4330388861157719
+-0.4292389925744527 -0.1654781027874459 -0.07721888439167002
+0.2059596359472754 -0.0381533441888445 0.2457693811615254
+0.2680266045401745 -0.0409369721715605 -0.1942463155450726
+-0.5684009439817774 -0.181284115 0.3093214345483903
+0.156376008505201 -0.03237108451866057 0.2901862018655822
+0.4036041502130215 0.07115527728618469 0.4897612657744972
+0.4145351070767421 0.04784708682520229 -0.4968945110667345
+0.5250185200556235 0.04036754828805152 0.3708378603636437
+-0.3939857586234845 -0.0354399188984108 0.5159839140024425
+-0.5136737465592929 -0.02096928334744927 -0.3939635237507689
+-0.6094018716296354 0.002003007624447968 -0.202297769504363
+-0.3663963947652291 0.008372259341285189 -0.228274073560665
+0.3184424023319196 -0.02249886458617977 0.3579632423854461
+0.006561687502009625 0.05724662934245741 -0.5358999954437873
+-0.02114722495813348 0.04872463253946129 -0.3390579201943842
+0.3048686051070211 0.1840817211670154 -0.5675677732621035
+-0.01038008191495194 0.05798805100217008 0.4357427118599579
+0.0008467820919496345 0.03331469483369875 0.5521021583643705
+0.407017633 0.1812843605 -0.50312203175
+0.05776611603134262 0.1376535741227746 -0.2918362873837625
+0.0497730822502663 0.1296850741 0.288305171
+0.2457107185925527 0.135139000195845 0.1648979522399937
+0.1686676516 0.1296850741 0.239057429
+-0.5000568779581299 -0.1795990531282913 0.4150386052352156
+0.5014528792180527 -0.1816753454552545 -0.408719237110252
+-0.5029512339302212 0.1812843605 -0.4072733907773048
+0.5029512152035382 0.1812843605 -0.4072733664139633
+-0.3764123707272886 0.09879670488745546 -0.4095454500084148
+-0.4725332676819864 0.005642352703116546 0.2020216355148748
+-0.1496650072925399 -0.235647257655321 0.5167782537253931
+-0.5302451570783469 0.2365965943548609 -0.04876828145860426
+-0.002591613671415457 -0.1026208303124244 0.3928908007681053
+-0.0523451173707068 0.1302623922386563 0.4927621326423263
+0.05860755375353332 0.1257279774771141 0.4794596148821863
+0.08802430931468684 -0.1225325715056166 0.5603036431373815
+0.1032241182142573 -0.0340591879952308 -0.5533129910255919
+0.00745278544232821 -0.06582211103224113 0.630052478596229
+-0.01082466888663697 -0.03801533319731521 -0.6156480556982972
+0.4726120106138331 0.12484313881195 0.3448375643845454
+0.4814544006975456 -0.05513774069059533 -0.2986534077813469
+0.4732694108739305 -0.05522915948677016 -0.1778180843447857
+0.4909415760273616 -0.03837679976116375 -0.06661192117720928
+0.100095691090951 0.05093218150821434 -0.4304550833388545
+0.1239385805155771 0.044544506316063 -0.3352807243241612
+-0.2802087049206544 -0.08144478342526922 0.4785192195300021
+0.09580812999656925 0.05650133103318054 0.5018653908681395
+0.1112308163202565 0.150059329766388 -0.5249317956161899
+0.6459383261078916 0.06758027157215296 0.3222791452973603
+-0.1565518800075456 0.04876135164867082 -0.3722630768346345
+0.5560387821509727 -0.04441632956197366 -0.1490117451147615
+0.581792943649261 -0.04102538424861867 -0.06392366822802879
+-0.2582127270014075 0.02913406223927319 0.2684441064386298
+0.2927387924644004 -0.0149633208788464 -0.4491729904496716
+0.2013878265835575 -0.1266401577586878 0.3266978710424491
+0.443141937 -0.2374316825 -0.279739961
+0.5157281007889414 -0.2374270833779515 -0.09271138174935373
+0.2090559597555721 -0.04395774488034123 0.4278392112683149
+-0.4944336897194478 -0.09005668250886321 0.3978113830106517
+-0.432532593947051 -0.2375984594420146 -0.2935702535581112
+0.2277292536980891 0.0428303539450235 -0.5320631122757074
+0.2865164264133694 -0.2374651039703354 0.4383398348635704
+0.2056064164492523 0.04985412590180793 0.3127630284553709
+-0.2820232971018125 0.2372968610762593 -0.4427223751947126
+0.4395616904484677 -0.2384988760845237 0.2719947621906035
+-0.5081604390019669 -0.2378210470469928 0.1169813244873835
+0.4327316470501742 0.2384381322497851 -0.2829623286064294
+0.2877680748853014 0.2378403864535273 -0.4344245922410273
+0.2797399535 0.237431735 0.4431415055
+-0.4340564080289104 0.2378165773830367 0.2886114810717543
+-0.1828011762689302 0.05364457025045295 -0.6355453293052928
+0.6375438199914241 -0.02935637925234931 -0.152892417653076
+0.2602975085172395 -0.09745952344616611 0.5477608240078249
+0.2775263424353848 -0.1228377492099226 0.384791984454249
+0.3596151937197254 -0.141597768176489 -0.4231164447026335
+0.3208415581685442 -0.1349795480412619 -0.2171832530745286
+0.3109056466661628 -0.1388776022384641 0.1987929501681949
+0.3335612390022412 -0.04552068754656854 -0.5281548867660718
+-0.4531333533695962 0.07692855650042288 -0.555266519638251
+-0.4585715218401867 -0.07760329815977847 -0.5513992488579733
+0.3396141930387401 -0.05279514643595638 -0.0921131507041876
+0.3204727004155962 -0.06529806721664831 0.1046288254150648
+0.31306525603795 -0.06567965594681423 0.2046364937964013
+0.3159038841314221 0.02599107147295122 -0.3415755577703607
+0.3351976816345975 0.06128680549085182 -0.1479704239571715
+0.3388606878224936 0.0394365795661426 -0.03384902201879005
+0.3437417281098993 0.05703090942030965 0.107072764716187
+0.3220169919082694 0.05095046011482658 0.2177406215607413
+0.0689665525288998 -0.01163147790780546 -0.665821750833281
+0.4247853193968322 0.138055140745489 0.2498450206885172
+0.5666235297019543 -0.1721782523580675 -0.1155446617485881
+0.2372398230317664 -0.03167176195468971 -0.6080155472507058
+0.3357930029995391 0.1567136729231967 0.4253357575546892
+0.3540986515356748 -0.1424058629083627 0.3969252358031086
+-0.3414012713464936 -0.0621048952609243 0.002901790927666791
+-0.006352275712959725 -0.06508036243897163 -0.3374551632923645
+0.4077025720526192 0.04826923006195883 -0.2421012815042307
+0.1654412905940297 0.04562478981903653 0.4212167249231981
+0.4197084439871971 0.05192469954844516 0.1814469788058192
+-0.2208049830591295 0.06251985565641553 -0.6877215877450071
+0.426338398304634 -0.1434752602320325 -0.3367315691514332
+0.4326170457437952 -0.1411491565218985 -0.2188400560397645
+0.4237305177426459 -0.141661095432702 -0.08709124284118519
+0.404215024391447 -0.1399533434716075 0.2156067827615666
+0.4328630722823912 -0.1328013499737094 0.3308716072960298
+0.2248175293217677 -0.06758012992784704 0.6854376795667962
+0.4161155946855566 -0.05584439860466436 -0.002441013836284896
+0.4313140076389336 -0.05978578617486206 0.1088070022131595
+0.450918256819464 -0.03847381900589373 0.2359583877933817
+0.4457060890403761 -0.02620527055913056 0.413482502816888
+0.09835692228621801 0.06442805687023616 0.3643175222483206
+0.4369762376240091 0.04583458804269828 -0.1157588923316206
+0.4259958964602643 0.06108205071788198 -0.01539096574106599
+0.4162805245750874 0.04502838616233909 0.3078736604558807
+-0.2079118128565157 -0.04963516806072479 -0.3889561128873697
+-0.4299064880738119 0.135160565 0.5506171529961174
+0.5281180042296583 -0.1378503329927562 -0.2334815132298401
+0.5223484067072454 -0.1458065956801332 -0.02071680486975328
+0.5425252574054265 -0.1373263383845702 0.1072054410899196
+0.5350977120239054 -0.05103806950915329 0.3245688546285393
+0.5333863472702021 0.05046379975240864 -0.1975902518114613
+0.532455096746828 0.04560488532328932 -0.005699071116475381
+0.5419193981501835 0.0486765864019862 0.1239391687217768
+0.5355481056583311 0.1414417937687622 -0.09261594688985184
+-0.4967510892678877 0.04316175247488441 -0.1928494949928883
+-0.02348498660855512 -0.05726929540916417 -0.4929404584818559
+0.3389491987958484 0.1263167279134933 0.5054477140885989
+0.6274560120419712 -0.05198890175872962 0.1099921569861211
+0.4878419111093683 0.05875103888030383 0.2200223268103224
+0.6240885685723052 0.04492717659879997 -0.1054570120072385
+-0.6018963927443802 0.05107175258897927 0.2237810152843244
+0.641493437015596 0.04698768983416271 0.1038913003334417
+-0.2638401636369636 -0.05493290412767491 -0.4459854414188743
+-0.4048759839159633 -0.06931554420171929 0.2011181734596874
+-0.6013782642278841 -0.008670811585460226 0.05953811030783254
+0.236902116816932 0.07230934141622231 -0.4053013921960443
+0.1152841078827855 0.0709724499571117 -0.6207345739323095
+-0.2104418741655573 -0.06950722531256681 -0.2601247953068311
+-0.2245041950568541 -0.1051655974782383 -0.3165675198391922
+0.2110263114297359 0.1100623185224954 -0.31596710503771
+-0.3303083506116173 -0.02760598174876897 0.4317847611411088
+-0.3969790557273846 0.08278970153870198 -0.223719143864455
+0.3181074745640283 0.001246966633677706 -0.2511003853726549
+-0.001060707671683717 -0.1065111122750068 -0.5541061858275393
+0.650853451752721 0.009920080387569559 0.011665510543036
+-0.3574599974014963 0.09734137741098607 -0.09965203923949038
+-0.1436064464398353 0.08831529589285453 -0.3151052839264627
+-0.007506786969251721 -0.004105502730003744 -0.4243101107139098
+0.1065931068429387 -0.0001085366789827557 0.4135578084754778
+-0.3329912408681484 0.06421172716095264 0.3029882505886588
+-0.3375421951262143 0.006229202633078193 -0.4349069127969654
+-0.6985554476013591 -0.1024719621527603 0.1073642970980115
+0.5452928391102743 0.01608060722268402 0.2319397301056004
+0.1155424676004419 -0.227407992 -0.5808709265000001
+0.4924387485 -0.227407992 -0.3290367425
+0.5805699011497513 -0.227407992 -0.1170558901122047
+0.3290369515 -0.227407992 0.492438585
+0.492438585 -0.227407992 0.329036959
+0.11554240060044 0.227408156 -0.580870569
+0.4924384355 0.227408156 -0.329036556
+0.5808706585 0.227408156 -0.115542013739575
+-0.329036869 0.227408156 -0.492438257
+-0.5770880277546183 -0.227407992 -0.1345605514496855
+-0.492438585 -0.227407992 0.3290369735
+0.3290368765 0.227408156 -0.492438212
+0.3290367645 0.227408156 0.4924383165
+-0.4846991967808343 0.2275824300242007 0.3384793634329527
+-0.4924384055 0.227408156 -0.3290366455
+-0.5808706285 0.227408156 -0.1155422394103346
+0.5263242134816848 0.1427634180929979 0.04084918483631195
+-0.1523500837504407 0.1543677763815984 -0.5036055611948859
+0.502190705004582 0.1453440444158882 0.1545363581935308
+0.1381249001229966 -0.1411164872603262 -0.4731299872355259
+-0.6070921062993293 0.07694558145276738 0.3755620352998136
+0.1406031141985266 0.1429805795156574 -0.4029942841166447
+-0.5103359034007181 0.2364667903916487 0.1533976511473124
+0.1425452530490057 0.237431735 0.5057831616462883
+-0.3731252291502142 0.1294891353399314 -0.4883120817928434
+0.3723381797994571 -0.04828163511992769 -0.2021711263110909
+0.3764661100207322 -0.04326195962319036 -0.3110841143459703
+-0.5149001436269404 0.1817831010578217 0.3883744154118514
+-0.4075790725065548 -0.07011207976826006 -0.5880659568874272
+-0.5303300891969429 -5.833858670062555e-08 0.5303300379042957
+0.3692070733341348 0.05887650239374177 0.3977133352200331
+-0.4079152010050289 -0.1850652088177073 -0.4973754617889673
+0.3329196737418877 0.1396696471672832 -0.5128027077454528
+-0.06310352592163579 -0.05063790301029709 0.5320612101990535
+-0.4016297809554171 0.07665157112216678 -0.5897760485424426
+-0.3792981735569309 0.2069810069713509 0.4866624706549424
+0.3021500544248019 -0.07243349234632183 -0.3680829388445839
+-0.3032017640904151 0.0466666413092313 -0.2590452631690672
+-0.2390805197549287 0.05934859095666144 -0.3203443511140383
+-0.3843687658895464 0.0597781261690172 -0.320510805268692
+-0.297150850631037 0.04789404968614406 -0.1751198455174624
+-0.491150875371558 -0.02431634563507673 -0.1034359022115692
+-0.3426425664506795 0.06567166007506782 -0.6329930304230099
+0.622054807140332 -0.06919338799472372 0.2517012930533061
+-0.1703098257617832 -0.1826550824458945 -0.6216246471829776
+-0.2174347219811193 0.01272135947138664 -0.245695297556412
+0.4439378877973604 0.06758027157215296 0.5646485581078916
+0.04763992432268208 -0.01224661208412182 0.5024657892071374
+-0.1708675632617437 -0.1854258582415338 0.6183160665788725
+-0.1716332338339093 -0.07729741666714569 0.6931634498852716
+0.4859623908309793 -0.1751256506962191 -0.1293025462109802
+-0.1895947160490057 0.135160565 0.6726003965825593
+0.5863066585133995 -0.05325755980125289 -0.2416842667002071
+-0.6726003999896268 0.135160565 0.1895947010490057
+0.1895946860490058 0.135160565 0.6726003904889689
+-0.6705388748474567 0.135160565 -0.1999589308460862
+0.6726004757712991 0.135160565 -0.1895945220490057
+-0.5959268895394246 -0.08763387546571111 -0.193621137504829
+0.2024962576489122 0.1321155658524761 -0.4660263074064109
+0.4354731070692088 0.1354985673547656 -0.1637449946554581
+-0.1637739673863473 0.08397379746190908 0.6927663054735529
+0.3265732257357251 -0.1509614322112238 0.2884515197475907
+0.2732793647740832 0.1546584917298763 0.3314554491719456
+0.3352013350452636 0.1560501476469682 0.2713065059666275
+0.1855214459446696 0.1402342518748386 0.377939225620567
+0.5952374280764472 0.05149610372169009 0.2848800021155177
+0.309976557537971 0.02941156572264442 -0.5861860739822928
+-0.5819583326726456 -0.05848943025699382 -0.2922827175629795
+0.4478022466495745 0.1487306241748066 -0.05278736440785489
+-0.06061965019220951 -0.1546782628110873 -0.4451638315554993
+-0.4739719375085265 0.1595241468053785 -0.07235625997418475
+-0.4389376217620313 -0.1571890255726863 0.05923078313502133
+0.03523894539594524 0.1322226216130693 -0.4287150964234601
+0.4406472348063602 -0.1457053958490441 0.05768599293734747
+-0.6888037686428277 -0.07036105566768017 -0.2037901556721537
+-0.06229448528435831 0.03133867538934622 -0.6561603563492422
+0.6623351609753214 -0.05696093651650429 -0.04555963134792926
+0.7142163401685105 -0.06509681597650166 -0.08380314178483944
+0.08210689966282012 0.05937132490740349 0.7162348457707524
+0.08333145252853005 -0.06595830440988804 -0.7140572377641591
+0.06608137356851983 0.1491054590402661 0.4009851807085034
+-0.3611274408840614 -0.1077702581600939 -0.06242896573356903
+0.3796094865805174 0.1486590723480749 0.3447589131660058
+0.04712138799494611 -0.09589795714366683 -0.6301910061738919
+0.0659446078747277 0.09224666523738477 0.621360874667907
+0.181154043491014 -0.08994650355324102 -0.6200918491966262
+0.5771762656224043 0.09484020020585483 0.1912421960319913
+0.0226914655921382 0.02659887758775728 0.6516329293572531
+0.3075185328989046 0.07299906362394958 -0.4985846099332604
+0.07577543452462263 -0.1433929495342712 -0.5746623127656189
+0.1596925585545952 -0.1348942439547208 -0.561311843514139
+0.4452187262509794 0.04287656012943429 0.1108911178589169
+-0.646405235051362 0.1812843605 -0.0536821029593403
+-0.2904552754354776 -0.04991148299524247 -0.2135005964108463
+-0.2027902505473725 0.04060653507155906 -0.5494798040191847
+0.312554733939242 -0.1507221313137781 -0.3192189438369041
+0.532405183857342 0.02947761865663639 -0.102715572874153
+0.5275086031262067 -0.1055867242650335 -0.1088883244036733
+-0.4264568237336529 0.03087572834513268 0.1118487827067294
+0.5386311781670815 -0.1739261713797737 0.3688656825855084
+0.318987690826632 0.08094470550083935 0.3082873048685877
+-0.5247960083693182 0.05760442579045268 0.2134851504654077
+0.6158593372512614 -0.1874400435104712 0.1715324352895766
+0.4315624334526753 -0.02798427575426788 -0.5103779956811643
+-0.4123433473060267 -0.04764382775535243 -0.5032775626162018
+0.7173603882156612 0.07561188915947202 -0.05247448317129177
+-0.2713328395803039 0.1161625451622493 0.5697169244581305
+-0.1741215833851504 -0.1867567049684828 0.4804577250082678
+0.6976598577362255 -0.06827042213568386 0.1623536943023283
+-0.04610012519939551 0.1448809950000666 0.5674450728739088
+-0.06820624315971494 0.1391422404993094 -0.5422448272563861
+0.04976206459513634 0.1459319893446545 0.5648956198046813
+-0.4405659160829608 -0.05935747034583092 -0.2987452142975358
+0.7101340715369242 0.06931532101520638 0.09809893503159287
+-0.5233272589156744 0.1371867973524671 -0.006070351955850449
+0.003411548988928413 0.1576623979034729 0.5143549750367112
+-0.007709896184820183 0.1617475887412644 -0.4979439886996553
+-0.5015913141449097 -0.148026251126252 -0.0007504796998853022
+0.3156046534344432 -0.02657801295699586 0.456855152278661
+-0.7146314176639721 -2.18556941e-08 -0.1778099321739148
+-0.714631391435433 -2.18556941e-08 0.1778099059453759
+-0.6889572874750536 -0.135160238 -0.1073642970980114
+-0.0800325114130878 -0.2144714877278948 -0.376277204125747
+-0.2045620552658866 -0.2184651849984501 -0.3362589268787387
+-0.6889570651027241 0.135160565 -0.1073642970980114
+-0.6889570579792537 0.135160565 0.1073642970980115
+0.07462547832493387 -0.2197393122455355 0.3888876602281924
+0.3226232787263165 -0.2162282417004459 0.2163220611664897
+-0.382677138 -0.2181964215 0.08886321938880395
+0.3260948967187077 0.2168535096272338 -0.2135434742241258
+-0.08047208479996108 0.2175162374763322 -0.3828568457923386
+-0.5709528055146412 -0.1788981212378028 -0.3103633892284121
+0.2294042978034777 0.2168584666811915 -0.3155098213988843
+-0.5989670613063136 -0.135160238 -0.3575461347945523
+0.38267687 0.2181962655 -0.0888628909245615
+0.091470285862678 0.217038063599734 -0.379622106314556
+-0.07140032689038553 0.2154323042171401 0.3800981761532723
+0.221030943918663 0.2171582416863385 0.3218790327721636
+-0.3857783053634699 0.2178326861474558 -0.06926851353584285
+-0.2269041027428502 0.2188124539906703 0.322227403264663
+-0.3317374084906508 0.2173518025519454 0.207025087688183
+-0.5835519514615468 -0.2268300252085159 0.105417351210259
+-0.3827407025570413 0.217881574844037 0.08507772784439768
+-0.5824973265862685 0.227408156 0.1073642970980115
+0.3812711629175531 -0.2165997755367423 0.0783551961348893
+-0.1521653160164021 -0.1287108372045364 -0.4187192410115158
+-0.4859042057485281 -0.227407992 -0.3388164423898491
+-0.4257266172768689 0.1457644899011558 -0.1483052091300335
+0.02270542428141074 -0.01774936420632196 0.3414903994776349
+-0.3716315400264734 0.1944972016295138 -0.508779491398935
+-0.3048382051472016 -0.1745592467809746 0.5805511771905953
+-0.3135551595490744 -0.1851134063945669 -0.5603592340360726
+-0.4356442171131527 -2.18556941e-08 -0.5935971483996163
+-0.07717212950074337 -0.1785652289067969 -0.6448708338027288
+-0.06507398806140052 -0.1761046441822036 0.6501169839026913
+0.6453716043734744 -0.1791687299460072 0.07115349393080496
+0.3897301333485112 0.1893134174198639 0.5037431591401457
+-0.6887090665053673 -0.07379341498840072 0.1991994430700723
+-0.5935971383366712 -2.18556941e-08 0.4356441969872622
+-0.6117749063923518 0.01644354433148199 -0.2978603801681667
+-0.387558001269515 -0.135160238 -0.5789137973090235
+-0.5789137969635547 -0.135160238 0.3875580010967806
+-0.3875580048364737 -0.135160238 0.5789138044429412
+-0.5789135088604425 0.135160565 -0.3875580605546097
+-0.3875580495343058 0.135160565 -0.5789134868198349
+0.5644643984827786 -0.06495018187921164 -0.4455770106383233
+-0.578913471633707 0.135160565 0.3875580419412419
+0.23709719603894 0.1014150416760966 0.2680955908015779
+0.04018451750921416 -0.1349437665400113 0.6245923834942313
+-0.6051502767477215 -0.1339196929326989 0.04824931533981232
+0.06106294228067399 0.1185684120684981 -0.6226282579399706
+-0.6062220019205854 0.1293499032270441 0.03599799757209045
+-0.6078126614727571 0.08914747057635643 -0.04573977024164903
+0.5754370663803664 0.1269034291391263 -0.2020234705263327
+-0.3709021398994805 -0.00134424386124089 -0.6363908604690129
+-0.1778099073798559 -2.18556941e-08 -0.7146313928699131
+-0.1778099039496093 -2.18556941e-08 0.7146313894396665
+0.4347152300153192 -0.03845077592829239 0.3242724391810436
+-0.3575457461164083 0.135160565 -0.598967070476627
+0.5212411926782172 -0.05775566056478709 0.01756777546771002
+0.5259509822148767 -0.03592485772890536 0.09957469724955148
+-0.1073642970980114 0.135160565 -0.6889570487660757
+-0.3575457351476239 0.135160565 0.5989670649922347
+-0.1073642970980114 0.135160565 0.6889570511651186
+-0.3462750200225362 -0.227407992 -0.4809205082873176
+-0.1073642970980114 -0.227407992 -0.5824976636260482
+-0.33153474006408 -0.227407992 0.4907696355829997
+-0.1073642970980114 -0.227407992 0.5824976644313991
+-0.1073642970980114 0.227408156 -0.5824973216541982
+-0.3318778745421381 0.227663389878087 0.4884459660073816
+-0.1073642970980114 0.227408156 0.5824973224595431
+-0.09142014233927777 -0.04957767833824132 -0.5334365820416362
+-0.1411060818092554 -0.05316603507842676 0.5382820154556561
+0.07839309595428723 -0.03606997118258356 0.5627924560811802
+0.2228311347285496 -0.04566485180113804 0.3316338944249109
+0.1778098936435355 -2.18556941e-08 0.7146313791335925
+0.1119377679059749 0.135160565 0.688047318674596
+0.1073642970980115 -0.227407992 0.5824976533568385
+0.1107310237709541 0.2263410543301188 0.5830591323502694
+0.1073642970980115 -0.135160238 -0.6889572750606456
+0.1778099085090079 -2.18556941e-08 -0.7146313939990649
+-0.2867197080342601 0.06935592017993335 0.2082907636499682
+-0.1040286901134598 0.04955933054357604 -0.428733056122008
+0.1087667398617572 0.05680384432486649 -0.5469337818933063
+0.3462749938603848 -0.227407992 -0.4809204952062419
+0.3575457135947208 0.135160565 0.5989670542157832
+0.3575461221925426 -0.135160238 -0.5989670550053088
+0.1812223911135857 -0.1736821308172768 -0.6298093261526846
+-0.6193708249721932 -0.181284115 0.1895947455490057
+0.1905191600437536 -0.1743820496510929 0.62715234095378
+-0.1895947310490057 0.1812843605 -0.6193705318270991
+-0.6237485270845429 0.1807169479230611 0.1708771116222541
+0.6193705496990755 0.1812843605 0.1895946860490058
+-0.6285656566370914 0.1761324746024394 -0.1732584543457864
+0.394701284275205 -0.1042605866668516 -0.4997370861425395
+0.4699929441616674 0.227408156 0.3626286470636558
+-0.5084742133742602 0.06489101169978406 0.3985956981616894
+0.5085238562446177 -0.09862272073648808 0.3981796479379747
+-0.252784993881451 0.08889640338330405 -0.2133526125177653
+-0.053682158699257 -0.2374316825 0.5234595132156995
+0.5789137897334826 -0.135160238 0.3875579974817446
+0.5789134714070765 0.135160565 -0.3875580418279266
+-0.5234595159721932 -0.2374316825 0.05368218361184548
+0.5789137748970357 -0.135160238 -0.387557990063521
+0.4119679658371732 0.171320395173378 -0.3619113785125
+0.5824973573981509 0.227408156 0.1073642970980115
+0.5824976994624926 -0.227407992 0.1073642970980115
+0.5989670542157832 0.135160565 0.3575457135947208
+-0.1851208683566414 0.124208603344928 -0.4239884656902839
+0.6889570984230848 0.135160565 0.1073642970980115
+0.173734377190098 -0.1592113573896186 0.4569211512536634
+-0.28606352997408 0.1545826835379782 -0.5211144100507749
+0.6889570315425984 0.135160565 -0.1073642970980114
+0.5456779809973004 -0.1215914160305011 0.2584213678038438
+-0.558393685464368 -0.1146177080545493 0.2834043871933823
+0.6190017582884673 -0.07274211245430767 -0.3599170327319804
+0.0411829889215951 -0.01367151147718778 0.4358118977414294
+-0.426429427626163 0.143843426080977 0.002542584081843323
+0.7146314120566302 -2.18556941e-08 0.1778099265665732
+0.7143730345430807 -0.00140176429054186 -0.1770398293756113
+0.3739725842088806 0.1215769468470212 -0.08292337630397037
+-0.05485930368709809 -0.1053031201782086 -0.3871347894732904
+-0.3714078393416314 -0.1180642596737125 0.05878671147875928
+0.3598360547299361 -0.1098711723824991 0.05711255573169563
+-0.2229579979104957 -0.01042827856541734 -0.3327072361197876
+-0.6422801729477911 -0.03894346107858589 -0.3425982442479343
+0.6608410879144642 -0.08766114178271175 0.05095820244838246
+0.1426328224684481 -0.01999499921288682 -0.6425278445708872
+0.1451338818735528 0.04608510717745574 0.6124456115996282
+0.01809742601197574 -0.1721964576789065 -0.4967334593128879
+-0.246127712574023 0.04135798095259782 0.5983282486609528
+-0.3138521513056136 -0.1556622707844267 -0.3161040462964457
+0.323493049226149 0.1290001483902456 -0.3253386948631966
+0.2728508941316176 0.07549347174791185 -0.2372820664953083
+0.5562842649028102 -0.0485295044900356 0.1953580131414835
+-0.3673911643395928 -0.09103973029133546 0.3705530982467184
+0.4355860589542803 -0.06553550803975287 -0.5709373490885763
+0.5632559126388801 -0.06387772482078147 0.4479415235371896
+-0.5623988653662189 -0.05767263513801224 0.4524406607131942
+-0.5561151775794455 0.06810076880820351 -0.4564393132378073
+0.5660902677743312 0.06010819246444307 -0.4456534833601336
+-0.2548913804596937 0.06258836563347484 -0.609930088042597
+0.6241570345002212 0.002226028570825955 0.2002465762605789
+-0.649776531707054 -0.0725164334290863 0.001715429544915426
+-0.004389374735116239 0.1180139820763546 0.6205176565062831
+-0.02316628772584089 0.1114646632479806 -0.6235726113015037
+-0.1543271382898399 -0.09275660230181169 -0.3310827964762754
+-0.6484132865773928 0.03340105755634293 -0.112249268939819
+0.08134865638375682 -0.0668181207163879 0.7141991738988013
+-0.08165379287038785 -0.05609759458137611 -0.7172863175211743
+-0.08318554957996099 -0.0696514590344952 0.7130018514806905
+-0.0739077083046028 0.05868607434484126 0.7180669935902767
+0.05266965457730004 -0.1751399486361745 0.6536976595518434
+0.05368213302461863 0.1812843605 0.6464052261462883
+-0.05328394604293371 0.1784463116146165 -0.6497597270761811
+-0.0536821640733928 0.1812843605 0.6464052317297715
+-0.6464055249721932 -0.181284115 0.05368220217617423
+0.6467232799244399 0.1809402739390439 0.05407987922160953
+0.234169056917011 0.05670640816227374 0.4156758517070452
+-0.5089134388924373 -0.1923102973818645 0.05068212359475061
+0.1676413756067232 -0.06781041643326767 0.531558722267077
+0.5865201611484786 0.1316140442522556 0.1131982866086703
+-0.04196278628353433 0.08189709568967014 -0.4641796369398359
+-0.2423508878776404 0.001876770083158745 0.1933769569910977
+0.2800534084650199 -0.001419473771088816 0.1515067266544594
+-0.1560211292574079 -0.0006481472840781907 0.2851380005602722
+0.7123616063516282 -0.08049241694007397 0.07040161526726069
+-0.6278805340950337 0.105766568169776 0.1909343800546901
+0.6415084338809066 0.0798150248930703 0.1822983339745222
+-0.193204923899704 -0.05572412844052755 0.6224482061031797
+-0.6304617438564843 -0.1035122462338923 0.198036709796241
+0.6156512441366255 -0.1032623802693025 0.1753596888902071
+0.6334392450885363 0.06696755323160408 -0.1838983985512123
+0.3782062441392018 -0.12204988584297 0.133183390216391
+-0.3828751918786762 -0.1285998340989022 0.1330862319117084
+0.5072024770378601 0.02634700497318234 0.4506209427980654
+-0.7191544659780258 -0.06197279360122413 -0.06358919318901379
+0.5728575186449349 0.07727439263062541 -0.2980850278327078
+-0.7044764983498082 0.06248231541307675 0.1366278139779501
+0.2566443629179671 -0.1170930898586065 -0.57977294954992
+-0.2765169719865896 0.01562580963005574 0.4859752387090623
+-0.1753814023370256 -0.124284950943586 0.367624994491605
+0.4898723741986995 -0.09038045200736297 0.1732492806675991
+0.3766615163973158 -0.123978037291708 -0.1575263032116939
+0.4881935107812874 -0.0085710500253026 0.1662459875931393
+-0.56444933379114 -0.002316203731541758 0.1710273760706686
+-0.5614368059721748 0.0973977351253799 0.1566922547789323
+-0.3759252044357331 0.0156099603600098 0.3811072818299944
+0.05383705383083659 0.2145299440226167 0.3816158270208281
+-0.1619732726120931 0.1330765460643622 0.3981378604129159
+0.3740296575279978 0.2111397287358895 0.05465499176783607
+0.382604670169172 0.2201042797991723 0.1102298907106016
+-0.05959478828599387 0.005930859013459864 -0.5663805162004295
+-0.01717673474360292 -0.03153853481555432 0.4675011682325878
+0.1364068407452007 -0.007277509535040018 0.4931110900239976
+0.385242784587982 0.00493529360549544 0.0469820988995634
+-0.6153711266794439 -0.1812035918895354 -0.2101699509978979
+-0.4726629202983678 -0.003327897542008701 0.3806000630414419
+-0.2761035454032154 0.007953612206295075 -0.3797424360944924
+-0.3888636207135883 -0.007938706908226399 0.04178998606509782
+-0.383278176165127 0.002973667381423688 -0.3690494541521624
+-0.3951191553982251 -0.008625205350272521 0.167258353233485
+-0.3778274958314471 0.097823632437333 0.06631071941621698
+-0.3790763659663187 0.1397429760054126 0.166309023532448
+-0.07173407266451474 -0.01249665451441885 -0.3804837643958644
+0.2877288837036373 0.09196999960831206 0.3768515569196144
+-0.2638412931493026 -0.1036766116893414 0.2391878653767805
+0.5991487400768469 -0.08920454298047388 0.02674751036901173
+0.607540993752861 0.1001621139512669 -0.03389076552791264
+0.5998837187108649 0.08338905575378201 0.04540625595553115
+-0.4743685905329021 0.09628227912602481 0.1566870273403166
+-0.4899423282037244 -0.08777947848176004 0.0496655557590468
+-0.4872238388481392 -0.008111734031781198 0.05133027066828713
+-0.2690792112134239 0.1005271315784323 0.2846467055547287
+-0.1622708114648139 0.01555625283271768 0.5870885011921256
+-0.1696039443719094 0.08373059661137741 0.606094424742615
+-0.4727827962661386 0.08448025899041636 0.06102069089748234
+-0.0605344123561698 0.008905324522109764 -0.4866242428196116
+-0.3815748147572086 0.001616454738300511 0.2542510822105668
+-0.3829317236935794 0.09050305714296698 0.249640564453501
+0.2616995180087382 -0.0944119383604532 0.2673071635684744
+0.2822514647509506 -0.005850493949298635 0.2691987114193257
+0.5935218637257337 0.002482111530269636 -0.3213259738383724
+-0.505464412258112 -0.1833568021761748 -0.3992898990550236
+-0.280967206550657 -0.1069018532045351 -0.2712158017948815
+-0.1161557276237301 0.1330592507396156 0.5699473656025384
+0.1369649530693391 0.1316506868926868 0.5592349600599259
+-0.1563140975 -0.12968538685 -0.247312054
+0.2471092834451507 -0.1351991643392156 -0.1628731266204674
+0.05673806489688069 -0.1305484283378361 -0.2874745836492385
+0.1628260980373148 -0.1376422746858275 -0.2489927473513118
+0.285898666730311 -0.1265875515597322 -0.05186365307744811
+-0.05510728922311799 -0.1288880401778301 -0.2867319091516609
+-0.05504061217906892 -0.1306847878369744 0.287899872612026
+0.05682477422099689 -0.1333662801572196 0.2892682689746576
+0.1581282015648371 -0.1267552300700679 0.2438786222378669
+-0.247312076 -0.12968538685 0.156314045
+0.2422066962597056 -0.1302997933916133 0.164651855644622
+-0.1563140525 -0.12968538685 0.247312076
+-0.1630249122458465 0.1419671064563262 -0.2521384231743916
+-0.289625310045959 -0.1340672575029545 -0.05729459453291589
+-0.2879229197619732 -0.1301596644734891 0.05322815267895153
+0.2896188458856734 0.1357133639383724 -0.06264541548807114
+-0.0627561069358414 0.1340128003260848 -0.2885039532850485
+-0.06003912720029972 0.1284922867886495 0.2854965770306342
+-0.2526884136545073 0.1362608592798777 0.1557278784104276
+-0.1651630450343733 0.1414745578076895 0.2503363810445914
+-0.247311957 0.1296850741 -0.156313896
+-0.2854066045 0.1296850741 -0.06434522086097889
+-0.2821769618407176 0.1225299473665231 0.05746447519469901
+0.2874402478974803 -0.131064917060987 0.05857953496711188
+0.2854065895 0.1296850741 0.064345362760046
+0.09956721556483739 0.008900787700942986 0.3040684694373372
+0.141227164390001 -0.03915237319037788 -0.4606711437015398
+0.7323157185262316 -2.18556941e-08 -0.08890473140017549
+-0.732315708831986 -2.18556941e-08 -0.08890490946352991
+0.08890493042999804 -2.18556941e-08 0.7323156895667963
+-0.08890494921809791 -2.18556941e-08 -0.7323156964349565
+0.08890495872633397 -2.18556941e-08 -0.7323156969995325
+-0.08890496836657437 -2.18556941e-08 0.7323156947198333
+-0.7323156957177165 -2.18556941e-08 0.08890500959611544
+0.7323157060283151 -2.18556941e-08 0.08890520766431409
+0.08886322676908474 -0.247455373 -0.446745351
+-0.08886321373091526 -0.247455373 -0.446745366
+-0.253061019 -0.247455373 -0.378732383
+0.4467454255 -0.247455373 -0.088862923672303
+0.378732547 -0.247455373 -0.2530607585
+0.2530610265 -0.247455373 -0.3787323535
+-0.08886321165025131 -0.247455373 0.446745366
+0.08886316884974869 -0.247455373 0.446745366
+0.253060922 -0.247455373 0.378732428
+0.378732428 -0.247455373 0.2530609295
+-0.3787325175 -0.247455373 -0.253060825
+-0.378732428 -0.247455373 0.253060937
+-0.446745366 -0.247455373 0.08886322906283976
+-0.446745396 -0.247455373 -0.08886309193716024
+0.0888631522690823 0.247455314 -0.4467449785
+-0.08886313923091771 0.247455314 -0.446744993
+-0.2530608105 0.247455314 -0.37873207
+0.446745053 0.247455314 -0.08886284917243099
+0.2610196563250436 0.247455314 -0.3734141119799477
+0.3787322345 0.247455314 -0.2530605495
+-0.0888631371502424 0.247455314 0.446744993
+0.0888630943497576 0.247455314 0.446744993
+0.2530607135 0.247455314 0.378732115
+0.378732115 0.247455314 0.253060721
+-0.446745023 0.247455314 -0.08886302493719224
+-0.378732115 0.247455314 0.2530607285
+-0.446744993 0.247455314 0.08886315456280776
+-0.3787322045 0.247455314 -0.253060624
+-0.253060736 0.247455314 0.378732115
+0.446745366 -0.247455373 0.08886333782769699
+0.446744993 0.247455314 0.088863263327569
+0.6200791714077696 0.03064473749778887 -0.2440277489762376
+-0.2626299684804731 -0.01779926795500601 -0.599686805331662
+-0.6123164101680636 -0.04121299126851069 0.2479495684496193
+-0.6378744981290908 -0.08641631458216771 -0.3245838369211331
+0.3222791452973603 0.06758027157215296 0.6459383261078916
+-0.6432533681683356 -2.18556941e-08 0.3613284019936311
+-0.2395605239587259 0.1861935899383363 -0.4408444524343927
+-0.01815759320534445 -0.1340331295755921 -0.618553481301664
+-0.416173620953785 0.1334507751933589 0.4501201060061978
+-0.4299310368060829 -0.1311833513982786 0.4365280856573984
+0.4154314094009814 -0.1274728968155736 0.4504484112711975
+0.3741153953545832 -0.1242355469020759 -0.0241854340486779
+-0.5578965797509108 0.07758988814764095 0.4488543656622259
+0.066887528377056 0.1134054046445166 -0.3500728402253111
+-0.05292311315347678 0.1260431071072435 0.3580833601168914
+0.3551564114844889 0.1039168763322923 0.03884608765805646
+0.2530163933438245 0.1514527965299385 0.5046020668611034
+0.2170199306452358 0.07035957400422863 -0.6861725016313338
+-0.6886531840337877 0.06831837761274545 0.2075619354184494
+0.2146550888955935 0.06925477135835592 0.6869673050358971
+0.6856670468292471 0.07175132639315042 0.2175067344931936
+-0.6855026363122276 0.06738785333983141 -0.224774707991908
+0.210947856979893 -0.08000473670797401 -0.6845483310126054
+0.6855619969327065 0.07218350698739592 -0.2173972238496296
+0.6854377980262316 -0.06758012992784704 -0.224817394281203
+0.2474381341489587 0.1061938412000234 0.5766180351873803
+0.489503016304909 -0.1785221406910227 0.263169924743284
+0.3037402902914204 -0.1480370568980555 -0.5174410365166965
+-0.4864719094610887 0.1752779821252042 0.2794938371976077
+0.4313217303001755 0.135160565 0.5496715059782117
+-0.5506173006531567 -0.135160238 -0.4299067178972762
+0.1092678841352424 -0.08993497320759923 -0.6208877979904343
+0.3315483361717592 -0.1186488286544302 -0.101273559173753
+-0.05332356464008531 -0.003220860878376586 -0.2495200389000687
+-0.04525869337901792 -0.0002733267622190005 0.2511242429814381
+0.1406911262572085 0.00458300473952665 0.2128336142806865
+-0.212131627 -1.862499999991107e-07 -0.141741749
+0.2502262665 -1.862499999991107e-07 0.049773196710046
+-0.3038750919021984 -0.00420447504443615 0.04991694629414084
+0.3060295077376545 0.01098691065300924 0.05504694712444477
+0.1170500682120619 0.1810802133846133 0.4998806125319112
+0.4856608853215326 0.07434546177884246 -0.4322363107862517
+-0.458826067180756 -0.1539076895358543 -0.2411783655387011
+0.2414409659261295 -0.1395981122085382 -0.4286050346936315
+0.4102733319937368 -0.03911917457333562 0.5089220698446709
+0.6436677085590493 0.05276964120720886 -0.3333546024610379
+-0.6328982967916651 0.06338561222163799 -0.3439693233029654
+0.6393865205766276 -0.06783917936103923 0.3319505522899195
+-0.6254841434299707 -0.07086294435058846 0.3511895693749568
+-0.3416269174305976 -0.06356443637116133 -0.6344016122869763
+0.3434770270001724 -0.06692247982426226 -0.6320022943216725
+-0.3433089855389704 0.06847439970572868 0.631576980383792
+0.01187510501014911 0.09071444418817076 0.3552258624282731
+-0.09777969011320647 0.1858866393441107 0.4930423179985466
+-0.09000200204206606 0.1904619032906356 -0.4874776471335208
+-0.1425452905490057 0.237431735 -0.5057831668270991
+-0.1960150597271896 0.1899289804033522 0.3766604375387921
+0.6036653880207526 -0.1001926936403398 -0.1444334652759952
+-0.5402624007491028 0.1237898832495177 0.2844891380745601
+-0.05006475582362858 -0.01280714490476897 0.3921732275300897
+0.1790506689861273 0.09320743189656971 -0.5309763578678544
+0.6040451972022797 -0.01620572259224715 0.2810845165686729
+0.1895947905490057 -0.135160238 -0.6726005975303229
+0.6726004202115424 0.135160565 0.1895946860490058
+-0.6726006637375268 -0.135160238 -0.1895946565490057
+-0.02211429515907533 0.1594037691029022 0.4252731110919391
+-0.2178001310488206 -0.2187878848473082 0.3282470318331274
+-0.5592332994570895 0.1902521000391926 -0.3047708475982757
+-0.5620171585001306 0.1836874142745606 0.3139790672500916
+0.5719226547333054 -0.184839971894952 0.2968062977771854
+-0.6502893879669944 -0.1778044424086221 -0.05434518036839411
+0.05368215214944767 -0.181284115 -0.6464055185303228
+-0.2158743658231015 0.09526841972257911 -0.2647745309902759
+-0.2114200026182485 0.1010409781318316 0.2608651734868205
+-0.1982647250058633 -0.09896759786522454 0.2555716819455021
+-0.3129920331155432 0.1084669587386941 0.1627058173366869
+-0.1551685730867522 0.1080878068838509 0.3164997837178271
+0.3107971034315091 -0.09707599796195117 -0.154823053830057
+-0.1583120171750342 -0.1054586665971662 0.303083453438425
+0.1842856487044458 0.1328246243631194 0.3071171654625506
+0.3405021210770199 0.1414651450899855 0.1906460150110045
+0.1222497898060191 -0.01459653842951159 0.6716419314541555
+0.6187727551000032 -0.1822425903685795 -0.1870407695448417
+-0.5140658381072688 -0.1017583303142997 -0.1591315148082528
+0.1506872594387387 0.107011086778144 -0.5785905499054989
+-0.4543830012629956 0.02070776700615354 -0.3534233502059753
+0.05208701996476486 0.2369451377659843 0.5271608231354115
+-0.05035418058057255 0.236541723503403 -0.5303113484986198
+-0.0536821586992481 0.237431735 0.5234591482297716
+0.652264938 -2.18556941e-08 -0.347841635
+-0.65226484875 -2.18556941e-08 -0.34784178425
+0.34784194825 -2.18556941e-08 0.652264714
+0.570974946 -2.18556941e-08 0.46950069075
+0.05288088412692972 -0.1696738401445088 0.4812655001975786
+-0.03458365933052948 -0.1696053900123612 0.4469547003571025
+0.5253901567920133 0.01334285814744612 -0.2715949297219139
+0.5008552018403365 0.0008968449184086402 -0.4476622468363466
+-0.4679785893234675 -0.1720388775723341 0.1441529655658877
+0.4608469644229725 -0.1715736804020539 0.1526932380534281
+0.4712710999359984 0.1910190031111572 -0.1336326997259548
+-0.4922261458666373 -0.1795631286234275 -0.1535029704981328
+-0.04003071875929925 -0.01735235223485209 0.6844048178359888
+0.05786895306571511 0.04951594845714467 -0.7239498885560181
+0.2127057635028024 -0.0833398813849658 -0.2538144673578778
+-0.5133981546337892 0.03912537763871422 0.4644387356716861
+0.3773758525022843 -0.1145068351912803 -0.2694092044220085
+0.1576327673835248 -0.00174623569951705 0.3567090232373112
+0.06760794136056919 -0.03105061583133411 -0.4613535665477629
+-0.7234264959800163 -0.05601355432624411 0.0509091710031585
+0.3307809421322569 -0.06714567745126444 0.6404082325370969
+-0.2708684508911888 -0.1157463251588329 0.3750957971723319
+-0.2789744190406261 0.03582508947728972 0.3637404139816443
+0.4699139694816132 0.01791589074177289 0.04241381727681382
+-0.1542487939470152 0.03758487944378665 0.3777753383082115
+0.370206414436605 -0.02919216874927832 0.1646086345337974
+-0.3843560426382542 -0.01459984482335379 -0.05331358427969477
+-0.3756036815077443 0.0655473812595731 0.1739739322222879
+0.3624013269252122 -0.0545436899147785 0.2752232163131648
+-0.4804420812630442 -0.05407407237313248 0.1595268585124839
+-0.1649969073003941 0.07391696382954899 -0.4781800483207995
+0.172943408404652 0.03270492546648051 -0.4770234506938139
+-0.5131791762068501 0.2357481102122256 -0.1642331900472321
+0.4967968321015735 0.01720857935661327 0.2988126091935098
+-0.3058843387849141 -0.09545112865391527 0.1671091894972072
+-0.6105761183708176 -0.01727895628303047 -0.05109497939867216
+-0.1020149918114597 0.1002042812521527 -0.4793742608257536
+0.34784208225 -2.18556941e-08 -0.6522646692499999
+
+CELLS 4436 22180
+4 416 356 836 690
+4 0 759 1017 1
+4 0 1 792 759
+4 0 1017 187 876
+4 899 180 560 106
+4 1 665 759 494
+4 667 314 610 668
+4 543 176 732 810
+4 145 370 320 156
+4 10 314 667 588
+4 2 187 668 667
+4 3 563 570 5
+4 812 200 199 553
+4 136 419 424 853
+4 414 573 870 572
+4 193 585 486 379
+4 314 511 10 374
+4 204 477 209 828
+4 492 803 250 1020
+4 6 12 202 730
+4 473 210 597 967
+4 312 296 479 272
+4 6 202 704 786
+4 6 911 202 786
+4 6 202 911 730
+4 22 216 951 1009
+4 10 214 610 21
+4 418 986 799 521
+4 774 400 405 356
+4 808 468 357 833
+4 11 22 951 1009
+4 1025 232 819 818
+4 228 826 819 1025
+4 207 994 608 353
+4 499 146 436 919
+4 953 155 303 919
+4 84 974 632 923
+4 328 1030 643 24
+4 554 212 179 115
+4 735 932 171 909
+4 15 18 755 225
+4 15 18 225 421
+4 525 17 224 352
+4 712 206 210 813
+4 525 224 230 352
+4 352 257 264 796
+4 561 166 929 784
+4 295 392 698 724
+4 617 979 184 1
+4 1027 222 594 817
+4 17 224 401 754
+4 17 352 918 224
+4 483 352 388 796
+4 18 28 225 520
+4 697 829 261 492
+4 1033 668 208 181
+4 752 420 599 266
+4 966 293 991 933
+4 548 991 459 169
+4 19 917 230 712
+4 63 697 395 982
+4 19 917 458 230
+4 478 332 252 426
+4 258 821 558 435
+4 623 557 446 419
+4 21 904 214 232
+4 21 374 610 10
+4 21 733 214 610
+4 21 610 566 733
+4 21 214 733 232
+4 240 589 608 355
+4 23 37 624 219
+4 23 219 1006 12
+4 226 484 536 355
+4 231 34 260 238
+4 25 903 233 636
+4 25 819 232 39
+4 25 636 819 39
+4 826 232 233 819
+4 27 33 220 244
+4 28 371 231 225
+4 28 231 238 34
+4 30 577 856 36
+4 30 857 738 37
+4 30 46 856 577
+4 30 46 577 437
+4 30 46 437 857
+4 30 857 437 738
+4 31 865 253 47
+4 920 445 423 449
+4 127 423 449 920
+4 178 550 744 128
+4 178 694 842 692
+4 178 842 744 692
+4 33 243 889 220
+4 272 115 390 179
+4 33 243 244 1019
+4 179 969 993 312
+4 272 312 179 993
+4 35 262 261 55
+4 723 351 269 182
+4 35 308 262 55
+4 1001 791 158 182
+4 35 262 308 906
+4 953 183 268 303
+4 36 22 344 216
+4 657 401 206 754
+4 37 248 49 857
+4 37 248 1032 49
+4 499 919 303 146
+4 37 790 219 242
+4 37 790 242 1032
+4 303 499 190 415
+4 38 905 643 24
+4 499 116 190 415
+4 728 191 669 503
+4 503 191 669 161
+4 39 818 254 819
+4 40 324 910 42
+4 40 44 538 757
+4 41 43 264 785
+4 41 556 785 746
+4 42 281 647 56
+4 42 245 281 910
+4 42 324 910 281
+4 44 251 757 279
+4 45 310 602 59
+4 46 947 49 47
+4 46 47 253 947
+4 47 49 51 947
+4 47 254 253 947
+4 50 62 945 536
+4 51 697 779 63
+4 68 315 762 72
+4 68 315 641 762
+4 52 480 589 60
+4 72 942 177 74
+4 52 32 888 747
+4 53 61 822 983
+4 53 242 243 822
+4 119 135 427 333
+4 119 333 427 749
+4 584 271 562 403
+4 55 829 697 982
+4 55 829 262 261
+4 558 405 596 821
+4 558 578 138 435
+4 56 281 647 241
+4 57 65 285 603
+4 58 66 330 513
+4 59 310 309 67
+4 59 686 310 67
+4 60 541 945 62
+4 61 781 75 63
+4 61 63 779 781
+4 61 289 983 73
+4 288 132 1000 913
+4 62 541 74 60
+4 62 74 541 981
+4 114 694 949 842
+4 554 212 584 179
+4 179 584 403 271
+4 528 584 271 302
+4 63 297 781 75
+4 63 982 297 75
+4 179 212 584 528
+4 63 395 697 779
+4 55 982 697 63
+4 554 584 403 179
+4 313 511 314 566
+4 314 313 668 620
+4 313 511 620 314
+4 314 313 610 668
+4 566 313 610 314
+4 184 1033 181 763
+4 65 69 975 797
+4 187 763 668 1033
+4 65 69 797 321
+4 537 227 313 208
+4 354 207 307 467
+4 65 884 321 603
+4 960 257 264 270
+4 66 342 963 893
+4 960 264 257 746
+4 960 746 602 45
+4 67 805 965 71
+4 67 343 805 71
+4 67 962 343 898
+4 68 72 848 315
+4 68 64 334 641
+4 69 326 849 73
+4 69 73 987 326
+4 69 284 797 987
+4 404 726 116 415
+4 70 342 306 66
+4 70 342 489 306
+4 404 726 415 416
+4 732 176 644 491
+4 71 75 860 335
+4 71 335 985 75
+4 375 176 644 732
+4 71 923 860 84
+4 360 453 491 644
+4 71 308 985 805
+4 72 177 541 74
+4 72 87 848 438
+4 73 75 781 943
+4 73 849 85 326
+4 73 85 943 326
+4 73 326 289 987
+4 74 358 859 88
+4 74 541 489 177
+4 85 644 375 850
+4 850 198 644 375
+4 75 335 943 86
+4 75 335 985 297
+4 75 297 781 335
+4 76 77 1010 380
+4 76 77 380 277
+4 76 583 767 78
+4 76 1010 767 583
+4 6 347 730 657
+4 77 79 650 664
+4 77 650 329 380
+4 78 760 771 80
+4 78 769 760 80
+4 78 769 580 760
+4 81 83 884 1003
+4 81 83 1003 622
+4 82 995 949 899
+4 82 376 974 611
+4 82 611 974 377
+4 83 375 850 85
+4 83 85 849 375
+4 83 375 849 321
+4 84 86 364 961
+4 84 961 923 86
+4 207 231 328 189
+4 85 86 943 644
+4 86 453 644 868
+4 86 644 335 943
+4 86 335 644 961
+4 87 89 438 845
+4 88 90 363 922
+4 88 922 358 90
+4 88 100 101 387
+4 89 91 565 745
+4 359 528 271 302
+4 359 212 179 528
+4 302 130 271 359
+4 359 212 528 507
+4 302 320 156 362
+4 507 528 302 362
+4 528 320 302 362
+4 176 375 316 1002
+4 316 176 198 375
+4 88 363 100 922
+4 100 363 103 922
+4 112 119 482 103
+4 749 119 482 112
+4 364 86 98 453
+4 364 98 102 453
+4 145 720 320 370
+4 94 666 761 96
+4 365 118 989 134
+4 366 110 118 663
+4 954 171 909 838
+4 95 97 765 381
+4 95 97 381 431
+4 838 909 548 171
+4 102 366 118 988
+4 988 366 118 663
+4 95 324 916 381
+4 869 379 386 1029
+4 506 367 220 657
+4 869 252 1029 386
+4 368 157 292 719
+4 96 311 571 97
+4 368 292 443 719
+4 497 719 368 443
+4 737 490 468 325
+4 18 659 225 369
+4 96 761 311 666
+4 194 479 666 311
+4 950 717 156 370
+4 86 453 868 98
+4 98 405 944 110
+4 129 303 190 415
+4 99 345 111 944
+4 452 155 158 953
+4 100 332 113 101
+4 884 603 65 373
+4 100 101 387 332
+4 683 373 322 884
+4 101 113 1012 332
+4 566 902 374 21
+4 511 902 374 566
+4 98 348 868 99
+4 98 868 348 405
+4 102 576 560 899
+4 178 744 934 128
+4 178 842 934 744
+4 27 220 918 244
+4 105 109 515 952
+4 751 220 243 244
+4 105 319 101 235
+4 107 212 554 115
+4 107 103 339 628
+4 711 382 578 432
+4 711 259 382 432
+4 723 351 382 259
+4 382 282 351 723
+4 110 780 345 111
+4 110 780 111 122
+4 161 555 149 211
+4 110 837 405 345
+4 110 405 837 430
+4 111 836 851 120
+4 111 425 853 124
+4 107 339 554 212
+4 339 410 212 107
+4 112 113 332 346
+4 100 112 482 103
+4 302 320 350 156
+4 362 320 156 145
+4 1012 323 332 346
+4 113 1012 332 346
+4 113 112 123 346
+4 969 179 390 554
+4 213 529 327 322
+4 809 176 732 543
+4 1016 869 379 386
+4 278 691 744 990
+4 278 744 689 277
+4 278 990 744 277
+4 992 200 216 537
+4 166 723 561 391
+4 391 723 561 269
+4 200 537 221 216
+4 568 517 390 892
+4 517 568 631 892
+4 118 558 559 138
+4 119 482 103 628
+4 959 133 434 562
+4 959 562 434 420
+4 122 124 946 780
+4 122 126 867 429
+4 122 429 948 126
+4 436 452 614 919
+4 919 452 614 953
+4 123 428 858 126
+4 46 47 50 253
+4 124 424 127 946
+4 124 424 866 127
+4 124 136 866 424
+4 424 789 425 419
+4 125 127 847 423
+4 125 941 847 137
+4 125 137 986 941
+4 126 924 142 867
+4 126 428 858 142
+4 126 924 428 142
+4 126 948 428 429
+4 206 754 401 813
+4 754 224 401 813
+4 129 1018 278 132
+4 276 218 642 839
+4 614 953 452 349
+4 129 415 116 705
+4 129 303 415 1018
+4 839 26 218 642
+4 130 562 312 133
+4 452 953 158 349
+4 131 133 434 959
+4 547 679 831 841
+4 134 341 989 429
+4 134 989 341 148
+4 547 679 841 686
+4 135 142 858 736
+4 15 421 225 600
+4 135 119 625 333
+4 136 150 1007 446
+4 524 600 648 422
+4 648 600 15 422
+4 458 917 257 230
+4 136 789 424 419
+4 136 446 789 419
+4 678 458 263 257
+4 263 917 257 458
+4 137 151 882 799
+4 137 151 799 445
+4 137 986 941 799
+4 793 1004 463 236
+4 237 293 572 173
+4 141 147 417 443
+4 141 417 591 443
+4 731 548 459 169
+4 142 736 428 858
+4 142 455 924 428
+4 142 428 736 455
+4 719 731 459 169
+4 143 153 445 920
+4 156 320 350 950
+4 144 154 652 282
+4 144 578 435 138
+4 144 578 282 435
+4 231 484 535 238
+4 231 535 371 238
+4 966 459 593 393
+4 433 593 966 459
+4 85 644 850 99
+4 99 198 644 850
+4 40 442 413 671
+4 184 553 354 181
+4 239 207 354 467
+4 677 671 413 442
+4 448 132 278 691
+4 150 162 1007 935
+4 448 691 278 300
+4 150 935 1007 446
+4 151 546 445 881
+4 207 189 467 239
+4 240 355 484 226
+4 152 721 512 164
+4 61 779 63 51
+4 153 445 920 460
+4 155 753 452 158
+4 155 919 452 713
+4 156 950 350 159
+4 159 292 599 157
+4 159 599 292 1005
+4 280 396 403 1029
+4 113 123 125 346
+4 1029 396 403 478
+4 123 428 126 125
+4 52 255 589 840
+4 22 216 36 951
+4 255 52 48 36
+4 125 126 127 428
+4 36 216 255 951
+4 164 773 824 172
+4 165 173 237 651
+4 106 258 180 560
+4 774 821 405 560
+4 170 561 929 758
+4 140 416 404 436
+4 404 146 140 436
+4 166 582 561 259
+4 112 482 749 332
+4 735 414 788 909
+4 351 1031 456 259
+4 167 788 669 909
+4 878 515 193 319
+4 168 170 539 956
+4 878 319 193 89
+4 302 130 562 271
+4 508 701 469 652
+4 235 121 591 323
+4 701 349 469 652
+4 925 701 469 508
+4 105 235 121 883
+4 170 539 970 758
+4 621 876 2 188
+4 876 188 187 2
+4 354 763 930 615
+4 172 825 773 824
+4 538 44 251 757
+4 538 670 910 251
+4 173 237 651 823
+4 173 823 572 237
+4 170 561 970 269
+4 170 956 269 970
+4 270 458 960 257
+4 185 204 203 477
+4 187 477 203 208
+4 203 828 208 477
+4 296 272 96 666
+4 207 307 467 328
+4 154 791 282 182
+4 282 791 452 351
+4 349 282 791 452
+4 349 154 791 282
+4 28 231 371 238
+4 330 915 724 66
+4 330 915 66 58
+4 28 520 504 273
+4 77 650 380 664
+4 274 213 322 529
+4 933 991 548 169
+4 275 357 606 331
+4 966 991 548 933
+4 677 770 761 96
+4 939 283 839 16
+4 277 77 380 664
+4 378 300 278 277
+4 56 64 281 241
+4 241 334 64 281
+4 129 415 705 278
+4 281 318 641 64
+4 129 278 705 300
+4 58 66 513 964
+4 44 279 413 706
+4 279 606 331 275
+4 44 279 706 58
+4 795 131 581 434
+4 737 325 820 490
+4 869 386 1016 319
+4 722 150 162 1007
+4 282 578 526 435
+4 907 150 722 1007
+4 880 241 334 64
+4 64 680 880 241
+4 129 415 278 1018
+4 288 132 1018 1000
+4 288 1018 217 1000
+4 217 1018 268 1000
+4 573 173 572 293
+4 104 108 886 726
+4 649 294 324 95
+4 926 312 130 296
+4 681 879 318 64
+4 148 514 721 160
+4 148 721 514 908
+4 650 77 329 301
+4 639 904 518 214
+4 639 215 518 14
+4 639 214 518 215
+4 519 114 694 949
+4 899 694 949 519
+4 304 704 786 6
+4 651 305 173 742
+4 173 782 742 305
+4 184 181 354 763
+4 537 467 313 226
+4 467 313 226 643
+4 307 551 7 930
+4 314 511 374 566
+4 21 566 610 374
+4 311 357 379 699
+4 566 314 610 374
+4 479 311 379 699
+4 97 431 1011 311
+4 163 719 497 459
+4 743 479 379 312
+4 312 562 434 133
+4 312 403 699 379
+4 163 719 459 169
+4 312 479 379 699
+4 696 133 312 434
+4 459 719 497 443
+4 427 555 454 439
+4 736 427 555 454
+4 181 313 668 208
+4 763 307 620 313
+4 610 313 208 668
+4 315 942 177 72
+4 315 820 325 177
+4 315 72 848 438
+4 848 89 737 438
+4 596 578 526 456
+4 596 821 526 578
+4 478 426 252 396
+4 396 426 252 532
+4 179 528 584 271
+4 359 528 179 271
+4 359 528 302 507
+4 528 320 584 302
+4 353 196 276 563
+4 563 276 353 608
+4 682 317 27 658
+4 27 682 244 317
+4 319 869 386 252
+4 145 720 212 320
+4 720 236 748 320
+4 701 217 469 349
+4 701 934 925 217
+4 925 217 175 186
+4 925 934 175 217
+4 469 217 186 349
+4 346 121 1012 323
+4 113 121 1012 346
+4 123 427 428 125
+4 125 428 127 423
+4 13 976 510 328
+4 58 330 727 279
+4 320 950 236 197
+4 252 386 387 478
+4 72 177 480 541
+4 541 246 534 740
+4 139 720 212 145
+4 68 334 481 762
+4 32 241 747 334
+4 241 246 334 475
+4 52 334 481 68
+4 334 32 52 747
+4 339 103 482 628
+4 564 340 512 152
+4 340 429 811 587
+4 148 807 341 134
+4 989 441 430 429
+4 341 587 429 340
+4 148 908 514 341
+4 809 543 360 361
+4 361 689 543 389
+4 361 543 360 389
+4 213 689 543 361
+4 213 543 809 361
+4 200 216 221 344
+4 677 442 413 44
+4 677 44 413 706
+4 679 556 547 831
+4 621 927 783 549
+4 549 707 783 621
+4 178 692 744 550
+4 30 344 577 36
+4 692 744 550 928
+4 307 620 551 930
+4 82 377 974 576
+4 551 307 709 620
+4 360 389 453 377
+4 185 204 477 188
+4 185 801 204 188
+4 82 576 974 84
+4 552 932 728 788
+4 185 201 203 204
+4 728 552 669 191
+4 728 788 669 552
+4 5 973 812 553
+4 98 99 944 348
+4 98 405 348 944
+4 99 851 111 345
+4 345 836 851 111
+4 345 836 690 397
+4 184 200 553 181
+4 187 188 477 208
+4 112 123 346 749
+4 1033 763 668 181
+4 346 125 986 423
+4 203 828 477 204
+4 188 209 801 204
+4 188 208 209 477
+4 188 801 209 473
+4 137 418 986 799
+4 188 214 802 209
+4 188 209 208 214
+4 365 118 663 989
+4 348 851 198 99
+4 348 99 345 851
+4 348 690 397 345
+4 288 400 175 614
+4 415 400 776 288
+4 415 614 400 288
+4 288 776 810 400
+4 288 175 400 810
+4 212 720 748 320
+4 139 720 748 212
+4 349 953 158 542
+4 938 349 652 154
+4 542 154 158 349
+4 777 708 514 582
+4 584 396 420 350
+4 777 721 514 708
+4 350 562 420 584
+4 791 158 452 753
+4 1001 753 158 791
+4 270 352 257 264
+4 353 196 563 207
+4 5 553 199 563
+4 41 264 658 270
+4 41 960 264 270
+4 7 655 930 3
+4 850 316 198 375
+4 104 316 198 850
+4 40 44 757 413
+4 201 203 204 827
+4 201 222 827 204
+4 202 219 1027 205
+4 279 275 590 413
+4 188 209 204 477
+4 203 200 537 221
+4 204 1027 801 205
+4 477 208 209 828
+4 204 222 828 209
+4 205 801 597 372
+4 205 219 1027 476
+4 206 813 223 210
+4 206 220 223 401
+4 200 992 181 537
+4 209 208 214 832
+4 209 222 828 594
+4 8 215 967 473
+4 210 228 223 372
+4 210 229 813 223
+4 210 223 228 229
+4 210 813 229 712
+4 210 234 712 229
+4 92 390 612 94
+4 92 390 568 612
+4 92 568 390 892
+4 92 501 390 94
+4 501 390 892 92
+4 328 313 1030 13
+4 207 231 994 225
+4 826 215 228 233
+4 353 15 196 267
+4 353 15 939 196
+4 608 246 189 355
+4 189 231 484 535
+4 355 589 246 533
+4 22 216 1009 344
+4 175 400 774 614
+4 821 435 526 578
+4 186 526 821 435
+4 506 27 889 220
+4 218 888 32 747
+4 500 447 140 146
+4 407 447 140 500
+4 115 390 107 501
+4 501 390 107 892
+4 221 815 828 222
+4 221 226 227 1024
+4 221 815 1024 227
+4 895 152 466 503
+4 503 152 466 164
+4 223 243 476 834
+4 223 250 803 224
+4 223 224 751 250
+4 223 250 834 229
+4 224 813 230 803
+4 224 483 803 230
+4 224 244 751 483
+4 161 211 409 502
+4 643 328 24 905
+4 226 247 355 536
+4 508 144 435 411
+4 226 247 488 1024
+4 228 826 233 819
+4 228 817 594 1025
+4 228 229 834 835
+4 826 1025 594 232
+4 228 835 819 233
+4 228 1025 834 817
+4 534 306 238 260
+4 238 306 34 260
+4 279 413 590 757
+4 229 492 250 834
+4 230 256 483 803
+4 728 503 466 164
+4 230 917 257 256
+4 728 466 824 164
+4 728 824 172 164
+4 2 668 620 588
+4 588 314 668 620
+4 314 511 620 588
+4 444 459 384 546
+4 546 593 459 384
+4 364 86 453 961
+4 364 453 102 576
+4 32 241 334 880
+4 242 822 249 243
+4 243 1019 751 244
+4 244 285 388 682
+4 249 395 492 250
+4 249 289 243 822
+4 886 726 404 416
+4 726 397 416 886
+4 28 520 371 225
+4 28 371 520 273
+4 371 493 251 273
+4 493 246 475 814
+4 238 273 34 306
+4 256 492 262 1020
+4 256 796 1020 298
+4 251 475 287 295
+4 287 251 295 590
+4 287 590 910 251
+4 245 287 251 475
+4 910 287 251 245
+4 273 34 306 894
+4 205 801 372 1027
+4 205 476 1027 372
+4 209 1027 594 372
+4 378 278 689 277
+4 601 824 472 487
+4 870 728 472 601
+4 728 601 824 472
+4 870 472 487 601
+4 809 968 327 360
+4 82 376 962 974
+4 337 343 841 376
+4 337 361 376 605
+4 389 377 842 180
+4 82 995 377 949
+4 361 389 377 607
+4 870 487 174 601
+4 96 97 571 873
+4 96 873 571 677
+4 0 876 187 2
+4 284 289 797 987
+4 286 688 290 291
+4 602 310 309 59
+4 602 309 257 678
+4 602 310 299 309
+4 602 299 257 309
+4 57 603 285 286
+4 57 603 286 322
+4 475 457 814 246
+4 603 285 286 322
+4 287 325 1028 295
+4 287 687 325 318
+4 246 814 534 740
+4 257 309 299 796
+4 290 297 298 1022
+4 290 327 1022 336
+4 257 299 746 796
+4 291 337 290 299
+4 291 830 337 299
+4 722 153 460 165
+4 153 461 460 569
+4 907 153 569 461
+4 153 907 722 461
+4 724 342 66 306
+4 724 306 392 342
+4 724 330 66 513
+4 724 342 513 66
+4 295 325 1028 698
+4 306 342 489 392
+4 76 380 1010 583
+4 297 1022 308 298
+4 298 308 309 805
+4 299 336 337 290
+4 76 380 583 277
+4 329 274 322 529
+4 380 274 361 689
+4 381 97 765 571
+4 381 97 311 431
+4 324 486 687 318
+4 66 963 342 513
+4 656 281 245 241
+4 236 426 522 439
+4 439 384 383 1004
+4 384 393 593 459
+4 445 460 385 449
+4 445 460 593 385
+4 385 394 460 593
+4 449 460 385 675
+4 460 385 675 394
+4 184 1033 200 181
+4 203 181 537 200
+4 244 751 483 1019
+4 388 290 286 285
+4 810 732 389 491
+4 378 176 689 776
+4 936 795 420 702
+4 689 744 361 583
+4 583 580 744 361
+4 322 688 329 529
+4 322 529 327 688
+4 447 462 729 451
+4 215 937 233 14
+4 233 215 214 826
+4 325 331 698 833
+4 518 215 233 14
+4 518 214 233 215
+4 280 795 434 420
+4 177 820 325 392
+4 246 814 740 457
+4 795 959 434 420
+4 295 392 325 698
+4 392 698 820 325
+4 420 795 959 702
+4 324 808 275 331
+4 331 778 606 1034
+4 572 394 472 414
+4 700 952 936 117
+4 173 742 572 823
+4 414 393 394 472
+4 394 675 487 464
+4 335 360 343 336
+4 968 336 327 360
+4 336 360 343 337
+4 336 337 327 360
+4 337 361 605 338
+4 337 343 376 360
+4 337 361 360 376
+4 337 360 809 327
+4 698 490 820 325
+4 698 325 833 490
+4 63 781 395 779
+4 63 395 781 297
+4 347 12 730 220
+4 12 506 220 347
+4 952 417 396 532
+4 43 264 286 646
+4 646 286 682 264
+4 42 281 656 647
+4 647 281 656 241
+4 527 656 241 647
+4 117 131 795 702
+4 117 795 936 702
+4 236 211 439 463
+4 370 717 236 950
+4 236 463 439 1004
+4 8 662 967 977
+4 602 59 309 678
+4 45 59 602 678
+4 263 59 678 309
+4 263 59 531 678
+4 504 674 58 727
+4 44 674 727 58
+4 7 207 307 655
+4 655 7 207 955
+4 655 207 354 563
+4 196 563 207 655
+4 207 267 196 655
+4 267 207 955 655
+4 307 207 354 655
+4 399 153 165 460
+4 715 884 1003 81
+4 318 468 687 325
+4 888 402 22 951
+4 886 108 404 726
+4 915 406 66 58
+4 407 935 162 150
+4 64 879 318 565
+4 889 27 33 220
+4 149 503 1008 161
+4 64 565 318 641
+4 161 211 149 409
+4 366 110 663 405
+4 988 366 663 405
+4 339 896 410 107
+4 410 145 139 212
+4 900 258 411 106
+4 411 144 435 138
+4 110 663 405 430
+4 988 663 558 405
+4 663 405 430 596
+4 412 29 234 35
+4 28 510 231 34
+4 328 1030 24 13
+4 458 525 230 352
+4 325 833 490 468
+4 334 641 64 281
+4 334 475 641 281
+4 40 413 910 324
+4 176 732 810 491
+4 40 413 324 671
+4 571 671 324 413
+4 571 413 324 275
+4 354 763 615 184
+4 930 354 615 3
+4 3 354 615 570
+4 735 933 909 171
+4 167 788 909 932
+4 238 273 306 295
+4 915 306 724 66
+4 361 389 360 377
+4 86 868 644 99
+4 98 868 86 99
+4 583 580 760 78
+4 583 78 574 580
+4 689 744 389 361
+4 95 431 381 579
+4 431 379 479 311
+4 381 311 357 379
+4 575 579 431 95
+4 743 431 379 479
+4 138 711 578 901
+4 559 138 578 901
+4 387 101 319 332
+4 165 399 460 433
+4 386 252 1029 478
+4 399 151 546 163
+4 312 403 379 434
+4 743 434 312 379
+4 931 131 434 581
+4 170 166 929 561
+4 689 543 389 810
+4 693 726 116 108
+4 758 474 470 465
+4 784 561 582 758
+4 379 1029 699 386
+4 517 339 554 107
+4 517 103 339 107
+4 991 433 966 459
+4 146 436 919 447
+4 415 499 404 436
+4 436 447 356 452
+4 186 217 175 614
+4 186 175 774 614
+4 102 899 560 106
+4 437 46 947 248
+4 54 714 260 981
+4 714 981 533 260
+4 738 221 222 815
+4 437 815 1024 221
+4 738 248 815 222
+4 72 87 438 942
+4 714 536 260 533
+4 54 863 260 714
+4 863 714 536 260
+4 315 72 438 942
+4 315 737 325 820
+4 774 405 400 440
+4 405 560 440 774
+4 360 389 491 453
+4 365 663 430 989
+4 989 663 430 559
+4 341 587 441 429
+4 110 663 430 365
+4 429 441 450 587
+4 441 800 451 450
+4 663 596 430 559
+4 341 432 514 148
+4 89 845 319 438
+4 89 105 319 845
+4 89 193 438 319
+4 693 81 79 1002
+4 681 91 318 879
+4 683 884 322 715
+4 637 775 201 408
+4 637 9 201 775
+4 553 239 199 563
+4 84 961 364 576
+4 364 961 453 576
+4 218 241 283 246
+4 886 416 140 557
+4 218 32 241 747
+4 886 557 140 120
+4 416 557 436 140
+4 415 303 953 217
+4 415 953 614 217
+4 98 453 868 405
+4 1015 440 400 405
+4 440 453 560 405
+4 56 64 241 680
+4 7 655 307 930
+4 560 106 258 900
+4 558 578 559 138
+4 307 655 354 930
+4 405 821 356 596
+4 68 334 762 641
+4 287 325 295 457
+4 457 295 392 325
+4 457 177 325 392
+4 360 732 644 491
+4 968 732 644 360
+4 809 732 360 543
+4 543 732 360 389
+4 732 360 389 491
+4 968 360 809 732
+4 232 233 214 826
+4 518 904 232 214
+4 518 214 232 233
+4 152 512 466 164
+4 152 564 466 512
+4 895 152 564 466
+4 417 443 532 591
+4 419 446 789 425
+4 222 828 594 815
+4 222 248 815 594
+4 594 227 832 818
+4 370 950 320 156
+4 39 232 818 819
+4 594 248 815 254
+4 346 986 521 423
+4 418 521 1014 323
+4 418 444 882 1014
+4 423 384 445 799
+4 423 445 384 385
+4 423 385 449 445
+4 424 1023 780 425
+4 424 948 429 811
+4 424 450 811 429
+4 425 780 430 1023
+4 425 446 1023 451
+4 356 837 456 1026
+4 356 447 1026 673
+4 356 452 447 673
+4 302 195 562 1035
+4 960 746 257 602
+4 602 678 257 960
+4 746 299 257 602
+4 425 451 1023 430
+4 430 441 451 1023
+4 430 451 441 456
+4 425 451 430 1026
+4 1026 430 456 451
+4 428 449 423 455
+4 429 430 1023 441
+4 429 450 811 587
+4 603 884 321 322
+4 884 322 603 373
+4 373 322 603 57
+4 603 285 322 321
+4 20 30 613 567
+4 344 613 20 30
+4 613 30 221 567
+4 344 221 613 30
+4 17 224 918 401
+4 657 367 401 17
+4 989 432 341 148
+4 240 467 537 226
+4 467 484 226 240
+4 467 643 226 484
+4 505 200 1009 199
+4 5 812 199 553
+4 202 1027 204 205
+4 185 204 205 202
+4 318 486 687 468
+4 446 729 451 447
+4 446 450 451 798
+4 446 729 798 451
+4 196 563 655 741
+4 912 563 196 741
+4 1031 561 462 495
+4 655 267 196 741
+4 441 471 465 514
+4 441 451 800 471
+4 651 305 742 470
+4 1031 495 462 451
+4 742 782 470 305
+4 742 470 487 823
+4 439 454 384 463
+4 742 823 651 470
+4 742 487 470 782
+4 4 914 911 473
+4 473 205 801 597
+4 8 967 210 473
+4 454 592 385 384
+4 8 4 473 914
+4 449 1021 811 450
+4 967 215 228 597
+4 449 385 423 455
+4 450 451 798 800
+4 285 797 290 327
+4 285 327 322 321
+4 322 285 290 327
+4 285 797 327 321
+4 45 556 746 831
+4 451 750 729 798
+4 831 556 746 830
+4 447 462 451 673
+4 476 242 1032 249
+4 455 1021 464 512
+4 223 224 918 751
+4 224 751 244 918
+4 194 479 296 666
+4 117 936 280 952
+4 272 666 479 390
+4 194 479 312 296
+4 143 127 739 920
+4 847 127 143 920
+4 127 449 428 811
+4 739 127 811 449
+4 423 449 428 127
+4 507 212 528 362
+4 212 320 528 362
+4 346 521 485 427
+4 387 100 482 103
+4 480 740 246 541
+4 481 740 457 246
+4 52 334 747 481
+4 481 740 246 480
+4 119 748 628 139
+4 339 628 748 139
+4 40 757 538 910
+4 384 463 454 592
+4 460 823 675 461
+4 385 454 464 592
+4 460 823 394 675
+4 538 757 251 910
+4 40 757 910 413
+4 387 332 478 482
+4 224 352 483 230
+4 224 244 483 317
+4 230 256 257 483
+4 244 483 317 388
+4 707 639 667 621
+4 483 796 256 257
+4 707 667 188 621
+4 264 291 388 796
+4 454 592 466 464
+4 454 463 466 592
+4 464 465 487 825
+4 91 318 565 745
+4 879 91 318 565
+4 328 231 484 189
+4 723 259 382 711
+4 723 259 711 160
+4 346 323 521 418
+4 787 461 729 750
+4 598 787 461 729
+4 798 750 729 461
+4 598 729 461 162
+4 1007 162 461 729
+4 1007 729 461 798
+4 95 579 381 916
+4 381 379 357 468
+4 658 17 918 27
+4 658 17 352 918
+4 394 487 824 464
+4 658 918 317 27
+4 658 918 352 317
+4 38 260 488 643
+4 226 247 536 488
+4 50 863 488 38
+4 70 74 489 859
+4 70 342 859 489
+4 319 490 358 386
+4 319 1016 490 386
+4 568 386 358 490
+4 90 922 358 568
+4 491 810 176 400
+4 491 176 198 400
+4 689 176 543 810
+4 491 389 810 440
+4 491 1015 400 198
+4 491 440 400 1015
+4 701 217 925 469
+4 925 217 186 469
+4 925 469 186 435
+4 137 882 418 799
+4 799 882 418 444
+4 229 492 835 234
+4 492 395 829 1020
+4 250 395 492 1020
+4 492 261 262 829
+4 367 918 401 17
+4 367 220 401 918
+4 731 383 719 459
+4 292 383 443 719
+4 719 383 443 459
+4 292 383 719 731
+4 385 464 454 455
+4 385 464 455 1021
+4 385 1021 675 464
+4 746 299 310 831
+4 746 310 299 602
+4 225 493 251 371
+4 836 1026 425 837
+4 836 557 425 1026
+4 837 430 1026 425
+4 517 390 107 554
+4 892 517 390 107
+4 554 115 390 107
+4 718 775 637 408
+4 718 9 637 775
+4 9 775 613 201
+4 471 582 495 465
+4 471 465 495 800
+4 209 826 214 802
+4 802 214 215 826
+4 802 826 597 209
+4 802 597 826 215
+4 775 567 201 890
+4 775 567 613 201
+4 775 408 890 201
+4 537 226 313 227
+4 991 163 433 459
+4 566 226 227 313
+4 537 227 221 226
+4 572 394 414 966
+4 456 432 259 471
+4 496 703 586 117
+4 163 497 398 459
+4 165 399 433 498
+4 3 7 655 955
+4 4 653 911 6
+4 4 6 911 957
+4 293 498 165 433
+4 5 11 199 812
+4 499 146 404 436
+4 162 935 407 500
+4 162 978 935 500
+4 501 115 390 272
+4 10 639 214 21
+4 504 727 58 406
+4 493 251 475 245
+4 251 493 475 295
+4 506 27 220 367
+4 507 212 362 145
+4 507 145 410 212
+4 16 527 283 26
+4 17 367 918 27
+4 508 652 435 144
+4 18 369 225 28
+4 234 509 523 29
+4 19 531 917 29
+4 509 29 234 412
+4 510 28 231 369
+4 511 13 313 709
+4 511 13 1030 313
+4 239 354 181 467
+4 745 486 468 193
+4 745 93 486 585
+4 193 486 468 379
+4 878 109 496 515
+4 93 496 585 745
+4 455 340 1021 512
+4 279 513 331 606
+4 510 24 328 905
+4 295 306 392 724
+4 891 22 344 36
+4 1028 513 331 279
+4 513 606 1034 331
+4 514 340 587 341
+4 341 441 587 514
+4 35 906 308 635
+4 37 889 219 23
+4 514 512 465 340
+4 40 42 910 958
+4 40 294 324 42
+4 41 43 785 545
+4 42 540 281 56
+4 745 515 585 193
+4 585 515 379 193
+4 43 646 286 57
+4 43 544 57 286
+4 52 619 334 68
+4 759 203 187 477
+4 53 69 284 975
+4 54 38 260 863
+4 1017 187 477 759
+4 187 1017 477 876
+4 876 477 187 188
+4 59 67 309 906
+4 41 785 264 746
+4 746 785 264 291
+4 36 216 577 247
+4 76 766 1010 77
+4 36 247 255 216
+4 76 766 875 1010
+4 386 478 517 387
+4 387 103 482 517
+4 85 644 326 375
+4 82 804 576 84
+4 966 991 293 433
+4 991 498 293 433
+4 212 320 362 145
+4 93 95 916 980
+4 102 84 576 804
+4 127 811 948 424
+4 739 127 424 811
+4 127 811 428 948
+4 106 633 560 102
+4 18 520 225 421
+4 520 251 727 273
+4 520 251 371 225
+4 520 371 251 273
+4 660 421 520 18
+4 520 674 727 251
+4 465 777 582 474
+4 582 784 708 166
+4 117 280 936 795
+4 510 369 231 659
+4 225 659 231 369
+4 659 231 207 225
+4 659 976 207 231
+4 659 510 976 231
+4 120 136 419 623
+4 715 81 1003 1002
+4 715 1003 322 213
+4 129 132 278 448
+4 715 1002 1003 213
+4 300 277 77 764
+4 138 144 578 711
+4 44 279 757 413
+4 139 409 720 145
+4 279 275 331 590
+4 146 595 919 155
+4 147 417 292 157
+4 147 157 292 368
+4 195 350 159 156
+4 149 895 1008 503
+4 748 236 426 320
+4 130 1035 562 133
+4 130 302 562 1035
+4 157 159 292 661
+4 478 426 396 320
+4 478 426 320 748
+4 478 396 584 320
+4 212 478 584 320
+4 212 478 320 748
+4 384 459 383 548
+4 444 443 383 459
+4 166 391 561 170
+4 925 949 180 842
+4 106 925 949 180
+4 539 170 970 956
+4 168 604 539 170
+4 168 598 162 729
+4 269 351 791 182
+4 173 174 572 782
+4 351 791 452 753
+4 269 753 791 351
+4 174 487 877 609
+4 224 317 483 352
+4 483 257 352 796
+4 182 351 791 282
+4 1014 444 443 383
+4 726 316 622 1002
+4 1014 383 443 522
+4 30 221 738 437
+4 30 437 577 221
+4 521 444 383 384
+4 567 30 221 738
+4 521 439 383 522
+4 8 967 215 14
+4 30 344 221 577
+4 937 14 977 509
+4 43 264 785 286
+4 388 286 290 291
+4 2 187 620 668
+4 187 620 668 763
+4 323 485 522 426
+4 349 452 614 526
+4 282 456 452 526
+4 356 526 452 456
+4 614 452 356 526
+4 578 711 144 382
+4 423 521 384 799
+4 288 928 128 744
+4 128 132 288 913
+4 450 676 1021 587
+4 676 464 465 487
+4 132 928 128 288
+4 758 750 465 470
+4 451 800 750 798
+4 461 470 676 750
+4 800 465 495 750
+4 128 288 744 934
+4 758 750 495 465
+4 128 288 934 913
+4 203 537 208 221
+4 203 181 208 537
+4 283 816 225 994
+4 600 493 241 245
+4 283 493 246 241
+4 493 475 241 245
+4 381 324 687 808
+4 381 468 808 687
+4 324 331 687 808
+4 331 325 687 833
+4 687 468 833 325
+4 493 475 246 241
+4 213 809 327 529
+4 329 274 529 361
+4 529 809 327 337
+4 274 213 689 378
+4 380 274 689 378
+4 277 380 689 378
+4 213 378 176 689
+4 359 130 271 179
+4 302 350 195 156
+4 532 522 426 323
+4 62 945 536 541
+4 484 238 260 533
+4 534 306 295 238
+4 534 295 306 392
+4 534 489 392 306
+4 621 794 188 927
+4 876 188 621 794
+4 656 600 241 245
+4 656 527 241 600
+4 355 535 533 246
+4 225 816 535 994
+4 488 50 536 863
+4 484 536 533 260
+4 151 444 546 459
+4 398 151 163 459
+4 151 163 459 546
+4 151 459 398 444
+4 563 276 608 951
+4 608 218 276 283
+4 276 218 608 951
+4 280 795 581 434
+4 117 795 586 280
+4 586 795 581 280
+4 15 421 600 648
+4 648 421 600 251
+4 382 711 144 723
+4 382 144 282 723
+4 825 465 487 474
+4 229 835 492 834
+4 249 395 697 492
+4 168 539 729 956
+4 168 787 729 539
+4 112 332 749 346
+4 332 323 532 426
+4 485 332 426 323
+4 60 480 589 541
+4 541 589 533 246
+4 541 534 246 533
+4 217 268 542 701
+4 349 217 542 701
+4 938 154 542 349
+4 883 235 121 591
+4 328 307 467 313
+4 43 658 264 646
+4 646 264 682 658
+4 223 243 834 250
+4 834 243 249 250
+4 283 493 241 600
+4 546 460 445 153
+4 546 433 459 593
+4 399 546 460 433
+4 546 153 399 460
+4 548 171 909 933
+4 280 434 379 403
+4 723 561 259 166
+4 785 264 291 286
+4 56 318 281 64
+4 56 681 318 64
+4 540 318 281 56
+4 681 56 318 540
+4 115 212 179 359
+4 554 584 478 403
+4 386 390 554 1029
+4 386 478 1029 554
+4 179 115 390 554
+4 211 463 555 439
+4 555 454 463 466
+4 439 463 555 454
+4 281 318 287 641
+4 641 325 287 457
+4 641 325 318 287
+4 397 836 557 120
+4 419 446 425 557
+4 430 596 456 432
+4 989 901 432 148
+4 41 658 264 43
+4 560 405 558 821
+4 560 633 988 102
+4 8 215 473 783
+4 215 707 783 8
+4 430 432 441 989
+4 430 559 432 989
+4 561 970 758 170
+4 121 141 591 882
+4 561 462 495 970
+4 121 418 137 882
+4 121 882 591 418
+4 878 109 515 105
+4 878 515 319 105
+4 878 105 319 89
+4 3 655 354 563
+4 563 354 239 207
+4 741 563 655 3
+4 264 746 796 257
+4 142 455 736 564
+4 564 464 455 454
+4 630 736 564 142
+4 565 318 325 468
+4 565 737 468 325
+4 1003 83 321 375
+4 1003 321 322 327
+4 1003 213 327 322
+4 1003 327 213 375
+4 226 643 313 566
+4 24 643 634 902
+4 567 222 827 201
+4 922 568 90 631
+4 143 569 920 739
+4 569 449 450 675
+4 640 739 569 143
+4 319 387 386 358
+4 319 386 387 252
+4 571 808 275 324
+4 735 573 414 293
+4 572 487 472 394
+4 870 572 174 487
+4 82 899 576 804
+4 102 804 576 899
+4 901 118 559 138
+4 989 901 118 559
+4 989 134 118 901
+4 148 134 989 901
+4 735 728 472 870
+4 414 573 572 293
+4 870 573 174 572
+4 908 152 340 806
+4 76 574 872 583
+4 148 908 341 807
+4 743 379 431 940
+4 874 431 97 575
+4 908 806 340 807
+4 908 340 341 807
+4 577 344 221 216
+4 902 1030 24 643
+4 46 253 50 247
+4 437 46 247 253
+4 437 253 247 1024
+4 1024 247 488 253
+4 596 578 456 432
+4 579 431 381 379
+4 940 379 431 579
+4 93 916 486 585
+4 579 379 381 486
+4 93 916 585 980
+4 580 607 389 361
+4 361 580 744 389
+4 744 842 389 580
+4 105 515 319 952
+4 105 319 235 952
+4 319 515 252 952
+4 319 252 235 952
+4 796 299 291 290
+4 796 298 299 290
+4 943 75 781 335
+4 280 581 379 434
+4 943 335 781 326
+4 743 581 434 379
+4 940 743 379 581
+4 582 758 465 474
+4 939 283 16 15
+4 582 495 465 758
+4 283 16 15 600
+4 563 276 627 629
+4 292 197 443 383
+4 583 380 361 689
+4 197 522 443 383
+4 96 311 761 571
+4 381 571 324 808
+4 381 571 357 311
+4 197 236 383 192
+4 292 197 383 192
+4 197 236 522 383
+4 950 192 236 197
+4 705 776 726 378
+4 212 584 478 554
+4 590 275 331 324
+4 910 413 590 324
+4 287 324 910 590
+4 287 331 324 590
+4 413 275 590 324
+4 745 585 486 193
+4 585 579 486 379
+4 585 579 379 940
+4 238 493 273 295
+4 371 238 493 273
+4 181 354 313 467
+4 471 514 582 465
+4 465 512 514 777
+4 585 940 379 586
+4 515 586 379 280
+4 585 515 586 379
+4 586 581 379 280
+4 586 379 581 940
+4 838 548 731 171
+4 200 973 812 505
+4 572 742 487 823
+4 572 174 487 782
+4 572 487 742 782
+4 570 563 553 5
+4 514 465 587 340
+4 514 465 441 587
+4 587 450 811 1021
+4 52 589 48 60
+4 52 255 48 589
+4 240 589 247 255
+4 355 247 589 536
+4 590 1028 331 279
+4 287 590 295 1028
+4 121 591 323 418
+4 591 1014 323 418
+4 591 882 1014 418
+4 616 911 185 801
+4 616 473 911 801
+4 394 592 464 824
+4 592 463 466 472
+4 237 593 460 394
+4 433 460 237 593
+4 546 460 593 445
+4 546 433 593 460
+4 733 21 232 31
+4 172 824 487 825
+4 464 825 824 512
+4 427 423 428 125
+4 427 125 346 423
+4 465 777 514 582
+4 412 25 903 233
+4 209 826 832 214
+4 209 222 594 1027
+4 214 826 832 232
+4 217 303 953 268
+4 1018 303 415 217
+4 217 303 268 1018
+4 149 555 630 135
+4 135 427 555 736
+4 555 736 630 135
+4 135 333 149 555
+4 35 29 234 263
+4 126 428 948 127
+4 31 253 733 488
+4 436 919 614 415
+4 415 919 614 953
+4 614 356 452 436
+4 558 821 578 435
+4 596 356 837 456
+4 597 210 372 228
+4 372 834 223 476
+4 478 332 426 482
+4 35 906 263 262
+4 86 961 644 453
+4 252 319 235 332
+4 420 959 562 266
+4 752 157 599 710
+4 225 251 493 600
+4 648 600 524 245
+4 648 600 245 251
+4 525 458 230 19
+4 155 713 452 753
+4 269 351 462 753
+4 269 716 753 462
+4 525 230 1013 19
+4 525 230 224 754
+4 654 754 206 712
+4 921 1013 19 525
+4 525 17 754 224
+4 525 754 1013 230
+4 654 525 754 1013
+4 207 353 196 267
+4 353 207 659 267
+4 51 39 254 984
+4 45 41 746 556
+4 239 216 951 240
+4 114 178 934 128
+4 349 452 526 282
+4 349 791 158 452
+4 353 225 283 15
+4 225 283 15 600
+4 225 283 600 493
+4 952 591 417 532
+4 578 144 282 382
+4 80 611 997 82
+4 82 997 376 611
+4 337 605 376 841
+4 337 605 841 338
+4 92 612 996 94
+4 94 761 770 96
+4 80 995 611 82
+4 82 611 377 995
+4 607 389 377 842
+4 580 842 389 607
+4 584 320 396 350
+4 350 320 396 197
+4 227 313 208 610
+4 610 832 214 208
+4 610 313 566 227
+4 80 607 605 611
+4 611 376 360 361
+4 611 361 360 377
+4 611 605 376 361
+4 611 361 377 607
+4 612 778 342 606
+4 612 342 778 568
+4 612 390 568 357
+4 9 613 200 665
+4 9 613 665 201
+4 613 203 201 827
+4 613 200 203 221
+4 618 89 565 737
+4 45 746 310 831
+4 618 89 91 565
+4 151 137 881 445
+4 619 64 334 68
+4 880 32 619 334
+4 235 952 591 883
+4 310 45 831 547
+4 591 121 883 141
+4 235 105 952 883
+4 622 104 726 108
+4 885 1002 622 81
+4 888 52 255 36
+4 36 255 888 951
+4 104 120 397 886
+4 120 623 419 557
+4 37 53 242 889
+4 624 738 30 567
+4 624 567 30 20
+4 624 738 37 30
+4 254 47 51 947
+4 30 891 344 36
+4 891 344 20 30
+4 107 628 339 896
+4 894 70 306 66
+4 70 306 54 894
+4 149 555 1008 630
+4 149 1008 895 630
+4 568 92 631 892
+4 631 103 517 107
+4 106 900 560 633
+4 633 118 138 558
+4 899 949 576 180
+4 634 488 31 733
+4 634 733 31 21
+4 634 31 488 38
+4 905 54 260 34
+4 905 38 260 54
+4 635 67 965 71
+4 71 635 55 308
+4 636 35 261 55
+4 636 55 261 39
+4 638 31 232 21
+4 150 1007 640 136
+4 150 1007 907 640
+4 641 565 318 325
+4 624 37 790 219
+4 1006 201 202 1027
+4 1006 219 1027 202
+4 567 222 201 1006
+4 1006 222 790 567
+4 1006 790 219 624
+4 136 1007 789 446
+4 1007 450 446 798
+4 1007 450 569 789
+4 1007 789 640 136
+4 386 390 517 554
+4 386 478 554 517
+4 568 386 390 517
+4 386 568 922 517
+4 226 484 488 536
+4 333 555 427 439
+4 555 564 454 466
+4 555 454 564 736
+4 660 520 645 18
+4 645 674 504 520
+4 255 48 247 36
+4 48 255 247 589
+4 123 135 427 119
+4 123 119 427 749
+4 674 251 520 660
+4 674 520 645 660
+4 544 650 329 301
+4 785 544 329 301
+4 650 683 322 79
+4 787 305 651 470
+4 651 722 460 165
+4 787 461 470 651
+4 653 304 786 6
+4 616 653 494 185
+4 743 194 479 312
+4 431 479 194 311
+4 502 161 211 236
+4 717 161 502 236
+4 349 614 186 526
+4 186 614 356 526
+4 157 661 292 719
+4 661 192 731 265
+4 759 184 1033 200
+4 979 200 184 759
+4 979 9 200 665
+4 664 274 380 378
+4 277 664 380 378
+4 300 378 664 277
+4 664 693 378 300
+4 164 512 466 824
+4 728 824 466 472
+4 916 486 324 318
+4 649 916 324 318
+4 650 79 322 274
+4 650 274 322 329
+4 665 201 203 185
+4 665 9 201 637
+4 94 390 612 666
+4 296 666 479 272
+4 272 94 666 390
+4 667 214 610 10
+4 667 188 208 214
+4 667 639 214 10
+4 10 314 610 667
+4 763 313 620 668
+4 2 667 668 588
+4 324 281 318 287
+4 540 324 281 318
+4 785 688 322 286
+4 544 322 286 785
+4 12 201 637 704
+4 704 12 201 202
+4 705 278 378 300
+4 300 693 378 705
+4 973 200 553 184
+4 617 973 184 200
+4 272 115 179 130
+4 14 707 639 215
+4 802 214 188 707
+4 669 472 466 463
+4 728 472 466 669
+4 503 669 466 161
+4 441 471 514 432
+4 521 384 383 439
+4 423 385 384 454
+4 356 673 1026 456
+4 356 452 673 456
+4 423 454 521 427
+4 673 1031 451 456
+4 423 384 521 454
+4 521 384 439 454
+4 384 548 383 1004
+4 675 823 676 461
+4 675 385 464 394
+4 449 450 675 1021
+4 450 1021 676 675
+4 675 487 464 676
+4 676 470 465 750
+4 416 415 400 726
+4 149 1008 555 161
+4 555 466 669 161
+4 161 669 555 211
+4 1008 466 555 161
+4 920 127 739 449
+4 920 569 449 739
+4 979 665 200 759
+4 287 331 325 687
+4 979 665 759 1
+4 291 688 290 337
+4 688 529 327 337
+4 744 689 389 810
+4 543 810 732 389
+4 1015 405 400 690
+4 345 837 405 690
+4 348 1015 690 405
+4 348 405 690 345
+4 304 665 185 704
+4 304 704 637 665
+4 496 109 117 515
+4 496 515 117 586
+4 515 117 586 280
+4 218 241 246 747
+4 172 474 773 825
+4 172 825 487 474
+4 609 474 725 172
+4 725 172 474 773
+4 609 172 487 474
+4 975 53 243 284
+4 975 243 1019 284
+4 678 458 531 263
+4 531 917 263 458
+4 228 834 1025 835
+4 254 984 697 51
+4 698 342 1028 724
+4 698 331 1034 778
+4 295 698 1028 724
+4 57 682 285 65
+4 666 357 699 390
+4 479 666 699 390
+4 699 1029 390 386
+4 974 84 632 82
+4 847 423 127 920
+4 568 92 90 631
+4 90 103 922 631
+4 123 427 858 428
+4 966 393 394 414
+4 663 405 596 558
+4 663 558 596 559
+4 271 403 179 312
+4 271 403 312 562
+4 703 581 131 971
+4 677 706 275 684
+4 706 279 275 684
+4 706 279 684 58
+4 310 547 831 841
+4 547 59 686 310
+4 679 841 338 831
+4 114 694 842 178
+4 725 777 474 582
+4 7 307 709 551
+4 728 669 466 503
+4 731 383 459 548
+4 192 383 731 838
+4 838 548 383 731
+4 292 192 383 731
+4 421 520 225 251
+4 660 251 520 421
+4 600 421 225 251
+4 648 421 251 530
+4 660 530 251 421
+4 656 600 245 524
+4 234 523 210 712
+4 654 210 516 712
+4 713 716 462 753
+4 595 462 447 713
+4 657 220 206 401
+4 353 659 207 225
+4 483 1019 250 290
+4 1020 483 250 290
+4 658 352 264 317
+4 584 302 562 271
+4 302 562 195 350
+4 125 423 847 941
+4 125 941 986 423
+4 941 986 423 799
+4 941 445 423 920
+4 847 423 920 941
+4 941 799 423 445
+4 375 968 326 327
+4 634 488 733 566
+4 634 566 733 21
+4 110 430 780 122
+4 122 780 429 430
+4 122 365 430 989
+4 122 430 429 989
+4 122 110 430 365
+4 322 650 329 544
+4 785 322 329 544
+4 211 333 409 139
+4 211 748 333 139
+4 211 139 409 720
+4 211 748 139 720
+4 837 430 456 1026
+4 596 837 430 456
+4 405 837 430 596
+4 330 273 295 724
+4 724 392 698 342
+4 1028 330 724 513
+4 1028 342 513 724
+4 273 306 295 724
+4 726 397 400 416
+4 176 378 726 776
+4 207 307 328 976
+4 976 207 231 328
+4 7 207 976 307
+4 659 7 207 976
+4 251 273 330 727
+4 44 674 251 727
+4 44 251 279 727
+4 595 729 447 462
+4 716 168 729 956
+4 716 729 595 462
+4 730 202 205 220
+4 657 730 206 220
+4 42 281 245 656
+4 643 902 1030 566
+4 511 902 566 1030
+4 936 280 420 795
+4 920 445 449 460
+4 613 567 827 201
+4 221 200 344 613
+4 564 455 464 512
+4 455 340 512 564
+4 455 142 340 564
+4 733 832 214 610
+4 733 610 566 227
+4 733 214 832 232
+4 974 360 376 343
+4 974 376 360 611
+4 974 611 360 377
+4 974 377 360 576
+4 320 370 236 950
+4 502 370 236 720
+4 196 276 563 629
+4 912 563 741 3
+4 680 527 241 647
+4 117 700 702 936
+4 60 589 48 945
+4 945 247 536 589
+4 651 460 461 823
+4 165 237 460 651
+4 237 460 651 823
+4 736 454 428 427
+4 736 428 454 455
+4 736 455 454 564
+4 227 566 488 226
+4 488 1024 227 226
+4 643 226 488 566
+4 634 488 643 38
+4 922 358 386 387
+4 922 386 358 568
+4 922 517 387 386
+4 143 153 920 569
+4 153 920 569 460
+4 641 737 565 325
+4 375 327 326 321
+4 1003 375 321 327
+4 569 920 449 460
+4 738 248 790 37
+4 567 738 221 222
+4 790 222 738 567
+4 624 790 37 738
+4 136 739 424 789
+4 739 450 811 424
+4 739 569 449 450
+4 789 450 569 739
+4 640 789 739 136
+4 236 522 383 439
+4 445 593 384 385
+4 385 393 593 384
+4 740 295 534 392
+4 740 177 392 534
+4 740 295 392 457
+4 740 177 457 392
+4 656 422 600 524
+4 966 593 394 393
+4 140 407 557 447
+4 146 140 436 447
+4 140 447 557 436
+4 385 393 592 394
+4 385 592 464 394
+4 471 800 495 451
+4 451 800 495 750
+4 493 251 273 295
+4 251 273 295 330
+4 295 251 330 590
+4 696 194 743 312
+4 696 434 312 743
+4 695 743 696 575
+4 695 696 743 581
+4 300 691 278 990
+4 990 574 691 744
+4 928 744 691 574
+4 404 416 415 436
+4 0 187 1017 759
+4 0 759 871 187
+4 759 203 477 185
+4 745 318 565 468
+4 745 193 468 565
+4 745 318 468 486
+4 252 332 235 532
+4 441 432 514 341
+4 989 432 441 341
+4 52 747 255 840
+4 747 241 246 334
+4 481 747 52 840
+4 416 356 436 557
+4 557 447 356 436
+4 557 447 1026 356
+4 426 748 478 482
+4 119 333 749 748
+4 339 482 478 748
+4 288 614 175 217
+4 415 217 614 288
+4 570 553 973 5
+4 749 119 748 482
+4 482 426 749 332
+4 749 332 426 485
+4 52 840 589 480
+4 570 553 184 973
+4 481 52 480 840
+4 480 246 589 541
+4 199 200 812 505
+4 970 750 462 495
+4 539 750 462 970
+4 283 527 241 26
+4 527 283 241 600
+4 147 417 443 292
+4 147 700 417 157
+4 700 710 417 157
+4 919 447 452 713
+4 146 595 447 919
+4 595 713 447 919
+4 918 367 220 27
+4 657 220 401 367
+4 918 317 244 224
+4 27 317 244 918
+4 276 218 839 283
+4 283 26 218 839
+4 147 292 443 368
+4 917 234 230 712
+4 234 523 712 917
+4 234 523 917 29
+4 144 652 435 282
+4 539 604 758 170
+4 917 234 256 230
+4 917 531 263 29
+4 539 604 787 758
+4 225 369 231 28
+4 745 878 515 193
+4 702 710 752 420
+4 270 352 658 525
+4 485 749 427 439
+4 749 439 333 427
+4 521 454 439 427
+4 521 485 427 439
+4 723 351 182 282
+4 682 285 65 33
+4 755 353 659 267
+4 717 156 756 950
+4 717 265 192 756
+4 245 656 524 958
+4 211 555 149 333
+4 211 333 149 409
+4 355 189 484 535
+4 371 816 493 238
+4 225 816 493 371
+4 535 816 371 238
+4 225 816 371 535
+4 467 313 643 328
+4 89 193 737 438
+4 438 193 737 490
+4 672 338 329 785
+4 672 338 785 556
+4 911 653 786 6
+4 616 801 185 188
+4 616 911 653 185
+4 616 473 801 188
+4 473 8 783 927
+4 168 604 787 539
+4 604 474 470 758
+4 734 474 604 758
+4 166 561 582 784
+4 615 354 184 570
+4 735 414 472 788
+4 181 537 313 208
+4 181 467 313 537
+4 239 467 181 537
+4 759 665 203 185
+4 2 667 588 10
+4 667 208 188 187
+4 667 187 668 208
+4 760 607 605 80
+4 760 338 605 361
+4 760 607 580 361
+4 583 580 361 760
+4 583 361 338 760
+4 94 612 606 761
+4 94 666 612 761
+4 761 357 275 571
+4 761 357 311 666
+4 761 357 606 275
+4 761 311 357 571
+4 614 356 436 416
+4 132 691 928 288
+4 691 278 744 288
+4 132 278 691 288
+4 288 691 928 744
+4 240 355 247 589
+4 216 247 255 240
+4 240 226 247 355
+4 216 240 226 247
+4 22 36 888 951
+4 432 514 259 471
+4 139 119 333 625
+4 453 180 560 576
+4 139 119 748 333
+4 139 897 333 409
+4 139 625 333 897
+4 735 870 472 414
+4 554 339 478 212
+4 211 439 555 333
+4 762 315 177 72
+4 762 315 325 177
+4 762 177 480 72
+4 762 177 457 481
+4 762 177 325 457
+4 762 177 481 480
+4 538 530 251 674
+4 307 620 930 763
+4 620 763 615 930
+4 677 671 571 413
+4 677 413 571 275
+4 83 321 69 884
+4 1003 83 884 321
+4 990 764 300 691
+4 95 294 324 765
+4 765 324 671 294
+4 766 301 329 77
+4 766 545 672 329
+4 287 457 295 475
+4 641 457 287 475
+4 556 767 672 338
+4 768 79 664 693
+4 768 693 664 300
+4 769 694 607 80
+4 769 694 842 607
+4 692 694 842 769
+4 677 684 275 770
+4 94 606 684 770
+4 770 606 684 275
+4 771 605 686 80
+4 771 338 841 605
+4 679 771 338 841
+4 772 9 665 637
+4 772 304 637 665
+4 621 639 667 10
+4 164 721 512 773
+4 773 825 777 512
+4 725 773 474 777
+4 332 252 387 478
+4 175 774 400 440
+4 965 805 308 71
+4 635 965 308 71
+4 906 309 308 965
+4 355 536 589 533
+4 541 536 533 589
+4 906 965 308 635
+4 965 309 308 805
+4 532 522 323 591
+4 582 495 561 259
+4 582 561 495 758
+4 859 74 489 358
+4 47 31 864 253
+4 47 864 50 253
+4 667 214 208 610
+4 667 208 668 610
+4 605 607 361 611
+4 760 607 361 605
+4 612 390 357 666
+4 612 357 606 761
+4 612 666 357 761
+4 665 613 200 203
+4 665 613 203 201
+4 759 665 200 203
+4 745 515 496 585
+4 496 515 586 585
+4 564 142 340 152
+4 278 378 689 776
+4 705 776 378 278
+4 142 924 455 340
+4 415 776 278 288
+4 216 951 240 255
+4 515 952 280 252
+4 1033 203 200 181
+4 759 1033 203 200
+4 81 622 1003 1002
+4 316 375 622 1002
+4 1002 622 1003 375
+4 497 147 398 443
+4 398 147 141 443
+4 28 273 504 406
+4 28 273 406 34
+4 310 547 841 686
+4 771 841 686 605
+4 679 771 841 686
+4 465 825 512 777
+4 160 514 721 708
+4 725 721 777 708
+4 773 777 721 512
+4 725 773 777 721
+4 778 568 358 490
+4 778 490 357 568
+4 778 833 357 490
+4 681 93 318 91
+4 91 93 318 745
+4 649 93 318 681
+4 93 916 318 486
+4 916 93 318 649
+4 745 93 318 486
+4 49 254 779 51
+4 51 697 254 779
+4 779 395 697 249
+4 61 289 73 781
+4 61 781 779 289
+4 781 289 395 779
+4 781 395 289 297
+4 780 111 124 425
+4 780 425 345 111
+4 780 837 110 345
+4 780 110 837 430
+4 224 751 250 483
+4 243 1019 250 751
+4 751 250 483 1019
+4 780 124 424 425
+4 254 697 249 779
+4 73 781 289 326
+4 934 288 175 217
+4 934 288 744 175
+4 558 596 559 578
+4 782 604 470 305
+4 782 174 487 877
+4 644 968 335 326
+4 644 335 968 360
+4 375 644 326 968
+4 179 403 969 312
+4 403 179 969 554
+4 312 403 969 699
+4 1029 969 554 403
+4 699 403 969 1029
+4 831 746 299 830
+4 679 556 831 338
+4 783 802 473 188
+4 802 707 188 783
+4 473 927 188 616
+4 794 616 188 927
+4 783 707 188 621
+4 784 758 582 474
+4 758 784 734 474
+4 609 725 474 784
+4 725 582 474 784
+4 785 286 291 688
+4 545 672 329 785
+4 301 545 329 785
+4 304 704 185 786
+4 653 494 185 304
+4 911 653 185 786
+4 787 750 729 539
+4 787 470 750 758
+4 787 604 470 758
+4 384 459 548 393
+4 305 604 470 787
+4 384 393 548 463
+4 617 184 973 570
+4 570 354 184 553
+4 788 472 669 463
+4 788 735 728 472
+4 594 227 818 815
+4 594 254 815 818
+4 728 472 669 788
+4 389 180 453 377
+4 541 981 533 714
+4 440 389 180 453
+4 541 536 714 533
+4 584 320 350 302
+4 641 315 325 762
+4 641 762 325 457
+4 641 737 325 315
+4 789 1007 450 446
+4 789 739 424 450
+4 790 222 219 476
+4 790 222 476 248
+4 1006 790 222 219
+4 738 248 222 790
+4 135 333 555 427
+4 871 615 620 763
+4 620 763 187 871
+4 620 187 2 871
+4 677 571 671 873
+4 876 188 794 616
+4 717 236 192 793
+4 282 456 526 578
+4 596 526 356 456
+4 220 223 751 243
+4 223 751 243 250
+4 160 582 708 166
+4 1019 285 797 290
+4 244 1019 388 285
+4 1019 388 285 290
+4 1020 297 290 289
+4 250 395 1020 289
+4 395 1020 289 297
+4 796 388 290 291
+4 483 796 388 290
+4 256 298 1020 262
+4 262 308 298 297
+4 309 310 299 298
+4 286 285 290 322
+4 810 776 176 400
+4 415 400 726 776
+4 176 776 726 400
+4 731 169 171 548
+4 569 449 675 460
+4 569 461 460 675
+4 798 676 750 461
+4 553 992 200 199
+4 973 200 812 553
+4 704 202 201 185
+4 786 202 704 185
+4 789 424 425 1023
+4 789 446 1023 425
+4 418 799 444 521
+4 799 384 445 444
+4 521 799 444 384
+4 449 385 455 1021
+4 1021 676 464 465
+4 449 1021 675 385
+4 1021 464 676 675
+4 441 587 800 450
+4 441 800 465 471
+4 450 800 676 587
+4 800 465 750 676
+4 564 466 464 454
+4 564 464 466 512
+4 911 473 205 801
+4 215 214 802 707
+4 783 215 473 802
+4 215 707 802 783
+4 458 352 230 257
+4 352 257 483 230
+4 352 317 388 264
+4 352 317 483 388
+4 224 813 803 223
+4 224 483 250 803
+4 803 1020 483 250
+4 234 256 492 262
+4 234 256 262 263
+4 297 1022 781 335
+4 1022 968 327 326
+4 290 336 337 327
+4 298 308 805 1022
+4 298 336 1022 805
+4 805 343 336 335
+4 310 343 337 336
+4 808 357 275 331
+4 381 468 357 808
+4 808 331 687 833
+4 571 357 275 808
+4 381 571 808 357
+4 337 360 361 809
+4 529 361 809 337
+4 175 440 400 810
+4 491 810 400 440
+4 428 811 449 455
+4 429 1023 450 441
+4 1023 441 451 450
+4 712 206 813 754
+4 754 230 224 813
+4 206 401 223 813
+4 790 476 219 242
+4 790 476 242 1032
+4 814 493 238 295
+4 814 534 295 238
+4 493 814 475 295
+4 475 457 295 814
+4 814 295 534 740
+4 814 295 740 457
+4 437 248 947 815
+4 815 248 947 254
+4 536 260 484 488
+4 316 176 726 400
+4 316 726 397 400
+4 222 248 594 817
+4 817 248 594 254
+4 817 254 249 248
+4 222 248 817 476
+4 476 249 248 817
+4 815 227 818 253
+4 815 254 253 818
+4 31 253 818 733
+4 31 818 253 865
+4 826 228 594 1025
+4 228 835 1025 819
+4 319 438 358 490
+4 438 820 358 490
+4 315 438 820 358
+4 342 568 358 778
+4 90 568 358 342
+4 859 342 358 489
+4 90 342 358 859
+4 918 220 751 244
+4 220 223 918 751
+4 425 1026 446 451
+4 1026 451 447 446
+4 557 425 1026 446
+4 417 532 443 197
+4 417 396 532 197
+4 417 710 197 292
+4 417 197 443 292
+4 417 420 396 197
+4 417 420 197 710
+4 205 223 210 206
+4 205 223 372 210
+4 205 597 210 372
+4 473 205 597 210
+4 911 210 206 205
+4 911 210 205 473
+4 225 535 231 994
+4 225 535 371 231
+4 428 423 454 455
+4 423 385 454 455
+4 117 586 795 703
+4 586 581 795 703
+4 475 287 641 281
+4 891 200 1009 505
+4 344 200 1009 891
+4 186 435 821 258
+4 560 558 900 258
+4 258 558 900 435
+4 239 467 537 240
+4 53 822 284 983
+4 785 329 322 688
+4 722 153 461 460
+4 651 722 461 460
+4 68 89 737 848
+4 618 68 89 737
+4 68 737 641 315
+4 618 68 737 641
+4 173 823 651 742
+4 823 470 676 461
+4 651 823 461 470
+4 787 461 750 470
+4 487 465 470 474
+4 676 487 465 470
+4 823 470 487 676
+4 251 330 590 279
+4 251 279 590 757
+4 465 825 777 474
+4 727 330 251 279
+4 773 474 777 825
+4 209 372 826 597
+4 597 826 215 228
+4 209 372 594 826
+4 826 232 819 1025
+4 827 203 204 828
+4 827 222 828 204
+4 567 222 221 827
+4 613 203 827 221
+4 613 567 221 827
+4 201 222 204 1027
+4 1006 201 1027 222
+4 1006 219 222 1027
+4 208 828 221 227
+4 219 889 243 220
+4 243 242 476 249
+4 219 476 243 242
+4 493 251 245 600
+4 239 189 467 240
+4 981 306 534 260
+4 982 297 829 395
+4 55 829 982 308
+4 982 297 395 63
+4 291 688 337 830
+4 785 291 830 688
+4 785 338 329 830
+4 299 830 337 831
+4 831 841 338 337
+4 209 208 832 828
+4 209 594 828 832
+4 610 227 832 208
+4 733 227 832 610
+4 833 357 490 468
+4 808 331 833 357
+4 687 468 808 833
+4 329 337 338 361
+4 380 274 329 361
+4 529 337 329 361
+4 583 329 338 361
+4 583 380 329 361
+4 331 357 606 778
+4 612 357 778 606
+4 612 778 357 568
+4 833 331 778 357
+4 834 492 250 249
+4 834 697 492 249
+4 835 261 492 697
+4 179 969 390 993
+4 272 993 179 390
+4 993 272 479 390
+4 993 969 390 699
+4 993 479 699 390
+4 64 618 565 641
+4 64 618 879 565
+4 809 375 327 968
+4 375 732 644 968
+4 375 968 809 732
+4 226 484 643 488
+4 488 260 484 643
+4 280 403 396 420
+4 403 584 396 420
+4 871 187 2 0
+4 280 434 403 420
+4 584 420 403 562
+4 434 562 403 420
+4 735 414 909 933
+4 548 933 909 414
+4 616 4 911 473
+4 627 5 11 199
+4 967 597 228 210
+4 4 8 473 927
+4 664 79 274 378
+4 664 79 378 693
+4 79 213 274 378
+4 693 1002 79 378
+4 79 1002 213 378
+4 627 951 199 11
+4 627 642 951 11
+4 408 12 23 1006
+4 6 12 704 202
+4 14 412 233 25
+4 967 215 14 937
+4 473 967 597 215
+4 202 205 220 219
+4 210 234 229 228
+4 234 835 229 228
+4 655 999 741 3
+4 422 600 15 16
+4 563 608 207 239
+4 111 853 836 120
+4 120 836 419 853
+4 345 425 836 111
+4 345 425 837 836
+4 836 356 1026 837
+4 836 425 557 419
+4 836 557 1026 356
+4 211 236 439 748
+4 439 236 426 748
+4 780 425 837 345
+4 780 837 425 430
+4 333 439 749 748
+4 654 712 206 210
+4 211 439 333 748
+4 426 439 748 749
+4 16 26 283 839
+4 793 909 463 1004
+4 1004 463 548 909
+4 527 16 283 600
+4 717 838 192 265
+4 265 192 731 838
+4 717 838 793 192
+4 839 629 627 276
+4 645 520 28 18
+4 353 283 939 15
+4 749 748 426 482
+4 840 255 589 246
+4 917 523 712 19
+4 840 747 255 246
+4 917 523 19 29
+4 481 747 840 246
+4 840 246 589 480
+4 481 840 480 246
+4 160 582 514 708
+4 512 721 514 777
+4 841 343 962 376
+4 841 605 376 962
+4 279 684 606 275
+4 279 513 606 684
+4 513 963 342 606
+4 842 377 607 949
+4 890 567 624 20
+4 607 842 949 694
+4 307 763 930 354
+4 520 727 504 273
+4 520 674 504 727
+4 902 566 634 21
+4 68 843 762 481
+4 68 52 843 481
+4 68 843 72 762
+4 904 638 232 21
+4 137 418 121 844
+4 137 844 125 986
+4 87 845 438 101
+4 846 101 113 1012
+4 846 113 121 1012
+4 847 920 143 137
+4 848 87 89 438
+4 852 1032 61 49
+4 852 53 61 822
+4 136 853 120 419
+4 124 424 425 853
+4 69 284 854 53
+4 69 987 73 854
+4 70 306 855 54
+4 70 489 74 855
+4 856 247 48 36
+4 906 29 35 263
+4 856 46 48 247
+4 857 248 49 46
+4 23 1006 219 624
+4 954 998 838 265
+4 265 838 731 998
+4 864 31 38 488
+4 363 90 103 922
+4 864 38 50 488
+4 24 634 643 38
+4 123 427 135 858
+4 865 39 254 51
+4 25 39 232 638
+4 655 267 741 999
+4 267 655 955 999
+4 859 358 90 88
+4 119 749 123 112
+4 860 75 86 335
+4 860 923 86 84
+4 15 353 755 267
+4 84 364 102 576
+4 861 51 63 697
+4 861 697 63 55
+4 71 55 862 308
+4 71 862 75 985
+4 269 791 1001 182
+4 269 753 1001 791
+4 253 31 864 488
+4 253 864 50 488
+4 47 865 254 51
+4 953 183 158 268
+4 953 268 158 542
+4 866 739 143 127
+4 866 136 143 739
+4 122 867 134 429
+4 867 924 142 134
+4 496 695 585 703
+4 868 198 644 99
+4 868 348 198 99
+4 868 1015 348 405
+4 868 198 453 644
+4 868 453 1015 405
+4 280 379 1029 403
+4 280 1029 379 869
+4 515 379 869 280
+4 635 35 55 308
+4 515 252 280 869
+4 478 482 517 387
+4 478 339 554 517
+4 334 641 475 457
+4 295 330 724 1028
+4 330 513 1028 279
+4 295 590 330 1028
+4 590 330 1028 279
+4 870 572 472 414
+4 735 573 870 414
+4 871 615 763 184
+4 792 871 184 615
+4 872 574 691 990
+4 990 872 764 691
+4 571 765 671 873
+4 875 766 672 329
+4 338 672 329 875
+4 767 875 672 338
+4 188 876 185 616
+4 494 616 185 876
+4 877 474 734 609
+4 470 877 474 604
+4 474 734 604 877
+4 974 376 962 343
+4 898 962 343 974
+4 898 974 343 632
+4 482 103 339 517
+4 670 40 910 958
+4 207 189 239 608
+4 478 339 517 482
+4 467 643 484 328
+4 608 189 239 240
+4 879 618 91 565
+4 64 880 619 334
+4 881 546 445 153
+4 672 556 785 41
+4 881 153 399 546
+4 540 42 281 324
+4 882 151 398 444
+4 544 785 286 43
+4 417 591 883 141
+4 122 365 989 134
+4 122 989 429 134
+4 700 883 141 417
+4 885 108 726 693
+4 108 726 622 885
+4 148 432 514 160
+4 140 886 404 416
+4 432 711 160 148
+4 432 160 259 514
+4 711 259 432 160
+4 887 150 446 407
+4 623 887 150 446
+4 49 249 1032 61
+4 49 249 248 1032
+4 49 61 779 249
+4 49 254 248 249
+4 49 249 779 254
+4 32 402 888 218
+4 890 408 23 1006
+4 37 1032 852 49
+4 23 1006 624 890
+4 952 396 417 420
+4 936 952 417 420
+4 891 1009 22 505
+4 344 1009 22 891
+4 33 65 975 285
+4 37 53 852 242
+4 854 983 61 53
+4 915 894 306 66
+4 915 894 66 406
+4 895 564 152 630
+4 680 647 241 56
+4 896 628 339 139
+4 897 149 333 409
+4 897 625 333 149
+4 898 962 974 82
+4 373 603 65 57
+4 898 82 974 632
+4 138 435 411 900
+4 900 558 138 435
+4 273 34 894 406
+4 900 138 558 633
+4 901 711 432 148
+4 78 338 771 760
+4 583 760 338 78
+4 767 78 338 679
+4 679 78 338 771
+4 767 583 338 78
+4 903 35 234 261
+4 412 35 234 903
+4 903 35 261 636
+4 854 983 73 61
+4 25 638 232 904
+4 905 34 260 231
+4 510 905 231 34
+4 906 309 965 67
+4 906 67 965 635
+4 907 569 153 640
+4 908 721 512 152
+4 908 152 512 340
+4 64 68 618 641
+4 65 321 884 69
+4 66 70 342 626
+4 67 632 343 71
+4 76 78 574 583
+4 767 875 1010 76
+4 277 872 583 76
+4 277 76 764 872
+4 381 431 311 379
+4 381 571 311 97
+4 67 898 343 632
+4 314 511 588 10
+4 322 884 1003 715
+4 66 626 342 893
+4 272 94 96 666
+4 194 96 311 666
+4 134 341 429 340
+4 807 806 340 134
+4 134 340 924 142
+4 782 877 470 604
+4 807 340 341 134
+4 793 909 1004 838
+4 838 1004 548 909
+4 806 142 340 134
+4 134 340 429 924
+4 105 101 846 235
+4 312 403 434 562
+4 746 291 299 830
+4 315 848 737 438
+4 68 848 737 315
+4 212 410 115 107
+4 81 1002 693 885
+4 404 108 116 726
+4 1019 285 244 33
+4 1019 975 797 285
+4 140 887 623 557
+4 557 407 446 447
+4 262 309 308 906
+4 262 906 263 309
+4 903 234 233 261
+4 700 109 883 952
+4 883 105 952 109
+4 104 397 120 851
+4 629 563 196 912
+4 629 5 563 912
+4 128 913 934 701
+4 217 913 268 701
+4 105 846 121 235
+4 914 210 516 654
+4 844 346 121 113
+4 654 206 957 914
+4 210 914 206 654
+4 844 113 125 346
+4 774 356 405 821
+4 349 282 652 154
+4 555 466 463 669
+4 669 463 555 211
+4 236 669 211 463
+4 793 669 909 167
+4 793 669 236 463
+4 439 384 1004 463
+4 384 548 1004 463
+4 908 340 514 341
+4 908 512 514 340
+4 33 53 242 243
+4 53 889 33 242
+4 33 243 242 889
+4 743 940 431 575
+4 695 940 743 575
+4 575 940 431 579
+4 695 940 575 579
+4 583 580 574 744
+4 692 744 574 580
+4 330 273 724 915
+4 330 727 915 58
+4 727 406 915 58
+4 273 306 724 915
+4 273 894 306 915
+4 273 894 915 406
+4 757 413 590 910
+4 332 323 235 532
+4 251 757 590 910
+4 218 246 608 255
+4 218 246 283 608
+4 246 747 255 218
+4 335 336 968 360
+4 1022 335 968 326
+4 1022 968 335 336
+4 1002 726 176 378
+4 726 176 316 1002
+4 237 966 572 293
+4 966 293 414 572
+4 360 377 453 576
+4 377 180 453 576
+4 717 669 793 167
+4 717 669 236 793
+4 334 457 475 246
+4 481 334 246 457
+4 87 101 358 88
+4 88 387 101 358
+4 319 101 387 358
+4 87 438 358 101
+4 438 101 319 358
+4 942 74 88 358
+4 942 358 88 87
+4 942 87 438 358
+4 315 942 438 358
+4 747 334 246 481
+4 381 486 687 324
+4 916 486 381 324
+4 650 274 329 380
+4 217 268 953 542
+4 349 217 953 542
+4 916 579 381 486
+4 195 599 420 266
+4 195 420 599 350
+4 630 736 142 135
+4 919 436 452 447
+4 235 591 532 323
+4 640 739 143 136
+4 270 264 658 352
+4 170 391 561 269
+4 269 723 561 351
+4 293 433 165 237
+4 677 413 275 706
+4 413 279 275 706
+4 654 1013 921 525
+4 654 712 516 921
+4 137 445 941 920
+4 847 941 920 137
+4 577 247 856 36
+4 577 46 856 247
+4 577 46 247 437
+4 577 437 1024 221
+4 69 326 321 849
+4 849 85 326 375
+4 849 375 326 321
+4 136 623 150 446
+4 857 248 738 37
+4 857 46 437 248
+4 857 248 437 738
+4 135 858 427 736
+4 858 736 428 427
+4 866 424 739 127
+4 866 136 739 424
+4 88 922 100 387
+4 88 387 358 922
+4 922 103 387 517
+4 100 922 103 387
+4 71 335 860 923
+4 923 961 335 86
+4 71 343 335 923
+4 923 360 343 335
+4 860 335 86 923
+4 865 254 253 47
+4 700 141 147 417
+4 594 254 818 1025
+4 865 39 818 254
+4 865 818 253 254
+4 126 429 924 867
+4 126 429 428 924
+4 924 811 429 428
+4 924 429 811 340
+4 867 429 924 134
+4 762 334 481 457
+4 762 334 457 641
+4 504 273 727 406
+4 330 273 915 727
+4 273 406 915 727
+4 484 231 260 238
+4 905 231 260 484
+4 630 564 152 142
+4 806 152 340 142
+4 881 143 153 445
+4 1013 230 712 19
+4 921 712 19 1013
+4 1013 754 712 230
+4 640 569 153 143
+4 654 1013 754 712
+4 654 712 921 1013
+4 502 211 409 720
+4 502 717 236 370
+4 925 175 258 186
+4 186 435 258 925
+4 696 194 312 926
+4 696 133 926 312
+4 40 44 413 442
+4 473 927 783 188
+4 4 927 473 616
+4 621 188 783 927
+4 758 929 734 784
+4 170 929 734 758
+4 609 725 784 929
+4 140 557 407 887
+4 696 931 133 434
+4 695 696 581 931
+4 932 735 728 788
+4 167 932 909 171
+4 40 671 324 294
+4 41 545 785 672
+4 735 293 414 933
+4 555 736 564 630
+4 141 882 398 443
+4 634 643 488 566
+4 922 568 631 517
+4 618 737 565 641
+4 1006 790 624 567
+4 624 790 738 567
+4 1007 789 569 640
+4 640 789 569 739
+4 151 881 399 546
+4 258 180 774 175
+4 258 175 774 186
+4 774 180 440 175
+4 114 842 925 934
+4 175 842 744 934
+4 276 283 839 939
+4 939 629 839 276
+4 353 283 276 939
+4 939 629 276 196
+4 282 154 182 723
+4 277 744 689 583
+4 282 144 154 723
+4 583 380 689 277
+4 237 823 394 460
+4 164 773 512 824
+4 756 156 159 950
+4 824 825 773 512
+4 608 239 951 240
+4 199 1009 992 200
+4 992 200 1009 216
+4 288 278 744 776
+4 278 689 744 776
+4 459 497 398 443
+4 276 642 218 951
+4 642 951 402 218
+4 510 976 231 328
+4 13 510 24 328
+4 150 935 446 407
+4 935 446 447 729
+4 935 447 407 500
+4 935 595 447 500
+4 595 935 447 729
+4 12 23 219 889
+4 12 202 730 220
+4 12 220 219 202
+4 657 347 730 220
+4 12 506 889 220
+4 347 506 220 657
+4 411 258 925 106
+4 925 508 435 411
+4 109 117 515 952
+4 700 952 117 109
+4 234 937 523 509
+4 233 412 14 937
+4 215 228 233 937
+4 967 215 937 228
+4 937 509 234 412
+4 643 260 484 905
+4 535 484 533 238
+4 355 535 484 533
+4 508 469 435 652
+4 469 349 435 652
+4 925 469 435 508
+4 701 349 652 938
+4 701 938 542 349
+4 353 939 276 196
+4 198 176 316 400
+4 104 886 397 726
+4 991 459 169 163
+4 695 743 940 581
+4 585 579 940 695
+4 585 695 940 703
+4 703 940 581 695
+4 692 842 744 580
+4 745 878 496 515
+4 908 721 514 512
+4 758 561 929 784
+4 929 972 784 166
+4 954 909 171 167
+4 644 176 198 491
+4 375 176 198 644
+4 58 513 330 279
+4 58 513 279 684
+4 598 168 787 729
+4 991 163 498 433
+4 936 420 417 710
+4 702 710 420 936
+4 936 700 702 710
+4 700 936 417 710
+4 933 293 991 169
+4 237 433 165 460
+4 169 171 548 933
+4 60 541 74 72
+4 60 480 541 72
+4 734 758 604 170
+4 756 265 1005 159
+4 100 332 112 113
+4 85 644 99 86
+4 609 172 174 487
+4 944 345 111 110
+4 111 780 124 122
+4 49 779 61 51
+4 61 781 73 75
+4 122 946 126 948
+4 946 948 127 126
+4 471 259 495 582
+4 471 514 259 582
+4 46 50 48 247
+4 85 943 326 644
+4 943 644 335 326
+4 46 248 49 947
+4 947 49 51 254
+4 122 429 780 948
+4 122 946 948 780
+4 946 424 127 948
+4 549 927 783 8
+4 899 949 180 106
+4 82 949 576 899
+4 377 949 180 576
+4 82 949 377 576
+4 576 180 560 899
+4 653 185 786 304
+4 129 116 415 190
+4 717 950 192 236
+4 350 1005 599 159
+4 717 950 756 192
+4 756 950 159 1005
+4 484 231 328 905
+4 510 328 231 905
+4 882 398 443 444
+4 398 459 443 444
+4 900 435 411 258
+4 411 435 925 258
+4 234 412 903 233
+4 233 234 412 937
+4 888 402 951 218
+4 218 747 255 888
+4 887 407 446 557
+4 407 935 446 447
+4 12 889 219 220
+4 682 244 285 33
+4 417 591 952 883
+4 700 952 883 417
+4 700 417 936 952
+4 953 155 158 183
+4 599 292 710 157
+4 415 499 436 919
+4 953 155 919 452
+4 499 919 415 303
+4 60 541 589 945
+4 945 589 536 541
+4 598 305 651 787
+4 598 461 787 651
+4 540 294 324 649
+4 540 649 324 318
+4 717 954 838 265
+4 717 954 793 838
+4 717 793 954 167
+4 955 7 207 659
+4 267 207 659 955
+4 956 716 269 462
+4 729 956 462 716
+4 914 516 210 8
+4 670 958 245 524
+4 538 674 251 44
+4 966 433 293 237
+4 560 900 558 633
+4 989 559 432 901
+4 84 974 923 961
+4 961 335 644 360
+4 84 961 576 974
+4 961 360 644 453
+4 961 453 576 360
+4 923 360 335 961
+4 382 456 578 432
+4 382 259 456 432
+4 382 351 456 259
+4 456 282 351 382
+4 456 578 282 382
+4 759 792 0 871
+4 67 686 962 898
+4 67 310 962 686
+4 82 376 997 962
+4 841 962 686 605
+4 310 841 962 686
+4 898 997 962 82
+4 66 963 964 893
+4 66 964 963 513
+4 92 612 963 996
+4 513 684 963 606
+4 893 963 996 92
+4 350 396 420 197
+4 350 197 420 599
+4 1 9 665 772
+4 58 964 513 684
+4 617 200 184 979
+4 964 963 684 893
+4 964 684 963 513
+4 979 9 665 1
+4 518 904 25 232
+4 518 233 25 14
+4 106 114 519 949
+4 899 519 949 106
+4 244 483 388 1019
+4 483 388 1019 290
+4 621 10 667 2
+4 395 829 1020 297
+4 616 4 653 911
+4 776 176 689 810
+4 912 5 563 3
+4 200 505 9 979
+4 1 665 494 304
+4 1 304 772 665
+4 657 957 730 6
+4 8 707 783 549
+4 662 8 210 516
+4 177 358 392 489
+4 177 358 820 392
+4 392 698 358 820
+4 489 342 358 392
+4 392 342 358 698
+4 394 823 487 675
+4 505 1009 22 11
+4 11 22 402 951
+4 627 563 629 5
+4 637 408 201 12
+4 8 977 967 14
+4 662 967 210 8
+4 215 14 707 8
+4 977 967 14 937
+4 523 967 234 210
+4 523 967 937 234
+4 15 755 353 225
+4 999 655 955 3
+4 525 17 352 658
+4 1018 217 415 288
+4 754 206 957 654
+4 74 177 489 358
+4 315 358 820 177
+4 942 358 177 74
+4 315 358 177 942
+4 656 16 600 422
+4 656 527 600 16
+4 754 657 957 206
+4 657 401 754 17
+4 225 755 659 18
+4 712 210 516 662
+4 712 523 210 662
+4 712 662 921 19
+4 712 19 523 662
+4 531 917 458 19
+4 639 21 904 214
+4 880 26 32 241
+4 682 244 33 27
+4 14 509 937 412
+4 541 740 534 177
+4 685 263 531 29
+4 685 906 263 29
+4 480 177 740 541
+4 481 177 457 740
+4 619 32 52 334
+4 481 177 740 480
+4 245 656 958 42
+4 649 95 324 916
+4 540 42 324 294
+4 544 301 785 43
+4 301 545 785 43
+4 44 727 279 58
+4 45 678 602 960
+4 45 59 547 310
+4 193 490 468 737
+4 319 193 438 490
+4 565 193 468 737
+4 353 225 994 283
+4 918 352 317 224
+4 547 556 45 831
+4 39 51 861 984
+4 843 52 60 480
+4 438 737 820 490
+4 855 981 62 54
+4 39 261 861 55
+4 862 55 63 982
+4 28 645 504 520
+4 263 59 309 906
+4 263 59 906 685
+4 843 60 72 480
+4 855 981 74 62
+4 349 435 652 282
+4 862 63 75 982
+4 560 821 558 258
+4 264 317 682 658
+4 682 264 388 317
+4 57 286 682 646
+4 682 57 285 286
+4 346 332 485 323
+4 749 332 485 346
+4 764 277 77 76
+4 77 79 664 768
+4 729 956 539 462
+4 970 561 462 269
+4 970 956 269 462
+4 539 970 462 956
+4 911 6 730 957
+4 914 206 957 911
+4 210 911 206 914
+4 914 210 911 473
+4 692 580 574 78
+4 692 769 580 78
+4 8 914 473 210
+4 41 264 960 746
+4 910 42 245 958
+4 670 910 245 958
+4 910 670 245 251
+4 131 959 434 795
+4 752 710 599 420
+4 878 745 91 89
+4 703 581 971 695
+4 695 931 581 971
+4 95 93 916 649
+4 929 725 784 972
+4 725 708 784 972
+4 575 431 97 95
+4 167 932 552 788
+4 552 167 669 191
+4 552 788 669 167
+4 695 579 575 95
+4 426 332 252 532
+4 97 311 1011 96
+4 677 761 571 96
+4 874 97 431 1011
+4 280 396 952 420
+4 936 280 952 420
+4 411 925 114 106
+4 523 967 210 662
+4 91 878 496 745
+4 227 566 733 488
+4 733 253 227 488
+4 733 818 832 227
+4 733 253 818 227
+4 974 360 343 923
+4 974 360 923 961
+4 974 961 576 360
+4 94 501 390 272
+4 186 774 356 614
+4 934 913 217 701
+4 934 288 217 913
+4 93 496 745 91
+4 93 980 585 496
+4 550 744 128 928
+4 258 180 560 774
+4 560 180 440 774
+4 440 453 180 560
+4 114 949 925 842
+4 842 377 949 180
+4 106 114 949 925
+4 77 768 664 300
+4 220 33 243 244
+4 35 234 262 263
+4 931 131 133 434
+4 971 931 581 131
+4 561 970 495 758
+4 758 750 970 495
+4 539 750 970 758
+4 195 266 562 1035
+4 953 155 183 303
+4 117 795 131 703
+4 795 131 959 702
+4 926 133 130 312
+4 309 678 263 257
+4 263 685 531 59
+4 114 508 925 411
+4 115 507 410 212
+4 79 81 715 1002
+4 79 213 322 274
+4 375 327 213 809
+4 375 176 809 213
+4 937 977 523 509
+4 523 967 977 937
+4 662 523 967 977
+4 978 595 935 500
+4 595 978 935 729
+4 716 978 595 729
+4 200 505 979 617
+4 349 154 158 791
+4 182 791 158 154
+4 980 95 579 695
+4 980 579 585 695
+4 980 695 585 496
+4 595 713 919 155
+4 713 462 716 595
+4 713 155 595 716
+4 752 157 159 599
+4 288 776 744 810
+4 288 175 810 744
+4 417 710 292 157
+4 119 748 482 628
+4 339 482 748 628
+4 702 752 710 157
+4 702 157 710 700
+4 748 139 212 339
+4 339 139 212 410
+4 339 139 410 896
+4 981 74 541 489
+4 981 489 534 306
+4 855 306 981 54
+4 855 489 74 981
+4 55 829 261 697
+4 697 395 829 492
+4 861 51 697 984
+4 861 261 697 55
+4 982 985 297 75
+4 862 55 982 308
+4 862 982 75 985
+4 54 62 714 981
+4 50 62 536 863
+4 54 863 714 62
+4 61 249 1032 822
+4 852 1032 822 61
+4 852 53 822 242
+4 851 836 397 120
+4 345 836 397 851
+4 236 161 211 669
+4 983 289 987 73
+4 854 284 983 53
+4 854 987 73 983
+4 346 121 323 418
+4 844 418 121 346
+4 844 346 125 986
+4 863 260 488 38
+4 488 863 536 260
+4 863 62 536 714
+4 978 162 935 729
+4 39 984 861 261
+4 861 984 697 261
+4 71 862 985 308
+4 982 308 297 985
+4 862 982 985 308
+4 722 162 598 461
+4 70 306 489 855
+4 855 306 489 981
+4 346 986 418 521
+4 986 423 799 521
+4 137 844 986 418
+4 844 346 986 418
+4 348 851 345 397
+4 124 424 853 136
+4 37 242 852 1032
+4 1032 249 242 822
+4 852 242 822 1032
+4 69 284 987 854
+4 983 289 284 987
+4 854 284 987 983
+4 723 351 259 561
+4 129 448 278 300
+4 983 61 822 289
+4 983 822 284 289
+4 111 425 836 853
+4 853 836 419 425
+4 972 708 784 166
+4 982 697 395 829
+4 982 829 297 308
+4 735 932 909 788
+4 102 118 633 988
+4 98 110 366 405
+4 102 98 366 988
+4 989 118 663 559
+4 717 161 669 167
+4 191 167 669 161
+4 598 168 305 787
+4 978 168 162 729
+4 305 604 787 168
+4 541 981 534 533
+4 933 293 414 966
+4 541 981 714 62
+4 541 536 62 714
+4 159 1005 661 265
+4 159 1005 292 661
+4 98 988 453 405
+4 988 453 405 560
+4 560 558 405 988
+4 988 118 558 663
+4 988 98 366 405
+4 110 118 663 365
+4 601 487 174 172
+4 181 354 763 313
+4 1033 187 203 208
+4 181 313 763 668
+4 573 173 174 572
+4 146 919 303 155
+4 953 919 303 415
+4 951 218 255 888
+4 914 911 957 4
+4 300 990 278 277
+4 277 990 744 583
+4 277 764 300 990
+4 277 990 583 872
+4 277 872 764 990
+4 642 11 402 951
+4 402 218 32 26
+4 670 524 245 648
+4 648 538 530 251
+4 186 526 356 821
+4 596 821 356 526
+4 26 241 880 680
+4 26 527 241 680
+4 660 251 530 674
+4 571 765 873 97
+4 541 534 489 177
+4 534 177 392 489
+4 355 536 533 484
+4 716 168 978 729
+4 6 12 730 347
+4 116 499 404 415
+4 114 128 934 701
+4 114 934 925 701
+4 114 701 925 508
+4 199 951 239 992
+4 239 992 951 216
+4 199 1009 951 992
+4 951 992 1009 216
+4 627 276 563 951
+4 627 642 276 951
+4 469 349 186 435
+4 359 130 179 115
+4 186 821 774 258
+4 186 356 774 821
+4 901 711 578 432
+4 559 901 578 432
+4 497 368 147 443
+4 500 595 447 146
+4 502 720 409 145
+4 502 370 720 145
+4 240 355 189 484
+4 467 189 484 240
+4 717 161 236 669
+4 207 231 189 994
+4 994 535 231 189
+4 608 816 994 189
+4 994 816 535 189
+4 389 440 491 453
+4 40 670 910 538
+4 1035 959 562 133
+4 430 456 441 432
+4 441 456 471 432
+4 441 451 471 456
+4 995 694 949 899
+4 995 607 377 949
+4 80 694 607 995
+4 995 607 949 694
+4 996 606 684 94
+4 996 606 963 684
+4 893 963 684 996
+4 80 605 686 997
+4 997 962 376 605
+4 997 605 686 962
+4 898 686 962 997
+4 648 251 245 670
+4 648 670 538 251
+4 718 20 775 408
+4 718 9 775 20
+4 930 655 354 3
+4 3 354 570 563
+4 570 354 553 563
+4 563 553 239 354
+4 349 217 186 614
+4 300 664 77 277
+4 767 679 338 556
+4 766 545 329 301
+4 9 20 200 613
+4 613 200 344 20
+4 20 200 891 505
+4 344 200 891 20
+4 1002 378 176 213
+4 884 1003 321 322
+4 683 322 79 715
+4 79 715 322 213
+4 9 20 613 775
+4 20 567 775 890
+4 20 567 613 775
+4 20 408 890 775
+4 769 607 760 80
+4 769 607 580 760
+4 94 606 770 761
+4 761 606 770 275
+4 771 760 605 80
+4 771 338 605 760
+4 793 236 192 1004
+4 838 1004 383 548
+4 192 236 383 1004
+4 793 838 1004 192
+4 192 1004 383 838
+4 1005 197 292 192
+4 756 265 192 1005
+4 950 192 197 1005
+4 756 950 1005 192
+4 1005 192 661 265
+4 1005 192 292 661
+4 12 1006 201 202
+4 408 12 1006 201
+4 890 567 201 1006
+4 890 408 1006 201
+4 1007 907 569 461
+4 1007 729 798 446
+4 722 1007 162 461
+4 907 1007 722 461
+4 1008 895 564 466
+4 1008 503 466 161
+4 1008 895 466 503
+4 1008 564 555 466
+4 705 726 116 693
+4 1002 693 726 378
+4 200 216 344 1009
+4 505 199 1009 11
+4 515 117 280 952
+4 416 436 614 415
+4 193 515 379 1016
+4 515 1016 193 319
+4 193 1016 379 468
+4 193 1016 468 490
+4 319 193 490 1016
+4 135 625 149 333
+4 1006 567 624 890
+4 517 892 631 107
+4 1007 569 907 640
+4 643 1030 313 566
+4 902 643 634 566
+4 1008 555 564 630
+4 1008 564 895 630
+4 48 589 247 945
+4 870 572 487 472
+4 871 1033 184 763
+4 763 1033 187 871
+4 871 759 184 1033
+4 95 765 324 381
+4 381 765 324 571
+4 571 324 671 765
+4 1010 77 329 380
+4 1010 329 338 583
+4 1010 380 329 583
+4 1010 766 329 77
+4 1010 766 875 329
+4 338 875 329 1010
+4 767 1010 338 583
+4 338 875 1010 767
+4 1017 759 494 1
+4 1017 477 185 759
+4 477 1017 185 876
+4 494 876 185 1017
+4 876 185 477 188
+4 173 572 742 782
+4 782 487 470 877
+4 470 487 474 877
+4 487 474 877 609
+4 416 415 614 400
+4 1011 431 194 311
+4 1011 311 194 96
+4 874 1011 431 194
+4 194 312 926 296
+4 195 159 599 266
+4 195 599 159 350
+4 101 1012 235 332
+4 846 101 1012 235
+4 649 681 318 540
+4 650 544 322 683
+4 651 598 461 722
+4 532 426 522 197
+4 532 396 426 197
+4 599 292 197 710
+4 123 346 749 427
+4 749 346 485 427
+4 521 439 522 485
+4 323 521 522 485
+4 444 383 384 459
+4 244 682 388 317
+4 1014 521 522 323
+4 591 522 323 1014
+4 591 443 522 1014
+4 418 444 1014 521
+4 521 444 1014 383
+4 521 383 1014 522
+4 443 532 522 197
+4 443 522 532 591
+4 444 546 384 445
+4 198 316 397 400
+4 198 690 400 397
+4 348 198 397 690
+4 348 397 198 851
+4 198 1015 400 690
+4 348 198 690 1015
+4 868 198 348 1015
+4 868 453 198 1015
+4 533 534 238 260
+4 981 534 533 260
+4 644 453 491 198
+4 453 440 1015 405
+4 491 453 1015 198
+4 491 440 1015 453
+4 240 608 189 355
+4 189 246 535 355
+4 608 255 246 589
+4 608 246 816 189
+4 816 246 535 189
+4 207 328 467 189
+4 467 328 484 189
+4 456 259 1031 471
+4 471 259 1031 495
+4 471 495 1031 451
+4 456 471 1031 451
+4 468 357 1016 379
+4 490 357 1016 468
+4 188 802 473 209
+4 473 802 597 209
+4 473 597 802 215
+4 403 478 396 584
+4 563 951 239 199
+4 563 951 608 239
+4 537 208 221 227
+4 225 493 816 283
+4 207 225 994 353
+4 608 276 353 283
+4 207 563 353 608
+4 207 994 189 608
+4 316 375 83 622
+4 910 324 287 281
+4 911 185 202 786
+4 909 788 669 463
+4 793 669 463 909
+4 130 271 179 312
+4 130 271 312 562
+4 349 526 186 435
+4 349 526 435 282
+4 341 441 989 429
+4 114 842 934 178
+4 118 558 663 559
+4 752 959 420 266
+4 702 959 420 752
+4 712 662 516 921
+4 678 458 257 960
+4 155 716 713 753
+4 353 659 225 755
+4 725 777 582 708
+4 725 708 582 784
+4 572 823 394 237
+4 572 823 487 394
+4 667 314 668 588
+4 374 314 610 10
+4 762 843 480 481
+4 762 843 72 480
+4 387 332 482 100
+4 642 218 402 26
+4 496 703 585 586
+4 585 703 940 586
+4 586 940 581 703
+4 734 609 474 784
+4 734 609 784 929
+4 692 744 928 574
+4 615 570 184 617
+4 617 792 184 615
+4 41 746 960 45
+4 730 202 911 205
+4 657 957 206 730
+4 911 730 206 957
+4 104 316 397 198
+4 622 104 316 726
+4 104 726 397 316
+4 850 198 104 99
+4 83 104 316 622
+4 211 236 748 720
+4 478 748 212 339
+4 83 316 850 375
+4 99 851 198 104
+4 851 397 198 104
+4 98 102 453 988
+4 102 453 988 560
+4 102 453 560 576
+4 599 420 710 197
+4 548 393 966 414
+4 548 459 966 393
+4 80 995 607 611
+4 611 607 377 995
+4 612 606 996 94
+4 612 606 342 963
+4 612 606 963 996
+4 80 605 997 611
+4 611 997 376 605
+4 511 1030 566 313
+4 950 320 350 197
+4 950 1005 350 159
+4 274 213 361 689
+4 213 689 176 543
+4 274 213 529 361
+4 213 361 809 529
+4 213 176 809 543
+4 1002 1003 213 375
+4 79 1002 715 213
+4 1016 515 379 869
+4 515 869 1016 319
+4 319 515 869 252
+4 216 1024 226 221
+4 240 537 216 226
+4 537 226 221 216
+4 556 338 785 830
+4 746 291 830 785
+4 746 556 785 830
+4 195 420 562 266
+4 195 562 420 350
+4 707 639 214 667
+4 707 214 188 667
+4 922 103 517 631
+4 89 565 737 193
+4 89 745 565 193
+4 878 193 745 89
+4 451 495 462 750
+4 346 427 423 521
+4 346 323 485 521
+4 381 379 468 486
+4 381 486 468 687
+4 283 816 246 493
+4 677 770 275 761
+4 677 275 571 761
+4 296 96 194 666
+4 557 447 446 1026
+4 28 238 273 34
+4 28 238 371 273
+4 288 1000 217 913
+4 217 1000 268 913
+4 614 217 953 349
+4 774 400 356 614
+4 430 559 596 432
+4 559 578 596 432
+4 776 689 744 810
+4 351 452 456 1031
+4 447 462 673 452
+4 351 753 452 462
+4 673 1031 456 452
+4 713 447 452 462
+4 713 462 452 753
+4 243 289 250 1019
+4 553 239 354 181
+4 553 200 992 181
+4 682 286 388 264
+4 1020 796 256 483
+4 250 1019 289 290
+4 1020 250 289 290
+4 1020 492 262 829
+4 1020 290 297 298
+4 1020 298 297 262
+4 256 257 796 309
+4 796 299 298 309
+4 262 298 308 309
+4 882 444 443 1014
+4 141 591 882 443
+4 591 443 1014 882
+4 485 426 749 439
+4 485 439 522 426
+4 151 444 445 546
+4 445 593 546 384
+4 512 464 465 1021
+4 1021 340 465 512
+4 340 587 1021 465
+4 911 202 185 205
+4 185 205 204 801
+4 911 185 801 205
+4 229 230 803 256
+4 229 250 492 803
+4 229 256 234 230
+4 229 256 492 234
+4 29 917 234 263
+4 69 797 321 326
+4 65 285 603 321
+4 797 321 326 327
+4 287 318 324 687
+4 287 687 324 331
+4 289 781 297 290
+4 289 290 797 326
+4 290 797 326 327
+4 290 297 1022 781
+4 290 327 326 1022
+4 298 336 299 290
+4 290 322 327 688
+4 290 688 327 337
+4 297 985 308 1022
+4 1022 327 968 336
+4 1022 308 805 985
+4 1022 336 335 805
+4 298 805 309 310
+4 298 310 299 336
+4 310 336 337 299
+4 71 805 335 343
+4 67 343 310 805
+4 67 310 343 962
+4 310 337 343 841
+4 310 841 343 962
+4 137 799 941 445
+4 739 450 449 811
+4 424 450 429 1023
+4 1023 446 450 451
+4 789 424 1023 450
+4 789 446 450 1023
+4 340 811 1021 587
+4 924 455 811 428
+4 924 811 455 340
+4 450 800 798 676
+4 800 676 750 798
+4 981 306 260 54
+4 218 255 608 951
+4 608 255 589 240
+4 608 589 246 355
+4 577 247 216 1024
+4 577 437 247 1024
+4 216 247 226 1024
+4 401 220 223 918
+4 712 754 813 230
+4 401 224 223 813
+4 488 253 227 1024
+4 712 813 229 230
+4 712 234 230 229
+4 39 819 254 984
+4 594 1025 818 232
+4 1025 817 594 254
+4 1025 254 249 817
+4 1025 249 254 697
+4 1025 697 254 984
+4 1025 818 819 254
+4 1025 984 254 819
+4 778 490 358 698
+4 698 490 358 820
+4 342 778 358 698
+4 26 241 283 218
+4 26 32 241 218
+4 400 356 614 416
+4 1026 447 451 673
+4 241 475 334 281
+4 394 487 472 824
+4 394 592 824 472
+4 592 472 466 824
+4 675 823 487 676
+4 203 221 208 828
+4 827 203 828 221
+4 827 222 221 828
+4 204 222 209 1027
+4 1027 219 222 476
+4 1027 476 817 372
+4 1027 476 222 817
+4 778 698 833 490
+4 698 331 778 833
+4 372 1027 594 817
+4 372 228 826 597
+4 372 228 594 826
+4 53 822 243 284
+4 249 250 243 289
+4 249 289 395 250
+4 61 779 249 289
+4 779 289 395 249
+4 822 61 249 289
+4 55 308 262 829
+4 785 688 830 329
+4 287 325 331 1028
+4 1028 325 331 698
+4 1028 1034 331 513
+4 287 590 1028 331
+4 1028 698 331 1034
+4 831 556 830 338
+4 830 338 337 831
+4 357 386 379 699
+4 1016 357 386 379
+4 490 357 386 1016
+4 568 490 357 386
+4 568 390 386 357
+4 357 386 699 390
+4 828 208 832 227
+4 828 594 227 832
+4 379 403 699 1029
+4 1029 478 403 554
+4 234 492 261 262
+4 262 261 234 35
+4 835 233 234 261
+4 835 492 261 234
+4 1025 835 834 697
+4 835 697 492 834
+4 834 243 476 249
+4 219 242 243 889
+4 967 228 234 210
+4 228 234 233 937
+4 967 228 937 234
+4 205 206 220 223
+4 205 219 476 220
+4 205 223 476 372
+4 476 220 219 243
+4 228 834 223 372
+4 228 223 834 229
+4 345 837 690 836
+4 836 356 837 690
+4 120 557 140 623
+4 120 836 557 419
+4 270 458 352 525
+4 270 257 352 458
+4 269 351 561 462
+4 252 235 952 532
+4 172 824 601 487
+4 728 172 824 601
+4 1 617 792 184
+4 979 759 184 1
+4 792 1 184 759
+4 759 792 871 184
+4 621 2 667 188
+4 2 188 187 667
+4 494 665 759 185
+4 494 665 185 304
+4 1017 759 185 494
+4 925 180 258 175
+4 925 842 180 175
+4 925 842 175 934
+4 25 233 232 819
+4 25 636 233 819
+4 67 309 965 805
+4 67 310 309 805
+4 799 151 882 444
+4 799 151 444 445
+4 65 797 975 285
+4 65 797 285 321
+4 696 434 743 581
+4 696 434 581 931
+4 165 293 237 173
+4 311 357 699 666
+4 479 311 699 666
+4 769 842 580 607
+4 692 842 580 769
+4 643 484 328 905
+4 665 201 185 704
+4 665 704 637 201
+4 839 627 642 276
+4 1002 176 375 213
+4 944 405 345 110
+4 944 99 345 348
+4 944 405 348 345
+4 239 537 216 240
+4 239 992 216 537
+4 1002 885 726 693
+4 885 726 622 1002
+4 622 83 1003 375
+4 375 732 809 176
+4 272 312 130 179
+4 272 296 130 312
+4 312 272 479 993
+4 312 969 993 699
+4 312 479 699 993
+4 440 180 389 175
+4 180 842 389 175
+4 175 842 389 744
+4 92 342 612 568
+4 793 954 909 838
+4 793 909 954 167
+4 845 101 319 438
+4 845 105 319 101
+4 202 1006 219 12
+4 236 439 383 1004
+4 197 426 522 236
+4 320 236 426 197
+4 320 426 396 197
+4 599 197 292 1005
+4 350 1005 197 599
+4 950 197 350 1005
+4 246 534 238 533
+4 246 493 238 814
+4 246 534 814 238
+4 816 246 493 238
+4 535 533 246 238
+4 535 246 816 238
+4 560 558 988 633
+4 633 118 558 988
+4 414 472 463 393
+4 548 414 463 393
+4 414 788 463 472
+4 414 909 463 788
+4 548 909 463 414
+4 981 541 534 489
+4 933 548 966 414
+4 966 991 459 548
+4 966 593 237 394
+4 433 237 966 593
+4 175 440 810 389
+4 744 175 810 389
+4 787 750 539 758
+4 282 452 456 351
+4 415 726 116 705
+4 415 776 726 705
+4 415 776 705 278
+4 104 316 850 83
+4 498 399 433 163
+4 9 505 200 20
+4 328 313 643 1030
+4 935 162 1007 729
+4 935 729 1007 446
+4 11 951 199 1009
+4 720 236 320 370
+4 33 53 243 975
+4 33 243 1019 975
+4 397 416 886 557
+4 397 557 886 120
+4 894 306 54 34
+4 260 306 34 54
+4 315 438 737 820
+4 437 221 738 815
+4 437 248 815 738
+4 401 918 223 224
+4 450 676 461 675
+4 569 461 675 450
+4 1007 569 450 461
+4 450 798 461 676
+4 1007 450 798 461
+4 592 393 385 384
+4 384 393 463 592
+4 1019 289 797 284
+4 1019 797 289 290
+4 223 250 229 803
+4 813 229 230 803
+4 813 229 803 223
+4 587 676 1021 465
+4 441 465 800 587
+4 587 800 676 465
+4 351 462 1031 561
+4 673 462 451 1031
+4 351 452 1031 462
+4 673 462 1031 452
+4 803 256 483 1020
+4 229 803 492 256
+4 492 803 1020 256
+4 558 596 578 821
+4 822 289 243 284
+4 243 284 289 1019
+4 245 475 281 287
+4 910 245 281 287
+4 245 241 281 475
+4 354 307 313 467
+4 354 307 763 313
+4 992 239 181 537
+4 553 239 992 199
+4 553 992 239 181
+4 69 987 797 326
+4 987 289 797 326
+4 424 419 425 853
+4 201 1027 204 202
+4 185 204 202 201
+4 352 264 388 796
+4 746 299 291 796
+4 746 264 796 291
+4 286 322 290 688
+4 829 262 297 308
+4 1020 829 262 297
+4 45 310 746 602
+4 37 790 1032 248
+4 476 1032 248 249
+4 790 476 1032 248
+4 256 298 262 309
+4 263 256 262 309
+4 256 298 309 796
+4 256 309 263 257
+4 796 290 1020 298
+4 1020 290 796 483
+4 951 255 608 240
+4 393 463 592 472
+4 385 393 394 593
+4 283 816 994 608
+4 283 246 816 608
+4 353 994 608 283
+4 805 310 336 343
+4 298 336 805 310
+4 781 1022 326 335
+4 289 326 781 290
+4 290 781 1022 326
+4 424 1023 429 780
+4 780 429 430 1023
+4 423 427 428 454
+4 1033 208 203 181
+4 187 668 208 1033
+4 759 1033 187 203
+4 871 759 1033 187
+4 437 46 253 947
+4 437 947 253 815
+4 815 947 253 254
+4 71 985 335 805
+4 297 335 985 1022
+4 1022 985 805 335
+4 815 253 1024 227
+4 437 253 1024 815
+4 948 428 429 811
+4 465 825 464 512
+4 372 228 834 817
+4 372 817 594 228
+4 464 824 466 512
+4 464 592 466 824
+4 834 1025 249 817
+4 834 249 1025 697
+4 476 249 817 834
+4 204 1027 209 801
+4 801 209 597 372
+4 801 209 372 1027
+4 473 801 209 597
+4 221 815 227 828
+4 828 227 594 815
+4 835 261 819 233
+4 835 697 1025 261
+4 835 261 1025 819
+4 1029 390 554 969
+4 699 969 390 1029
+4 290 336 1022 298
+4 39 819 984 261
+4 1025 697 984 261
+4 1025 261 984 819
+4 299 337 310 831
+4 831 337 310 841
+4 594 832 232 818
+4 733 818 232 832
+4 449 1021 455 811
+4 340 811 455 1021
+4 917 263 257 256
+4 917 263 256 234
+4 280 952 396 252
+4 252 952 396 532
+4 252 387 319 332
+4 101 235 319 332
+4 1034 778 606 342
+4 513 606 342 1034
+4 698 1034 342 778
+4 1028 342 1034 513
+4 1028 698 1034 342
+4 209 826 594 832
+4 832 826 594 232
+4 393 472 592 394
+4 280 396 1029 252
+4 252 396 1029 478
+4 280 252 1029 869
+4 688 337 329 529
+4 830 329 337 338
+4 688 329 337 830
+4 464 825 487 824
+4 397 557 836 416
+4 416 557 836 356
+4 397 400 416 690
+4 690 400 416 356
+4 397 416 836 690
+4 730 205 206 220
+4 730 205 911 206
+4 205 220 476 223
+4 476 220 243 223
+4 451 750 462 729
+4 539 729 462 750
+4 234 233 835 228
+4 372 817 834 476
+4 1026 673 451 456
+4 405 356 837 596
+4 690 356 837 405
+4 690 356 405 400
+4 52 888 255 747
+4 650 79 274 664
+4 650 274 380 664
+4 623 887 446 557
+4 136 623 446 419
+4 37 889 242 219
+4 975 69 284 797
+4 33 975 1019 285
+4 975 797 284 1019
+4 38 260 643 905
+4 636 903 233 261
+4 636 261 819 39
+4 636 261 233 819
+4 774 821 560 258
+4 258 106 180 925
+4 200 973 505 617
+4 199 812 11 505
+4 92 612 342 963
+4 893 342 963 92
+4 893 626 342 92
+4 100 482 112 332
+4 843 52 480 481
+4 502 236 211 720
+4 237 394 572 966
+4 166 582 259 160
+4 582 514 259 160
+4 723 259 160 166
+4 1031 259 561 495
+4 351 561 1031 259
+4 627 5 199 563
+4 627 951 563 199
+4 682 286 285 388
+4 235 591 952 532
+4 1012 121 235 323
+4 1012 323 235 332
+4 846 1012 121 235
+4 137 445 920 143
+4 881 137 143 445
+4 626 70 342 90
+4 90 342 859 70
+4 568 92 342 90
+4 626 90 342 92
+4 632 923 343 71
+4 632 84 923 71
+4 632 974 343 923
+4 31 39 232 818
+4 31 818 232 733
+4 31 39 818 865
+4 638 39 232 31
+4 69 849 321 83
+4 1018 288 278 132
+4 1018 415 278 288
+4 36 216 344 577
+4 221 577 216 1024
+4 780 124 946 424
+4 780 429 424 948
+4 780 946 948 424
+4 947 49 254 248
+4 73 943 781 326
+4 48 50 945 247
+4 488 50 247 536
+4 253 50 247 488
+4 50 945 247 536
+4 123 125 346 427
+4 954 171 838 998
+4 998 838 731 171
+4 266 959 562 1035
+4 159 752 599 266
+4 661 192 292 731
+4 719 661 292 731
+4 291 264 388 286
+4 976 307 328 13
+4 307 709 313 13
+4 7 307 13 709
+4 7 976 13 307
+4 328 307 313 13
+4 544 57 286 322
+4 683 57 322 373
+4 683 57 544 322
+4 378 726 705 693
+4 215 707 639 214
+4 518 232 25 233
+4 916 95 579 980
+4 916 579 486 585
+4 916 579 585 980
+4 115 212 359 507
+4 212 320 584 528
+4 350 302 562 584
+4 307 620 313 709
+4 511 709 313 620
+4 795 581 131 703
+4 163 433 459 546
+4 399 163 546 433
+4 743 431 479 194
+4 696 431 743 194
+4 696 743 431 575
+4 696 431 874 575
+4 696 874 431 194
+4 583 574 990 744
+4 872 574 990 583
+
+CELL_TYPES 4436
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
+10
diff --git a/data/reduced_torus/torus_textured.obj b/data/reduced_torus/torus_textured.obj
new file mode 100644
index 000000000..ede99fd1d
--- /dev/null
+++ b/data/reduced_torus/torus_textured.obj
@@ -0,0 +1,2270 @@
+# Blender v2.79 (sub 0) OBJ File: ''
+# www.blender.org
+mtllib torus_textured.mtl
+o torus
+v -0.710313 -0.135160 -0.000000
+v -0.750000 -0.000000 -0.000000
+v -0.719154 -0.061973 -0.063589
+v -0.723426 -0.056014 0.050909
+v -0.710313 0.135161 0.000000
+v -0.732316 0.000000 -0.088905
+v -0.732316 -0.000000 0.088905
+v -0.646406 -0.181284 0.053682
+v -0.603854 -0.227408 -0.000000
+v -0.650289 -0.177804 -0.054345
+v -0.698555 -0.102472 0.107364
+v -0.683279 -0.135160 0.135913
+v -0.688957 -0.135160 -0.107364
+v -0.646405 0.181284 -0.053682
+v -0.603853 0.227408 0.000000
+v -0.688957 0.135161 0.107364
+v -0.688957 0.135161 -0.107364
+v -0.688804 -0.070361 -0.203790
+v -0.692910 0.000000 -0.287012
+v -0.656244 -0.135160 -0.271825
+v -0.637874 -0.086416 -0.324584
+v -0.685503 0.067388 -0.224775
+v -0.656244 0.135161 -0.271825
+v -0.632898 0.063386 -0.343969
+v -0.714631 0.000000 -0.177810
+v -0.642280 -0.038943 -0.342598
+v -0.652265 0.000000 -0.347842
+v -0.656244 -0.135160 0.271825
+v -0.692910 -0.000000 0.287013
+v -0.688709 -0.073793 0.199199
+v -0.625484 -0.070863 0.351190
+v -0.643253 -0.000000 0.361328
+v -0.656244 0.135161 0.271825
+v -0.688653 0.068318 0.207562
+v -0.714631 -0.000000 0.177810
+v -0.570953 -0.178898 -0.310363
+v -0.558142 -0.227247 -0.230745
+v -0.615371 -0.181204 -0.210170
+v -0.672601 -0.135160 -0.189595
+v -0.598967 -0.135160 -0.357546
+v -0.568401 -0.181284 0.309321
+v -0.557888 -0.227408 0.231085
+v -0.619371 -0.181284 0.189595
+v -0.578914 -0.135160 0.387558
+v -0.557888 0.227408 -0.231085
+v -0.628566 0.176132 -0.173258
+v -0.559233 0.190252 -0.304771
+v -0.670539 0.135161 -0.199959
+v -0.578914 0.135161 -0.387558
+v -0.557888 0.227408 0.231085
+v -0.623749 0.180717 0.170877
+v -0.562017 0.183687 0.313979
+v -0.607092 0.076946 0.375562
+v -0.578913 0.135161 0.387558
+v -0.672600 0.135161 0.189595
+v -0.464421 -0.247455 -0.000000
+v -0.577088 -0.227408 -0.134561
+v -0.523460 -0.237432 0.053682
+v -0.583552 -0.226830 0.105417
+v -0.464421 0.247455 0.000000
+v -0.530245 0.236597 -0.048768
+v -0.582497 0.227408 0.107364
+v -0.580871 0.227408 -0.115542
+v -0.429069 -0.247455 -0.177726
+v -0.432533 -0.237598 -0.293570
+v -0.485904 -0.227408 -0.338816
+v -0.508160 -0.237821 0.116981
+v -0.429671 -0.247455 0.174700
+v -0.378732 -0.247455 0.253061
+v -0.492439 -0.227408 0.329037
+v -0.492438 0.227408 -0.329037
+v -0.429069 0.247455 -0.177726
+v -0.513179 0.235748 -0.164233
+v -0.429069 0.247455 0.177726
+v -0.434056 0.237817 0.288611
+v -0.510336 0.236467 0.153398
+v -0.484699 0.227582 0.338479
+v -0.530330 0.000000 -0.530330
+v -0.458572 -0.077603 -0.551399
+v -0.502268 -0.135160 -0.502267
+v -0.550617 -0.135160 -0.429907
+v -0.453133 0.076929 -0.555267
+v -0.502267 0.135161 -0.502267
+v -0.556115 0.068101 -0.456439
+v -0.611620 0.000000 -0.408671
+v -0.599787 -0.066530 -0.391893
+v -0.435644 0.000000 -0.593597
+v -0.426989 -0.227408 -0.426989
+v -0.407915 -0.185065 -0.497375
+v -0.505464 -0.183357 -0.399290
+v -0.387558 -0.135160 -0.578914
+v -0.426989 -0.227408 0.426989
+v -0.502267 -0.135160 0.502267
+v -0.500057 -0.179599 0.415039
+v -0.387558 -0.135160 0.578914
+v -0.530330 -0.000000 0.530330
+v -0.562399 -0.057673 0.452441
+v -0.426989 0.227408 -0.426989
+v -0.502951 0.181284 -0.407273
+v -0.371632 0.194497 -0.508779
+v -0.387558 0.135161 -0.578913
+v -0.426989 0.227408 0.426989
+v -0.514900 0.181783 0.388374
+v -0.502267 0.135161 0.502267
+v -0.379298 0.206981 0.486662
+v -0.429906 0.135161 0.550617
+v -0.557897 0.077590 0.448854
+v -0.336285 -0.188937 -0.000000
+v -0.382677 -0.218196 0.088863
+v -0.446745 -0.247455 -0.088863
+v -0.446745 -0.247455 0.088863
+v -0.336285 0.188937 0.000000
+v -0.385778 0.217833 -0.069269
+v -0.382741 0.217882 0.085078
+v -0.446745 0.247455 -0.088863
+v -0.446745 0.247455 0.088863
+v -0.310687 -0.188937 -0.128691
+v -0.378733 -0.247455 -0.253061
+v -0.310687 -0.188937 0.128691
+v -0.310686 0.188937 -0.128690
+v -0.378732 0.247455 -0.253061
+v -0.310686 0.188937 0.128691
+v -0.331737 0.217352 0.207025
+v -0.378732 0.247455 0.253061
+v -0.328396 -0.247455 -0.328395
+v -0.253061 -0.247455 -0.378732
+v -0.346275 -0.227408 -0.480921
+v -0.328395 -0.247455 0.328395
+v -0.331535 -0.227408 0.490770
+v -0.282023 0.237297 -0.442722
+v -0.328395 0.247455 -0.328395
+v -0.329037 0.227408 -0.492438
+v -0.328395 0.247455 0.328395
+v -0.253061 0.247455 0.378732
+v -0.331878 0.227663 0.488446
+v -0.289625 -0.134067 -0.057295
+v -0.287923 -0.130160 0.053228
+v -0.260127 -0.070433 -0.000000
+v -0.285407 0.129685 -0.064345
+v -0.282177 0.122530 0.057464
+v -0.260127 0.070433 0.000000
+v -0.204562 -0.218465 -0.336259
+v -0.237789 -0.188937 -0.237789
+v -0.237789 -0.188937 0.237789
+v -0.217800 -0.218788 0.328247
+v -0.177726 -0.247455 0.429069
+v -0.237789 0.188937 -0.237789
+v -0.253061 0.247455 -0.378732
+v -0.226904 0.218812 0.322227
+v -0.237789 0.188937 0.237789
+v -0.240326 -0.070433 -0.099546
+v -0.247312 -0.129685 0.156314
+v -0.240326 -0.070433 0.099546
+v -0.240326 0.070433 -0.099546
+v -0.247312 0.129685 -0.156314
+v -0.240326 0.070433 0.099546
+v -0.252688 0.136261 0.155728
+v -0.271825 -0.135160 -0.656244
+v -0.287013 0.000000 -0.692910
+v -0.135913 -0.135160 -0.683279
+v -0.341627 -0.063564 -0.634402
+v -0.220805 0.062520 -0.687722
+v -0.271825 0.135161 -0.656244
+v -0.342643 0.065672 -0.632993
+v -0.177810 0.000000 -0.714631
+v -0.370902 -0.001344 -0.636391
+v -0.171633 -0.077297 0.693163
+v -0.287013 -0.000000 0.692910
+v -0.271825 -0.135160 0.656244
+v -0.163774 0.083974 0.692766
+v -0.271825 0.135161 0.656244
+v -0.343309 0.068474 0.631577
+v -0.396167 -0.000062 0.619953
+v -0.177810 -0.000000 0.714631
+v -0.231085 -0.227408 -0.557888
+v -0.170310 -0.182655 -0.621625
+v -0.313555 -0.185113 -0.560359
+v -0.170868 -0.185426 0.618316
+v -0.231085 -0.227408 0.557888
+v -0.304838 -0.174559 0.580551
+v -0.135913 -0.135160 0.683279
+v -0.231085 0.227408 -0.557888
+v -0.357546 0.135161 -0.598967
+v -0.189595 0.181284 -0.619371
+v -0.107364 0.135161 -0.688957
+v -0.231085 0.227408 0.557888
+v -0.189595 0.135161 0.672600
+v -0.357546 0.135161 0.598967
+v -0.212132 0.000000 -0.141742
+v -0.183937 -0.070433 -0.183937
+v -0.183937 -0.070433 0.183937
+v -0.183937 0.070433 -0.183937
+v -0.182603 0.070438 0.184833
+v -0.156314 -0.129685 -0.247312
+v -0.128691 -0.188937 -0.310687
+v -0.156314 -0.129685 0.247312
+v -0.128691 -0.188937 0.310687
+v -0.163025 0.141967 -0.252138
+v -0.128691 0.188937 -0.310686
+v -0.165163 0.141475 0.250336
+v -0.128691 0.188937 0.310686
+v -0.177726 -0.247455 -0.429069
+v -0.107364 -0.227408 -0.582498
+v -0.149665 -0.235647 0.516778
+v -0.107364 -0.227408 0.582498
+v -0.177726 0.247455 -0.429069
+v -0.142545 0.237432 -0.505783
+v -0.107364 0.227408 -0.582497
+v -0.177726 0.247455 0.429069
+v -0.107364 0.227408 0.582497
+v -0.099546 0.070433 -0.240326
+v -0.099546 -0.070433 -0.240326
+v -0.099546 0.070433 0.240326
+v -0.099546 -0.070433 0.240326
+v -0.080033 -0.214471 -0.376277
+v -0.088863 -0.247455 -0.446745
+v -0.088863 -0.247455 0.446745
+v -0.080472 0.217516 -0.382857
+v -0.088863 0.247455 -0.446745
+v -0.071400 0.215432 0.380098
+v -0.088863 0.247455 0.446745
+v -0.055107 -0.128888 -0.286732
+v 0.000000 -0.188937 -0.336285
+v -0.055041 -0.130685 0.287900
+v -0.000000 -0.188937 0.336285
+v -0.062756 0.134013 -0.288504
+v 0.000000 0.188937 -0.336285
+v -0.060039 0.128492 0.285497
+v -0.000000 0.188937 0.336285
+v -0.053324 -0.003221 -0.249520
+v 0.000000 -0.070433 -0.260127
+v -0.045259 -0.000273 0.251124
+v -0.000000 -0.070433 0.260127
+v 0.000000 0.070433 -0.260127
+v -0.000000 0.070433 0.260127
+v -0.000000 -0.135160 0.710313
+v 0.081349 -0.066818 0.714199
+v -0.000000 -0.000000 0.750000
+v -0.083186 -0.069651 0.713002
+v -0.002247 0.135161 0.709866
+v 0.082107 0.059371 0.716235
+v -0.073908 0.058686 0.718067
+v 0.088905 -0.000000 0.732316
+v -0.088905 -0.000000 0.732316
+v -0.000000 -0.227408 0.603854
+v -0.065074 -0.176105 0.650117
+v 0.052670 -0.175140 0.653698
+v 0.135913 -0.135160 0.683279
+v -0.000000 0.227408 0.603853
+v 0.053682 0.181284 0.646405
+v -0.053682 0.181284 0.646405
+v 0.111938 0.135161 0.688047
+v -0.107364 0.135161 0.688957
+v 0.005294 -0.247455 0.463368
+v 0.107364 -0.227408 0.582498
+v -0.053682 -0.237432 0.523460
+v -0.000000 0.247455 0.464421
+v 0.052087 0.236945 0.527161
+v -0.053682 0.237432 0.523459
+v 0.110731 0.226341 0.583059
+v 0.074625 -0.219739 0.388888
+v 0.088863 -0.247455 0.446745
+v 0.053837 0.214530 0.381616
+v 0.088863 0.247455 0.446745
+v 0.056825 -0.133366 0.289268
+v 0.128691 -0.188937 0.310687
+v 0.049773 0.129685 0.288305
+v 0.128691 0.188937 0.310686
+v 0.099546 -0.070433 0.240326
+v 0.099546 0.070433 0.240326
+v 0.099546 -0.070433 -0.240326
+v 0.056738 -0.130548 -0.287475
+v 0.057766 0.137654 -0.291836
+v 0.099546 0.070433 -0.240326
+v 0.000000 -0.247455 -0.464421
+v 0.088863 -0.247455 -0.446745
+v 0.128691 -0.188937 -0.310687
+v 0.000000 0.247455 -0.464421
+v 0.091470 0.217038 -0.379622
+v 0.128691 0.188937 -0.310686
+v 0.000000 -0.227408 -0.603854
+v 0.115542 -0.227408 -0.580871
+v 0.000000 0.227408 -0.603853
+v 0.115542 0.227408 -0.580871
+v -0.050354 0.236542 -0.530311
+v 0.088863 0.247455 -0.446745
+v -0.077172 -0.178565 -0.644871
+v 0.000000 -0.135160 -0.710313
+v 0.053682 -0.181284 -0.646406
+v 0.127426 0.182095 -0.630801
+v 0.000000 0.135161 -0.710313
+v -0.053284 0.178446 -0.649760
+v 0.000000 0.000000 -0.750000
+v 0.083331 -0.065958 -0.714057
+v -0.081654 -0.056098 -0.717286
+v 0.107364 -0.135160 -0.688957
+v -0.088905 0.000000 -0.732316
+v 0.057869 0.049516 -0.723950
+v 0.135913 0.135161 -0.683278
+v 0.124700 0.065746 -0.705891
+v 0.088905 0.000000 -0.732316
+v 0.140691 0.004583 0.212834
+v 0.168668 0.129685 0.239057
+v 0.183937 0.070433 0.183937
+v 0.158128 -0.126755 0.243879
+v 0.183937 -0.070433 0.183937
+v 0.183937 -0.070433 -0.183937
+v 0.183937 0.070433 -0.183937
+v 0.162826 -0.137642 -0.248993
+v 0.177726 0.247455 0.429069
+v 0.221031 0.217158 0.321879
+v 0.237789 0.188937 0.237789
+v 0.229404 0.216858 -0.315510
+v 0.177726 0.247455 -0.429069
+v 0.237789 0.188937 -0.237789
+v 0.177726 -0.247455 0.429069
+v 0.253061 -0.247455 0.378732
+v 0.237789 -0.188937 0.237789
+v 0.177726 -0.247455 -0.429069
+v 0.253061 -0.247455 -0.378732
+v 0.237789 -0.188937 -0.237789
+v 0.231085 0.227408 0.557888
+v 0.279740 0.237432 0.443142
+v 0.142545 0.237432 0.505783
+v 0.253061 0.247455 0.378732
+v 0.287768 0.237840 -0.434425
+v 0.231085 0.227408 -0.557888
+v 0.261020 0.247455 -0.373414
+v 0.286516 -0.237465 0.438340
+v 0.231085 -0.227408 0.557888
+v 0.231085 -0.227408 -0.557888
+v 0.346275 -0.227408 -0.480920
+v 0.240326 0.070433 0.099546
+v 0.245711 0.135139 0.164898
+v 0.242207 -0.130300 0.164652
+v 0.240597 -0.070433 0.098185
+v 0.240326 0.070433 -0.099546
+v 0.247109 -0.135199 -0.162873
+v 0.240326 -0.070433 -0.099546
+v 0.271825 0.135161 0.656244
+v 0.169224 0.181284 0.623422
+v 0.357546 0.135161 0.598967
+v 0.329037 0.227408 0.492438
+v 0.271825 0.135161 -0.656244
+v 0.304869 0.184082 -0.567568
+v 0.329037 0.227408 -0.492438
+v 0.300431 -0.181284 0.574341
+v 0.271825 -0.135160 0.656244
+v 0.190519 -0.174382 0.627152
+v 0.329037 -0.227408 0.492439
+v 0.357546 -0.135160 -0.598967
+v 0.271825 -0.135160 -0.656244
+v 0.181222 -0.173682 -0.629809
+v 0.310686 0.188937 0.128691
+v 0.378732 0.247455 0.253061
+v 0.328395 0.247455 0.328395
+v 0.310687 0.188937 -0.128690
+v 0.326095 0.216854 -0.213543
+v 0.328395 0.247455 -0.328395
+v 0.322623 -0.216228 0.216322
+v 0.310687 -0.188937 0.128691
+v 0.328395 -0.247455 0.328395
+v 0.310687 -0.188937 -0.128691
+v 0.378733 -0.247455 -0.253061
+v 0.328396 -0.247455 -0.328395
+v 0.250226 -0.000000 0.049773
+v 0.260127 0.070433 0.000000
+v 0.285407 0.129685 0.064345
+v 0.289619 0.135713 -0.062645
+v 0.287440 -0.131065 0.058580
+v 0.260127 -0.070433 -0.000000
+v 0.285899 -0.126588 -0.051864
+v 0.336285 0.188937 0.000000
+v 0.336285 -0.188937 -0.000000
+v 0.322279 0.067580 0.645938
+v 0.287013 -0.000000 0.692910
+v 0.214655 0.069255 0.686967
+v 0.189595 0.135161 0.672600
+v 0.224818 -0.067580 0.685438
+v 0.330781 -0.067146 0.640408
+v 0.387046 -0.135160 0.579256
+v 0.287013 0.000000 -0.692910
+v 0.217020 0.070360 -0.686173
+v 0.347842 0.000000 -0.652265
+v 0.387046 0.135161 -0.579255
+v 0.210948 -0.080005 -0.684548
+v 0.343477 -0.066922 -0.632002
+v 0.189595 -0.135160 -0.672601
+v 0.177810 -0.000000 0.714631
+v 0.347842 -0.000000 0.652265
+v 0.177810 0.000000 -0.714631
+v 0.374030 0.211140 0.054655
+v 0.429069 0.247455 0.177726
+v 0.382605 0.220104 0.110230
+v 0.382677 0.218196 -0.088863
+v 0.429069 0.247455 -0.177726
+v 0.381271 -0.216600 0.078355
+v 0.428583 -0.247391 0.178203
+v 0.446745 -0.247455 -0.088863
+v 0.429069 -0.247455 -0.177726
+v 0.426989 0.227408 0.426989
+v 0.469993 0.227408 0.362629
+v 0.426989 0.227408 -0.426989
+v 0.432732 0.238438 -0.282962
+v 0.378732 0.247455 -0.253061
+v 0.426989 -0.227408 0.426989
+v 0.492439 -0.227408 0.329037
+v 0.439562 -0.238499 0.271995
+v 0.378732 -0.247455 0.253061
+v 0.426989 -0.227408 -0.426989
+v 0.443142 -0.237432 -0.279740
+v 0.464421 0.247455 0.000000
+v 0.464421 -0.247455 -0.000000
+v 0.502267 0.135161 0.502267
+v 0.389730 0.189313 0.503743
+v 0.598967 0.135161 0.357546
+v 0.502267 0.135161 -0.502267
+v 0.407018 0.181284 -0.503122
+v 0.502951 0.181284 -0.407273
+v 0.492438 0.227408 -0.329037
+v 0.502267 -0.135160 0.502267
+v 0.538631 -0.173926 0.368866
+v 0.501453 -0.181675 -0.408719
+v 0.502268 -0.135160 -0.502267
+v 0.492439 -0.227408 -0.329037
+v 0.557888 0.227408 0.231085
+v 0.582497 0.227408 0.107364
+v 0.446745 0.247455 0.088863
+v 0.557888 0.227408 -0.231084
+v 0.580871 0.227408 -0.115542
+v 0.446745 0.247455 -0.088863
+v 0.557888 -0.227408 0.231085
+v 0.582498 -0.227408 0.107364
+v 0.446745 -0.247455 0.088863
+v 0.557888 -0.227408 -0.231085
+v 0.515728 -0.237427 -0.092711
+v 0.603853 0.227408 0.000000
+v 0.603854 -0.227408 -0.000000
+v 0.530330 -0.000000 0.530330
+v 0.556944 0.067580 0.455469
+v 0.443938 0.067580 0.564649
+v 0.431322 0.135161 0.549672
+v 0.455469 -0.067580 0.556944
+v 0.563256 -0.063878 0.447942
+v 0.578914 -0.135160 0.387558
+v 0.530330 0.000000 -0.530330
+v 0.414705 0.058506 -0.587324
+v 0.566090 0.060108 -0.445653
+v 0.578913 0.135161 -0.387558
+v 0.564464 -0.064950 -0.445577
+v 0.435586 -0.065536 -0.570937
+v 0.578914 -0.135160 -0.387558
+v 0.570975 -0.000000 0.469501
+v 0.408671 -0.000000 0.611620
+v 0.408671 0.000000 -0.611620
+v 0.611620 0.000000 -0.408671
+v 0.619371 0.181284 0.189595
+v 0.656244 0.135161 0.271825
+v 0.615971 0.183777 -0.192222
+v 0.656244 0.135161 -0.271825
+v 0.615859 -0.187440 0.171532
+v 0.656244 -0.135160 0.271825
+v 0.571923 -0.184840 0.296806
+v 0.656244 -0.135160 -0.271825
+v 0.618773 -0.182243 -0.187041
+v 0.580570 -0.227408 -0.117056
+v 0.710313 0.135161 0.000000
+v 0.688957 0.135161 -0.107364
+v 0.646723 0.180940 0.054080
+v 0.710313 -0.135160 -0.000000
+v 0.683279 -0.135160 -0.135912
+v 0.645372 -0.179169 0.071153
+v 0.692910 -0.000000 0.287013
+v 0.645938 0.067580 0.322279
+v 0.685667 0.071751 0.217507
+v 0.672600 0.135161 0.189595
+v 0.692910 0.000000 -0.287012
+v 0.685562 0.072184 -0.217397
+v 0.643668 0.052770 -0.333355
+v 0.672600 0.135161 -0.189595
+v 0.697660 -0.068270 0.162354
+v 0.639387 -0.067839 0.331951
+v 0.683279 -0.135160 0.135913
+v 0.619002 -0.072742 -0.359917
+v 0.685438 -0.067580 -0.224817
+v 0.611620 -0.000000 0.408671
+v 0.714631 -0.000000 0.177810
+v 0.652265 0.000000 -0.347842
+v 0.714373 -0.001402 -0.177040
+v 0.750000 0.000000 0.000000
+v 0.717360 0.075612 -0.052474
+v 0.710134 0.069315 0.098099
+v 0.688957 0.135161 0.107364
+v 0.714216 -0.065097 -0.083803
+v 0.712362 -0.080492 0.070402
+v 0.732316 0.000000 -0.088905
+v 0.732316 -0.000000 0.088905
+v -0.401630 0.076652 -0.589776
+v -0.407579 -0.070112 -0.588066
+v -0.593597 -0.000000 0.435644
+v -0.704476 0.062482 0.136628
+vt 0.732166 0.155461
+vt 0.714953 0.202717
+vt 0.708046 0.168831
+vt 0.732209 0.193512
+vt 0.701021 0.251467
+vt 0.695974 0.187245
+vt 0.732616 0.220277
+vt 0.754661 0.148648
+vt 0.752805 0.114521
+vt 0.726540 0.123737
+vt 0.750726 0.190465
+vt 0.761929 0.186795
+vt 0.705871 0.132777
+vt 0.684170 0.264421
+vt 0.689922 0.296828
+vt 0.721587 0.273032
+vt 0.678525 0.235129
+vt 0.673377 0.143118
+vt 0.648399 0.162273
+vt 0.657651 0.109185
+vt 0.637606 0.123659
+vt 0.657819 0.193767
+vt 0.641663 0.215784
+vt 0.626501 0.182337
+vt 0.675241 0.174073
+vt 0.631458 0.141944
+vt 0.630026 0.157329
+vt 0.787143 0.223027
+vt 0.768265 0.265466
+vt 0.764144 0.222215
+vt 0.792111 0.265020
+vt 0.782493 0.287007
+vt 0.751329 0.309317
+vt 0.747242 0.270599
+vt 0.749382 0.239903
+vt 0.637385 0.079834
+vt 0.670821 0.061503
+vt 0.677846 0.091493
+vt 0.682660 0.118885
+vt 0.624903 0.100431
+vt 0.809123 0.224691
+vt 0.807142 0.186241
+vt 0.784644 0.186679
+vt 0.810694 0.259651
+vt 0.636653 0.264964
+vt 0.657977 0.245210
+vt 0.622512 0.240774
+vt 0.657917 0.223189
+vt 0.609208 0.210333
+vt 0.736728 0.350100
+vt 0.729357 0.309709
+vt 0.756807 0.349975
+vt 0.777270 0.318929
+vt 0.773538 0.344441
+vt 0.736840 0.290959
+vt 0.773212 0.086238
+vt 0.710285 0.078135
+vt 0.778034 0.118471
+vt 0.780520 0.144897
+vt 0.682155 0.331179
+vt 0.674913 0.302893
+vt 0.711978 0.320993
+vt 0.663737 0.279519
+vt 0.686618 0.026488
+vt 0.615441 0.030872
+vt 0.610289 0.048084
+vt 0.795710 0.140692
+vt 0.823961 0.159192
+vt 0.846338 0.197017
+vt 0.830037 0.222870
+vt 0.608258 0.261143
+vt 0.633294 0.302000
+vt 0.646561 0.284317
+vt 0.725937 0.380887
+vt 0.751537 0.397237
+vt 0.720810 0.348908
+vt 0.759506 0.387496
+vt 0.572717 0.157060
+vt 0.550689 0.130920
+vt 0.567080 0.102975
+vt 0.595570 0.098918
+vt 0.557603 0.192476
+vt 0.576749 0.211301
+vt 0.592411 0.182042
+vt 0.610858 0.154722
+vt 0.613963 0.128021
+vt 0.544142 0.165540
+vt 0.558895 0.053757
+vt 0.538934 0.082993
+vt 0.593524 0.073932
+vt 0.524143 0.116033
+vt 0.849912 0.262118
+vt 0.831806 0.298238
+vt 0.830327 0.263014
+vt 0.853031 0.335173
+vt 0.813224 0.338775
+vt 0.809127 0.300664
+vt 0.579717 0.261025
+vt 0.594540 0.233878
+vt 0.555612 0.250329
+vt 0.545339 0.222559
+vt 0.778401 0.417103
+vt 0.772003 0.373190
+vt 0.795140 0.379753
+vt 0.794726 0.432209
+vt 0.807905 0.403747
+vt 0.791039 0.341872
+vt 0.777303 0.081668
+vt 0.808131 0.125476
+vt 0.738283 0.051098
+vt 0.802615 0.121174
+vt 0.680844 0.337119
+vt 0.659824 0.319965
+vt 0.705886 0.361169
+vt 0.657941 0.315887
+vt 0.704116 0.355911
+vt 0.690307 0.020639
+vt 0.620443 0.010475
+vt 0.827880 0.156348
+vt 0.632737 0.308394
+vt 0.607532 0.299189
+vt 0.724071 0.386196
+vt 0.741288 0.410397
+vt 0.745291 0.413243
+vt 0.548336 0.017192
+vt 0.487740 0.035724
+vt 0.515689 0.065301
+vt 0.864626 0.235997
+vt 0.870093 0.296989
+vt 0.551111 0.289679
+vt 0.581695 0.298427
+vt 0.551969 0.271928
+vt 0.765346 0.444757
+vt 0.783325 0.481829
+vt 0.796791 0.453835
+vt 0.726111 0.068061
+vt 0.788546 0.134500
+vt 0.740594 0.136936
+vt 0.658119 0.291607
+vt 0.711562 0.332488
+vt 0.695953 0.271534
+vt 0.475413 0.039567
+vt 0.545788 0.010956
+vt 0.867288 0.231608
+vt 0.885709 0.269207
+vt 0.902567 0.306617
+vt 0.582023 0.304881
+vt 0.556526 0.308969
+vt 0.779949 0.479179
+vt 0.763030 0.449472
+vt 0.662670 0.087831
+vt 0.833443 0.207774
+vt 0.795630 0.206399
+vt 0.639341 0.237593
+vt 0.611510 0.276146
+vt 0.744783 0.327369
+vt 0.747761 0.392049
+vt 0.486801 0.140337
+vt 0.502736 0.189221
+vt 0.454509 0.169171
+vt 0.513471 0.154072
+vt 0.496408 0.222087
+vt 0.515249 0.239396
+vt 0.525421 0.202483
+vt 0.479772 0.208969
+vt 0.525237 0.174009
+vt 0.883124 0.418480
+vt 0.855998 0.414593
+vt 0.873856 0.373097
+vt 0.862673 0.470842
+vt 0.837274 0.455346
+vt 0.835143 0.414988
+vt 0.836735 0.380732
+vt 0.872868 0.442582
+vt 0.466878 0.097675
+vt 0.455985 0.137528
+vt 0.499622 0.101112
+vt 0.895900 0.374250
+vt 0.890087 0.335009
+vt 0.870984 0.340420
+vt 0.896040 0.407532
+vt 0.525010 0.285953
+vt 0.537275 0.226482
+vt 0.507137 0.272752
+vt 0.482511 0.270077
+vt 0.818664 0.491352
+vt 0.850143 0.478738
+vt 0.821176 0.427867
+vt 0.610858 0.154722
+vt 0.563964 0.081082
+vt 0.839672 0.282054
+vt 0.578128 0.233361
+vt 0.788378 0.397577
+vt 0.494584 0.059202
+vt 0.441925 0.063170
+vt 0.878372 0.291927
+vt 0.904765 0.301757
+vt 0.552629 0.294068
+vt 0.532881 0.327257
+vt 0.790271 0.471398
+vt 0.800484 0.521446
+vt 0.446194 0.067982
+vt 0.431086 0.131496
+vt 0.906513 0.342316
+vt 0.912981 0.369336
+vt 0.531749 0.321170
+vt 0.513678 0.315340
+vt 0.498610 0.311098
+vt 0.803287 0.517141
+vt 0.840770 0.533423
+vt 0.519727 0.260004
+vt 0.478779 0.121076
+vt 0.829233 0.471520
+vt 0.881037 0.356176
+vt 0.412798 0.096853
+vt 0.412829 0.101481
+vt 0.922967 0.336681
+vt 0.510893 0.344643
+vt 0.509021 0.343328
+vt 0.821724 0.560558
+vt 0.822089 0.556499
+vt 0.425124 0.119531
+vt 0.385244 0.136150
+vt 0.916869 0.355988
+vt 0.944665 0.361840
+vt 0.506450 0.322646
+vt 0.488308 0.371526
+vt 0.831928 0.538303
+vt 0.841600 0.597216
+vt 0.473819 0.210666
+vt 0.418854 0.186932
+vt 0.880657 0.454366
+vt 0.925216 0.422444
+vt 0.468860 0.310922
+vt 0.875211 0.546434
+vt 0.918970 0.440998
+vt 0.925575 0.481920
+vt 0.902561 0.486000
+vt 0.896941 0.443427
+vt 0.883383 0.528908
+vt 0.910084 0.524586
+vt 0.881846 0.486746
+vt 0.918615 0.505815
+vt 0.887461 0.464965
+vt 0.932833 0.399055
+vt 0.913384 0.407004
+vt 0.934728 0.435260
+vt 0.944408 0.469025
+vt 0.863381 0.566968
+vt 0.885323 0.563297
+vt 0.863798 0.532753
+vt 0.905684 0.558359
+vt 0.864124 0.501681
+vt 0.944240 0.368654
+vt 0.954966 0.422268
+vt 0.926555 0.368431
+vt 0.845075 0.592979
+vt 0.867898 0.598015
+vt 0.842547 0.560430
+vt 0.888553 0.602345
+vt 0.965193 0.386940
+vt 0.965377 0.390038
+vt 0.859677 0.623326
+vt 0.869185 0.631885
+vt 0.960307 0.408648
+vt 0.989236 0.406110
+vt 0.878491 0.610715
+vt 0.898281 0.670197
+vt 0.976083 0.473363
+vt 0.935136 0.612290
+vt 0.372877 0.261846
+vt 0.376389 0.191811
+vt 0.461048 0.381657
+vt 0.424681 0.377190
+vt 0.388719 0.140387
+vt 0.365733 0.176867
+vt 0.344128 0.211920
+vt 0.486574 0.366047
+vt 0.463411 0.405150
+vt 0.448408 0.431610
+vt 0.407025 0.166398
+vt 0.382820 0.202659
+vt 0.476477 0.334311
+vt 0.455101 0.366330
+vt 0.491794 0.335460
+vt 0.466611 0.396685
+vt 0.434533 0.164564
+vt 0.427452 0.203914
+vt 0.407442 0.200613
+vt 0.446802 0.345775
+vt 0.462614 0.292369
+vt 0.479025 0.299446
+vt 0.446205 0.247366
+vt 0.422783 0.246750
+vt 0.454062 0.210015
+vt 0.407768 0.231685
+vt 0.462258 0.227551
+vt 0.442411 0.276979
+vt 0.439684 0.325834
+vt 0.433137 0.299007
+vt 0.431105 0.268402
+vt 0.990655 0.568941
+vt 0.963373 0.680418
+vt 1.020321 0.652284
+vt 1.008054 0.447965
+vt 1.034484 0.500005
+vt 0.331412 0.336988
+vt 0.383315 0.451313
+vt 0.335139 0.262725
+vt 0.902550 0.665384
+vt 0.945561 0.701796
+vt 1.002144 0.722411
+vt 0.425317 0.471964
+vt 0.446211 0.426749
+vt 0.410931 0.501758
+vt 0.988105 0.412197
+vt 1.012882 0.424397
+vt 1.038379 0.428486
+vt 0.346931 0.216225
+vt 0.326969 0.251537
+vt 0.306674 0.283894
+vt 0.923234 0.635692
+vt 0.949612 0.676160
+vt 0.893228 0.630835
+vt 0.944096 0.697642
+vt 0.421030 0.447656
+vt 0.433731 0.398357
+vt 0.426013 0.466591
+vt 1.009071 0.444110
+vt 0.981366 0.447413
+vt 0.362307 0.242015
+vt 0.337833 0.284999
+vt 1.119026 0.645535
+vt 1.073562 0.702905
+vt 1.063205 0.457200
+vt 1.096489 0.495430
+vt 0.339273 0.526967
+vt 0.294721 0.336695
+vt 0.288427 0.405997
+vt 0.943157 0.593030
+vt 0.912268 0.594851
+vt 0.970053 0.611910
+vt 0.963612 0.664209
+vt 0.417500 0.360270
+vt 0.415391 0.398637
+vt 0.414252 0.435434
+vt 0.989174 0.479580
+vt 0.971605 0.493970
+vt 0.962383 0.463761
+vt 1.008325 0.461439
+vt 0.364820 0.305499
+vt 0.380918 0.278021
+vt 0.385853 0.241185
+vt 1.146663 0.712727
+vt 1.076798 0.722892
+vt 1.004691 0.716174
+vt 0.371523 0.577019
+vt 0.390379 0.540042
+vt 0.408270 0.497369
+vt 1.063624 0.431204
+vt 1.089093 0.424973
+vt 1.038052 0.434940
+vt 0.267715 0.347171
+vt 0.288935 0.320124
+vt 0.308989 0.288609
+vt 0.183777 0.495430
+vt 0.206314 0.645535
+vt 0.227056 0.554546
+vt 0.284238 0.596430
+vt 0.262651 0.666920
+vt 0.233951 0.712727
+vt 0.160849 0.702905
+vt 0.337858 0.595497
+vt 0.204354 0.439361
+vt 0.239596 0.461832
+vt 0.150493 0.457200
+vt 0.176381 0.424973
+vt 0.252082 0.401558
+vt 0.320946 0.651698
+vt 0.224488 0.396248
+vt 0.963855 0.577209
+vt 0.959093 0.544145
+vt 0.936817 0.557082
+vt 0.923067 0.576550
+vt 0.954202 0.510228
+vt 0.978773 0.528469
+vt 1.001556 0.510744
+vt 0.399642 0.318773
+vt 0.418583 0.324153
+vt 0.388934 0.337410
+vt 0.396769 0.398025
+vt 0.399253 0.276549
+vt 0.379012 0.318837
+vt 0.393787 0.254629
+vt 0.936128 0.524397
+vt 0.975207 0.555084
+vt 0.416511 0.290785
+vt 0.294810 0.676578
+vt 0.230262 0.706879
+vt 0.263792 0.696624
+vt 0.164086 0.722892
+vt 0.351775 0.607890
+vt 0.368251 0.572809
+vt 0.200368 0.415126
+vt 0.150912 0.431204
+vt 0.176759 0.431387
+vt 0.247759 0.377455
+vt 0.269581 0.352479
+vt 1.015251 0.679609
+vt 1.052308 0.685232
+vt 0.393555 0.471248
+vt 0.380569 0.525541
+vt 0.389982 0.536349
+vt 1.036073 0.472342
+vt 1.064614 0.472224
+vt 1.069055 0.452709
+vt 1.063888 0.434178
+vt 0.322045 0.316264
+vt 0.292974 0.340665
+vt 0.316856 0.647128
+vt 0.225799 0.402187
+vt 1.023436 0.630392
+vt 0.987854 0.650405
+vt 1.081260 0.632936
+vt 0.375450 0.435129
+vt 0.395287 0.432891
+vt 0.373041 0.473426
+vt 0.373681 0.510497
+vt 1.033105 0.522065
+vt 1.063461 0.503179
+vt 0.319761 0.353604
+vt 0.338784 0.353613
+vt 0.301066 0.349590
+vt 1.142974 0.706879
+vt 1.127029 0.672004
+vt 0.263805 0.648829
+vt 0.214317 0.672004
+vt 0.281927 0.682268
+vt 0.350785 0.547125
+vt 0.326759 0.585500
+vt 0.346259 0.612192
+vt 0.180297 0.468403
+vt 0.156343 0.452709
+vt 0.209285 0.452692
+vt 0.151176 0.434178
+vt 0.201585 0.417479
+vt 0.280371 0.383266
+vt 0.250851 0.398078
+vt 0.296449 0.618845
+vt 0.233566 0.436538
+vt 1.029073 0.576306
+vt 1.047618 0.605928
+vt 1.002193 0.596620
+vt 0.996477 0.623833
+vt 1.013677 0.544731
+vt 1.051511 0.553164
+vt 1.065564 0.523033
+vt 0.356868 0.394591
+vt 0.383243 0.379132
+vt 0.351943 0.435491
+vt 0.354338 0.473716
+vt 0.335349 0.397184
+vt 0.362542 0.349044
+vt 0.317182 0.388926
+vt 1.047889 0.578710
+vt 0.992528 0.564366
+vt 0.378158 0.356573
+vt 0.335038 0.432001
+vt 0.228691 0.638896
+vt 0.201295 0.624182
+vt 0.168547 0.632936
+vt 0.329528 0.546675
+vt 0.330787 0.510340
+vt 0.200336 0.482368
+vt 0.185307 0.517582
+vt 0.169454 0.495114
+vt 0.151902 0.472224
+vt 0.294973 0.424049
+vt 0.275947 0.419133
+vt 0.257603 0.410106
+vt 0.275810 0.577905
+vt 0.299668 0.553712
+vt 0.270851 0.611088
+vt 0.244665 0.481900
+vt 0.270596 0.454206
+vt 0.224259 0.472619
+vt 0.192043 0.571094
+vt 0.181929 0.601642
+vt 0.213389 0.592512
+vt 0.226304 0.614482
+vt 0.311909 0.467900
+vt 0.310849 0.506078
+vt 0.329207 0.468913
+vt 0.316114 0.532588
+vt 0.215993 0.531738
+vt 0.173374 0.548576
+vt 0.215898 0.502176
+vt 0.152852 0.523033
+vt 0.318356 0.420778
+vt 0.294029 0.459078
+vt 0.154502 0.578644
+vt 0.218885 0.559294
+vt 0.323573 0.450375
+vt 0.292730 0.493163
+vt 0.258597 0.530649
+vt 0.278864 0.546234
+vt 0.244265 0.573574
+vt 0.249515 0.600590
+vt 0.268136 0.491207
+vt 0.235424 0.513720
+vt 0.276260 0.513089
+vt 0.239618 0.546121
+vt 1.067214 0.578644
+vt 0.542951 0.198214
+vt 0.533776 0.140417
+vt 0.150749 0.503179
+vt 0.796380 0.309665
+vt 0.734856 0.252555
+vn -0.9425 -0.2767 -0.1875
+vn -0.9425 -0.2767 0.1875
+vn -0.9425 0.2767 -0.1875
+vn -0.9425 0.2767 0.1875
+vn -0.6494 -0.7494 0.1292
+vn -0.6494 -0.7494 -0.1292
+vn -0.6494 0.7494 -0.1292
+vn -0.6494 0.7494 0.1292
+vn -0.7990 -0.2767 -0.5339
+vn -0.7990 0.2767 -0.5339
+vn -0.7990 -0.2768 -0.5339
+vn -0.7990 -0.2767 0.5339
+vn -0.7990 0.2767 0.5339
+vn -0.5504 -0.7500 -0.3669
+vn -0.5505 -0.7494 -0.3678
+vn -0.5505 -0.7494 0.3678
+vn -0.5505 0.7494 -0.3678
+vn -0.5505 0.7494 0.3678
+vn -0.1423 -0.9894 -0.0283
+vn -0.1423 -0.9894 0.0283
+vn -0.1456 -0.9888 0.0335
+vn -0.1423 0.9894 -0.0283
+vn -0.1423 0.9894 0.0283
+vn -0.1218 -0.9893 -0.0805
+vn -0.1427 -0.9893 -0.0298
+vn -0.1214 -0.9894 -0.0797
+vn -0.5505 -0.7499 -0.3668
+vn -0.1203 -0.9896 0.0782
+vn -0.1481 -0.9886 0.0257
+vn -0.1206 -0.9894 0.0806
+vn -0.1206 0.9894 -0.0806
+vn -0.1206 0.9894 0.0806
+vn -0.5446 0.7527 0.3699
+vn -0.5339 -0.2767 -0.7990
+vn -0.5339 0.2767 -0.7990
+vn -0.3678 -0.7494 -0.5505
+vn -0.3678 -0.7494 0.5505
+vn -0.5339 -0.2767 0.7990
+vn -0.3678 0.7494 -0.5505
+vn -0.3678 0.7494 0.5505
+vn -0.5339 0.2767 0.7990
+vn 0.4140 -0.9065 -0.0824
+vn 0.4140 -0.9065 0.0824
+vn -0.1422 -0.9894 0.0283
+vn 0.4140 0.9065 0.0824
+vn 0.4140 0.9065 -0.0824
+vn -0.1422 0.9894 -0.0283
+vn 0.4140 0.9065 0.0823
+vn 0.3510 -0.9065 0.2345
+vn -0.1206 -0.9894 -0.0806
+vn 0.4140 -0.9065 -0.0823
+vn 0.3559 -0.9055 -0.2313
+vn 0.3510 0.9065 0.2345
+vn 0.3510 0.9065 -0.2345
+vn 0.4140 0.9065 -0.0823
+vn -0.1422 0.9894 0.0283
+vn -0.0806 -0.9894 -0.1206
+vn -0.0806 -0.9894 0.1206
+vn -0.0806 0.9894 -0.1206
+vn -0.0806 0.9894 0.1206
+vn -0.5494 0.7542 0.3597
+vn -0.3528 0.7621 0.5429
+vn 0.8297 -0.5332 0.1650
+vn 0.4140 -0.9065 0.0823
+vn 0.8297 -0.5332 -0.1650
+vn 0.8297 0.5332 0.1650
+vn 0.8297 0.5332 -0.1650
+vn 0.2345 -0.9065 0.3510
+vn 0.3510 -0.9065 -0.2345
+vn 0.2345 -0.9065 -0.3510
+vn 0.2345 0.9065 0.3510
+vn 0.2345 0.9065 -0.3510
+vn 0.7034 -0.5332 0.4700
+vn 0.7034 -0.5332 -0.4700
+vn 0.7034 0.5332 0.4700
+vn 0.7034 0.5332 -0.4700
+vn -0.1875 -0.2767 -0.9425
+vn -0.1875 0.2767 -0.9425
+vn -0.5412 0.2686 -0.7969
+vn -0.1875 -0.2767 0.9425
+vn -0.1875 0.2767 0.9425
+vn -0.5341 0.2765 0.7989
+vn -0.1292 -0.7494 -0.6494
+vn -0.1292 -0.7494 0.6494
+vn -0.1292 0.7494 -0.6494
+vn -0.1292 0.7494 0.6494
+vn 0.9808 0.0000 -0.1951
+vn 0.9808 -0.0000 0.1951
+vn 0.8315 -0.0000 0.5556
+vn 0.8315 0.0000 -0.5556
+vn 0.8281 -0.0043 -0.5605
+vn 0.6994 0.5354 -0.4734
+vn 0.4700 -0.5332 0.7034
+vn 0.4700 -0.5332 -0.7034
+vn 0.4700 0.5332 0.7034
+vn 0.6998 0.5366 -0.4715
+vn 0.4700 0.5332 -0.7034
+vn -0.0283 -0.9894 -0.1423
+vn -0.0283 -0.9894 0.1423
+vn -0.0283 0.9894 -0.1423
+vn -0.0283 0.9894 0.1423
+vn -0.3575 0.7746 0.5217
+vn 0.5556 -0.0000 0.8315
+vn 0.5555 0.0000 -0.8315
+vn 0.5556 0.0000 -0.8315
+vn 0.0824 -0.9065 0.4140
+vn 0.0824 -0.9065 -0.4140
+vn 0.0824 0.9065 0.4140
+vn -0.0283 0.9894 -0.1422
+vn 0.0824 0.9065 -0.4140
+vn 0.1650 -0.5332 0.8297
+vn 0.0823 -0.9065 0.4140
+vn 0.1650 -0.5332 -0.8297
+vn 0.1650 0.5332 0.8297
+vn 0.1651 0.5332 -0.8297
+vn 0.1650 0.5332 -0.8297
+vn 0.1951 -0.0000 0.9808
+vn 0.1951 0.0000 -0.9808
+vn 0.1875 -0.2767 0.9425
+vn 0.1829 0.2826 0.9416
+vn 0.1875 0.2767 0.9425
+vn 0.1292 -0.7494 0.6494
+vn 0.1245 0.7472 0.6528
+vn 0.1802 0.2798 0.9430
+vn 0.1248 0.7471 0.6529
+vn 0.0283 -0.9894 0.1423
+vn -0.0253 -0.9898 0.1403
+vn 0.0283 0.9894 0.1423
+vn 0.1292 0.7494 0.6494
+vn 0.0374 0.9882 0.1483
+vn -0.0824 -0.9065 -0.4140
+vn 0.0741 -0.9047 -0.4197
+vn -0.0248 -0.9897 0.1407
+vn -0.0824 0.9065 -0.4140
+vn -0.0283 0.9894 0.1422
+vn -0.1650 -0.5332 -0.8297
+vn -0.1650 0.5332 -0.8297
+vn -0.1951 0.0000 -0.9808
+vn -0.1951 -0.0000 0.9808
+vn -0.1650 -0.5332 0.8297
+vn -0.1651 0.5332 0.8297
+vn -0.1650 0.5332 0.8297
+vn -0.0824 -0.9065 0.4140
+vn -0.0824 0.9065 0.4140
+vn 0.0283 -0.9894 -0.1423
+vn 0.0283 0.9894 -0.1423
+vn 0.1292 -0.7494 -0.6494
+vn 0.1292 0.7494 -0.6494
+vn 0.1875 -0.2767 -0.9425
+vn 0.1875 0.2767 -0.9425
+vn -0.5556 0.0000 -0.8315
+vn -0.4700 0.5332 -0.7034
+vn -0.4700 -0.5332 -0.7034
+vn -0.5556 -0.0000 0.8315
+vn -0.4700 0.5332 0.7034
+vn -0.4700 -0.5332 0.7034
+vn -0.2345 0.9065 -0.3510
+vn -0.0823 0.9065 -0.4140
+vn -0.2345 0.9065 0.3510
+vn -0.0823 0.9065 0.4140
+vn -0.2345 -0.9065 -0.3510
+vn -0.2345 -0.9065 0.3510
+vn 0.0806 0.9894 0.1206
+vn 0.0283 0.9894 0.1422
+vn 0.0806 0.9894 -0.1206
+vn 0.0806 -0.9894 0.1206
+vn 0.0806 -0.9894 -0.1206
+vn -0.8315 0.0000 -0.5556
+vn -0.7034 0.5332 -0.4700
+vn -0.7034 -0.5332 -0.4700
+vn -0.8343 0.0037 -0.5513
+vn -0.7045 -0.5357 -0.4655
+vn -0.8315 -0.0000 0.5556
+vn -0.7034 0.5332 0.4700
+vn -0.7034 -0.5332 0.4700
+vn 0.3678 0.7494 0.5505
+vn 0.0229 0.9882 0.1513
+vn 0.3678 0.7494 -0.5505
+vn 0.3678 -0.7494 0.5505
+vn 0.3678 -0.7494 -0.5505
+vn -0.3510 0.9065 -0.2345
+vn -0.3510 0.9065 0.2345
+vn -0.3510 -0.9065 -0.2345
+vn -0.3510 -0.9065 0.2345
+vn -0.9808 -0.0000 -0.1951
+vn -0.8297 0.5332 -0.1650
+vn -0.9808 -0.0000 0.1951
+vn -0.8297 0.5332 0.1650
+vn -0.8297 -0.5332 -0.1650
+vn -0.7038 -0.5362 -0.4659
+vn -0.8297 -0.5332 0.1650
+vn 0.5339 0.2767 0.7990
+vn 0.5339 -0.2767 0.7990
+vn 0.5339 0.2767 -0.7990
+vn 0.5339 -0.2767 -0.7990
+vn -0.4140 0.9065 -0.0824
+vn -0.4140 0.9065 -0.0823
+vn -0.4140 0.9065 0.0824
+vn -0.4140 -0.9065 -0.0824
+vn -0.4144 -0.9063 -0.0831
+vn -0.4140 -0.9065 0.0823
+vn -0.4140 -0.9065 0.0824
+vn 0.1206 0.9894 0.0806
+vn 0.1206 0.9894 -0.0806
+vn 0.1206 -0.9894 0.0806
+vn 0.1206 -0.9894 -0.0806
+vn 0.5505 0.7494 0.3678
+vn 0.5505 0.7494 -0.3678
+vn 0.5505 -0.7494 0.3678
+vn 0.5505 -0.7494 -0.3678
+vn 0.1423 0.9894 0.0283
+vn 0.1423 0.9894 -0.0283
+vn 0.1203 -0.9895 0.0797
+vn 0.1414 -0.9895 0.0281
+vn 0.1209 -0.9895 0.0797
+vn -0.4138 -0.9065 -0.0835
+vn 0.1421 -0.9894 0.0296
+vn 0.1423 -0.9894 -0.0283
+vn 0.1423 -0.9894 0.0283
+vn 0.7990 0.2767 0.5339
+vn 0.7990 -0.2767 0.5339
+vn 0.7990 0.2767 -0.5339
+vn 0.7990 -0.2767 -0.5339
+vn 0.6494 0.7494 0.1292
+vn 0.6494 0.7494 -0.1292
+vn 0.6494 -0.7494 0.1292
+vn 0.6494 -0.7494 -0.1292
+vn 0.9425 0.2767 0.1875
+vn 0.9425 0.2767 -0.1875
+vn 0.9425 -0.2767 0.1875
+vn 0.9425 -0.2767 -0.1875
+vn 0.9454 0.2709 -0.1811
+vn -0.5337 0.2766 0.7991
+vn -0.5341 0.2764 0.7990
+vn -0.1487 -0.9884 0.0299
+vn -0.5444 0.7557 0.3641
+vn 0.0196 0.9885 0.1500
+vn -0.5281 0.2636 -0.8072
+vn -0.9425 -0.2768 -0.1875
+vn -0.3679 0.7494 -0.5505
+vn 0.0387 0.9884 0.1469
+vn 0.9412 0.2752 -0.1960
+vn 0.9454 0.2695 -0.1834
+usemtl None
+s off
+f 1/1/1 2/2/1 3/3/1
+f 4/4/2 2/2/2 1/1/2
+f 5/5/3 6/6/3 2/2/3
+f 5/5/4 2/2/4 7/7/4
+f 6/6/1 3/3/1 2/2/1
+f 7/7/2 2/2/2 4/4/2
+f 8/8/5 1/1/5 9/9/5
+f 1/1/6 10/10/6 9/9/6
+f 11/11/2 1/1/2 12/12/2
+f 12/12/5 1/1/5 8/8/5
+f 11/11/2 4/4/2 1/1/2
+f 13/13/1 1/1/1 3/3/1
+f 1/1/6 13/13/6 10/10/6
+f 14/14/7 5/5/7 15/15/7
+f 5/5/8 16/16/8 15/15/8
+f 17/17/7 5/5/7 14/14/7
+f 5/5/3 17/17/3 6/6/3
+f 7/7/4 16/16/4 5/5/4
+f 18/18/1 19/19/1 20/20/1
+f 19/19/9 21/21/9 20/20/9
+f 22/22/3 23/23/3 19/19/3
+f 24/24/10 19/19/10 23/23/10
+f 25/25/1 19/19/1 18/18/1
+f 25/25/3 22/22/3 19/19/3
+f 26/26/9 21/21/9 19/19/9
+f 19/19/11 27/27/11 26/26/11
+f 24/24/10 27/27/10 19/19/10
+f 28/28/2 29/29/2 30/30/2
+f 31/31/12 29/29/12 28/28/12
+f 32/32/13 33/33/13 29/29/13
+f 34/34/4 29/29/4 33/33/4
+f 29/29/2 35/35/2 30/30/2
+f 35/35/4 29/29/4 34/34/4
+f 31/31/12 32/32/12 29/29/12
+f 20/20/14 36/36/14 37/37/14
+f 38/38/6 20/20/6 37/37/6
+f 39/39/1 18/18/1 20/20/1
+f 40/40/15 36/36/15 20/20/15
+f 21/21/9 40/40/9 20/20/9
+f 39/39/6 20/20/6 38/38/6
+f 41/41/16 28/28/16 42/42/16
+f 42/42/5 28/28/5 43/43/5
+f 28/28/2 30/30/2 12/12/2
+f 28/28/5 12/12/5 43/43/5
+f 44/44/16 28/28/16 41/41/16
+f 28/28/12 44/44/12 31/31/12
+f 45/45/7 23/23/7 46/46/7
+f 47/47/17 23/23/17 45/45/17
+f 46/46/7 23/23/7 48/48/7
+f 22/22/3 48/48/3 23/23/3
+f 49/49/10 24/24/10 23/23/10
+f 47/47/17 49/49/17 23/23/17
+f 33/33/8 50/50/8 51/51/8
+f 50/50/18 33/33/18 52/52/18
+f 53/53/13 54/54/13 33/33/13
+f 33/33/13 32/32/13 53/53/13
+f 55/55/8 33/33/8 51/51/8
+f 33/33/4 55/55/4 34/34/4
+f 52/52/18 33/33/18 54/54/18
+f 56/56/19 9/9/19 57/57/19
+f 56/56/20 58/58/20 9/9/20
+f 10/10/6 57/57/6 9/9/6
+f 9/9/21 58/58/21 59/59/21
+f 59/59/5 8/8/5 9/9/5
+f 15/15/22 60/60/22 61/61/22
+f 60/60/23 15/15/23 62/62/23
+f 61/61/22 63/63/22 15/15/22
+f 15/15/7 63/63/7 14/14/7
+f 15/15/8 16/16/8 62/62/8
+f 64/64/24 37/37/24 65/65/24
+f 64/64/25 57/57/25 37/37/25
+f 37/37/26 66/66/26 65/65/26
+f 57/57/6 38/38/6 37/37/6
+f 37/37/27 36/36/27 66/66/27
+f 42/42/20 67/67/20 68/68/20
+f 69/69/28 42/42/28 68/68/28
+f 41/41/16 42/42/16 70/70/16
+f 42/42/29 59/59/29 67/67/29
+f 70/70/30 42/42/30 69/69/30
+f 59/59/5 42/42/5 43/43/5
+f 71/71/31 45/45/31 72/72/31
+f 45/45/22 73/73/22 72/72/22
+f 47/47/17 45/45/17 71/71/17
+f 46/46/7 63/63/7 45/45/7
+f 45/45/22 63/63/22 73/73/22
+f 74/74/32 50/50/32 75/75/32
+f 74/74/23 76/76/23 50/50/23
+f 75/75/32 50/50/32 77/77/32
+f 77/77/33 50/50/33 52/52/33
+f 76/76/23 62/62/23 50/50/23
+f 51/51/8 50/50/8 62/62/8
+f 78/78/34 79/79/34 80/80/34
+f 80/80/9 81/81/9 78/78/9
+f 82/82/35 78/78/35 83/83/35
+f 83/83/10 78/78/10 84/84/10
+f 85/85/9 78/78/9 86/86/9
+f 86/86/9 78/78/9 81/81/9
+f 84/84/10 78/78/10 85/85/10
+f 87/87/35 78/78/35 82/82/35
+f 78/78/34 87/87/34 79/79/34
+f 88/88/36 80/80/36 89/89/36
+f 90/90/15 80/80/15 88/88/15
+f 79/79/34 91/91/34 80/80/34
+f 80/80/36 91/91/36 89/89/36
+f 90/90/15 81/81/15 80/80/15
+f 92/92/16 93/93/16 94/94/16
+f 92/92/37 95/95/37 93/93/37
+f 93/93/16 44/44/16 94/94/16
+f 95/95/38 96/96/38 93/93/38
+f 93/93/12 96/96/12 97/97/12
+f 97/97/12 44/44/12 93/93/12
+f 98/98/17 83/83/17 99/99/17
+f 98/98/39 100/100/39 83/83/39
+f 99/99/17 83/83/17 49/49/17
+f 83/83/35 101/101/35 82/82/35
+f 100/100/39 101/101/39 83/83/39
+f 83/83/10 84/84/10 49/49/10
+f 102/102/18 103/103/18 104/104/18
+f 102/102/40 104/104/40 105/105/40
+f 104/104/41 96/96/41 106/106/41
+f 106/106/40 105/105/40 104/104/40
+f 54/54/18 104/104/18 103/103/18
+f 104/104/13 107/107/13 96/96/13
+f 104/104/13 54/54/13 107/107/13
+f 108/108/42 109/109/42 56/56/42
+f 56/56/43 110/110/43 108/108/43
+f 67/67/44 58/58/44 56/56/44
+f 67/67/20 56/56/20 111/111/20
+f 110/110/19 56/56/19 57/57/19
+f 109/109/42 111/111/42 56/56/42
+f 112/112/45 113/113/45 60/60/45
+f 60/60/46 114/114/46 112/112/46
+f 60/60/47 115/115/47 61/61/47
+f 113/113/48 115/115/48 60/60/48
+f 60/60/46 116/116/46 114/114/46
+f 60/60/23 62/62/23 116/116/23
+f 117/117/49 64/64/49 118/118/49
+f 117/117/43 110/110/43 64/64/43
+f 65/65/50 118/118/50 64/64/50
+f 64/64/19 110/110/19 57/57/19
+f 119/119/51 68/68/51 109/109/51
+f 68/68/52 119/119/52 69/69/52
+f 67/67/20 111/111/20 68/68/20
+f 109/109/42 68/68/42 111/111/42
+f 120/120/48 72/72/48 113/113/48
+f 72/72/53 120/120/53 121/121/53
+f 121/121/31 71/71/31 72/72/31
+f 113/113/48 72/72/48 115/115/48
+f 73/73/22 115/115/22 72/72/22
+f 122/122/54 74/74/54 123/123/54
+f 114/114/55 74/74/55 122/122/55
+f 74/74/32 75/75/32 124/124/32
+f 116/116/56 76/76/56 74/74/56
+f 123/123/54 74/74/54 124/124/54
+f 116/116/55 74/74/55 114/114/55
+f 125/125/50 65/65/50 88/88/50
+f 88/88/57 126/126/57 125/125/57
+f 65/65/50 66/66/50 88/88/50
+f 127/127/36 88/88/36 89/89/36
+f 66/66/15 90/90/15 88/88/15
+f 126/126/57 88/88/57 127/127/57
+f 128/128/58 129/129/58 92/92/58
+f 92/92/30 69/69/30 128/128/30
+f 94/94/16 70/70/16 92/92/16
+f 92/92/30 70/70/30 69/69/30
+f 92/92/37 129/129/37 95/95/37
+f 130/130/59 98/98/59 131/131/59
+f 131/131/31 98/98/31 71/71/31
+f 99/99/17 71/71/17 98/98/17
+f 132/132/59 98/98/59 130/130/59
+f 100/100/39 98/98/39 132/132/39
+f 133/133/32 75/75/32 102/102/32
+f 102/102/60 134/134/60 133/133/60
+f 75/75/32 77/77/32 102/102/32
+f 102/102/61 77/77/61 103/103/61
+f 105/105/62 135/135/62 102/102/62
+f 102/102/60 135/135/60 134/134/60
+f 136/136/63 108/108/63 117/117/63
+f 117/117/64 108/108/64 110/110/64
+f 119/119/42 109/109/42 108/108/42
+f 119/119/65 108/108/65 137/137/65
+f 138/138/63 108/108/63 136/136/63
+f 137/137/65 108/108/65 138/138/65
+f 120/120/45 113/113/45 112/112/45
+f 112/112/66 139/139/66 120/120/66
+f 112/112/46 114/114/46 122/122/46
+f 140/140/67 112/112/67 122/122/67
+f 112/112/66 141/141/66 139/139/66
+f 141/141/67 112/112/67 140/140/67
+f 125/125/68 142/142/68 143/143/68
+f 125/125/49 143/143/49 118/118/49
+f 65/65/50 125/125/50 118/118/50
+f 125/125/68 126/126/68 142/142/68
+f 69/69/69 144/144/69 128/128/69
+f 145/145/70 128/128/70 144/144/70
+f 146/146/58 129/129/58 128/128/58
+f 146/146/70 128/128/70 145/145/70
+f 147/147/71 148/148/71 131/131/71
+f 131/131/53 121/121/53 147/147/53
+f 130/130/59 131/131/59 148/148/59
+f 131/131/31 71/71/31 121/121/31
+f 133/133/72 149/149/72 150/150/72
+f 150/150/54 123/123/54 133/133/54
+f 124/124/32 75/75/32 133/133/32
+f 149/149/72 133/133/72 134/134/72
+f 123/123/54 124/124/54 133/133/54
+f 117/117/73 143/143/73 151/151/73
+f 151/151/63 136/136/63 117/117/63
+f 117/117/49 118/118/49 143/143/49
+f 152/152/74 119/119/74 153/153/74
+f 153/153/65 119/119/65 137/137/65
+f 144/144/74 119/119/74 152/152/74
+f 69/69/69 119/119/69 144/144/69
+f 120/120/75 154/154/75 155/155/75
+f 120/120/66 139/139/66 154/154/66
+f 155/155/75 147/147/75 120/120/75
+f 147/147/53 121/121/53 120/120/53
+f 156/156/76 122/122/76 157/157/76
+f 156/156/67 140/140/67 122/122/67
+f 122/122/54 123/123/54 150/150/54
+f 157/157/76 122/122/76 150/150/76
+f 158/158/77 159/159/77 160/160/77
+f 161/161/34 159/159/34 158/158/34
+f 162/162/78 159/159/78 163/163/78
+f 163/163/35 159/159/35 164/164/35
+f 160/160/77 159/159/77 165/165/77
+f 165/165/78 159/159/78 162/162/78
+f 164/164/79 159/159/79 166/166/79
+f 161/161/34 166/166/34 159/159/34
+f 167/167/80 168/168/80 169/169/80
+f 169/169/38 168/168/38 95/95/38
+f 170/170/81 171/171/81 168/168/81
+f 172/172/41 168/168/41 171/171/41
+f 95/95/38 168/168/38 173/173/38
+f 173/173/82 168/168/82 172/172/82
+f 174/174/80 168/168/80 167/167/80
+f 168/168/81 174/174/81 170/170/81
+f 175/175/83 158/158/83 176/176/83
+f 177/177/36 158/158/36 175/175/36
+f 160/160/83 176/176/83 158/158/83
+f 91/91/36 158/158/36 177/177/36
+f 158/158/34 91/91/34 161/161/34
+f 178/178/84 169/169/84 179/179/84
+f 179/179/37 169/169/37 180/180/37
+f 169/169/84 178/178/84 181/181/84
+f 169/169/80 181/181/80 167/167/80
+f 180/180/37 169/169/37 95/95/37
+f 182/182/39 163/163/39 183/183/39
+f 184/184/85 163/163/85 182/182/85
+f 163/163/78 185/185/78 162/162/78
+f 163/163/35 164/164/35 183/183/35
+f 184/184/85 185/185/85 163/163/85
+f 186/186/86 171/171/86 187/187/86
+f 188/188/40 171/171/40 186/186/40
+f 170/170/81 187/187/81 171/171/81
+f 172/172/41 171/171/41 188/188/41
+f 153/153/87 138/138/87 141/141/87
+f 141/141/88 138/138/88 154/154/88
+f 154/154/88 138/138/88 151/151/88
+f 138/138/63 136/136/63 151/151/63
+f 153/153/65 137/137/65 138/138/65
+f 153/153/87 141/141/87 156/156/87
+f 139/139/66 141/141/66 154/154/66
+f 156/156/67 141/141/67 140/140/67
+f 154/154/89 151/151/89 189/189/89
+f 151/151/73 143/143/73 190/190/73
+f 151/151/89 190/190/89 189/189/89
+f 191/191/90 153/153/90 156/156/90
+f 191/191/74 152/152/74 153/153/74
+f 155/155/75 154/154/75 192/192/75
+f 192/192/89 154/154/89 189/189/89
+f 193/193/91 191/191/91 156/156/91
+f 156/156/92 157/157/92 193/193/92
+f 143/143/93 194/194/93 190/190/93
+f 195/195/68 143/143/68 142/142/68
+f 143/143/93 195/195/93 194/194/93
+f 144/144/74 152/152/74 191/191/74
+f 191/191/94 196/196/94 144/144/94
+f 196/196/94 197/197/94 144/144/94
+f 145/145/70 144/144/70 197/197/70
+f 192/192/95 198/198/95 147/147/95
+f 192/192/75 147/147/75 155/155/75
+f 198/198/95 199/199/95 147/147/95
+f 147/147/71 199/199/71 148/148/71
+f 193/193/96 157/157/96 150/150/96
+f 150/150/97 200/200/97 193/193/97
+f 149/149/72 201/201/72 150/150/72
+f 150/150/97 201/201/97 200/200/97
+f 127/127/57 175/175/57 202/202/57
+f 202/202/98 175/175/98 203/203/98
+f 176/176/83 203/203/83 175/175/83
+f 175/175/36 127/127/36 177/177/36
+f 146/146/99 204/204/99 179/179/99
+f 146/146/58 179/179/58 129/129/58
+f 204/204/99 205/205/99 179/179/99
+f 179/179/84 205/205/84 178/178/84
+f 129/129/37 179/179/37 180/180/37
+f 182/182/59 130/130/59 206/206/59
+f 207/207/100 182/182/100 206/206/100
+f 182/182/59 132/132/59 130/130/59
+f 183/183/39 132/132/39 182/182/39
+f 208/208/85 184/184/85 182/182/85
+f 208/208/100 182/182/100 207/207/100
+f 209/209/101 186/186/101 210/210/101
+f 134/134/60 186/186/60 209/209/60
+f 188/188/40 186/186/40 105/105/40
+f 186/186/102 135/135/102 105/105/102
+f 186/186/86 187/187/86 210/210/86
+f 135/135/60 186/186/60 134/134/60
+f 211/211/103 192/192/103 190/190/103
+f 189/189/89 190/190/89 192/192/89
+f 211/211/103 190/190/103 212/212/103
+f 190/190/93 194/194/93 212/212/93
+f 213/213/104 191/191/104 193/193/104
+f 214/214/105 191/191/105 213/213/105
+f 214/214/94 196/196/94 191/191/94
+f 211/211/95 198/198/95 192/192/95
+f 193/193/97 200/200/97 213/213/97
+f 195/195/106 202/202/106 215/215/106
+f 195/195/68 142/142/68 202/202/68
+f 215/215/106 202/202/106 216/216/106
+f 126/126/68 202/202/68 142/142/68
+f 127/127/57 202/202/57 126/126/57
+f 202/202/98 203/203/98 216/216/98
+f 217/217/107 146/146/107 197/197/107
+f 197/197/70 146/146/70 145/145/70
+f 146/146/99 217/217/99 204/204/99
+f 218/218/108 206/206/108 199/199/108
+f 206/206/71 148/148/71 199/199/71
+f 130/130/59 148/148/59 206/206/59
+f 219/219/108 206/206/108 218/218/108
+f 207/207/109 206/206/109 219/219/109
+f 201/201/110 209/209/110 220/220/110
+f 201/201/72 149/149/72 209/209/72
+f 220/220/110 209/209/110 221/221/110
+f 149/149/72 134/134/72 209/209/72
+f 221/221/101 209/209/101 210/210/101
+f 194/194/93 195/195/93 212/212/93
+f 212/212/111 195/195/111 222/222/111
+f 195/195/112 215/215/112 223/223/112
+f 222/222/111 195/195/111 223/223/111
+f 224/224/113 197/197/113 214/214/113
+f 214/214/94 197/197/94 196/196/94
+f 225/225/113 197/197/113 224/224/113
+f 197/197/107 225/225/107 217/217/107
+f 211/211/95 199/199/95 198/198/95
+f 226/226/114 199/199/114 211/211/114
+f 227/227/108 218/218/108 199/199/108
+f 226/226/114 227/227/114 199/199/114
+f 213/213/115 201/201/115 228/228/115
+f 200/200/97 201/201/97 213/213/97
+f 201/201/110 220/220/110 229/229/110
+f 228/228/116 201/201/116 229/229/116
+f 211/211/117 212/212/117 230/230/117
+f 231/231/111 212/212/111 222/222/111
+f 230/230/117 212/212/117 231/231/117
+f 232/232/118 214/214/118 213/213/118
+f 224/224/113 214/214/113 233/233/113
+f 233/233/118 214/214/118 232/232/118
+f 226/226/114 211/211/114 234/234/114
+f 211/211/117 230/230/117 234/234/117
+f 213/213/116 228/228/116 235/235/116
+f 232/232/118 213/213/118 235/235/118
+f 236/236/119 237/237/119 238/238/119
+f 236/236/80 238/238/80 239/239/80
+f 240/240/120 238/238/120 241/241/120
+f 242/242/81 238/238/81 240/240/81
+f 241/241/121 238/238/121 243/243/121
+f 243/243/119 238/238/119 237/237/119
+f 239/239/80 238/238/80 244/244/80
+f 238/238/81 242/242/81 244/244/81
+f 245/245/84 236/236/84 246/246/84
+f 247/247/122 236/236/122 245/245/122
+f 236/236/119 248/248/119 237/237/119
+f 248/248/122 236/236/122 247/247/122
+f 181/181/84 246/246/84 236/236/84
+f 236/236/80 239/239/80 181/181/80
+f 249/249/123 240/240/123 250/250/123
+f 251/251/86 240/240/86 249/249/86
+f 241/241/124 252/252/124 240/240/124
+f 253/253/81 242/242/81 240/240/81
+f 251/251/86 253/253/86 240/240/86
+f 240/240/125 252/252/125 250/250/125
+f 254/254/126 255/255/126 245/245/126
+f 254/254/127 245/245/127 256/256/127
+f 245/245/84 246/246/84 205/205/84
+f 245/245/99 205/205/99 256/256/99
+f 255/255/122 247/247/122 245/245/122
+f 257/257/128 249/249/128 258/258/128
+f 259/259/101 249/249/101 257/257/101
+f 210/210/86 251/251/86 249/249/86
+f 210/210/101 249/249/101 259/259/101
+f 249/249/129 250/250/129 260/260/129
+f 258/258/130 249/249/130 260/260/130
+f 261/261/131 254/254/131 225/225/131
+f 225/225/132 254/254/132 217/217/132
+f 261/261/131 262/262/131 254/254/131
+f 255/255/126 254/254/126 262/262/126
+f 254/254/133 256/256/133 217/217/133
+f 257/257/110 229/229/110 220/220/110
+f 229/229/134 257/257/134 263/263/134
+f 220/220/110 221/221/110 257/257/110
+f 263/263/134 257/257/134 264/264/134
+f 257/257/135 221/221/135 259/259/135
+f 264/264/128 257/257/128 258/258/128
+f 233/233/113 225/225/113 224/224/113
+f 265/265/136 225/225/136 233/233/136
+f 261/261/131 225/225/131 266/266/131
+f 265/265/136 266/266/136 225/225/136
+f 235/235/137 229/229/137 267/267/137
+f 235/235/116 228/228/116 229/229/116
+f 267/267/137 229/229/137 268/268/137
+f 263/263/134 268/268/134 229/229/134
+f 269/269/138 233/233/138 235/235/138
+f 235/235/118 233/233/118 232/232/118
+f 265/265/136 233/233/136 269/269/136
+f 235/235/138 270/270/138 269/269/138
+f 235/235/137 267/267/137 270/270/137
+f 234/234/139 231/231/139 271/271/139
+f 234/234/117 230/230/117 231/231/117
+f 272/272/140 231/231/140 223/223/140
+f 231/231/111 222/222/111 223/223/111
+f 271/271/140 231/231/140 272/272/140
+f 227/227/141 234/234/141 273/273/141
+f 227/227/114 226/226/114 234/234/114
+f 274/274/139 234/234/139 271/271/139
+f 273/273/142 234/234/142 274/274/142
+f 223/223/106 215/215/106 275/275/106
+f 275/275/143 276/276/143 223/223/143
+f 272/272/140 223/223/140 277/277/140
+f 223/223/143 276/276/143 277/277/143
+f 278/278/108 218/218/108 227/227/108
+f 279/279/144 278/278/144 227/227/144
+f 227/227/142 273/273/142 280/280/142
+f 279/279/144 227/227/144 280/280/144
+f 275/275/145 281/281/145 282/282/145
+f 275/275/98 203/203/98 281/281/98
+f 276/276/145 275/275/145 282/282/145
+f 215/215/106 216/216/106 275/275/106
+f 216/216/98 203/203/98 275/275/98
+f 283/283/146 278/278/146 284/284/146
+f 285/285/100 278/278/100 283/283/100
+f 286/286/146 284/284/146 278/278/146
+f 278/278/108 219/219/108 218/218/108
+f 286/286/144 278/278/144 279/279/144
+f 285/285/109 219/219/109 278/278/109
+f 287/287/83 288/288/83 281/281/83
+f 289/289/147 281/281/147 288/288/147
+f 282/282/147 281/281/147 289/289/147
+f 203/203/83 287/287/83 281/281/83
+f 283/283/148 290/290/148 291/291/148
+f 292/292/85 283/283/85 291/291/85
+f 290/290/148 283/283/148 284/284/148
+f 208/208/85 283/283/85 292/292/85
+f 208/208/100 285/285/100 283/283/100
+f 293/293/149 294/294/149 288/288/149
+f 293/293/77 288/288/77 295/295/77
+f 288/288/83 287/287/83 160/160/83
+f 295/295/77 288/288/77 160/160/77
+f 294/294/149 296/296/149 288/288/149
+f 296/296/147 289/289/147 288/288/147
+f 297/297/78 291/291/78 293/293/78
+f 298/298/150 293/293/150 291/291/150
+f 291/291/150 299/299/150 300/300/150
+f 300/300/150 298/298/150 291/291/150
+f 290/290/148 299/299/148 291/291/148
+f 291/291/85 185/185/85 292/292/85
+f 185/185/78 291/291/78 297/297/78
+f 293/293/149 301/301/149 294/294/149
+f 293/293/77 295/295/77 297/297/77
+f 298/298/150 301/301/150 293/293/150
+f 269/269/151 270/270/151 302/302/151
+f 270/270/137 267/267/137 268/268/137
+f 270/270/152 268/268/152 303/303/152
+f 304/304/152 270/270/152 303/303/152
+f 302/302/151 270/270/151 304/304/151
+f 266/266/136 265/265/136 269/269/136
+f 266/266/153 269/269/153 305/305/153
+f 305/305/153 269/269/153 306/306/153
+f 306/306/151 269/269/151 302/302/151
+f 307/307/154 274/274/154 271/271/154
+f 280/280/155 274/274/155 308/308/155
+f 273/273/142 274/274/142 280/280/142
+f 308/308/154 274/274/154 307/307/154
+f 271/271/140 272/272/140 277/277/140
+f 271/271/156 277/277/156 309/309/156
+f 271/271/156 309/309/156 307/307/156
+f 268/268/157 310/310/157 311/311/157
+f 310/310/134 268/268/134 264/264/134
+f 303/303/152 268/268/152 312/312/152
+f 312/312/157 268/268/157 311/311/157
+f 264/264/158 268/268/158 263/263/158
+f 313/313/159 314/314/159 280/280/159
+f 314/314/160 279/279/160 280/280/160
+f 280/280/155 308/308/155 315/315/155
+f 280/280/159 315/315/159 313/313/159
+f 316/316/131 261/261/131 266/266/131
+f 316/316/161 266/266/161 317/317/161
+f 318/318/153 266/266/153 305/305/153
+f 317/317/161 266/266/161 318/318/161
+f 277/277/143 276/276/143 319/319/143
+f 319/319/162 320/320/162 277/277/162
+f 309/309/156 277/277/156 321/321/156
+f 321/321/162 277/277/162 320/320/162
+f 322/322/163 323/323/163 310/310/163
+f 322/322/128 310/310/128 324/324/128
+f 323/323/163 325/325/163 310/310/163
+f 310/310/164 264/264/164 324/324/164
+f 311/311/157 310/310/157 325/325/157
+f 314/314/165 326/326/165 327/327/165
+f 314/314/146 327/327/146 284/284/146
+f 314/314/165 328/328/165 326/326/165
+f 314/314/146 284/284/146 286/286/146
+f 328/328/159 314/314/159 313/313/159
+f 314/314/144 286/286/144 279/279/144
+f 316/316/166 329/329/166 330/330/166
+f 330/330/126 255/255/126 316/316/126
+f 316/316/166 317/317/166 329/329/166
+f 261/261/131 316/316/131 262/262/131
+f 255/255/126 262/262/126 316/316/126
+f 319/319/145 282/282/145 331/331/145
+f 331/331/167 332/332/167 319/319/167
+f 319/319/145 276/276/145 282/282/145
+f 319/319/167 332/332/167 320/320/167
+f 306/306/168 304/304/168 333/333/168
+f 306/306/151 302/302/151 304/304/151
+f 334/334/169 304/304/169 312/312/169
+f 304/304/152 303/303/152 312/312/152
+f 334/334/169 333/333/169 304/304/169
+f 305/305/153 306/306/153 318/318/153
+f 318/318/170 306/306/170 335/335/170
+f 336/336/171 306/306/171 333/333/171
+f 335/335/172 306/306/172 336/336/172
+f 308/308/173 307/307/173 337/337/173
+f 337/337/174 315/315/174 308/308/174
+f 321/321/175 338/338/175 307/307/175
+f 307/307/156 309/309/156 321/321/156
+f 337/337/173 307/307/173 339/339/173
+f 307/307/175 338/338/175 339/339/175
+f 340/340/129 322/322/129 341/341/129
+f 342/342/176 322/322/176 340/340/176
+f 341/341/129 322/322/129 260/260/129
+f 323/323/163 322/322/163 343/343/163
+f 343/343/176 322/322/176 342/342/176
+f 322/322/177 324/324/177 260/260/177
+f 344/344/148 290/290/148 327/327/148
+f 327/327/178 345/345/178 344/344/178
+f 290/290/148 284/284/148 327/327/148
+f 345/345/178 327/327/178 346/346/178
+f 346/346/165 327/327/165 326/326/165
+f 347/347/179 348/348/179 330/330/179
+f 330/330/122 348/348/122 349/349/122
+f 330/330/179 350/350/179 347/347/179
+f 350/350/166 330/330/166 329/329/166
+f 330/330/122 349/349/122 255/255/122
+f 351/351/180 331/331/180 352/352/180
+f 352/352/147 331/331/147 353/353/147
+f 331/331/147 282/282/147 353/353/147
+f 332/332/180 331/331/180 351/351/180
+f 354/354/169 334/334/169 312/312/169
+f 355/355/181 354/354/181 312/312/181
+f 312/312/157 311/311/157 356/356/157
+f 356/356/181 355/355/181 312/312/181
+f 315/315/174 337/337/174 357/357/174
+f 315/315/182 357/357/182 358/358/182
+f 358/358/182 359/359/182 315/315/182
+f 313/313/159 315/315/159 359/359/159
+f 360/360/183 318/318/183 361/361/183
+f 335/335/170 361/361/170 318/318/170
+f 362/362/183 318/318/183 360/360/183
+f 362/362/161 317/317/161 318/318/161
+f 321/321/175 363/363/175 338/338/175
+f 363/363/184 321/321/184 364/364/184
+f 364/364/184 321/321/184 365/365/184
+f 365/365/162 321/321/162 320/320/162
+f 336/366/185 333/367/185 366/368/185
+f 367/369/186 333/367/186 368/370/186
+f 366/368/185 333/367/185 367/369/185
+f 354/371/169 333/367/169 334/372/169
+f 368/370/186 333/367/186 354/371/186
+f 367/369/187 337/337/187 339/339/187
+f 369/373/188 337/337/188 367/369/188
+f 357/357/188 337/337/188 369/373/188
+f 370/374/189 336/366/189 371/375/189
+f 371/375/185 336/366/185 366/368/185
+f 335/376/190 336/366/190 361/377/190
+f 361/377/189 336/366/189 370/374/189
+f 367/369/187 339/339/187 371/375/187
+f 371/375/191 339/339/191 372/378/191
+f 338/338/175 363/363/175 339/339/175
+f 372/378/191 339/339/191 363/363/191
+f 371/375/185 366/368/185 367/369/185
+f 369/373/188 367/369/188 373/379/188
+f 373/379/186 367/369/186 368/370/186
+f 371/375/191 372/378/191 374/380/191
+f 374/380/189 370/374/189 371/375/189
+f 375/381/192 340/340/192 376/382/192
+f 377/383/121 376/382/121 340/340/121
+f 340/340/129 341/341/129 378/384/129
+f 340/340/121 378/384/121 377/383/121
+f 342/342/192 340/340/192 375/381/192
+f 379/385/119 348/348/119 376/382/119
+f 376/382/193 348/348/193 380/386/193
+f 381/387/179 348/348/179 347/347/179
+f 248/248/119 348/348/119 379/385/119
+f 349/349/122 348/348/122 248/248/122
+f 380/386/193 348/348/193 381/387/193
+f 382/388/150 383/389/150 344/344/150
+f 382/388/194 344/344/194 384/390/194
+f 299/299/148 290/290/148 344/344/148
+f 344/344/150 383/389/150 299/299/150
+f 345/345/178 385/391/178 344/344/178
+f 384/390/194 344/344/194 385/391/194
+f 352/352/149 386/392/149 382/388/149
+f 387/393/195 352/352/195 382/388/195
+f 351/351/195 352/352/195 387/393/195
+f 352/352/147 353/353/147 388/394/147
+f 352/352/149 388/394/149 386/392/149
+f 389/395/119 379/385/119 376/382/119
+f 389/395/121 376/382/121 377/383/121
+f 375/381/192 376/382/192 390/396/192
+f 390/396/193 376/382/193 380/386/193
+f 382/388/150 391/397/150 383/389/150
+f 386/392/149 391/397/149 382/388/149
+f 382/388/195 384/390/195 387/393/195
+f 354/371/196 392/398/196 373/379/196
+f 373/379/186 368/370/186 354/371/186
+f 354/371/196 393/399/196 394/400/196
+f 355/401/181 393/399/181 354/371/181
+f 354/371/197 394/400/197 392/398/197
+f 373/379/198 395/402/198 357/357/198
+f 373/379/188 357/357/188 369/373/188
+f 358/358/182 357/357/182 396/403/182
+f 395/402/198 396/403/198 357/357/198
+f 374/380/199 397/404/199 361/377/199
+f 361/377/189 370/374/189 374/380/189
+f 360/405/183 361/377/183 398/406/183
+f 397/404/200 398/406/200 361/377/200
+f 374/380/191 372/378/191 363/363/191
+f 363/363/201 399/407/201 374/380/201
+f 363/363/202 400/408/202 399/407/202
+f 400/408/184 363/363/184 364/364/184
+f 356/356/163 323/323/163 401/409/163
+f 402/410/203 356/356/203 401/409/203
+f 323/323/163 356/356/163 325/325/163
+f 311/311/157 325/325/157 356/356/157
+f 355/355/203 356/356/203 402/410/203
+f 403/411/204 359/359/204 404/412/204
+f 403/411/165 326/326/165 359/359/165
+f 404/412/204 359/359/204 405/413/204
+f 328/328/165 359/359/165 326/326/165
+f 405/413/182 359/359/182 358/358/182
+f 359/359/159 328/328/159 313/313/159
+f 406/414/166 329/329/166 362/362/166
+f 362/362/205 407/415/205 406/414/205
+f 317/317/166 362/362/166 329/329/166
+f 362/362/205 408/416/205 407/415/205
+f 408/416/205 362/362/205 409/417/205
+f 409/417/183 362/362/183 360/360/183
+f 410/418/206 411/419/206 365/365/206
+f 365/365/167 332/332/167 410/418/167
+f 364/364/206 365/365/206 411/419/206
+f 320/320/167 332/332/167 365/365/167
+f 412/420/198 395/402/198 373/379/198
+f 373/379/196 392/398/196 412/420/196
+f 413/421/199 397/404/199 374/380/199
+f 374/380/202 399/407/202 413/421/202
+f 414/422/176 401/409/176 415/423/176
+f 416/424/207 401/409/207 414/422/207
+f 323/323/163 343/343/163 401/409/163
+f 401/409/176 343/343/176 415/423/176
+f 416/424/207 402/410/207 401/409/207
+f 417/425/178 418/426/178 403/411/178
+f 417/425/208 403/411/208 419/427/208
+f 418/426/178 346/346/178 403/411/178
+f 403/411/208 420/428/208 419/427/208
+f 404/412/204 420/428/204 403/411/204
+f 403/411/165 346/346/165 326/326/165
+f 381/387/179 406/414/179 421/429/179
+f 421/429/209 406/414/209 422/430/209
+f 381/387/179 350/350/179 406/414/179
+f 406/414/166 350/350/166 329/329/166
+f 406/414/209 407/415/209 422/430/209
+f 423/431/210 410/418/210 424/432/210
+f 424/432/180 410/418/180 332/332/180
+f 423/431/210 425/433/210 410/418/210
+f 410/418/206 425/433/206 411/419/206
+f 393/434/203 402/410/203 426/435/203
+f 427/436/211 393/399/211 426/437/211
+f 393/434/203 355/355/203 402/410/203
+f 428/438/211 393/399/211 427/436/211
+f 394/400/196 393/399/196 428/438/196
+f 396/403/204 429/439/204 404/412/204
+f 429/439/212 396/403/212 430/440/212
+f 404/412/204 405/413/204 396/403/204
+f 430/440/212 396/403/212 431/441/212
+f 396/403/182 405/413/182 358/358/182
+f 431/441/198 396/403/198 395/402/198
+f 432/442/213 408/443/213 398/406/213
+f 398/406/214 433/444/214 432/442/214
+f 408/443/215 409/445/215 398/406/215
+f 409/445/183 360/405/183 398/406/183
+f 434/446/216 398/406/216 397/404/216
+f 398/406/217 434/446/217 433/444/217
+f 400/408/206 411/419/206 435/447/206
+f 435/447/218 436/448/218 400/408/218
+f 400/408/206 364/364/206 411/419/206
+f 399/407/218 400/408/218 436/448/218
+f 437/449/212 430/440/212 412/420/212
+f 437/449/211 412/420/211 427/436/211
+f 430/440/212 431/441/212 412/420/212
+f 412/420/198 431/441/198 395/402/198
+f 412/420/211 428/438/211 427/436/211
+f 392/398/196 428/438/196 412/420/196
+f 413/421/218 436/448/218 438/450/218
+f 438/450/219 433/444/219 413/421/219
+f 413/421/218 399/407/218 436/448/218
+f 413/421/199 434/446/199 397/404/199
+f 434/446/219 413/421/219 433/444/219
+f 439/451/220 440/452/220 414/422/220
+f 414/422/192 441/453/192 439/451/192
+f 416/424/220 414/422/220 440/452/220
+f 414/422/192 442/454/192 441/453/192
+f 415/423/176 442/454/176 414/422/176
+f 443/455/193 421/429/193 439/451/193
+f 439/451/221 421/429/221 444/456/221
+f 381/387/193 421/429/193 443/455/193
+f 445/457/209 421/429/209 422/430/209
+f 444/456/221 421/429/221 445/457/221
+f 446/458/194 447/459/194 417/425/194
+f 417/425/222 448/460/222 446/458/222
+f 447/459/194 385/391/194 417/425/194
+f 417/425/178 385/391/178 418/426/178
+f 419/427/208 449/461/208 417/425/208
+f 417/425/222 449/461/222 448/460/222
+f 450/462/223 424/432/223 446/458/223
+f 424/432/195 451/463/195 446/458/195
+f 452/464/210 423/431/210 424/432/210
+f 452/464/223 424/432/223 450/462/223
+f 332/332/180 351/351/180 424/432/180
+f 424/432/195 351/351/195 451/463/195
+f 439/451/220 453/465/220 440/452/220
+f 454/466/193 443/455/193 439/451/193
+f 441/453/192 454/466/192 439/451/192
+f 444/456/221 453/465/221 439/451/221
+f 455/467/194 447/459/194 446/458/194
+f 450/462/223 446/458/223 456/468/223
+f 446/458/222 448/460/222 456/468/222
+f 455/467/195 446/458/195 451/463/195
+f 457/469/224 426/437/224 458/470/224
+f 426/437/207 416/471/207 458/470/207
+f 427/436/224 426/437/224 457/469/224
+f 402/410/207 416/424/207 426/435/207
+f 429/439/225 459/472/225 460/473/225
+f 460/473/208 449/461/208 429/439/208
+f 429/439/225 430/440/225 459/472/225
+f 404/412/204 429/439/204 420/428/204
+f 429/439/208 449/461/208 420/428/208
+f 461/474/226 462/475/226 432/442/226
+f 462/475/209 463/476/209 432/442/209
+f 408/443/205 432/442/205 407/477/205
+f 407/477/209 432/442/209 463/476/209
+f 432/442/226 433/444/226 461/474/226
+f 464/478/210 435/447/210 452/464/210
+f 464/478/227 465/479/227 435/447/227
+f 425/433/206 435/447/206 411/419/206
+f 435/447/218 466/480/218 436/448/218
+f 452/464/210 435/447/210 425/433/210
+f 435/447/227 465/479/227 466/480/227
+f 467/481/225 468/482/225 437/449/225
+f 467/481/224 437/449/224 469/483/224
+f 437/449/225 468/482/225 430/440/225
+f 469/483/224 437/449/224 427/436/224
+f 470/484/227 438/450/227 471/485/227
+f 472/486/226 438/450/226 470/484/226
+f 466/480/227 471/485/227 438/450/227
+f 466/480/218 438/450/218 436/448/218
+f 438/450/226 472/486/226 433/444/226
+f 473/487/220 458/470/220 474/488/220
+f 458/470/228 473/487/228 475/489/228
+f 474/488/220 458/470/220 416/471/220
+f 458/470/224 476/490/224 457/469/224
+f 458/470/228 475/489/228 476/490/228
+f 477/491/229 460/473/229 478/492/229
+f 477/491/222 479/493/222 460/473/222
+f 459/472/225 480/494/225 460/473/225
+f 478/492/229 460/473/229 480/494/229
+f 479/493/222 449/461/222 460/473/222
+f 473/487/230 462/475/230 481/495/230
+f 482/496/221 462/475/221 473/487/221
+f 462/475/226 461/474/226 483/497/226
+f 462/475/230 483/497/230 481/495/230
+f 482/496/221 445/498/221 462/475/221
+f 462/475/209 445/498/209 463/476/209
+f 464/478/223 484/499/223 477/491/223
+f 485/500/231 464/478/231 477/491/231
+f 464/478/231 485/500/231 471/485/231
+f 464/478/227 471/485/227 465/479/227
+f 464/478/223 452/464/223 484/499/223
+f 486/501/220 473/487/220 474/488/220
+f 482/496/221 473/487/221 486/501/221
+f 481/495/230 487/502/230 473/487/230
+f 475/489/228 473/487/228 487/502/228
+f 484/499/223 488/503/223 477/491/223
+f 478/492/232 489/504/232 477/491/232
+f 477/491/231 489/504/231 485/500/231
+f 488/503/222 479/493/222 477/491/222
+f 490/505/229 491/506/229 467/481/229
+f 467/481/228 492/507/228 490/505/228
+f 491/506/229 468/482/229 467/481/229
+f 493/508/228 492/507/228 467/481/228
+f 469/483/224 493/508/224 467/481/224
+f 470/484/231 494/509/231 490/505/231
+f 495/510/230 470/484/230 490/505/230
+f 471/485/231 494/509/231 470/484/231
+f 483/497/226 472/486/226 470/484/226
+f 483/497/230 470/484/230 495/510/230
+f 494/509/231 496/511/231 490/505/231
+f 490/505/229 496/511/229 491/506/229
+f 497/512/228 490/505/228 492/507/228
+f 497/512/230 495/510/230 490/505/230
+f 378/384/129 341/341/129 252/252/129
+f 252/252/129 341/341/129 260/260/129
+f 486/513/220 416/424/220 440/452/220
+f 453/465/220 486/513/220 440/452/220
+f 381/387/193 443/455/193 454/466/193
+f 350/350/179 381/387/179 347/347/179
+f 430/440/225 468/482/225 459/472/225
+f 459/472/225 468/482/225 480/494/225
+f 383/389/150 300/300/150 299/299/150
+f 300/300/150 391/397/150 301/301/150
+f 383/389/150 391/397/150 300/300/150
+f 300/300/150 301/301/150 298/298/150
+f 384/390/194 447/459/194 455/467/194
+f 384/390/194 385/391/194 447/459/194
+f 26/26/9 85/85/9 86/86/9
+f 86/86/9 40/40/9 21/21/9
+f 86/86/9 81/81/9 40/40/9
+f 86/86/9 21/21/9 26/26/9
+f 484/499/223 450/462/223 456/468/223
+f 448/460/222 449/461/222 456/468/222
+f 456/468/222 449/461/222 479/493/222
+f 484/499/223 456/468/223 488/503/223
+f 456/468/222 479/493/222 488/503/222
+f 455/467/195 451/463/195 387/393/195
+f 384/390/195 455/467/195 387/393/195
+f 49/49/10 84/84/10 85/85/10
+f 49/49/10 85/85/10 24/24/10
+f 27/27/11 85/85/11 26/26/11
+f 24/24/10 85/85/10 27/27/10
+f 380/386/193 381/387/193 454/466/193
+f 342/342/192 454/466/192 441/453/192
+f 342/342/192 375/381/192 454/466/192
+f 375/381/192 390/396/192 454/466/192
+f 390/396/193 380/386/193 454/466/193
+f 486/501/220 474/488/220 416/471/220
+f 445/457/221 486/513/221 444/456/221
+f 445/498/221 482/496/221 486/501/221
+f 444/456/221 486/513/221 453/465/221
+f 96/96/233 173/173/233 106/106/233
+f 106/106/234 173/173/234 172/172/234
+f 95/95/38 173/173/38 96/96/38
+f 466/480/227 465/479/227 471/485/227
+f 471/485/231 489/504/231 494/509/231
+f 485/500/231 489/504/231 471/485/231
+f 287/287/83 176/176/83 160/160/83
+f 165/165/77 295/295/77 160/160/77
+f 248/248/119 379/385/119 389/395/119
+f 389/395/119 237/237/119 248/248/119
+f 349/349/122 248/248/122 255/255/122
+f 248/248/122 247/247/122 255/255/122
+f 181/181/84 178/178/84 246/246/84
+f 181/181/80 239/239/80 167/167/80
+f 385/391/178 345/345/178 346/346/178
+f 385/391/178 346/346/178 418/426/178
+f 12/12/2 30/30/2 11/11/2
+f 43/43/5 12/12/5 59/59/5
+f 12/12/5 8/8/5 59/59/5
+f 483/497/226 461/474/226 472/486/226
+f 483/497/230 495/510/230 481/495/230
+f 44/44/16 41/41/16 70/70/16
+f 44/44/16 70/70/16 94/94/16
+f 452/464/210 425/433/210 423/431/210
+f 49/49/17 71/71/17 99/99/17
+f 419/427/208 420/428/208 449/461/208
+f 217/217/99 205/205/99 204/204/99
+f 115/115/22 63/63/22 61/61/22
+f 59/59/235 58/58/235 67/67/235
+f 498/514/35 87/87/35 82/82/35
+f 82/82/35 101/101/35 498/514/35
+f 87/87/34 499/515/34 79/79/34
+f 499/515/34 91/91/34 79/79/34
+f 162/162/78 185/185/78 165/165/78
+f 106/106/40 188/188/40 105/105/40
+f 172/172/41 188/188/41 106/106/41
+f 30/30/2 35/35/2 11/11/2
+f 7/7/2 11/11/2 35/35/2
+f 4/4/2 11/11/2 7/7/2
+f 353/353/147 282/282/147 296/296/147
+f 282/282/147 289/289/147 296/296/147
+f 407/477/209 463/476/209 422/516/209
+f 183/183/39 100/100/39 132/132/39
+f 13/13/6 39/39/6 57/57/6
+f 13/13/6 57/57/6 10/10/6
+f 57/57/6 39/39/6 38/38/6
+f 415/423/176 343/343/176 342/342/176
+f 77/77/236 52/52/236 103/103/236
+f 71/71/17 49/49/17 47/47/17
+f 14/14/7 63/63/7 17/17/7
+f 17/17/7 63/63/7 46/46/7
+f 73/73/22 63/63/22 115/115/22
+f 53/53/13 32/32/13 500/517/13
+f 53/53/13 500/517/13 107/107/13
+f 107/107/13 54/54/13 53/53/13
+f 116/116/23 62/62/23 76/76/23
+f 324/324/237 264/264/237 260/260/237
+f 52/52/18 54/54/18 103/103/18
+f 87/87/34 166/166/34 499/515/34
+f 161/161/34 91/91/34 499/515/34
+f 499/515/34 166/166/34 161/161/34
+f 96/96/12 500/517/12 97/97/12
+f 107/107/13 500/517/13 96/96/13
+f 177/177/36 89/89/36 91/91/36
+f 177/177/36 127/127/36 89/89/36
+f 164/164/35 87/87/35 498/514/35
+f 183/183/35 164/164/35 498/514/35
+f 498/514/35 101/101/35 183/183/35
+f 166/166/238 87/87/238 164/164/238
+f 176/176/83 287/287/83 203/203/83
+f 442/454/192 342/342/192 441/453/192
+f 205/205/84 246/246/84 178/178/84
+f 167/167/80 239/239/80 174/174/80
+f 170/170/81 253/253/81 187/187/81
+f 210/210/86 187/187/86 253/253/86
+f 16/16/8 55/55/8 51/51/8
+f 55/55/4 16/16/4 34/34/4
+f 378/384/121 252/252/121 377/383/121
+f 46/46/7 48/48/7 17/17/7
+f 22/22/3 17/17/3 48/48/3
+f 478/492/229 480/494/229 468/482/229
+f 242/242/81 170/170/81 174/174/81
+f 170/170/81 242/242/81 253/253/81
+f 13/13/1 25/25/1 18/18/1
+f 39/39/1 13/13/1 18/18/1
+f 494/509/231 489/504/231 496/511/231
+f 241/241/121 243/243/121 389/395/121
+f 389/395/121 377/383/121 241/241/121
+f 377/383/121 252/252/121 241/241/121
+f 391/397/149 296/296/149 294/294/149
+f 301/301/149 391/397/149 294/294/149
+f 463/476/209 445/498/209 422/516/209
+f 433/444/226 472/486/226 461/474/226
+f 491/506/229 496/511/229 468/482/229
+f 497/512/230 487/502/230 481/495/230
+f 481/495/230 495/510/230 497/512/230
+f 475/489/228 492/507/228 493/508/228
+f 487/502/228 497/512/228 492/507/228
+f 475/489/228 487/502/228 492/507/228
+f 25/25/1 13/13/1 3/3/1
+f 25/25/3 6/6/3 17/17/3
+f 25/25/3 17/17/3 22/22/3
+f 25/25/239 3/3/239 6/6/239
+f 501/518/4 7/7/4 35/35/4
+f 34/34/4 501/518/4 35/35/4
+f 16/16/8 51/51/8 62/62/8
+f 16/16/4 7/7/4 501/518/4
+f 34/34/4 16/16/4 501/518/4
+f 40/40/15 90/90/15 36/36/15
+f 36/36/15 90/90/15 66/66/15
+f 40/40/15 81/81/15 90/90/15
+f 100/100/240 183/183/240 101/101/240
+f 129/129/37 180/180/37 95/95/37
+f 415/423/176 342/342/176 442/454/176
+f 31/31/12 97/97/12 500/517/12
+f 31/31/12 500/517/12 32/32/12
+f 44/44/12 97/97/12 31/31/12
+f 484/499/223 452/464/223 450/462/223
+f 165/165/78 185/185/78 297/297/78
+f 297/297/77 295/295/77 165/165/77
+f 239/239/80 244/244/80 174/174/80
+f 244/244/81 242/242/81 174/174/81
+f 208/208/85 185/185/85 184/184/85
+f 292/292/85 185/185/85 208/208/85
+f 210/210/86 253/253/86 251/251/86
+f 256/256/99 205/205/99 217/217/99
+f 208/208/100 207/207/100 219/219/100
+f 208/208/100 219/219/100 285/285/100
+f 259/259/101 221/221/101 210/210/101
+f 389/395/119 243/243/119 237/237/119
+f 250/250/129 252/252/129 260/260/129
+f 264/264/241 258/258/241 260/260/241
+f 386/392/149 296/296/149 391/397/149
+f 388/394/147 353/353/147 296/296/147
+f 388/394/149 296/296/149 386/392/149
+f 451/463/195 351/351/195 387/393/195
+f 457/469/224 493/508/224 427/436/224
+f 476/490/224 493/508/224 457/469/224
+f 427/436/224 493/508/224 469/483/224
+f 476/490/228 475/489/228 493/508/228
+f 496/511/242 489/504/242 468/482/242
+f 489/504/243 478/492/243 468/482/243
+f 394/400/197 428/438/197 392/398/197
diff --git a/examples/DeformableDemo/LoadDeformed.cpp b/examples/DeformableDemo/LoadDeformed.cpp
new file mode 100644
index 000000000..55c322779
--- /dev/null
+++ b/examples/DeformableDemo/LoadDeformed.cpp
@@ -0,0 +1,261 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "LoadDeformed.h"
+///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
+#include "btBulletDynamicsCommon.h"
+#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
+#include "BulletSoftBody/btSoftBody.h"
+#include "BulletSoftBody/btSoftBodyHelpers.h"
+#include "BulletSoftBody/btDeformableBodySolver.h"
+#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
+#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
+#include "../CommonInterfaces/CommonParameterInterface.h"
+#include <stdio.h> //printf debugging
+
+#include "../CommonInterfaces/CommonDeformableBodyBase.h"
+#include "../Utils/b3ResourcePath.h"
+#include "../Utils/b3BulletDefaultFileIO.h"
+
+class LoadDeformed : public CommonDeformableBodyBase
+{
+ int steps;
+ btSoftBody* psb;
+ char filename;
+ int reset_frame;
+ float sim_time;
+
+public:
+ LoadDeformed(struct GUIHelperInterface* helper)
+ : CommonDeformableBodyBase(helper)
+ {
+ steps = 0;
+ psb = nullptr;
+ reset_frame = 0;
+ sim_time = 0;
+ }
+ virtual ~LoadDeformed()
+ {
+ }
+ void initPhysics();
+
+ void exitPhysics();
+
+ void resetCamera()
+ {
+ float dist = 2;
+ float pitch = -45;
+ float yaw = 100;
+ float targetPos[3] = {0, 0, 0};
+ m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
+ }
+
+ void stepSimulation(float deltaTime)
+ {
+ steps++;
+ sim_time += deltaTime;
+ //// int seconds = 1/deltaTime;
+ if (0)
+ {
+ // if (reset_frame==0 && steps<100){
+ //// printf("steps %d, seconds %d, steps/seconds %d\n", steps,seconds,steps/seconds);
+ char filename[100];
+ sprintf(filename, "%s_%d_%d.txt", "states", reset_frame, steps);
+ btSoftBodyHelpers::writeState(filename, psb);
+ }
+ if (sim_time + reset_frame * 0.05 >= 5) exit(0);
+ float internalTimeStep = 1. / 240.f;
+ // float internalTimeStep = 0.1f;
+ m_dynamicsWorld->stepSimulation(deltaTime, deltaTime / internalTimeStep, internalTimeStep);
+ }
+
+ void addCloth(const btVector3& origin);
+
+ virtual void renderScene()
+ {
+ CommonDeformableBodyBase::renderScene();
+ btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
+
+ for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
+ {
+ btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
+ {
+ btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
+ btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
+ }
+ }
+ }
+};
+
+void LoadDeformed::initPhysics()
+{
+ m_guiHelper->setUpAxis(1);
+
+ ///collision configuration contains default setup for memory, collision setup
+ m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
+
+ ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
+ m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
+
+ m_broadphase = new btDbvtBroadphase();
+ btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
+
+ btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
+ sol->setDeformableSolver(deformableBodySolver);
+ m_solver = sol;
+
+ m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
+ btVector3 gravity = btVector3(0, -9.8, 0);
+ m_dynamicsWorld->setGravity(gravity);
+ getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
+ getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
+
+ m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
+
+ {
+ ///create a ground
+ btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(2.5), btScalar(150.)));
+ groundShape->setMargin(0.02);
+ m_collisionShapes.push_back(groundShape);
+
+ btTransform groundTransform;
+ groundTransform.setIdentity();
+ groundTransform.setOrigin(btVector3(0, -3.5, 0));
+ groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
+ btScalar mass(0.);
+
+ //rigidbody is dynamic if and only if mass is non zero, otherwise static
+ bool isDynamic = (mass != 0.f);
+
+ btVector3 localInertia(0, 0, 0);
+ if (isDynamic)
+ groundShape->calculateLocalInertia(mass, localInertia);
+
+ //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
+ btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
+ btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
+ btRigidBody* body = new btRigidBody(rbInfo);
+ body->setFriction(4);
+
+ //add the ground to the dynamics world
+ m_dynamicsWorld->addRigidBody(body);
+ }
+ addCloth(btVector3(0, 1, 0));
+ getDeformableDynamicsWorld()->setImplicit(false);
+ getDeformableDynamicsWorld()->setLineSearch(false);
+ m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
+}
+
+void LoadDeformed::addCloth(const btVector3& origin)
+// create a piece of cloth
+{
+ const btScalar s = 0.6;
+ const btScalar h = 0;
+
+ psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -2 * s),
+ btVector3(+s, h, -2 * s),
+ btVector3(-s, h, +2 * s),
+ btVector3(+s, h, +2 * s),
+ 15, 30,
+ 0, true, 0.0);
+
+ psb->getCollisionShape()->setMargin(0.02);
+ psb->generateBendingConstraints(2);
+ psb->setTotalMass(.5);
+ psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
+ psb->m_cfg.kCHR = 1; // collision hardness with rigid body
+ psb->m_cfg.kDF = 0.1;
+ psb->rotate(btQuaternion(0, SIMD_PI / 2, 0));
+ btTransform clothTransform;
+ clothTransform.setIdentity();
+ clothTransform.setOrigin(btVector3(0, 0.2, 0) + origin);
+ psb->transform(clothTransform);
+
+ b3BulletDefaultFileIO fileio;
+ char absolute_path[1024];
+ char filename[100];
+ sprintf(filename, "/Users/fuchuyuan/Documents/mybullet/build_cmake/examples/ExampleBrowser/states_0_%d.txt", reset_frame);
+ fileio.findResourcePath(filename, absolute_path, 1024);
+ btAlignedObjectArray<btVector3> qs;
+ btAlignedObjectArray<btVector3> vs;
+ btSoftBodyHelpers::loadDeformableState(qs, vs, absolute_path, &fileio);
+ if (reset_frame > 0)
+ psb->updateState(qs, vs);
+ psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
+ psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_MDF;
+ psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
+ // psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
+ psb->setCollisionFlags(0);
+ psb->setCacheBarycenter(true);
+ getDeformableDynamicsWorld()->addSoftBody(psb);
+ psb->setSelfCollision(false);
+
+ btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(2, 0.2, true);
+ psb->setSpringStiffness(4);
+ getDeformableDynamicsWorld()->addForce(psb, mass_spring);
+ m_forces.push_back(mass_spring);
+ btVector3 gravity = btVector3(0, -9.8, 0);
+ btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
+ getDeformableDynamicsWorld()->addForce(psb, gravity_force);
+ // getDeformableDynamicsWorld()->setUseProjection(true);
+ m_forces.push_back(gravity_force);
+}
+
+void LoadDeformed::exitPhysics()
+{
+ //cleanup in the reverse order of creation/initialization
+ removePickingConstraint();
+ //remove the rigidbodies from the dynamics world and delete them
+ int i;
+ for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
+ {
+ btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
+ btRigidBody* body = btRigidBody::upcast(obj);
+ if (body && body->getMotionState())
+ {
+ delete body->getMotionState();
+ }
+ m_dynamicsWorld->removeCollisionObject(obj);
+ delete obj;
+ }
+ // delete forces
+ for (int j = 0; j < m_forces.size(); j++)
+ {
+ btDeformableLagrangianForce* force = m_forces[j];
+ delete force;
+ }
+ m_forces.clear();
+
+ //delete collision shapes
+ for (int j = 0; j < m_collisionShapes.size(); j++)
+ {
+ btCollisionShape* shape = m_collisionShapes[j];
+ delete shape;
+ }
+ m_collisionShapes.clear();
+
+ delete m_dynamicsWorld;
+
+ delete m_solver;
+
+ delete m_broadphase;
+
+ delete m_dispatcher;
+
+ delete m_collisionConfiguration;
+}
+
+class CommonExampleInterface* LoadDeformedCreateFunc(struct CommonExampleOptions& options)
+{
+ return new LoadDeformed(options.m_guiHelper);
+}
diff --git a/examples/DeformableDemo/LoadDeformed.h b/examples/DeformableDemo/LoadDeformed.h
new file mode 100644
index 000000000..b2c1a1598
--- /dev/null
+++ b/examples/DeformableDemo/LoadDeformed.h
@@ -0,0 +1,19 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef _LOAD_DEFORMED_H
+#define _LOAD_DEFORMED_H
+
+class CommonExampleInterface* LoadDeformedCreateFunc(struct CommonExampleOptions& options);
+
+#endif //_LOAD_DEFORMED_H
diff --git a/examples/ExampleBrowser/CMakeLists.txt b/examples/ExampleBrowser/CMakeLists.txt
index 4e40d7072..6271ca915 100644
--- a/examples/ExampleBrowser/CMakeLists.txt
+++ b/examples/ExampleBrowser/CMakeLists.txt
@@ -379,6 +379,8 @@ SET(BulletExampleBrowser_SRCS
../DeformableDemo/Collide.cpp
../DeformableDemo/Collide.h
../DeformableDemo/LargeDeformation.cpp
+ ../DeformableDemo/LoadDeformed.h
+ ../DeformableDemo/LoadDeformed.cpp
../DeformableDemo/LargeDeformation.h
../DeformableDemo/DeformableClothAnchor.cpp
../DeformableDemo/DeformableClothAnchor.h
@@ -388,6 +390,24 @@ SET(BulletExampleBrowser_SRCS
../MultiBody/MultiDofDemo.h
../RigidBody/RigidBodySoftContact.cpp
../RigidBody/KinematicRigidBodyExample.cpp
+ ../ReducedDeformableDemo/ConservationTest.cpp
+ ../ReducedDeformableDemo/ConservationTest.h
+ ../ReducedDeformableDemo/Springboard.cpp
+ ../ReducedDeformableDemo/Springboard.h
+ ../ReducedDeformableDemo/ModeVisualizer.cpp
+ ../ReducedDeformableDemo/ModeVisualizer.h
+ ../ReducedDeformableDemo/FreeFall.cpp
+ ../ReducedDeformableDemo/FreeFall.h
+ ../ReducedDeformableDemo/FrictionSlope.cpp
+ ../ReducedDeformableDemo/FrictionSlope.h
+ ../ReducedDeformableDemo/ReducedCollide.cpp
+ ../ReducedDeformableDemo/ReducedCollide.h
+ ../ReducedDeformableDemo/ReducedGrasp.cpp
+ ../ReducedDeformableDemo/ReducedGrasp.h
+ ../ReducedDeformableDemo/ReducedBenchmark.cpp
+ ../ReducedDeformableDemo/ReducedBenchmark.h
+ ../ReducedDeformableDemo/ReducedMotorGrasp.cpp
+ ../ReducedDeformableDemo/ReducedMotorGrasp.h
../Constraints/TestHingeTorque.cpp
../Constraints/TestHingeTorque.h
../Constraints/ConstraintDemo.cpp
diff --git a/examples/ExampleBrowser/ExampleEntries.cpp b/examples/ExampleBrowser/ExampleEntries.cpp
index 9f8ab035c..715a4396d 100644
--- a/examples/ExampleBrowser/ExampleEntries.cpp
+++ b/examples/ExampleBrowser/ExampleEntries.cpp
@@ -55,6 +55,7 @@
#include "../DeformableDemo/DeformableMultibody.h"
#include "../DeformableDemo/VolumetricDeformable.h"
#include "../DeformableDemo/LargeDeformation.h"
+#include "../DeformableDemo/LoadDeformed.h"
#include "../DeformableDemo/Collide.h"
#include "../DeformableDemo/GraspDeformable.h"
#include "../DeformableDemo/DeformableContact.h"
@@ -72,6 +73,15 @@
#include "../RoboticsLearning/R2D2GraspExample.h"
#include "../RoboticsLearning/KukaGraspExample.h"
#include "../RoboticsLearning/GripperGraspExample.h"
+#include "../ReducedDeformableDemo/ConservationTest.h"
+#include "../ReducedDeformableDemo/ModeVisualizer.h"
+#include "../ReducedDeformableDemo/Springboard.h"
+#include "../ReducedDeformableDemo/FreeFall.h"
+#include "../ReducedDeformableDemo/FrictionSlope.h"
+#include "../ReducedDeformableDemo/ReducedCollide.h"
+#include "../ReducedDeformableDemo/ReducedGrasp.h"
+#include "../ReducedDeformableDemo/ReducedMotorGrasp.h"
+#include "../ReducedDeformableDemo/ReducedBenchmark.h"
#include "../InverseKinematics/InverseKinematicsExample.h"
#ifdef B3_ENABLE_TINY_AUDIO
@@ -209,11 +219,24 @@ static ExampleEntry gDefaultExamples[] =
ExampleEntry(1, "Grasp Deformable with Motor", "Grasping test", GraspDeformableCreateFunc),
ExampleEntry(1, "Volumetric Deformable Objects", "Volumetric Deformable test", VolumetricDeformableCreateFunc),
ExampleEntry(1, "Extreme Deformation", "Recovery from extreme deformation", LargeDeformationCreateFunc),
+ ExampleEntry(1, "Load Deformed", "Reconstruct a deformed object", LoadDeformedCreateFunc),
ExampleEntry(1, "Colliding Test", "Volumetric deformable collide with rigid box", CollideCreateFunc),
ExampleEntry(1, "Rigid Cloth Anchor", "Deformable Rigid body Anchor test", DeformableClothAnchorCreateFunc),
ExampleEntry(1, "Multibody Cloth Anchor", "Deformable Multibody Anchor test", MultibodyClothAnchorCreateFunc),
ExampleEntry(1, "Deformable-MultiBody Contact", "MultiBody and Deformable contact", DeformableMultibodyCreateFunc),
// ExampleEntry(1, "MultiBody Baseline", "MultiBody Baseline", MultiBodyBaselineCreateFunc),
+
+ ExampleEntry(0, "Reduced Deformabe Body"),
+ ExampleEntry(1, "Mode Visualizer", "Visualizer the modes for reduced deformable objects", ReducedModeVisualizerCreateFunc),
+ ExampleEntry(1, "Reduced Conservation Test", "Momentum conservation test for the reduced deformable objects", ReducedConservationTestCreateFunc),
+ ExampleEntry(1, "Reduced Springboard", "Moving rigid object colliding with a fixed reduced deformable objects", ReducedSpringboardCreateFunc),
+ ExampleEntry(1, "Reduced Free Fall", "Free fall ground contact test for the reduced deformable model", ReducedFreeFallCreateFunc),
+ ExampleEntry(1, "Reduced Collision Test", "Collision between a reduced block and the a rigid block", ReducedCollideCreateFunc),
+ ExampleEntry(1, "Reduced Grasp", "Grasp a reduced deformable block", ReducedGraspCreateFunc),
+ ExampleEntry(1, "Reduced Motor Grasp", "Grasp a reduced deformable block with motor", ReducedMotorGraspCreateFunc),
+ ExampleEntry(1, "Reduced Friction Slope", "Grasp a reduced deformable block", FrictionSlopeCreateFunc),
+ ExampleEntry(1, "Reduced Benchmark", "Reduced deformable performance benchmark example", ReducedBenchmarkCreateFunc),
+ // ExampleEntry(1, "Simple Reduced Deformable Test", "Simple dynamics test for the reduced deformable objects", ReducedBasicTestCreateFunc),
#ifdef INCLUDE_CLOTH_DEMOS
ExampleEntry(0, "Soft Body"),
diff --git a/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp b/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp
index cb7607b1a..e24437d7d 100644
--- a/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp
+++ b/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp
@@ -1541,3 +1541,8 @@ const struct UrdfDeformable& BulletURDFImporter::getDeformableModel() const
{
return m_data->m_urdfParser.getDeformable();
}
+
+const struct UrdfReducedDeformable& BulletURDFImporter::getReducedDeformableModel() const
+{
+ return m_data->m_urdfParser.getReducedDeformable();
+}
diff --git a/examples/Importers/ImportURDFDemo/BulletUrdfImporter.h b/examples/Importers/ImportURDFDemo/BulletUrdfImporter.h
index 66bb908de..5fe7f8c5f 100644
--- a/examples/Importers/ImportURDFDemo/BulletUrdfImporter.h
+++ b/examples/Importers/ImportURDFDemo/BulletUrdfImporter.h
@@ -93,6 +93,7 @@ public:
virtual void setEnableTinyRenderer(bool enable);
void convertURDFToVisualShapeInternal(const struct UrdfVisual* visual, const char* urdfPathPrefix, const class btTransform& visualTransform, btAlignedObjectArray<struct GLInstanceVertex>& verticesOut, btAlignedObjectArray<int>& indicesOut, btAlignedObjectArray<struct BulletURDFTexture>& texturesOut, struct b3ImportMeshData& meshData) const;
const struct UrdfDeformable& getDeformableModel() const;
+ const struct UrdfReducedDeformable& getReducedDeformableModel() const;
};
#endif //BULLET_URDF_IMPORTER_H
diff --git a/examples/Importers/ImportURDFDemo/UrdfParser.cpp b/examples/Importers/ImportURDFDemo/UrdfParser.cpp
index 96f7538a2..aea391592 100644
--- a/examples/Importers/ImportURDFDemo/UrdfParser.cpp
+++ b/examples/Importers/ImportURDFDemo/UrdfParser.cpp
@@ -1282,6 +1282,171 @@ bool UrdfParser::parseDeformable(UrdfModel& model, tinyxml2::XMLElement* config,
return true;
}
+bool UrdfParser::parseReducedDeformable(UrdfModel& model, tinyxml2::XMLElement* config, ErrorLogger* logger)
+{
+ UrdfReducedDeformable& reduced_deformable = model.m_reducedDeformable;
+ const char* name = config->Attribute("name");
+ if (!name)
+ {
+ logger->reportError("Reduced deformable with no name");
+ return false;
+ }
+ reduced_deformable.m_name = name;
+
+ {
+ XMLElement* numModes_xml = config->FirstChildElement("num_modes");
+ if (numModes_xml)
+ {
+ if (!numModes_xml->Attribute("value"))
+ {
+ logger->reportError("numModes_xml element must have value attribute");
+ return false;
+ }
+ reduced_deformable.m_numModes = urdfLexicalCast<double>(numModes_xml->Attribute("value"));
+ }
+ }
+
+ {
+ XMLElement* mass_xml = config->FirstChildElement("mass");
+ if (mass_xml)
+ {
+ if (!mass_xml->Attribute("value"))
+ {
+ logger->reportError("mass_xml element must have value attribute");
+ return false;
+ }
+ reduced_deformable.m_mass = urdfLexicalCast<double>(mass_xml->Attribute("value"));
+ }
+ }
+
+ {
+ XMLElement* stiffnessScale_xml = config->FirstChildElement("stiffness_scale");
+ if (stiffnessScale_xml)
+ {
+ if (!stiffnessScale_xml->Attribute("value"))
+ {
+ logger->reportError("stiffnessScale_xml element must have value attribute");
+ return false;
+ }
+ reduced_deformable.m_stiffnessScale = urdfLexicalCast<double>(stiffnessScale_xml->Attribute("value"));
+ }
+ }
+
+ {
+ XMLElement* collisionMargin_xml = config->FirstChildElement("collision_margin");
+ if (collisionMargin_xml)
+ {
+ if (!collisionMargin_xml->Attribute("value"))
+ {
+ logger->reportError("collision_margin element must have value attribute");
+ return false;
+ }
+ reduced_deformable.m_collisionMargin = urdfLexicalCast<double>(collisionMargin_xml->Attribute("value"));
+ }
+ }
+
+ {
+ XMLElement* erp_xml = config->FirstChildElement("erp");
+ if (erp_xml)
+ {
+ if (!erp_xml->Attribute("value"))
+ {
+ logger->reportError("friction element must have value attribute");
+ return false;
+ }
+ reduced_deformable.m_erp = urdfLexicalCast<double>(erp_xml->Attribute("value"));
+ }
+ }
+
+ {
+ XMLElement* cfm_xml = config->FirstChildElement("cfm");
+ if (cfm_xml)
+ {
+ if (!cfm_xml->Attribute("value"))
+ {
+ logger->reportError("cfm element must have value attribute");
+ return false;
+ }
+ reduced_deformable.m_cfm = urdfLexicalCast<double>(cfm_xml->Attribute("value"));
+ }
+ }
+
+ {
+ XMLElement* damping_xml = config->FirstChildElement("damping_coefficient");
+ if (damping_xml)
+ {
+ if (!damping_xml->Attribute("value"))
+ {
+ logger->reportError("damping_coefficient element must have value attribute");
+ return false;
+ }
+ reduced_deformable.m_damping = urdfLexicalCast<double>(damping_xml->Attribute("value"));
+ }
+ }
+
+ {
+ XMLElement* friction_xml = config->FirstChildElement("friction");
+ if (friction_xml)
+ {
+ if (!friction_xml->Attribute("value"))
+ {
+ logger->reportError("friction element must have value attribute");
+ return false;
+ }
+ reduced_deformable.m_friction = urdfLexicalCast<double>(friction_xml->Attribute("value"));
+ }
+ }
+
+ XMLElement* vis_xml = config->FirstChildElement("visual");
+ if (!vis_xml)
+ {
+ logger->reportError("expected an visual element");
+ return false;
+ }
+ if (!vis_xml->Attribute("filename"))
+ {
+ logger->reportError("expected a filename for visual geometry");
+ return false;
+ }
+ std::string fn = vis_xml->Attribute("filename");
+ reduced_deformable.m_visualFileName = fn;
+
+ int out_type(0);
+ bool success = UrdfFindMeshFile(m_fileIO,
+ model.m_sourceFile, fn, sourceFileLocation(vis_xml),
+ &reduced_deformable.m_visualFileName, &out_type);
+
+ if (!success)
+ {
+ // warning already printed
+ return false;
+ }
+
+ // collision mesh is optional
+ XMLElement* col_xml = config->FirstChildElement("collision");
+ if (col_xml)
+ {
+ if (!col_xml->Attribute("filename"))
+ {
+ logger->reportError("expected a filename for collision geoemtry");
+ return false;
+ }
+ fn = col_xml->Attribute("filename");
+ success = UrdfFindMeshFile(m_fileIO,
+ model.m_sourceFile, fn, sourceFileLocation(col_xml),
+ &reduced_deformable.m_simFileName, &out_type);
+
+ if (!success)
+ {
+ // warning already printed
+ return false;
+ }
+ }
+
+ ParseUserData(config, reduced_deformable.m_userData, logger);
+ return true;
+}
+
bool UrdfParser::parseJointLimits(UrdfJoint& joint, XMLElement* config, ErrorLogger* logger)
{
joint.m_lowerLimit = 0.f;
@@ -2126,9 +2291,16 @@ bool UrdfParser::loadUrdf(const char* urdfText, ErrorLogger* logger, bool forceF
// logger->printMessage(msg);
+
+ XMLElement* reduced_deformable_xml = robot_xml->FirstChildElement("reduced_deformable");
+ if (reduced_deformable_xml) {
+ return parseReducedDeformable(m_urdf2Model, reduced_deformable_xml, logger);
+ }
+
XMLElement* deformable_xml = robot_xml->FirstChildElement("deformable");
- if(deformable_xml)
+ if (deformable_xml) {
return parseDeformable(m_urdf2Model, deformable_xml, logger);
+ }
for (XMLElement* link_xml = robot_xml->FirstChildElement("link"); link_xml; link_xml = link_xml->NextSiblingElement("link"))
{
diff --git a/examples/Importers/ImportURDFDemo/UrdfParser.h b/examples/Importers/ImportURDFDemo/UrdfParser.h
index b234fa66b..8256099a5 100644
--- a/examples/Importers/ImportURDFDemo/UrdfParser.h
+++ b/examples/Importers/ImportURDFDemo/UrdfParser.h
@@ -247,6 +247,37 @@ struct UrdfDeformable
}
};
+struct UrdfReducedDeformable
+{
+ std::string m_name;
+ int m_numModes;
+
+ double m_mass;
+ double m_stiffnessScale;
+ double m_erp;
+ double m_cfm;
+ double m_friction;
+ double m_collisionMargin;
+ double m_damping;
+
+ std::string m_visualFileName;
+ std::string m_simFileName;
+ btHashMap<btHashString, std::string> m_userData;
+
+ UrdfReducedDeformable()
+ : m_numModes(1),
+ m_mass(1),
+ m_stiffnessScale(100),
+ m_erp(0.2), // generally, 0.2 is a good value for erp and cfm
+ m_cfm(0.2),
+ m_friction(0),
+ m_collisionMargin(0.02),
+ m_damping(0),
+ m_visualFileName(""),
+ m_simFileName("")
+ {}
+};
+
struct UrdfModel
{
std::string m_name;
@@ -256,6 +287,7 @@ struct UrdfModel
btHashMap<btHashString, UrdfLink*> m_links;
btHashMap<btHashString, UrdfJoint*> m_joints;
UrdfDeformable m_deformable;
+ UrdfReducedDeformable m_reducedDeformable;
// Maps user data keys to user data values.
btHashMap<btHashString, std::string> m_userData;
@@ -333,7 +365,7 @@ protected:
bool parseSensor(UrdfModel& model, UrdfLink& link, UrdfJoint& joint, tinyxml2::XMLElement* config, ErrorLogger* logger);
bool parseLameCoefficients(LameCoefficients& lameCoefficients, tinyxml2::XMLElement* config, ErrorLogger* logger);
bool parseDeformable(UrdfModel& model, tinyxml2::XMLElement* config, ErrorLogger* logger);
-
+ bool parseReducedDeformable(UrdfModel& model, tinyxml2::XMLElement* config, ErrorLogger* logger);
public:
UrdfParser(struct CommonFileIOInterface* fileIO);
@@ -413,6 +445,11 @@ public:
return m_urdf2Model.m_deformable;
}
+ const UrdfReducedDeformable& getReducedDeformable() const
+ {
+ return m_urdf2Model.m_reducedDeformable;
+ }
+
bool mergeFixedLinks(UrdfModel& model, UrdfLink* link, ErrorLogger* logger, bool forceFixedBase, int level);
bool printTree(UrdfLink* link, ErrorLogger* logger, int level);
bool recreateModel(UrdfModel& model, UrdfLink* link, ErrorLogger* logger);
diff --git a/examples/MultiBody/MultiDofDemo.cpp b/examples/MultiBody/MultiDofDemo.cpp
index 33f9e7a9f..6cd3a2c96 100644
--- a/examples/MultiBody/MultiDofDemo.cpp
+++ b/examples/MultiBody/MultiDofDemo.cpp
@@ -165,7 +165,7 @@ void MultiDofDemo::initPhysics()
btVector3 linkHalfExtents(0.05, 0.37, 0.1);
btVector3 baseHalfExtents(0.05, 0.37, 0.1);
- btMultiBody* mbC = createFeatherstoneMultiBody_testMultiDof(world, numLinks, btVector3(-0.4f, 3.f, 0.f), linkHalfExtents, baseHalfExtents, spherical, g_floatingBase);
+ btMultiBody* mbC = createFeatherstoneMultiBody_testMultiDof(world, numLinks, btVector3(-0.4f, 3.f, 0.f), baseHalfExtents, linkHalfExtents, spherical, g_floatingBase);
//mbC->forceMultiDof(); //if !spherical, you can comment this line to check the 1DoF algorithm
mbC->setCanSleep(canSleep);
diff --git a/examples/OpenGLWindow/X11OpenGLWindow.cpp b/examples/OpenGLWindow/X11OpenGLWindow.cpp
index f3aa1fe6a..3d7e4de65 100644
--- a/examples/OpenGLWindow/X11OpenGLWindow.cpp
+++ b/examples/OpenGLWindow/X11OpenGLWindow.cpp
@@ -566,7 +566,7 @@ void X11OpenGLWindow::enableOpenGL()
//Access pthreads as a workaround for a bug in Linux/Ubuntu
//See https://bugs.launchpad.net/ubuntu/+source/nvidia-graphics-drivers-319/+bug/1248642
-#if !defined(__NetBSD__)
+#if !defined(__NetBSD__) && !defined(__ANDROID__)
int i = pthread_getconcurrency();
printf("pthread_getconcurrency()=%d\n", i);
#endif
diff --git a/examples/ReducedDeformableDemo/ConservationTest.cpp b/examples/ReducedDeformableDemo/ConservationTest.cpp
new file mode 100644
index 000000000..05b7394da
--- /dev/null
+++ b/examples/ReducedDeformableDemo/ConservationTest.cpp
@@ -0,0 +1,316 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "ConservationTest.h"
+///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
+#include "btBulletDynamicsCommon.h"
+#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.h"
+#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
+#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
+#include "../CommonInterfaces/CommonParameterInterface.h"
+#include <stdio.h> //printf debugging
+#include <random>
+
+#include "../CommonInterfaces/CommonDeformableBodyBase.h"
+#include "../Utils/b3ResourcePath.h"
+
+static btScalar damping_alpha = 0.0;
+static btScalar damping_beta = 0.0;
+static int start_mode = 6;
+static int num_modes = 20;
+
+class ConservationTest : public CommonDeformableBodyBase
+{
+ btScalar sim_time;
+ bool first_step;
+
+ // get deformed shape
+ void getDeformedShape(btReducedDeformableBody* rsb, const int mode_n, const btScalar scale = 1)
+ {
+ // for (int i = 0; i < rsb->m_nodes.size(); ++i)
+ // for (int k = 0; k < 3; ++k)
+ // rsb->m_nodes[i].m_x[k] += rsb->m_modes[mode_n][3 * i + k] * scale;
+
+ // rsb->m_reducedDofs[mode_n] = scale;
+ // rsb->m_reducedDofsBuffer[mode_n] = scale;
+
+ srand(1);
+ for (int r = 0; r < rsb->m_nReduced; r++)
+ {
+ rsb->m_reducedDofs[r] = (btScalar(rand()) / btScalar(RAND_MAX) - 0.5);
+ rsb->m_reducedDofsBuffer[r] = rsb->m_reducedDofs[r];
+ }
+
+ rsb->mapToFullPosition(rsb->getRigidTransform());
+ // std::cout << "-----------\n";
+ // std::cout << rsb->m_nodes[0].m_x[0] << '\t' << rsb->m_nodes[0].m_x[1] << '\t' << rsb->m_nodes[0].m_x[2] << '\n';
+ // std::cout << "-----------\n";
+ }
+
+public:
+ ConservationTest(struct GUIHelperInterface* helper)
+ : CommonDeformableBodyBase(helper)
+ {
+ sim_time = 0;
+ first_step = true;
+ }
+ virtual ~ConservationTest()
+ {
+ }
+ void initPhysics();
+
+ void exitPhysics();
+
+ // TODO: disable pick force, non-interactive for now.
+ bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) {
+ return false;
+ }
+
+ void resetCamera()
+ {
+ float dist = 10;
+ float pitch = 0;
+ float yaw = 90;
+ float targetPos[3] = {0, 3, 0};
+ m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
+ }
+
+ void checkMomentum(btReducedDeformableBody* rsb)
+ {
+ btVector3 x_com(0, 0, 0);
+ btVector3 total_linear(0, 0, 0);
+ btVector3 total_angular(0, 0, 0);
+ {
+ std::ofstream myfile("center_of_mass.txt", std::ios_base::app);
+ for (int i = 0; i < rsb->m_nFull; ++i)
+ {
+ x_com += rsb->m_nodalMass[i] * rsb->m_nodes[i].m_x;
+ }
+ x_com /= rsb->getTotalMass();
+ myfile << sim_time << "\t" << x_com[0] << "\t" << x_com[1] << "\t" << x_com[2] << "\n";
+ myfile.close();
+ }
+ {
+ std::ofstream myfile("linear_momentum.txt", std::ios_base::app);
+ for (int i = 0; i < rsb->m_nFull; ++i)
+ {
+ total_linear += rsb->m_nodalMass[i] * rsb->m_nodes[i].m_v;
+ }
+ myfile << sim_time << "\t" << total_linear[0] << "\t" << total_linear[1] << "\t" << total_linear[2] << "\n";
+ myfile.close();
+ }
+ {
+ std::ofstream myfile("angular_momentum.txt", std::ios_base::app);
+ // btVector3 ri(0, 0, 0);
+ // for (int i = 0; i < rsb->m_nFull; ++i)
+ // {
+ // ri = rsb->m_nodes[i].m_x - x_com;
+ // total_angular += rsb->m_nodalMass[i] * ri.cross(rsb->m_nodes[i].m_v);
+ // }
+ total_angular = rsb->computeTotalAngularMomentum();
+ myfile << sim_time << "\t" << total_angular[0] << "\t" << total_angular[1] << "\t" << total_angular[2] << "\n";
+ myfile.close();
+ }
+ {
+ btVector3 angular_rigid(0, 0, 0);
+ std::ofstream myfile("angular_momentum_rigid.txt", std::ios_base::app);
+ btVector3 ri(0, 0, 0);
+ for (int i = 0; i < rsb->m_nFull; ++i)
+ {
+ ri = rsb->m_nodes[i].m_x - x_com;
+ btMatrix3x3 ri_star = Cross(ri);
+ angular_rigid += rsb->m_nodalMass[i] * (ri_star.transpose() * ri_star * rsb->getAngularVelocity());
+ }
+ myfile << sim_time << "\t" << angular_rigid[0] << "\t" << angular_rigid[1] << "\t" << angular_rigid[2] << "\n";
+ myfile.close();
+ }
+
+ {
+ std::ofstream myfile("reduced_velocity.txt", std::ios_base::app);
+ myfile << sim_time << "\t" << rsb->m_reducedVelocity[0] << "\t" << rsb->m_reducedDofs[0] << "\n";
+ myfile.close();
+ }
+ }
+
+ void stepSimulation(float deltaTime)
+ {
+ // add initial deformation
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(static_cast<btDeformableMultiBodyDynamicsWorld*>(m_dynamicsWorld)->getSoftBodyArray()[0]);
+ if (first_step /* && !rsb->m_bUpdateRtCst*/)
+ {
+ getDeformedShape(rsb, 0, 1);
+ first_step = false;
+ }
+
+ float internalTimeStep = 1. / 240.f;
+ m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
+
+ sim_time += internalTimeStep;
+ checkMomentum(rsb);
+ }
+
+ virtual void renderScene()
+ {
+ CommonDeformableBodyBase::renderScene();
+ btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
+
+ for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
+ {
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(deformableWorld->getSoftBodyArray()[i]);
+ {
+ btSoftBodyHelpers::DrawFrame(rsb, deformableWorld->getDebugDrawer());
+ btSoftBodyHelpers::Draw(rsb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
+
+ btVector3 origin = rsb->getRigidTransform().getOrigin();
+ btVector3 line_x = rsb->getRigidTransform().getBasis() * 2 * btVector3(1, 0, 0) + origin;
+ btVector3 line_y = rsb->getRigidTransform().getBasis() * 2 * btVector3(0, 1, 0) + origin;
+ btVector3 line_z = rsb->getRigidTransform().getBasis() * 2 * btVector3(0, 0, 1) + origin;
+
+ deformableWorld->getDebugDrawer()->drawLine(origin, line_x, btVector3(1, 0, 0));
+ deformableWorld->getDebugDrawer()->drawLine(origin, line_y, btVector3(0, 1, 0));
+ deformableWorld->getDebugDrawer()->drawLine(origin, line_z, btVector3(0, 0, 1));
+
+ deformableWorld->getDebugDrawer()->drawSphere(btVector3(0, 0, 0), 0.1, btVector3(1, 1, 1));
+ deformableWorld->getDebugDrawer()->drawSphere(btVector3(0, 2, 0), 0.1, btVector3(1, 1, 1));
+ deformableWorld->getDebugDrawer()->drawSphere(btVector3(0, 4, 0), 0.1, btVector3(1, 1, 1));
+ }
+ }
+ }
+};
+
+void ConservationTest::initPhysics()
+{
+ m_guiHelper->setUpAxis(1);
+
+ ///collision configuration contains default setup for memory, collision setup
+ m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
+
+ ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
+ m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
+
+ m_broadphase = new btDbvtBroadphase();
+ btReducedDeformableBodySolver* reducedSoftBodySolver = new btReducedDeformableBodySolver();
+ btVector3 gravity = btVector3(0, 0, 0);
+ reducedSoftBodySolver->setGravity(gravity);
+
+ btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
+ sol->setDeformableSolver(reducedSoftBodySolver);
+ m_solver = sol;
+
+ m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, reducedSoftBodySolver);
+ m_dynamicsWorld->setGravity(gravity);
+ m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
+
+ // create volumetric reduced deformable body
+ {
+ std::string file_path("../../../data/reduced_beam/");
+ std::string vtk_file("beam_mesh_origin.vtk");
+ btReducedDeformableBody* rsb = btReducedDeformableBodyHelpers::createReducedDeformableObject(
+ getDeformableDynamicsWorld()->getWorldInfo(),
+ file_path,
+ vtk_file,
+ num_modes,
+ false);
+
+ getDeformableDynamicsWorld()->addSoftBody(rsb);
+ rsb->getCollisionShape()->setMargin(0.1);
+
+ btTransform init_transform;
+ init_transform.setIdentity();
+ init_transform.setOrigin(btVector3(0, 4, 0));
+ // init_transform.setRotation(btQuaternion(btVector3(0, 1, 0), SIMD_PI / 2.0));
+ rsb->transformTo(init_transform);
+
+ rsb->setStiffnessScale(100);
+ rsb->setDamping(damping_alpha, damping_beta);
+
+ rsb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
+ rsb->m_cfg.kCHR = 1; // collision hardness with rigid body
+ rsb->m_cfg.kDF = 0;
+ rsb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
+ rsb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
+ rsb->m_sleepingThreshold = 0;
+ btSoftBodyHelpers::generateBoundaryFaces(rsb);
+
+ // rsb->setVelocity(btVector3(0, -COLLIDING_VELOCITY, 0));
+ // rsb->setRigidVelocity(btVector3(0, 1, 0));
+ // rsb->setRigidAngularVelocity(btVector3(1, 0, 0));
+ }
+ getDeformableDynamicsWorld()->setImplicit(false);
+ getDeformableDynamicsWorld()->setLineSearch(false);
+ getDeformableDynamicsWorld()->setUseProjection(false);
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_erp = 0.3;
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_cfm = 0.2;
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_maxErrorReduction = btScalar(200);
+ getDeformableDynamicsWorld()->getSolverInfo().m_leastSquaresResidualThreshold = 1e-3;
+ getDeformableDynamicsWorld()->getSolverInfo().m_splitImpulse = false;
+ getDeformableDynamicsWorld()->getSolverInfo().m_numIterations = 100;
+
+ m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
+}
+
+void ConservationTest::exitPhysics()
+{
+ //cleanup in the reverse order of creation/initialization
+ removePickingConstraint();
+ //remove the rigidbodies from the dynamics world and delete them
+ int i;
+ for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
+ {
+ btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
+ btRigidBody* body = btRigidBody::upcast(obj);
+ if (body && body->getMotionState())
+ {
+ delete body->getMotionState();
+ }
+ m_dynamicsWorld->removeCollisionObject(obj);
+ delete obj;
+ }
+ // delete forces
+ for (int j = 0; j < m_forces.size(); j++)
+ {
+ btDeformableLagrangianForce* force = m_forces[j];
+ delete force;
+ }
+ m_forces.clear();
+
+ //delete collision shapes
+ for (int j = 0; j < m_collisionShapes.size(); j++)
+ {
+ btCollisionShape* shape = m_collisionShapes[j];
+ delete shape;
+ }
+ m_collisionShapes.clear();
+
+ delete m_dynamicsWorld;
+
+ delete m_solver;
+
+ delete m_broadphase;
+
+ delete m_dispatcher;
+
+ delete m_collisionConfiguration;
+}
+
+
+
+class CommonExampleInterface* ReducedConservationTestCreateFunc(struct CommonExampleOptions& options)
+{
+ return new ConservationTest(options.m_guiHelper);
+}
+
+
diff --git a/examples/ReducedDeformableDemo/ConservationTest.h b/examples/ReducedDeformableDemo/ConservationTest.h
new file mode 100644
index 000000000..3528f1e15
--- /dev/null
+++ b/examples/ReducedDeformableDemo/ConservationTest.h
@@ -0,0 +1,19 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef _REDUCED_CONSERVATION_TEST_H
+#define _REDUCED_CONSERVATION_TEST_H
+
+class CommonExampleInterface* ReducedConservationTestCreateFunc(struct CommonExampleOptions& options);
+
+#endif //_REDUCED_CONSERVATION_TEST_H
diff --git a/examples/ReducedDeformableDemo/FreeFall.cpp b/examples/ReducedDeformableDemo/FreeFall.cpp
new file mode 100644
index 000000000..f63db542d
--- /dev/null
+++ b/examples/ReducedDeformableDemo/FreeFall.cpp
@@ -0,0 +1,276 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "FreeFall.h"
+///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
+#include "btBulletDynamicsCommon.h"
+#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.h"
+#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
+#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
+#include "../CommonInterfaces/CommonParameterInterface.h"
+#include <stdio.h> //printf debugging
+
+#include "../CommonInterfaces/CommonDeformableBodyBase.h"
+#include "../Utils/b3ResourcePath.h"
+
+///The BasicTest shows the contact between volumetric deformable objects and rigid objects.
+// static btScalar E = 50;
+// static btScalar nu = 0.3;
+static btScalar damping_alpha = 0.0;
+static btScalar damping_beta = 0.0001;
+static btScalar COLLIDING_VELOCITY = 0;
+static int num_modes = 40;
+
+class FreeFall : public CommonDeformableBodyBase
+{
+public:
+ FreeFall(struct GUIHelperInterface* helper)
+ : CommonDeformableBodyBase(helper)
+ {
+ }
+ virtual ~FreeFall()
+ {
+ }
+ void initPhysics();
+
+ void exitPhysics();
+
+ // TODO: disable pick force, non-interactive for now.
+ bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) {
+ return false;
+ }
+
+ void resetCamera()
+ {
+ float dist = 8;
+ float pitch = -10;
+ float yaw = 90;
+ float targetPos[3] = {0, 2, 0};
+ // float dist = 10;
+ // float pitch = -30;
+ // float yaw = 125;
+ // float targetPos[3] = {0, 2, 0};
+ m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
+ }
+
+ void Ctor_RbUpStack(const btVector3& origin)
+ {
+ float mass = 10;
+ btCollisionShape* shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
+ // btCollisionShape* shape = new btBoxShape(btVector3(1, 1, 1));
+ btTransform startTransform;
+ startTransform.setIdentity();
+ // startTransform.setOrigin(btVector3(0, 12, 0));
+ // btRigidBody* rb0 = createRigidBody(mass, startTransform, shape);
+ // rb0->setLinearVelocity(btVector3(0, 0, 0));
+
+ startTransform.setOrigin(origin);
+ // startTransform.setRotation(btQuaternion(btVector3(1, 0, 1), SIMD_PI / 4.0));
+ btRigidBody* rb1 = createRigidBody(mass, startTransform, shape);
+ rb1->setActivationState(DISABLE_DEACTIVATION);
+ rb1->setLinearVelocity(btVector3(0, 0, 0));
+ }
+
+ void createReducedDeformableObject(const btVector3& origin, const btQuaternion& rotation)
+ {
+ std::string file_path("../../../data/reduced_cube/");
+ std::string vtk_file("cube_mesh.vtk");
+ btReducedDeformableBody* rsb = btReducedDeformableBodyHelpers::createReducedDeformableObject(
+ getDeformableDynamicsWorld()->getWorldInfo(),
+ file_path,
+ vtk_file,
+ num_modes,
+ false);
+
+ getDeformableDynamicsWorld()->addSoftBody(rsb);
+ rsb->getCollisionShape()->setMargin(0.01);
+ // rsb->scale(btVector3(1, 1, 0.5));
+
+ rsb->setTotalMass(10);
+
+ btTransform init_transform;
+ init_transform.setIdentity();
+ init_transform.setOrigin(origin);
+ init_transform.setRotation(rotation);
+ rsb->transformTo(init_transform);
+
+ rsb->setStiffnessScale(25);
+ rsb->setDamping(damping_alpha, damping_beta);
+ // rsb->scale(btVector3(0.5, 0.5, 0.5));
+
+ rsb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
+ rsb->m_cfg.kCHR = 1; // collision hardness with rigid body
+ rsb->m_cfg.kDF = 0;
+ rsb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
+ rsb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
+ rsb->m_sleepingThreshold = 0;
+ btSoftBodyHelpers::generateBoundaryFaces(rsb);
+ }
+
+ void stepSimulation(float deltaTime)
+ {
+ float internalTimeStep = 1. / 60.f;
+ m_dynamicsWorld->stepSimulation(deltaTime, 1, internalTimeStep);
+ }
+
+ virtual void renderScene()
+ {
+ CommonDeformableBodyBase::renderScene();
+ btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
+ // int flag = 0;
+
+ for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
+ {
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(deformableWorld->getSoftBodyArray()[i]);
+ {
+ btSoftBodyHelpers::DrawFrame(rsb, deformableWorld->getDebugDrawer());
+ // btSoftBodyHelpers::Draw(rsb, deformableWorld->getDebugDrawer(), flag);
+ btSoftBodyHelpers::Draw(rsb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
+
+ // for (int p = 0; p < rsb->m_fixedNodes.size(); ++p)
+ // {
+ // deformableWorld->getDebugDrawer()->drawSphere(rsb->m_nodes[rsb->m_fixedNodes[p]].m_x, 0.2, btVector3(1, 0, 0));
+ // }
+ // for (int p = 0; p < rsb->m_nodeRigidContacts.size(); ++p)
+ // {
+ // deformableWorld->getDebugDrawer()->drawSphere(rsb->m_nodes[rsb->m_contactNodesList[p]].m_x, 0.2, btVector3(0, 1, 0));
+ // }
+
+ // deformableWorld->getDebugDrawer()->drawSphere(btVector3(0, 0, 0), 0.1, btVector3(1, 1, 1));
+ // deformableWorld->getDebugDrawer()->drawSphere(btVector3(0, 5, 0), 0.1, btVector3(1, 1, 1));
+ // deformableWorld->getDebugDrawer()->drawSphere(btVector3(0, 10, 0), 0.1, btVector3(1, 1, 1));
+ }
+ }
+ }
+};
+
+void FreeFall::initPhysics()
+{
+ m_guiHelper->setUpAxis(1);
+
+ ///collision configuration contains default setup for memory, collision setup
+ m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
+
+ ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
+ m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
+
+ m_broadphase = new btDbvtBroadphase();
+ btReducedDeformableBodySolver* reducedSoftBodySolver = new btReducedDeformableBodySolver();
+
+ btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
+ sol->setDeformableSolver(reducedSoftBodySolver);
+ m_solver = sol;
+
+ m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, reducedSoftBodySolver);
+ btVector3 gravity = btVector3(0, -9.8, 0);
+ m_dynamicsWorld->setGravity(gravity);
+ m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
+ // m_dynamicsWorld->getSolverInfo().m_solverMode |= SOLVER_RANDMIZE_ORDER;
+
+ // 2 reduced deformable cubes
+ createReducedDeformableObject(btVector3(0, 4, -2), btQuaternion(0, 0, 0));
+ createReducedDeformableObject(btVector3(0, 4, 2), btQuaternion(0, 0, 0));
+
+ // 2 rigid cubes
+ Ctor_RbUpStack(btVector3(0, 10, -2));
+ Ctor_RbUpStack(btVector3(0, 10, 2));
+
+ // create a static rigid box as the ground
+ {
+ // btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50), btScalar(50), btScalar(50)));
+ btBoxShape* groundShape = createBoxShape(btVector3(btScalar(10), btScalar(2), btScalar(10)));
+ m_collisionShapes.push_back(groundShape);
+
+ btTransform groundTransform;
+ groundTransform.setIdentity();
+ // groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI / 6.0));
+ // groundTransform.setRotation(btQuaternion(btVector3(0, 0, 1), SIMD_PI / 6.0));
+ groundTransform.setOrigin(btVector3(0, -2, 0));
+ // groundTransform.setOrigin(btVector3(0, 0, 6));
+ // groundTransform.setOrigin(btVector3(0, -50, 0));
+ {
+ btScalar mass(0.);
+ createRigidBody(mass, groundTransform, groundShape, btVector4(0,0,0,0));
+ }
+ }
+
+ getDeformableDynamicsWorld()->setImplicit(false);
+ getDeformableDynamicsWorld()->setLineSearch(false);
+ getDeformableDynamicsWorld()->setUseProjection(false);
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_erp = 0.2;
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_cfm = 0.2;
+ getDeformableDynamicsWorld()->getSolverInfo().m_friction = 0.5;
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_maxErrorReduction = btScalar(200);
+ getDeformableDynamicsWorld()->getSolverInfo().m_leastSquaresResidualThreshold = 1e-3;
+ getDeformableDynamicsWorld()->getSolverInfo().m_splitImpulse = false;
+ getDeformableDynamicsWorld()->getSolverInfo().m_numIterations = 100;
+
+ m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
+ m_dynamicsWorld->setGravity(gravity);
+}
+
+void FreeFall::exitPhysics()
+{
+ //cleanup in the reverse order of creation/initialization
+ removePickingConstraint();
+ //remove the rigidbodies from the dynamics world and delete them
+ int i;
+ for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
+ {
+ btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
+ btRigidBody* body = btRigidBody::upcast(obj);
+ if (body && body->getMotionState())
+ {
+ delete body->getMotionState();
+ }
+ m_dynamicsWorld->removeCollisionObject(obj);
+ delete obj;
+ }
+ // delete forces
+ for (int j = 0; j < m_forces.size(); j++)
+ {
+ btDeformableLagrangianForce* force = m_forces[j];
+ delete force;
+ }
+ m_forces.clear();
+
+ //delete collision shapes
+ for (int j = 0; j < m_collisionShapes.size(); j++)
+ {
+ btCollisionShape* shape = m_collisionShapes[j];
+ delete shape;
+ }
+ m_collisionShapes.clear();
+
+ delete m_dynamicsWorld;
+
+ delete m_solver;
+
+ delete m_broadphase;
+
+ delete m_dispatcher;
+
+ delete m_collisionConfiguration;
+}
+
+
+
+class CommonExampleInterface* ReducedFreeFallCreateFunc(struct CommonExampleOptions& options)
+{
+ return new FreeFall(options.m_guiHelper);
+}
+
+
diff --git a/examples/ReducedDeformableDemo/FreeFall.h b/examples/ReducedDeformableDemo/FreeFall.h
new file mode 100644
index 000000000..b71d8027f
--- /dev/null
+++ b/examples/ReducedDeformableDemo/FreeFall.h
@@ -0,0 +1,19 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef _REDUCED_FREE_FALL_H
+#define _REDUCED_FREE_FALL_H
+
+class CommonExampleInterface* ReducedFreeFallCreateFunc(struct CommonExampleOptions& options);
+
+#endif //_REDUCED_FREE_FALL_H
diff --git a/examples/ReducedDeformableDemo/FrictionSlope.cpp b/examples/ReducedDeformableDemo/FrictionSlope.cpp
new file mode 100644
index 000000000..20eac36e8
--- /dev/null
+++ b/examples/ReducedDeformableDemo/FrictionSlope.cpp
@@ -0,0 +1,288 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "FrictionSlope.h"
+///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
+#include "btBulletDynamicsCommon.h"
+#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.h"
+#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
+#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
+#include "../CommonInterfaces/CommonParameterInterface.h"
+#include <stdio.h> //printf debugging
+
+#include "../CommonInterfaces/CommonDeformableBodyBase.h"
+#include "../Utils/b3ResourcePath.h"
+
+///The BasicTest shows the contact between volumetric deformable objects and rigid objects.
+// static btScalar E = 50;
+// static btScalar nu = 0.3;
+static btScalar damping_alpha = 0.0;
+static btScalar damping_beta = 0.001;
+static btScalar COLLIDING_VELOCITY = 0;
+static int num_modes = 20;
+
+class FrictionSlope : public CommonDeformableBodyBase
+{
+public:
+ FrictionSlope(struct GUIHelperInterface* helper)
+ : CommonDeformableBodyBase(helper)
+ {}
+ virtual ~FrictionSlope()
+ {
+ }
+ void initPhysics();
+
+ void exitPhysics();
+
+ // TODO: disable pick force, non-interactive for now.
+ bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) {
+ return false;
+ }
+
+ void resetCamera()
+ {
+ float dist = 20;
+ float pitch = -20;
+ float yaw = 90;
+ float targetPos[3] = {0, 0, 0.5};
+ m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
+ }
+
+ void Ctor_RbUpStack()
+ {
+ float mass = 1;
+ btCollisionShape* shape = new btBoxShape(btVector3(1, 1, 1));
+ // btCollisionShape* shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
+ // btCollisionShape* shape = new btBoxShape(btVector3(0.5, 0.25, 2));
+ btTransform startTransform;
+ startTransform.setIdentity();
+
+ startTransform.setOrigin(btVector3(0,4,0));
+ btRigidBody* rb1 = createRigidBody(mass, startTransform, shape);
+ rb1->setLinearVelocity(btVector3(0, 0, 0));
+ }
+
+ void createGround()
+ {
+ btBoxShape* groundShape = createBoxShape(btVector3(btScalar(10), btScalar(2), btScalar(10)));
+ m_collisionShapes.push_back(groundShape);
+
+ btTransform groundTransform;
+ groundTransform.setIdentity();
+ // groundTransform.setRotation(btQuaternion(btVector3(0, 0, 1), SIMD_PI / 6.0));
+ groundTransform.setOrigin(btVector3(0, 0, 0));
+ btScalar mass(1e6);
+ btRigidBody* ground = createRigidBody(mass, groundTransform, groundShape, btVector4(0,0,0,0));
+ // ground->setFriction(1);
+ }
+
+ void stepSimulation(float deltaTime)
+ {
+ float internalTimeStep = 1. / 60.f;
+ m_dynamicsWorld->stepSimulation(deltaTime, 1, internalTimeStep);
+ }
+
+ virtual void renderScene()
+ {
+ CommonDeformableBodyBase::renderScene();
+ btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
+
+ for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
+ {
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(deformableWorld->getSoftBodyArray()[i]);
+ {
+ btSoftBodyHelpers::DrawFrame(rsb, deformableWorld->getDebugDrawer());
+ // btSoftBodyHelpers::Draw(rsb, deformableWorld->getDebugDrawer(), flag);
+ btSoftBodyHelpers::Draw(rsb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
+
+ // for (int p = 0; p < rsb->m_fixedNodes.size(); ++p)
+ // {
+ // deformableWorld->getDebugDrawer()->drawSphere(rsb->m_nodes[rsb->m_fixedNodes[p]].m_x, 0.2, btVector3(1, 0, 0));
+ // }
+ // for (int p = 0; p < rsb->m_nodeRigidContacts.size(); ++p)
+ // {
+ // deformableWorld->getDebugDrawer()->drawSphere(rsb->m_nodes[rsb->m_contactNodesList[p]].m_x, 0.2, btVector3(0, 1, 0));
+ // }
+ }
+ }
+ }
+};
+
+namespace FrictionSlopeHelper
+{
+ void groundMotion(btScalar time, btDeformableMultiBodyDynamicsWorld* world)
+ {
+ btAlignedObjectArray<btRigidBody*>& rbs = world->getNonStaticRigidBodies();
+
+ btRigidBody* ground = rbs[0];
+ btAssert(ground->getMass() > 1e5);
+
+ btScalar start_time = 2;
+ btScalar end_time = 8;
+ btScalar start_angle = 0;
+ btScalar end_angle = SIMD_PI / 6;
+ btScalar current_angle = 0;
+ btScalar turn_speed = (end_angle - start_angle) / (end_time - start_time);
+
+ if (time >= start_time)
+ {
+ current_angle = (time - start_time) * turn_speed;
+ if (time > end_time)
+ {
+ current_angle = end_angle;
+ turn_speed = 0;
+ }
+ }
+ else
+ {
+ current_angle = start_angle;
+ turn_speed = 0;
+ }
+
+ btTransform groundTransform;
+ groundTransform.setIdentity();
+ // groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI / 6.0));
+ groundTransform.setRotation(btQuaternion(btVector3(0, 0, 1), current_angle));
+
+ ground->setCenterOfMassTransform(groundTransform);
+ ground->setLinearVelocity(btVector3(0, 0, 0));
+ ground->setAngularVelocity(btVector3(0, 0, 0));
+ }
+};
+
+void FrictionSlope::initPhysics()
+{
+ m_guiHelper->setUpAxis(1);
+
+ ///collision configuration contains default setup for memory, collision setup
+ m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
+
+ ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
+ m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
+
+ m_broadphase = new btDbvtBroadphase();
+ btReducedDeformableBodySolver* reducedSoftBodySolver = new btReducedDeformableBodySolver();
+ btVector3 gravity = btVector3(0, -10, 0);
+ reducedSoftBodySolver->setGravity(gravity);
+
+ btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
+ sol->setDeformableSolver(reducedSoftBodySolver);
+ m_solver = sol;
+
+ m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, reducedSoftBodySolver);
+ m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
+
+ // create volumetric reduced deformable body
+ {
+ std::string file_path("../../../data/reduced_beam/");
+ std::string vtk_file("beam_mesh_origin.vtk");
+ btReducedDeformableBody* rsb = btReducedDeformableBodyHelpers::createReducedDeformableObject(
+ getDeformableDynamicsWorld()->getWorldInfo(),
+ file_path,
+ vtk_file,
+ num_modes,
+ false);
+
+ getDeformableDynamicsWorld()->addSoftBody(rsb);
+ rsb->getCollisionShape()->setMargin(0.01);
+
+ btTransform init_transform;
+ init_transform.setIdentity();
+ init_transform.setOrigin(btVector3(0, 4, 0));
+ init_transform.setRotation(btQuaternion(btVector3(0, 0, 1), SIMD_PI / 2.0));
+ rsb->transform(init_transform);
+ rsb->setStiffnessScale(50);
+ rsb->setDamping(damping_alpha, damping_beta);
+
+ rsb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
+ rsb->m_cfg.kCHR = 1; // collision hardness with rigid body
+ rsb->m_cfg.kDF = 0;
+ rsb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
+ rsb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
+ rsb->m_sleepingThreshold = 0;
+ btSoftBodyHelpers::generateBoundaryFaces(rsb);
+ }
+
+ createGround();
+ // add a few rigid bodies
+ // Ctor_RbUpStack();
+
+ getDeformableDynamicsWorld()->setImplicit(false);
+ getDeformableDynamicsWorld()->setLineSearch(false);
+ getDeformableDynamicsWorld()->setUseProjection(false);
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_erp = 0.2;
+ getDeformableDynamicsWorld()->getSolverInfo().m_friction = 1;
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_maxErrorReduction = btScalar(200);
+ getDeformableDynamicsWorld()->getSolverInfo().m_leastSquaresResidualThreshold = 1e-3;
+ getDeformableDynamicsWorld()->getSolverInfo().m_splitImpulse = false;
+ getDeformableDynamicsWorld()->getSolverInfo().m_numIterations = 100;
+ getDeformableDynamicsWorld()->setSolverCallback(FrictionSlopeHelper::groundMotion);
+ m_dynamicsWorld->setGravity(gravity);
+ m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
+}
+
+void FrictionSlope::exitPhysics()
+{
+ //cleanup in the reverse order of creation/initialization
+ removePickingConstraint();
+ //remove the rigidbodies from the dynamics world and delete them
+ int i;
+ for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
+ {
+ btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
+ btRigidBody* body = btRigidBody::upcast(obj);
+ if (body && body->getMotionState())
+ {
+ delete body->getMotionState();
+ }
+ m_dynamicsWorld->removeCollisionObject(obj);
+ delete obj;
+ }
+ // delete forces
+ for (int j = 0; j < m_forces.size(); j++)
+ {
+ btDeformableLagrangianForce* force = m_forces[j];
+ delete force;
+ }
+ m_forces.clear();
+
+ //delete collision shapes
+ for (int j = 0; j < m_collisionShapes.size(); j++)
+ {
+ btCollisionShape* shape = m_collisionShapes[j];
+ delete shape;
+ }
+ m_collisionShapes.clear();
+
+ delete m_dynamicsWorld;
+
+ delete m_solver;
+
+ delete m_broadphase;
+
+ delete m_dispatcher;
+
+ delete m_collisionConfiguration;
+}
+
+
+
+class CommonExampleInterface* FrictionSlopeCreateFunc(struct CommonExampleOptions& options)
+{
+ return new FrictionSlope(options.m_guiHelper);
+}
+
+
diff --git a/examples/ReducedDeformableDemo/FrictionSlope.h b/examples/ReducedDeformableDemo/FrictionSlope.h
new file mode 100644
index 000000000..d2cdd737b
--- /dev/null
+++ b/examples/ReducedDeformableDemo/FrictionSlope.h
@@ -0,0 +1,19 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef _FRICTION_SLOPE_H
+#define _FRICTION_SLOPE_H
+
+class CommonExampleInterface* FrictionSlopeCreateFunc(struct CommonExampleOptions& options);
+
+#endif //_REDUCED_FREE_FALL_H
diff --git a/examples/ReducedDeformableDemo/ModeVisualizer.cpp b/examples/ReducedDeformableDemo/ModeVisualizer.cpp
new file mode 100644
index 000000000..becf6bcee
--- /dev/null
+++ b/examples/ReducedDeformableDemo/ModeVisualizer.cpp
@@ -0,0 +1,227 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "ModeVisualizer.h"
+///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
+#include "btBulletDynamicsCommon.h"
+#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.h"
+#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
+#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
+#include "../CommonInterfaces/CommonParameterInterface.h"
+#include <stdio.h> //printf debugging
+
+#include "../CommonInterfaces/CommonDeformableBodyBase.h"
+#include "../Utils/b3ResourcePath.h"
+
+
+static int num_modes = 20;
+static btScalar visualize_mode = 0;
+static btScalar frequency_scale = 1;
+
+class ModeVisualizer : public CommonDeformableBodyBase
+{
+ btScalar sim_time;
+
+ // get deformed shape
+ void getDeformedShape(btReducedDeformableBody* rsb, const int mode_n, const btScalar time_term = 1)
+ {
+ for (int i = 0; i < rsb->m_nodes.size(); ++i)
+ for (int k = 0; k < 3; ++k)
+ rsb->m_nodes[i].m_x[k] = rsb->m_x0[i][k] + rsb->m_modes[mode_n][3 * i + k] * time_term;
+ }
+
+ btVector3 computeMassWeightedColumnSum(btReducedDeformableBody* rsb, const int mode_n)
+ {
+ btVector3 sum(0, 0, 0);
+ for (int i = 0; i < rsb->m_nodes.size(); ++i)
+ {
+ for (int k = 0; k < 3; ++k)
+ {
+ sum[k] += rsb->m_nodalMass[i] * rsb->m_modes[mode_n][3 * i + k];
+ }
+ }
+ return sum;
+ }
+
+public:
+ ModeVisualizer(struct GUIHelperInterface* helper)
+ : CommonDeformableBodyBase(helper)
+ {
+ sim_time = 0;
+ }
+ virtual ~ModeVisualizer()
+ {
+ }
+ void initPhysics();
+
+ void exitPhysics();
+
+ // disable pick force. non-interactive example.
+ bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) {
+ return false;
+ }
+
+ void resetCamera()
+ {
+ float dist = 10;
+ float pitch = 0;
+ float yaw = 90;
+ float targetPos[3] = {0, 3, 0};
+ m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
+ }
+
+ void stepSimulation(float deltaTime)
+ {
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(static_cast<btDeformableMultiBodyDynamicsWorld*>(m_dynamicsWorld)->getSoftBodyArray()[0]);
+
+ sim_time += deltaTime;
+ int n_mode = floor(visualize_mode);
+ btScalar scale = sin(sqrt(rsb->m_eigenvalues[n_mode]) * sim_time / frequency_scale);
+ getDeformedShape(rsb, n_mode, scale);
+ // btVector3 mass_weighted_column_sum = computeMassWeightedColumnSum(rsb, visualize_mode);
+ // std::cout << "mode=" << int(visualize_mode) << "\t" << mass_weighted_column_sum[0] << "\t"
+ // << mass_weighted_column_sum[1] << "\t"
+ // << mass_weighted_column_sum[2] << "\n";
+ }
+
+ virtual void renderScene()
+ {
+ CommonDeformableBodyBase::renderScene();
+ btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
+
+ for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
+ {
+ btSoftBody* rsb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
+ {
+ btSoftBodyHelpers::DrawFrame(rsb, deformableWorld->getDebugDrawer());
+ btSoftBodyHelpers::Draw(rsb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
+ }
+ }
+ }
+};
+
+void ModeVisualizer::initPhysics()
+{
+ m_guiHelper->setUpAxis(1);
+
+ ///collision configuration contains default setup for memory, collision setup
+ m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
+
+ ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
+ m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
+
+ m_broadphase = new btDbvtBroadphase();
+ btReducedDeformableBodySolver* reducedSoftBodySolver = new btReducedDeformableBodySolver();
+
+ btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
+ sol->setDeformableSolver(reducedSoftBodySolver);
+ m_solver = sol;
+
+ m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, reducedSoftBodySolver);
+ m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
+
+ // create volumetric soft body
+ {
+ std::string file_path("../../../data/reduced_cube/");
+ std::string vtk_file("cube_mesh.vtk");
+ btReducedDeformableBody* rsb = btReducedDeformableBodyHelpers::createReducedDeformableObject(
+ getDeformableDynamicsWorld()->getWorldInfo(),
+ file_path,
+ vtk_file,
+ num_modes,
+ false);
+
+ getDeformableDynamicsWorld()->addSoftBody(rsb);
+ rsb->getCollisionShape()->setMargin(0.1);
+
+ btTransform init_transform;
+ init_transform.setIdentity();
+ init_transform.setOrigin(btVector3(0, 2, 0));
+ // init_transform.setRotation(btQuaternion(btVector3(0, 1, 0), SIMD_PI / 2.0));
+ rsb->transform(init_transform);
+ btSoftBodyHelpers::generateBoundaryFaces(rsb);
+ }
+ getDeformableDynamicsWorld()->setImplicit(false);
+ m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
+
+ {
+ SliderParams slider("Visualize Mode", &visualize_mode);
+ slider.m_minVal = 0;
+ slider.m_maxVal = num_modes - 1;
+ if (m_guiHelper->getParameterInterface())
+ m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
+ }
+ {
+ SliderParams slider("Frequency Reduction", &frequency_scale);
+ slider.m_minVal = 1;
+ slider.m_maxVal = 1e3;
+ if (m_guiHelper->getParameterInterface())
+ m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
+ }
+}
+
+void ModeVisualizer::exitPhysics()
+{
+ //cleanup in the reverse order of creation/initialization
+ removePickingConstraint();
+ //remove the rigidbodies from the dynamics world and delete them
+ int i;
+ for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
+ {
+ btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
+ btRigidBody* body = btRigidBody::upcast(obj);
+ if (body && body->getMotionState())
+ {
+ delete body->getMotionState();
+ }
+ m_dynamicsWorld->removeCollisionObject(obj);
+ delete obj;
+ }
+ // delete forces
+ for (int j = 0; j < m_forces.size(); j++)
+ {
+ btDeformableLagrangianForce* force = m_forces[j];
+ delete force;
+ }
+ m_forces.clear();
+
+ //delete collision shapes
+ for (int j = 0; j < m_collisionShapes.size(); j++)
+ {
+ btCollisionShape* shape = m_collisionShapes[j];
+ delete shape;
+ }
+ m_collisionShapes.clear();
+
+ delete m_dynamicsWorld;
+
+ delete m_solver;
+
+ delete m_broadphase;
+
+ delete m_dispatcher;
+
+ delete m_collisionConfiguration;
+}
+
+
+
+class CommonExampleInterface* ReducedModeVisualizerCreateFunc(struct CommonExampleOptions& options)
+{
+ return new ModeVisualizer(options.m_guiHelper);
+}
+
+
diff --git a/examples/ReducedDeformableDemo/ModeVisualizer.h b/examples/ReducedDeformableDemo/ModeVisualizer.h
new file mode 100644
index 000000000..e6f292b73
--- /dev/null
+++ b/examples/ReducedDeformableDemo/ModeVisualizer.h
@@ -0,0 +1,19 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef _REDUCED_MODE_VISUALIZER_H
+#define _REDUCED_MODE_VISUALIZER_H
+
+class CommonExampleInterface* ReducedModeVisualizerCreateFunc(struct CommonExampleOptions& options);
+
+#endif //_REDUCED_MODE_VISUALIZER_H
diff --git a/examples/ReducedDeformableDemo/ReducedBenchmark.cpp b/examples/ReducedDeformableDemo/ReducedBenchmark.cpp
new file mode 100644
index 000000000..05ddc0362
--- /dev/null
+++ b/examples/ReducedDeformableDemo/ReducedBenchmark.cpp
@@ -0,0 +1,349 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "ReducedBenchmark.h"
+///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
+#include "btBulletDynamicsCommon.h"
+#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.h"
+#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
+#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
+#include "../CommonInterfaces/CommonParameterInterface.h"
+#include <stdio.h> //printf debugging
+
+#include "../CommonInterfaces/CommonDeformableBodyBase.h"
+#include "../Utils/b3ResourcePath.h"
+
+static btScalar damping_alpha = 0.0;
+static btScalar damping_beta = 0.0001;
+static btScalar COLLIDING_VELOCITY = 0;
+static int num_modes = 20;
+static bool run_reduced = true;
+
+class ReducedBenchmark : public CommonDeformableBodyBase
+{
+ btVector3 m_gravity;
+public:
+ ReducedBenchmark(struct GUIHelperInterface* helper)
+ : CommonDeformableBodyBase(helper)
+ {
+ }
+ virtual ~ReducedBenchmark()
+ {
+ }
+ void initPhysics();
+
+ void exitPhysics();
+
+ // TODO: disable pick force, non-interactive for now.
+ bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) {
+ return false;
+ }
+
+ void resetCamera()
+ {
+ // float dist = 6;
+ // float pitch = -10;
+ // float yaw = 90;
+ // float targetPos[3] = {0, 2, 0};
+ float dist = 10;
+ float pitch = -30;
+ float yaw = 125;
+ float targetPos[3] = {0, 2, 0};
+ m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
+ }
+
+ void Ctor_RbUpStack(const btVector3& origin)
+ {
+ float mass = 10;
+ btCollisionShape* shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
+ // btCollisionShape* shape = new btBoxShape(btVector3(1, 1, 1));
+ btTransform startTransform;
+ startTransform.setIdentity();
+ // startTransform.setOrigin(btVector3(0, 12, 0));
+ // btRigidBody* rb0 = createRigidBody(mass, startTransform, shape);
+ // rb0->setLinearVelocity(btVector3(0, 0, 0));
+
+ startTransform.setOrigin(origin);
+ // startTransform.setRotation(btQuaternion(btVector3(1, 0, 1), SIMD_PI / 4.0));
+ btRigidBody* rb1 = createRigidBody(mass, startTransform, shape);
+ rb1->setActivationState(DISABLE_DEACTIVATION);
+ // rb1->setLinearVelocity(btVector3(0, 0, 4));
+ }
+
+ void createDeform(const btVector3& origin, const btQuaternion& rotation)
+ {
+
+ if (run_reduced)
+ {
+ std::string file_path("../../../data/reduced_torus/");
+ std::string vtk_file("torus_mesh.vtk");
+ btReducedDeformableBody* rsb = btReducedDeformableBodyHelpers::createReducedDeformableObject(
+ getDeformableDynamicsWorld()->getWorldInfo(),
+ file_path,
+ vtk_file,
+ num_modes,
+ false);
+
+ getDeformableDynamicsWorld()->addSoftBody(rsb);
+ rsb->getCollisionShape()->setMargin(0.01);
+ // rsb->scale(btVector3(1, 1, 0.5));
+
+ rsb->setTotalMass(10);
+
+ btTransform init_transform;
+ init_transform.setIdentity();
+ init_transform.setOrigin(origin);
+ init_transform.setRotation(rotation);
+ rsb->transformTo(init_transform);
+
+ rsb->setStiffnessScale(5);
+ rsb->setDamping(damping_alpha, damping_beta);
+ // rsb->scale(btVector3(0.5, 0.5, 0.5));
+
+ rsb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
+ rsb->m_cfg.kCHR = 1; // collision hardness with rigid body
+ rsb->m_cfg.kDF = 0;
+ rsb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
+ rsb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
+ rsb->m_sleepingThreshold = 0;
+ btSoftBodyHelpers::generateBoundaryFaces(rsb);
+
+ std::cout << "Running reduced deformable\n";
+ }
+ else // create full deformable cube
+ {
+ std::string filepath("../../../data/reduced_torus/");
+ std::string filename = filepath + "torus_mesh.vtk";
+ btSoftBody* psb = btSoftBodyHelpers::CreateFromVtkFile(getDeformableDynamicsWorld()->getWorldInfo(), filename.c_str());
+
+ btTransform init_transform;
+ init_transform.setIdentity();
+ init_transform.setOrigin(origin);
+ init_transform.setRotation(rotation);
+ psb->transform(init_transform);
+ psb->getCollisionShape()->setMargin(0.015);
+ psb->setTotalMass(10);
+ psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
+ psb->m_cfg.kCHR = 1; // collision hardness with rigid body
+ psb->m_cfg.kDF = .5;
+ psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
+ psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
+ getDeformableDynamicsWorld()->addSoftBody(psb);
+ btSoftBodyHelpers::generateBoundaryFaces(psb);
+
+ btDeformableGravityForce* gravity_force = new btDeformableGravityForce(m_gravity);
+ getDeformableDynamicsWorld()->addForce(psb, gravity_force);
+ m_forces.push_back(gravity_force);
+
+ btScalar E = 10000;
+ btScalar nu = 0.3;
+ btScalar lambda = E * nu / ((1 + nu) * (1 - 2 * nu));
+ btScalar mu = E / (2 * (1 + nu));
+ btDeformableNeoHookeanForce* neohookean = new btDeformableNeoHookeanForce(lambda, mu, 0.01);
+ // neohookean->setPoissonRatio(0.3);
+ // neohookean->setYoungsModulus(25);
+ neohookean->setDamping(0.01);
+ psb->m_cfg.drag = 0.001;
+ getDeformableDynamicsWorld()->addForce(psb, neohookean);
+ m_forces.push_back(neohookean);
+
+ std::cout << "Running full deformable\n";
+ }
+
+ // btReducedDeformableBody* rsb = btReducedDeformableBodyHelpers::createReducedTorus(getDeformableDynamicsWorld()->getWorldInfo(), num_modes);
+
+ // getDeformableDynamicsWorld()->addSoftBody(rsb);
+ // rsb->getCollisionShape()->setMargin(0.01);
+ // // rsb->scale(btVector3(1, 1, 0.5));
+
+ // rsb->setTotalMass(10);
+
+ // btTransform init_transform;
+ // init_transform.setIdentity();
+ // init_transform.setOrigin(origin);
+ // init_transform.setRotation(rotation);
+ // rsb->transformTo(init_transform);
+
+ // rsb->setStiffnessScale(5);
+ // rsb->setDamping(damping_alpha, damping_beta);
+ // // rsb->scale(btVector3(0.5, 0.5, 0.5));
+
+ // rsb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
+ // rsb->m_cfg.kCHR = 1; // collision hardness with rigid body
+ // rsb->m_cfg.kDF = 0;
+ // rsb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
+ // rsb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
+ // rsb->m_sleepingThreshold = 0;
+ // btSoftBodyHelpers::generateBoundaryFaces(rsb);
+ }
+
+ void stepSimulation(float deltaTime)
+ {
+ float internalTimeStep = 1. / 240.f;
+ m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
+ }
+
+ virtual void renderScene()
+ {
+ CommonDeformableBodyBase::renderScene();
+ btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
+
+ for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
+ {
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(deformableWorld->getSoftBodyArray()[i]);
+ {
+ btSoftBodyHelpers::DrawFrame(rsb, deformableWorld->getDebugDrawer());
+ btSoftBodyHelpers::Draw(rsb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
+ }
+ }
+ }
+};
+
+void ReducedBenchmark::initPhysics()
+{
+ m_guiHelper->setUpAxis(1);
+
+ ///collision configuration contains default setup for memory, collision setup
+ m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
+
+ ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
+ m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
+
+ m_broadphase = new btDbvtBroadphase();
+
+ if (run_reduced)
+ {
+ btReducedDeformableBodySolver* solver = new btReducedDeformableBodySolver();
+
+ btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
+ sol->setDeformableSolver(solver);
+ m_solver = sol;
+ m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, solver);
+ }
+ else
+ {
+ btDeformableBodySolver* solver = new btDeformableBodySolver();
+
+ btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
+ sol->setDeformableSolver(solver);
+ m_solver = sol;
+ m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, solver);
+ }
+
+ // m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, solver);
+ btVector3 gravity = btVector3(0, -10, 0);
+ m_gravity = gravity;
+ m_dynamicsWorld->setGravity(gravity);
+ getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
+ m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
+
+ // 3x3 torus
+ createDeform(btVector3(4, 4, -4), btQuaternion(SIMD_PI / 2.0, SIMD_PI / 2.0, 0));
+ createDeform(btVector3(4, 4, 0), btQuaternion(SIMD_PI / 2.0, SIMD_PI / 2.0, 0));
+ createDeform(btVector3(4, 4, 4), btQuaternion(SIMD_PI / 2.0, SIMD_PI / 2.0, 0));
+ createDeform(btVector3(0, 4, -4), btQuaternion(SIMD_PI / 2.0, SIMD_PI / 2.0, 0));
+ createDeform(btVector3(0, 4, 0), btQuaternion(SIMD_PI / 2.0, SIMD_PI / 2.0, 0));
+ createDeform(btVector3(0, 4, 4), btQuaternion(SIMD_PI / 2.0, SIMD_PI / 2.0, 0));
+ createDeform(btVector3(-4, 4, -4), btQuaternion(SIMD_PI / 2.0, SIMD_PI / 2.0, 0));
+ createDeform(btVector3(-4, 4, 0), btQuaternion(SIMD_PI / 2.0, SIMD_PI / 2.0, 0));
+ createDeform(btVector3(-4, 4, 4), btQuaternion(SIMD_PI / 2.0, SIMD_PI / 2.0, 0));
+
+ // create a static rigid box as the ground
+ {
+ // btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50), btScalar(50), btScalar(50)));
+ btBoxShape* groundShape = createBoxShape(btVector3(btScalar(20), btScalar(2), btScalar(20)));
+ m_collisionShapes.push_back(groundShape);
+
+ btTransform groundTransform;
+ groundTransform.setIdentity();
+ // groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI / 6.0));
+ // groundTransform.setRotation(btQuaternion(btVector3(0, 0, 1), SIMD_PI / 6.0));
+ groundTransform.setOrigin(btVector3(0, 0, 0));
+ // groundTransform.setOrigin(btVector3(0, 0, 6));
+ // groundTransform.setOrigin(btVector3(0, -50, 0));
+ {
+ btScalar mass(0.);
+ createRigidBody(mass, groundTransform, groundShape, btVector4(0,0,0,0));
+ }
+ }
+
+ getDeformableDynamicsWorld()->setImplicit(false);
+ getDeformableDynamicsWorld()->setLineSearch(false);
+ getDeformableDynamicsWorld()->setUseProjection(false);
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_erp = 0.2;
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_cfm = 0.2;
+ getDeformableDynamicsWorld()->getSolverInfo().m_friction = 0.5;
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_maxErrorReduction = btScalar(200);
+ getDeformableDynamicsWorld()->getSolverInfo().m_leastSquaresResidualThreshold = 1e-3;
+ getDeformableDynamicsWorld()->getSolverInfo().m_splitImpulse = false;
+ getDeformableDynamicsWorld()->getSolverInfo().m_numIterations = 100;
+
+ m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
+ m_dynamicsWorld->setGravity(gravity);
+}
+
+void ReducedBenchmark::exitPhysics()
+{
+ //cleanup in the reverse order of creation/initialization
+ removePickingConstraint();
+ //remove the rigidbodies from the dynamics world and delete them
+ int i;
+ for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
+ {
+ btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
+ btRigidBody* body = btRigidBody::upcast(obj);
+ if (body && body->getMotionState())
+ {
+ delete body->getMotionState();
+ }
+ m_dynamicsWorld->removeCollisionObject(obj);
+ delete obj;
+ }
+ // delete forces
+ for (int j = 0; j < m_forces.size(); j++)
+ {
+ btDeformableLagrangianForce* force = m_forces[j];
+ delete force;
+ }
+ m_forces.clear();
+
+ //delete collision shapes
+ for (int j = 0; j < m_collisionShapes.size(); j++)
+ {
+ btCollisionShape* shape = m_collisionShapes[j];
+ delete shape;
+ }
+ m_collisionShapes.clear();
+
+ delete m_dynamicsWorld;
+
+ delete m_solver;
+
+ delete m_broadphase;
+
+ delete m_dispatcher;
+
+ delete m_collisionConfiguration;
+}
+
+
+
+class CommonExampleInterface* ReducedBenchmarkCreateFunc(struct CommonExampleOptions& options)
+{
+ return new ReducedBenchmark(options.m_guiHelper);
+}
+
+
diff --git a/examples/ReducedDeformableDemo/ReducedBenchmark.h b/examples/ReducedDeformableDemo/ReducedBenchmark.h
new file mode 100644
index 000000000..ffaa4fcff
--- /dev/null
+++ b/examples/ReducedDeformableDemo/ReducedBenchmark.h
@@ -0,0 +1,19 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef _REDUCED_BENCHMARK_H
+#define _REDUCED_BENCHMARK_H
+
+class CommonExampleInterface* ReducedBenchmarkCreateFunc(struct CommonExampleOptions& options);
+
+#endif //_REDUCED_BENCHMARK_H
diff --git a/examples/ReducedDeformableDemo/ReducedCollide.cpp b/examples/ReducedDeformableDemo/ReducedCollide.cpp
new file mode 100644
index 000000000..dd84946ae
--- /dev/null
+++ b/examples/ReducedDeformableDemo/ReducedCollide.cpp
@@ -0,0 +1,522 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "ReducedCollide.h"
+///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
+#include "btBulletDynamicsCommon.h"
+#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.h"
+#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
+#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
+#include "../CommonInterfaces/CommonParameterInterface.h"
+#include <stdio.h> //printf debugging
+
+#include "../CommonInterfaces/CommonDeformableBodyBase.h"
+#include "../Utils/b3ResourcePath.h"
+
+///The BasicTest shows the contact between volumetric deformable objects and rigid objects.
+// static btScalar E = 50;
+// static btScalar nu = 0.3;
+static btScalar damping_alpha = 0.0;
+static btScalar damping_beta = 0.0;
+static btScalar COLLIDING_VELOCITY = 4;
+static int num_modes = 20;
+
+class ReducedCollide : public CommonDeformableBodyBase
+{
+public:
+ ReducedCollide(struct GUIHelperInterface* helper)
+ : CommonDeformableBodyBase(helper)
+ {
+ }
+ virtual ~ReducedCollide()
+ {
+ }
+ void initPhysics();
+
+ void exitPhysics();
+
+ btMultiBody* createFeatherstoneMultiBody_testMultiDof(class btMultiBodyDynamicsWorld* world, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical = false, bool floating = false);
+ void addColliders_testMultiDof(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents);
+
+ // TODO: disable pick force, non-interactive for now.
+ bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) {
+ return false;
+ }
+
+ void resetCamera()
+ {
+ // float dist = 20;
+ // float pitch = -10;
+ float dist = 10;
+ float pitch = -5;
+ float yaw = 90;
+ float targetPos[3] = {0, 0, 0};
+
+ // float dist = 5;
+ // float pitch = -35;
+ // float yaw = 50;
+ // float targetPos[3] = {-3, 2.8, -2.5};
+ m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
+ }
+
+ void Ctor_RbUpStack()
+ {
+ float mass = 10;
+
+ btCollisionShape* shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
+ // btCollisionShape* shape = new btBoxShape(btVector3(1, 1, 1));
+ btVector3 localInertia(0, 0, 0);
+ if (mass != 0.f)
+ shape->calculateLocalInertia(mass, localInertia);
+
+ btTransform startTransform;
+ startTransform.setIdentity();
+ startTransform.setOrigin(btVector3(0,-2,0));
+ // startTransform.setRotation(btQuaternion(btVector3(1, 0, 1), SIMD_PI / 3.0));
+ btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
+
+ btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, shape, localInertia);
+ btRigidBody* body = new btRigidBody(rbInfo);
+
+ m_dynamicsWorld->addRigidBody(body, 1, 1+2);
+
+ body->setActivationState(DISABLE_DEACTIVATION);
+ body->setLinearVelocity(btVector3(0, COLLIDING_VELOCITY, 0));
+ // body->setFriction(1);
+ }
+
+ void rigidBar()
+ {
+ float mass = 10;
+
+ btCollisionShape* shape = new btBoxShape(btVector3(0.5, 0.25, 2));
+ btVector3 localInertia(0, 0, 0);
+ if (mass != 0.f)
+ shape->calculateLocalInertia(mass, localInertia);
+
+ btTransform startTransform;
+ startTransform.setIdentity();
+ startTransform.setOrigin(btVector3(0,10,0));
+ // startTransform.setRotation(btQuaternion(btVector3(1, 0, 1), SIMD_PI / 3.0));
+ btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
+
+ btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, shape, localInertia);
+ btRigidBody* body = new btRigidBody(rbInfo);
+
+ m_dynamicsWorld->addRigidBody(body, 1, 1+2);
+
+ body->setActivationState(DISABLE_DEACTIVATION);
+ body->setLinearVelocity(btVector3(0, 0, 0));
+ // body->setFriction(0);
+ }
+
+ void createGround()
+ {
+ // float mass = 55;
+ float mass = 0;
+
+ btCollisionShape* shape = new btBoxShape(btVector3(10, 2, 10));
+ btVector3 localInertia(0, 0, 0);
+ if (mass != 0.f)
+ shape->calculateLocalInertia(mass, localInertia);
+
+ btTransform startTransform;
+ startTransform.setIdentity();
+ startTransform.setOrigin(btVector3(0,-2,0));
+ // startTransform.setRotation(btQuaternion(btVector3(1, 0, 1), SIMD_PI / 3.0));
+ btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
+
+ btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, shape, localInertia);
+ btRigidBody* body = new btRigidBody(rbInfo);
+
+ m_dynamicsWorld->addRigidBody(body, 1, 1+2);
+
+ body->setActivationState(DISABLE_DEACTIVATION);
+ body->setLinearVelocity(btVector3(0, 0, 0));
+ // body->setFriction(1);
+ }
+
+ void stepSimulation(float deltaTime)
+ {
+ float internalTimeStep = 1. / 60.f;
+ m_dynamicsWorld->stepSimulation(deltaTime, 1, internalTimeStep);
+ }
+
+ virtual void renderScene()
+ {
+ CommonDeformableBodyBase::renderScene();
+ btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
+
+ for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
+ {
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(deformableWorld->getSoftBodyArray()[i]);
+ {
+ btSoftBodyHelpers::DrawFrame(rsb, deformableWorld->getDebugDrawer());
+ btSoftBodyHelpers::Draw(rsb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
+ }
+
+ for (int p = 0; p < rsb->m_contactNodesList.size(); ++p)
+ {
+ int index = rsb->m_contactNodesList[p];
+ deformableWorld->getDebugDrawer()->drawSphere(rsb->m_nodes[index].m_x, 0.2, btVector3(0, 1, 0));
+ }
+ }
+ }
+};
+
+void ReducedCollide::initPhysics()
+{
+ m_guiHelper->setUpAxis(1);
+
+ ///collision configuration contains default setup for memory, collision setup
+ m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
+
+ ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
+ m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
+
+ m_broadphase = new btDbvtBroadphase();
+ btReducedDeformableBodySolver* reducedSoftBodySolver = new btReducedDeformableBodySolver();
+ btVector3 gravity = btVector3(0, 0, 0);
+ reducedSoftBodySolver->setGravity(gravity);
+
+ btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
+ sol->setDeformableSolver(reducedSoftBodySolver);
+ m_solver = sol;
+
+ m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, reducedSoftBodySolver);
+ m_dynamicsWorld->setGravity(gravity);
+ m_dynamicsWorld->getSolverInfo().m_globalCfm = 1e-3;
+ m_dynamicsWorld->getSolverInfo().m_solverMode |= SOLVER_RANDMIZE_ORDER;
+ m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
+
+ // create volumetric reduced deformable body
+ {
+ std::string file_path("../../../data/reduced_cube/");
+ std::string vtk_file("cube_mesh.vtk");
+ btReducedDeformableBody* rsb = btReducedDeformableBodyHelpers::createReducedDeformableObject(
+ getDeformableDynamicsWorld()->getWorldInfo(),
+ file_path,
+ vtk_file,
+ num_modes,
+ false);
+
+ getDeformableDynamicsWorld()->addSoftBody(rsb);
+ rsb->getCollisionShape()->setMargin(0.1);
+ // rsb->scale(btVector3(0.5, 0.5, 0.5));
+
+ rsb->setStiffnessScale(100);
+ rsb->setDamping(damping_alpha, damping_beta);
+
+ rsb->setTotalMass(15);
+
+ btTransform init_transform;
+ init_transform.setIdentity();
+ init_transform.setOrigin(btVector3(0, 4, 0));
+ // init_transform.setRotation(btQuaternion(0, SIMD_PI / 2.0, SIMD_PI / 2.0));
+ rsb->transformTo(init_transform);
+
+ rsb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
+ rsb->m_cfg.kCHR = 1; // collision hardness with rigid body
+ rsb->m_cfg.kDF = 0;
+ rsb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
+ rsb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
+ rsb->m_sleepingThreshold = 0;
+ btSoftBodyHelpers::generateBoundaryFaces(rsb);
+
+ rsb->setRigidVelocity(btVector3(0, -COLLIDING_VELOCITY, 0));
+ // rsb->setRigidAngularVelocity(btVector3(1, 0, 0));
+ b3Printf("total mass: %e", rsb->getTotalMass());
+ }
+ // rigidBar();
+
+ // add a few rigid bodies
+ Ctor_RbUpStack();
+
+ // create ground
+ // createGround();
+
+ // create multibody
+ // {
+ // bool damping = false;
+ // bool gyro = true;
+ // int numLinks = 0;
+ // bool spherical = true; //set it ot false -to use 1DoF hinges instead of 3DoF sphericals
+ // bool multibodyOnly = true;
+ // bool canSleep = false;
+ // bool selfCollide = true;
+ // bool multibodyConstraint = false;
+ // btVector3 linkHalfExtents(0.05, 0.37, 0.1);
+ // btVector3 baseHalfExtents(1, 1, 1);
+ // // btVector3 baseHalfExtents(2.5, 0.5, 2.5);
+ // // btVector3 baseHalfExtents(0.05, 0.37, 0.1);
+
+ // bool g_floatingBase = true;
+ // // btMultiBody* mbC = createFeatherstoneMultiBody_testMultiDof(m_dynamicsWorld, numLinks, btVector3(0, 4, 0), linkHalfExtents, baseHalfExtents, spherical, g_floatingBase);
+ // btMultiBody* mbC = createFeatherstoneMultiBody_testMultiDof(m_dynamicsWorld, numLinks, btVector3(0.f, 4.f, 0.f), baseHalfExtents, linkHalfExtents, spherical, g_floatingBase);
+ // //mbC->forceMultiDof(); //if !spherical, you can comment this line to check the 1DoF algorithm
+
+ // mbC->setCanSleep(canSleep);
+ // mbC->setHasSelfCollision(selfCollide);
+ // mbC->setUseGyroTerm(gyro);
+ // //
+ // if (!damping)
+ // {
+ // mbC->setLinearDamping(0.f);
+ // mbC->setAngularDamping(0.f);
+ // }
+ // else
+ // {
+ // mbC->setLinearDamping(0.1f);
+ // mbC->setAngularDamping(0.9f);
+ // }
+ // //
+ // //////////////////////////////////////////////
+ // // if (numLinks > 0)
+ // // {
+ // // btScalar q0 = 45.f * SIMD_PI / 180.f;
+ // // if (!spherical)
+ // // {
+ // // mbC->setJointPosMultiDof(0, &q0);
+ // // }
+ // // else
+ // // {
+ // // btQuaternion quat0(btVector3(1, 1, 0).normalized(), q0);
+ // // quat0.normalize();
+ // // mbC->setJointPosMultiDof(0, quat0);
+ // // }
+ // // }
+ // ///
+ // addColliders_testMultiDof(mbC, m_dynamicsWorld, baseHalfExtents, linkHalfExtents);
+ // }
+
+ getDeformableDynamicsWorld()->setImplicit(false);
+ getDeformableDynamicsWorld()->setLineSearch(false);
+ getDeformableDynamicsWorld()->setUseProjection(false);
+ getDeformableDynamicsWorld()->getSolverInfo().m_friction = 1;
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_erp = 0.2;
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_cfm = 0.2;
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_maxErrorReduction = btScalar(200);
+ getDeformableDynamicsWorld()->getSolverInfo().m_leastSquaresResidualThreshold = 1e-3;
+ getDeformableDynamicsWorld()->getSolverInfo().m_splitImpulse = false;
+ getDeformableDynamicsWorld()->getSolverInfo().m_numIterations = 100;
+ m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
+
+ // {
+ // SliderParams slider("Young's Modulus", &E);
+ // slider.m_minVal = 0;
+ // slider.m_maxVal = 2000;
+ // if (m_guiHelper->getParameterInterface())
+ // m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
+ // }
+ // {
+ // SliderParams slider("Poisson Ratio", &nu);
+ // slider.m_minVal = 0.05;
+ // slider.m_maxVal = 0.49;
+ // if (m_guiHelper->getParameterInterface())
+ // m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
+ // }
+ // {
+ // SliderParams slider("Mass Damping", &damping_alpha);
+ // slider.m_minVal = 0;
+ // slider.m_maxVal = 1;
+ // if (m_guiHelper->getParameterInterface())
+ // m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
+ // }
+ // {
+ // SliderParams slider("Stiffness Damping", &damping_beta);
+ // slider.m_minVal = 0;
+ // slider.m_maxVal = 0.1;
+ // if (m_guiHelper->getParameterInterface())
+ // m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
+ // }
+}
+
+void ReducedCollide::exitPhysics()
+{
+ //cleanup in the reverse order of creation/initialization
+ removePickingConstraint();
+ //remove the rigidbodies from the dynamics world and delete them
+ int i;
+ for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
+ {
+ btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
+ btRigidBody* body = btRigidBody::upcast(obj);
+ if (body && body->getMotionState())
+ {
+ delete body->getMotionState();
+ }
+ m_dynamicsWorld->removeCollisionObject(obj);
+ delete obj;
+ }
+ // delete forces
+ for (int j = 0; j < m_forces.size(); j++)
+ {
+ btDeformableLagrangianForce* force = m_forces[j];
+ delete force;
+ }
+ m_forces.clear();
+
+ //delete collision shapes
+ for (int j = 0; j < m_collisionShapes.size(); j++)
+ {
+ btCollisionShape* shape = m_collisionShapes[j];
+ delete shape;
+ }
+ m_collisionShapes.clear();
+
+ delete m_dynamicsWorld;
+
+ delete m_solver;
+
+ delete m_broadphase;
+
+ delete m_dispatcher;
+
+ delete m_collisionConfiguration;
+}
+
+btMultiBody* ReducedCollide::createFeatherstoneMultiBody_testMultiDof(btMultiBodyDynamicsWorld* pWorld, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical, bool floating)
+{
+ //init the base
+ btVector3 baseInertiaDiag(0.f, 0.f, 0.f);
+ float baseMass = 10;
+
+ if (baseMass)
+ {
+ btCollisionShape* pTempBox = new btBoxShape(btVector3(baseHalfExtents[0], baseHalfExtents[1], baseHalfExtents[2]));
+ pTempBox->calculateLocalInertia(baseMass, baseInertiaDiag);
+ delete pTempBox;
+ }
+
+ bool canSleep = false;
+
+ btMultiBody* pMultiBody = new btMultiBody(numLinks, baseMass, baseInertiaDiag, !floating, canSleep);
+
+ btQuaternion baseOriQuat(0.f, 0.f, 0.f, 1.f);
+ // btQuaternion baseOriQuat(btVector3(0, 0, 1), -SIMD_PI / 6.0);
+ pMultiBody->setBasePos(basePosition);
+ pMultiBody->setWorldToBaseRot(baseOriQuat);
+ btVector3 vel(0, 0, 0);
+
+ //init the links
+ btVector3 hingeJointAxis(1, 0, 0);
+ float linkMass = 1.f;
+ btVector3 linkInertiaDiag(0.f, 0.f, 0.f);
+
+ btCollisionShape* pTempBox = new btBoxShape(btVector3(linkHalfExtents[0], linkHalfExtents[1], linkHalfExtents[2]));
+ pTempBox->calculateLocalInertia(linkMass, linkInertiaDiag);
+ delete pTempBox;
+
+ //y-axis assumed up
+ btVector3 parentComToCurrentCom(0, -linkHalfExtents[1] * 2.f, 0); //par body's COM to cur body's COM offset
+ btVector3 currentPivotToCurrentCom(0, -linkHalfExtents[1], 0); //cur body's COM to cur body's PIV offset
+ btVector3 parentComToCurrentPivot = parentComToCurrentCom - currentPivotToCurrentCom; //par body's COM to cur body's PIV offset
+
+ //////
+ btScalar q0 = 0.f * SIMD_PI / 180.f;
+ btQuaternion quat0(btVector3(0, 1, 0).normalized(), q0);
+ quat0.normalize();
+ /////
+
+ for (int i = 0; i < numLinks; ++i)
+ {
+ if (!spherical)
+ pMultiBody->setupRevolute(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), hingeJointAxis, parentComToCurrentPivot, currentPivotToCurrentCom, true);
+ else
+ //pMultiBody->setupPlanar(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f)/*quat0*/, btVector3(1, 0, 0), parentComToCurrentPivot*2, false);
+ pMultiBody->setupSpherical(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), parentComToCurrentPivot, currentPivotToCurrentCom, true);
+ }
+
+ pMultiBody->finalizeMultiDof();
+ pMultiBody->setBaseVel(vel);
+
+ ///
+ pWorld->addMultiBody(pMultiBody);
+ ///
+ return pMultiBody;
+}
+
+void ReducedCollide::addColliders_testMultiDof(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents)
+{
+ btAlignedObjectArray<btQuaternion> world_to_local;
+ world_to_local.resize(pMultiBody->getNumLinks() + 1);
+
+ btAlignedObjectArray<btVector3> local_origin;
+ local_origin.resize(pMultiBody->getNumLinks() + 1);
+ world_to_local[0] = pMultiBody->getWorldToBaseRot();
+ local_origin[0] = pMultiBody->getBasePos();
+
+ {
+ // float pos[4]={local_origin[0].x(),local_origin[0].y(),local_origin[0].z(),1};
+ btScalar quat[4] = {-world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w()};
+
+ if (1)
+ {
+ btCollisionShape* box = new btBoxShape(baseHalfExtents);
+ btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, -1);
+ col->setCollisionShape(box);
+
+ btTransform tr;
+ tr.setIdentity();
+ tr.setOrigin(local_origin[0]);
+ tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
+ col->setWorldTransform(tr);
+
+ pWorld->addCollisionObject(col, 2, 1 + 2);
+
+ col->setFriction(1);
+ pMultiBody->setBaseCollider(col);
+ }
+ }
+
+ for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
+ {
+ const int parent = pMultiBody->getParent(i);
+ world_to_local[i + 1] = pMultiBody->getParentToLocalRot(i) * world_to_local[parent + 1];
+ local_origin[i + 1] = local_origin[parent + 1] + (quatRotate(world_to_local[i + 1].inverse(), pMultiBody->getRVector(i)));
+ }
+
+ for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
+ {
+ btVector3 posr = local_origin[i + 1];
+ // float pos[4]={posr.x(),posr.y(),posr.z(),1};
+
+ btScalar quat[4] = {-world_to_local[i + 1].x(), -world_to_local[i + 1].y(), -world_to_local[i + 1].z(), world_to_local[i + 1].w()};
+
+ btCollisionShape* box = new btBoxShape(linkHalfExtents);
+ btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, i);
+
+ col->setCollisionShape(box);
+ btTransform tr;
+ tr.setIdentity();
+ tr.setOrigin(posr);
+ tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
+ col->setWorldTransform(tr);
+ col->setFriction(1);
+ pWorld->addCollisionObject(col, 2, 1 + 2);
+
+ pMultiBody->getLink(i).m_collider = col;
+ }
+}
+
+
+
+class CommonExampleInterface* ReducedCollideCreateFunc(struct CommonExampleOptions& options)
+{
+ return new ReducedCollide(options.m_guiHelper);
+}
+
+
diff --git a/examples/ReducedDeformableDemo/ReducedCollide.h b/examples/ReducedDeformableDemo/ReducedCollide.h
new file mode 100644
index 000000000..cd2ed89f5
--- /dev/null
+++ b/examples/ReducedDeformableDemo/ReducedCollide.h
@@ -0,0 +1,19 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef _REDUCED_COLLIDE_H
+#define _REDUCED_COLLIDE_H
+
+class CommonExampleInterface* ReducedCollideCreateFunc(struct CommonExampleOptions& options);
+
+#endif //_REDUCED_COLLIDE_H
diff --git a/examples/ReducedDeformableDemo/ReducedGrasp.cpp b/examples/ReducedDeformableDemo/ReducedGrasp.cpp
new file mode 100644
index 000000000..c40e0c554
--- /dev/null
+++ b/examples/ReducedDeformableDemo/ReducedGrasp.cpp
@@ -0,0 +1,457 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "ReducedGrasp.h"
+///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
+#include "btBulletDynamicsCommon.h"
+#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.h"
+#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
+#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
+#include "../CommonInterfaces/CommonParameterInterface.h"
+#include <stdio.h> //printf debugging
+
+#include "../CommonInterfaces/CommonDeformableBodyBase.h"
+#include "../Utils/b3ResourcePath.h"
+
+///The BasicTest shows the contact between volumetric deformable objects and rigid objects.
+// static btScalar E = 50;
+// static btScalar nu = 0.3;
+static btScalar damping_alpha = 0.0;
+static btScalar damping_beta = 0.0001;
+static int num_modes = 20;
+
+class ReducedGrasp : public CommonDeformableBodyBase
+{
+public:
+ ReducedGrasp(struct GUIHelperInterface* helper)
+ : CommonDeformableBodyBase(helper)
+ {
+ }
+ virtual ~ReducedGrasp()
+ {
+ }
+ void initPhysics();
+
+ void exitPhysics();
+
+ void resetCamera()
+ {
+ float dist = 10;
+ float pitch = -10;
+ float yaw = 90;
+
+ // float dist = 25;
+ // float pitch = -30;
+ // float yaw = 100;
+ float targetPos[3] = {0, 0, 0};
+ m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
+ }
+
+ void stepSimulation(float deltaTime)
+ {
+ //use a smaller internal timestep, there are stability issues
+ float internalTimeStep = 1. / 240.f;
+ m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
+ // float internalTimeStep = 1. / 60.f;
+ // m_dynamicsWorld->stepSimulation(deltaTime, 1, internalTimeStep);
+ }
+
+ void createGrip()
+ {
+ int count = 2;
+ float mass = 1e6;
+ btCollisionShape* shape = new btBoxShape(btVector3(1, 1, 0.25));
+ {
+ btTransform startTransform;
+ startTransform.setIdentity();
+ startTransform.setOrigin(btVector3(0,1,0));
+ startTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
+ createRigidBody(mass, startTransform, shape);
+ }
+ {
+ btTransform startTransform;
+ startTransform.setIdentity();
+ startTransform.setOrigin(btVector3(0,1,-4));
+ startTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
+ createRigidBody(mass, startTransform, shape);
+ }
+
+ }
+
+ void Ctor_RbUpStack()
+ {
+ float mass = 8;
+ btCollisionShape* shape = new btBoxShape(btVector3(0.25, 2, 0.5));
+ btTransform startTransform;
+ startTransform.setIdentity();
+
+ startTransform.setOrigin(btVector3(0,9.5,0));
+ btRigidBody* rb1 = createRigidBody(mass, startTransform, shape);
+ rb1->setLinearVelocity(btVector3(0, 0, 0));
+ rb1->setFriction(0.7);
+ }
+
+ virtual void renderScene()
+ {
+ CommonDeformableBodyBase::renderScene();
+ btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
+
+ for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
+ {
+ // btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(deformableWorld->getSoftBodyArray()[i]);
+ // {
+ // btSoftBodyHelpers::DrawFrame(rsb, deformableWorld->getDebugDrawer());
+ // btSoftBodyHelpers::Draw(rsb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
+ // }
+
+ // for (int p = 0; p < rsb->m_nodeRigidContacts.size(); ++p)
+ // {
+ // deformableWorld->getDebugDrawer()->drawSphere(rsb->m_nodes[rsb->m_contactNodesList[p]].m_x, 0.1, btVector3(0, 1, 0));
+ // }
+
+ btSoftBody* psb = static_cast<btSoftBody*>(deformableWorld->getSoftBodyArray()[i]);
+ {
+ btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
+ btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
+ }
+ }
+ }
+
+ static void GripperDynamics(btScalar time, btDeformableMultiBodyDynamicsWorld* world);
+};
+
+void ReducedGrasp::GripperDynamics(btScalar time, btDeformableMultiBodyDynamicsWorld* world)
+{
+ btAlignedObjectArray<btRigidBody*>& rbs = world->getNonStaticRigidBodies();
+ if (rbs.size()<2)
+ return;
+ btRigidBody* rb0 = rbs[0];
+ // btScalar pressTime = 0.9;
+ // btScalar pressTime = 0.96;
+ btScalar pressTime = 1.26;
+ btScalar liftTime = 2.5;
+ btScalar shiftTime = 6;
+ btScalar holdTime = 7;
+ btScalar dropTime = 10;
+ // btScalar holdTime = 500;
+ // btScalar dropTime = 1000;
+ btTransform rbTransform;
+ rbTransform.setIdentity();
+ btVector3 translation;
+ btVector3 velocity;
+
+ btVector3 initialTranslationLeft = btVector3(0,1,0); // inner face has z=2
+ btVector3 initialTranslationRight = btVector3(0,1,-4); // inner face has z=-2
+ btVector3 pinchVelocityLeft = btVector3(0,0,-1);
+ btVector3 pinchVelocityRight = btVector3(0,0,1);
+ btVector3 liftVelocity = btVector3(0,4,0);
+ btVector3 shiftVelocity = btVector3(0,0,2);
+ btVector3 holdVelocity = btVector3(0,0,0);
+ btVector3 openVelocityLeft = btVector3(0,0,4);
+ btVector3 openVelocityRight = btVector3(0,0,-4);
+
+ if (time < pressTime)
+ {
+ velocity = pinchVelocityLeft;
+ translation = initialTranslationLeft + pinchVelocityLeft * time;
+ }
+ // else
+ // {
+ // velocity = btVector3(0, 0, 0);
+ // translation = initialTranslationLeft + pinchVelocityLeft * pressTime;
+ // }
+ else if (time < liftTime)
+ {
+ velocity = liftVelocity;
+ translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (time - pressTime);
+ }
+ else if (time < shiftTime)
+ {
+ velocity = shiftVelocity;
+ translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (time - liftTime);
+ }
+ else if (time < holdTime)
+ {
+ velocity = btVector3(0,0,0);
+ translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (time - shiftTime);
+ }
+ else if (time < dropTime)
+ {
+ velocity = openVelocityLeft;
+ translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityLeft * (time - holdTime);
+ }
+ else
+ {
+ velocity = holdVelocity;
+ translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityLeft * (dropTime - holdTime);
+ }
+ rbTransform.setOrigin(translation);
+ rbTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
+ rb0->setCenterOfMassTransform(rbTransform);
+ rb0->setAngularVelocity(btVector3(0,0,0));
+ rb0->setLinearVelocity(velocity);
+
+ btRigidBody* rb1 = rbs[1];
+ if (time < pressTime)
+ {
+ velocity = pinchVelocityRight;
+ translation = initialTranslationRight + pinchVelocityRight * time;
+ }
+ // else
+ // {
+ // velocity = btVector3(0, 0, 0);
+ // translation = initialTranslationRight + pinchVelocityRight * pressTime;
+ // }
+ else if (time < liftTime)
+ {
+ velocity = liftVelocity;
+ translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (time - pressTime);
+ }
+ else if (time < shiftTime)
+ {
+ velocity = shiftVelocity;
+ translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (time - liftTime);
+ }
+ else if (time < holdTime)
+ {
+ velocity = btVector3(0,0,0);
+ translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (time - shiftTime);
+ }
+ else if (time < dropTime)
+ {
+ velocity = openVelocityRight;
+ translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityRight * (time - holdTime);
+ }
+ else
+ {
+ velocity = holdVelocity;
+ translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityRight * (dropTime - holdTime);
+ }
+ rbTransform.setOrigin(translation);
+ rbTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
+ rb1->setCenterOfMassTransform(rbTransform);
+ rb1->setAngularVelocity(btVector3(0,0,0));
+ rb1->setLinearVelocity(velocity);
+
+ rb0->setFriction(20);
+ rb1->setFriction(20);
+}
+
+void ReducedGrasp::initPhysics()
+{
+ m_guiHelper->setUpAxis(1);
+
+ ///collision configuration contains default setup for memory, collision setup
+ m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
+
+ ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
+ m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
+
+ m_broadphase = new btDbvtBroadphase();
+ // btDeformableBodySolver* solver = new btDeformableBodySolver();
+ btReducedDeformableBodySolver* solver = new btReducedDeformableBodySolver();
+
+ btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
+ sol->setDeformableSolver(solver);
+ m_solver = sol;
+
+ m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, solver);
+ btVector3 gravity = btVector3(0, -10, 0);
+ m_dynamicsWorld->setGravity(gravity);
+ getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
+ getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
+ getDeformableDynamicsWorld()->setSolverCallback(GripperDynamics);
+ m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
+
+ // create volumetric reduced deformable body
+ {
+ std::string file_path("../../../data/reduced_cube/");
+ std::string vtk_file("cube_mesh.vtk");
+ btReducedDeformableBody* rsb = btReducedDeformableBodyHelpers::createReducedDeformableObject(
+ getDeformableDynamicsWorld()->getWorldInfo(),
+ file_path,
+ vtk_file,
+ num_modes,
+ false);
+
+ getDeformableDynamicsWorld()->addSoftBody(rsb);
+ rsb->getCollisionShape()->setMargin(0.015);
+
+ btTransform init_transform;
+ init_transform.setIdentity();
+ init_transform.setOrigin(btVector3(0, 1, -2));
+ // init_transform.setRotation(btQuaternion(0, SIMD_PI / 2.0, SIMD_PI / 2.0));
+ // init_transform.setRotation(btQuaternion(btVector3(0, 1, 0), SIMD_PI / 2.0));
+ rsb->transform(init_transform);
+
+ rsb->setStiffnessScale(100);
+ rsb->setDamping(damping_alpha, damping_beta);
+
+ rsb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
+ rsb->m_cfg.kCHR = 1; // collision hardness with rigid body
+ rsb->m_cfg.kDF = 0;
+ rsb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
+ rsb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
+ rsb->m_sleepingThreshold = 0;
+ btSoftBodyHelpers::generateBoundaryFaces(rsb);
+ }
+
+ // create full deformable cube
+ {
+ // std::string filepath("../../../examples/SoftDemo/cube/");
+ // std::string filename = filepath + "mesh.vtk";
+ // btSoftBody* psb = btSoftBodyHelpers::CreateFromVtkFile(getDeformableDynamicsWorld()->getWorldInfo(), filename.c_str());
+
+ // // psb->scale(btVector3(2, 2, 2));
+ // psb->translate(btVector3(0, 1, -2));
+ // psb->getCollisionShape()->setMargin(0.05);
+ // psb->setTotalMass(28.6);
+ // psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
+ // psb->m_cfg.kCHR = 1; // collision hardness with rigid body
+ // psb->m_cfg.kDF = .5;
+ // psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
+ // psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
+ // getDeformableDynamicsWorld()->addSoftBody(psb);
+ // btSoftBodyHelpers::generateBoundaryFaces(psb);
+
+ // btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
+ // getDeformableDynamicsWorld()->addForce(psb, gravity_force);
+ // m_forces.push_back(gravity_force);
+
+ // btScalar E = 10000;
+ // btScalar nu = 0.3;
+ // btScalar lambda = E * nu / ((1 + nu) * (1 - 2 * nu));
+ // btScalar mu = E / (2 * (1 + nu));
+ // btDeformableNeoHookeanForce* neohookean = new btDeformableNeoHookeanForce(lambda, mu, 0.02);
+ // // neohookean->setPoissonRatio(0.3);
+ // // neohookean->setYoungsModulus(25);
+ // neohookean->setDamping(0.01);
+ // psb->m_cfg.drag = 0.001;
+ // getDeformableDynamicsWorld()->addForce(psb, neohookean);
+ // m_forces.push_back(neohookean);
+ }
+
+ getDeformableDynamicsWorld()->setImplicit(false);
+ getDeformableDynamicsWorld()->setLineSearch(false);
+ getDeformableDynamicsWorld()->setUseProjection(false);
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_erp = 0.2;
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_cfm = 0.2;
+ getDeformableDynamicsWorld()->getSolverInfo().m_friction = 1;
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_maxErrorReduction = btScalar(200);
+ getDeformableDynamicsWorld()->getSolverInfo().m_leastSquaresResidualThreshold = 1e-3;
+ getDeformableDynamicsWorld()->getSolverInfo().m_splitImpulse = false;
+ getDeformableDynamicsWorld()->getSolverInfo().m_numIterations = 100;
+
+ // grippers
+ createGrip();
+
+ // rigid block
+ // Ctor_RbUpStack();
+
+ // {
+ // float mass = 10;
+ // btCollisionShape* shape = new btBoxShape(btVector3(0.25, 2, 0.5));
+ // btTransform startTransform;
+ // startTransform.setIdentity();
+ // startTransform.setOrigin(btVector3(0,4,0));
+ // btRigidBody* rb1 = createRigidBody(mass, startTransform, shape);
+ // rb1->setLinearVelocity(btVector3(0, 0, 0));
+ // }
+
+ //create a ground
+ {
+ btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
+
+ m_collisionShapes.push_back(groundShape);
+
+ btTransform groundTransform;
+ groundTransform.setIdentity();
+ groundTransform.setOrigin(btVector3(0, -25, 0));
+ groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
+ //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
+ btScalar mass(0.);
+
+ //rigidbody is dynamic if and only if mass is non zero, otherwise static
+ bool isDynamic = (mass != 0.f);
+
+ btVector3 localInertia(0, 0, 0);
+ if (isDynamic)
+ groundShape->calculateLocalInertia(mass, localInertia);
+
+ //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
+ btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
+ btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
+ btRigidBody* body = new btRigidBody(rbInfo);
+ body->setFriction(0.5);
+
+ //add the ground to the dynamics world
+ m_dynamicsWorld->addRigidBody(body);
+ }
+
+ m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
+}
+
+void ReducedGrasp::exitPhysics()
+{
+ //cleanup in the reverse order of creation/initialization
+ removePickingConstraint();
+ //remove the rigidbodies from the dynamics world and delete them
+ int i;
+ for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
+ {
+ btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
+ btRigidBody* body = btRigidBody::upcast(obj);
+ if (body && body->getMotionState())
+ {
+ delete body->getMotionState();
+ }
+ m_dynamicsWorld->removeCollisionObject(obj);
+ delete obj;
+ }
+ // delete forces
+ for (int j = 0; j < m_forces.size(); j++)
+ {
+ btDeformableLagrangianForce* force = m_forces[j];
+ delete force;
+ }
+ m_forces.clear();
+ //delete collision shapes
+ for (int j = 0; j < m_collisionShapes.size(); j++)
+ {
+ btCollisionShape* shape = m_collisionShapes[j];
+ delete shape;
+ }
+ m_collisionShapes.clear();
+
+ delete m_dynamicsWorld;
+
+ delete m_solver;
+
+ delete m_broadphase;
+
+ delete m_dispatcher;
+
+ delete m_collisionConfiguration;
+}
+
+
+
+class CommonExampleInterface* ReducedGraspCreateFunc(struct CommonExampleOptions& options)
+{
+ return new ReducedGrasp(options.m_guiHelper);
+}
+
+
diff --git a/examples/ReducedDeformableDemo/ReducedGrasp.h b/examples/ReducedDeformableDemo/ReducedGrasp.h
new file mode 100644
index 000000000..12d274849
--- /dev/null
+++ b/examples/ReducedDeformableDemo/ReducedGrasp.h
@@ -0,0 +1,19 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef _REDUCED_GRASP_H
+#define _REDUCED_GRASP_H
+
+class CommonExampleInterface* ReducedGraspCreateFunc(struct CommonExampleOptions& options);
+
+#endif //_REDUCED_GRASP_H
diff --git a/examples/ReducedDeformableDemo/ReducedMotorGrasp.cpp b/examples/ReducedDeformableDemo/ReducedMotorGrasp.cpp
new file mode 100644
index 000000000..5dda30f97
--- /dev/null
+++ b/examples/ReducedDeformableDemo/ReducedMotorGrasp.cpp
@@ -0,0 +1,558 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "ReducedMotorGrasp.h"
+///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
+#include "btBulletDynamicsCommon.h"
+#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.h"
+#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
+#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
+#include "BulletDynamics/Featherstone/btMultiBodyJointMotor.h"
+#include <stdio.h> //printf debugging
+
+#include "../CommonInterfaces/CommonDeformableBodyBase.h"
+#include "../Utils/b3ResourcePath.h"
+#include "../Importers/ImportURDFDemo/BulletUrdfImporter.h"
+#include "../Importers/ImportURDFDemo/MyMultiBodyCreator.h"
+#include "../Importers/ImportURDFDemo/URDF2Bullet.h"
+#include "../Utils/b3BulletDefaultFileIO.h"
+#include "../CommonInterfaces/CommonMultiBodyBase.h"
+#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
+#include "../CommonInterfaces/CommonParameterInterface.h"
+#include "../CommonInterfaces/CommonFileIOInterface.h"
+#include "Bullet3Common/b3FileUtils.h"
+
+///The ReducedMotorGrasp shows grasping a volumetric deformable objects with multibody gripper with moter constraints.
+static btScalar sGripperVerticalVelocity = 0.f;
+static btScalar sGripperClosingTargetVelocity = 0.f;
+static btScalar damping_alpha = 0.0;
+static btScalar damping_beta = 0.0001;
+static int num_modes = 20;
+static float friction = 1.;
+struct TetraCube
+{
+#include "../SoftDemo/cube.inl"
+};
+
+struct TetraBunny
+{
+#include "../SoftDemo/bunny.inl"
+};
+
+static bool supportsJointMotor(btMultiBody* mb, int mbLinkIndex)
+{
+ bool canHaveMotor = (mb->getLink(mbLinkIndex).m_jointType == btMultibodyLink::eRevolute
+ || mb->getLink(mbLinkIndex).m_jointType == btMultibodyLink::ePrismatic);
+ return canHaveMotor;
+}
+
+class ReducedMotorGrasp : public CommonDeformableBodyBase
+{
+ btAlignedObjectArray<btDeformableLagrangianForce*> m_forces;
+public:
+ ReducedMotorGrasp(struct GUIHelperInterface* helper)
+ :CommonDeformableBodyBase(helper)
+ {
+ }
+ virtual ~ReducedMotorGrasp()
+ {
+ }
+ void initPhysics();
+
+ void exitPhysics();
+
+ void Ctor_RbUpStack()
+ {
+ float mass = 8;
+ btCollisionShape* shape = new btBoxShape(btVector3(2, 0.25, 0.5));
+ btTransform startTransform;
+ startTransform.setIdentity();
+
+ startTransform.setOrigin(btVector3(0,0.25,0));
+ btRigidBody* rb1 = createRigidBody(mass, startTransform, shape);
+ rb1->setLinearVelocity(btVector3(0, 0, 0));
+ rb1->setFriction(0.7);
+ }
+
+ void resetCamera()
+ {
+ // float dist = 0.3;
+ // float pitch = -45;
+ // float yaw = 100;
+ // float targetPos[3] = {0, -0.1, 0};
+ float dist = 0.4;
+ float pitch = -25;
+ float yaw = 90;
+ float targetPos[3] = {0, 0, 0};
+ m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
+ }
+
+ btMultiBody* createFeatherstoneMultiBody(btMultiBodyDynamicsWorld* pWorld,const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool floating);
+
+ void addColliders(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents);
+
+ btMultiBody* createFeatherstoneMultiBody_testMultiDof(btMultiBodyDynamicsWorld* pWorld, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical, bool floating);
+
+ void stepSimulation(float deltaTime)
+ {
+ double fingerTargetVelocities[2] = {sGripperVerticalVelocity, sGripperClosingTargetVelocity};
+ int num_multiBody = getDeformableDynamicsWorld()->getNumMultibodies();
+ for (int i = 0; i < num_multiBody; ++i)
+ {
+ btMultiBody* mb = getDeformableDynamicsWorld()->btMultiBodyDynamicsWorld::getMultiBody(i);
+ mb->setBaseVel(btVector3(0,sGripperVerticalVelocity, 0));
+ int dofIndex = 6; //skip the 3 linear + 3 angular degree of freedom entries of the base
+ for (int link = 0; link < mb->getNumLinks(); link++)
+ {
+ if (supportsJointMotor(mb, link))
+ {
+ btMultiBodyJointMotor* motor = (btMultiBodyJointMotor*)mb->getLink(link).m_userPtr;
+ if (motor)
+ {
+ if (dofIndex == 6)
+ {
+ motor->setVelocityTarget(-fingerTargetVelocities[1], 1);
+ motor->setMaxAppliedImpulse(10);
+ }
+ if (dofIndex == 7)
+ {
+ motor->setVelocityTarget(fingerTargetVelocities[1], 1);
+ motor->setMaxAppliedImpulse(10);
+ }
+ motor->setMaxAppliedImpulse(25);
+ }
+ }
+ dofIndex += mb->getLink(link).m_dofCount;
+ }
+ }
+
+ //use a smaller internal timestep, there are stability issues
+ float internalTimeStep = 1. / 240.f;
+ m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
+ // float internalTimeStep = 1. / 60.f;
+ // m_dynamicsWorld->stepSimulation(deltaTime, 1, internalTimeStep);
+ }
+
+ void createGrip()
+ {
+ int count = 2;
+ float mass = 2;
+ btCollisionShape* shape[] = {
+ new btBoxShape(btVector3(3, 3, 0.5)),
+ };
+ static const int nshapes = sizeof(shape) / sizeof(shape[0]);
+ for (int i = 0; i < count; ++i)
+ {
+ btTransform startTransform;
+ startTransform.setIdentity();
+ startTransform.setOrigin(btVector3(10, 0, 0));
+ startTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
+ createRigidBody(mass, startTransform, shape[i % nshapes]);
+ }
+ }
+
+ virtual const btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld() const
+ {
+ return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
+ }
+
+ virtual btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld()
+ {
+ return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
+ }
+
+ virtual void renderScene()
+ {
+ CommonDeformableBodyBase::renderScene();
+ btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
+
+ for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
+ {
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(deformableWorld->getSoftBodyArray()[i]);
+ {
+ btSoftBodyHelpers::DrawFrame(rsb, deformableWorld->getDebugDrawer());
+ btSoftBodyHelpers::Draw(rsb, deformableWorld->getDebugDrawer(), fDrawFlags::Faces);// deformableWorld->getDrawFlags());
+ }
+ // for (int p = 0; p < rsb->m_contactNodesList.size(); ++p)
+ // {
+ // int index = rsb->m_contactNodesList[p];
+ // deformableWorld->getDebugDrawer()->drawSphere(rsb->m_nodes[index].m_x, 0.2, btVector3(0, 1, 0));
+ // }
+ }
+ }
+
+ virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
+ {
+ return false;
+ }
+ virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
+ {
+ return false;
+ }
+ virtual void removePickingConstraint(){}
+};
+
+
+void ReducedMotorGrasp::initPhysics()
+{
+ m_guiHelper->setUpAxis(1);
+
+ m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
+
+ m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
+
+ m_broadphase = new btDbvtBroadphase();
+ btReducedDeformableBodySolver* reducedSoftBodySolver = new btReducedDeformableBodySolver();
+ // btVector3 gravity = btVector3(0, 0, 0);
+ btVector3 gravity = btVector3(0, -9.81, 0);
+ reducedSoftBodySolver->setGravity(gravity);
+
+ btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
+ sol->setDeformableSolver(reducedSoftBodySolver);
+ m_solver = sol;
+
+ m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, reducedSoftBodySolver);
+ m_dynamicsWorld->setGravity(gravity);
+ getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
+ // getDeformableDynamicsWorld()->getSolverInfo().m_deformable_erp = 0.1;
+ // getDeformableDynamicsWorld()->getSolverInfo().m_deformable_cfm = 0;
+ // getDeformableDynamicsWorld()->getSolverInfo().m_numIterations = 150;
+ m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
+ m_maxPickingForce = 0.001;
+ // build a gripper
+ {
+ bool damping = true;
+ bool gyro = false;
+ bool canSleep = false;
+ bool selfCollide = true;
+ int numLinks = 2;
+ // btVector3 linkHalfExtents(0.02, 0.018, .003);
+ // btVector3 baseHalfExtents(0.02, 0.002, .002);
+ btVector3 linkHalfExtents(0.03, 0.04, 0.006);
+ btVector3 baseHalfExtents(0.02, 0.015, 0.015);
+ btVector3 basePosition(0, 0.3, 0);
+ // btMultiBody* mbC = createFeatherstoneMultiBody(getDeformableDynamicsWorld(), btVector3(0.f, 0.05f,0.f), baseHalfExtents, linkHalfExtents, false);
+ btMultiBody* mbC = createFeatherstoneMultiBody(getDeformableDynamicsWorld(), basePosition, baseHalfExtents, linkHalfExtents, false);
+
+ mbC->setCanSleep(canSleep);
+ mbC->setHasSelfCollision(selfCollide);
+ mbC->setUseGyroTerm(gyro);
+
+ for (int i = 0; i < numLinks; i++)
+ {
+ int mbLinkIndex = i;
+ double maxMotorImpulse = 1;
+
+ if (supportsJointMotor(mbC, mbLinkIndex))
+ {
+ int dof = 0;
+ btScalar desiredVelocity = 0.f;
+ btMultiBodyJointMotor* motor = new btMultiBodyJointMotor(mbC, mbLinkIndex, dof, desiredVelocity, maxMotorImpulse);
+ motor->setPositionTarget(0, 0);
+ motor->setVelocityTarget(0, 1);
+ mbC->getLink(mbLinkIndex).m_userPtr = motor;
+ getDeformableDynamicsWorld()->addMultiBodyConstraint(motor);
+ motor->finalizeMultiDof();
+ }
+ }
+
+ if (!damping)
+ {
+ mbC->setLinearDamping(0.0f);
+ mbC->setAngularDamping(0.0f);
+ }
+ else
+ {
+ mbC->setLinearDamping(0.04f);
+ mbC->setAngularDamping(0.04f);
+ }
+ btScalar q0 = 0.f * SIMD_PI / 180.f;
+ if (numLinks > 0)
+ mbC->setJointPosMultiDof(0, &q0);
+ addColliders(mbC, getDeformableDynamicsWorld(), baseHalfExtents, linkHalfExtents);
+ }
+
+ //create a ground
+ {
+ btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(10.), btScalar(5.), btScalar(10.)));
+ groundShape->setMargin(0.001);
+ m_collisionShapes.push_back(groundShape);
+
+ btTransform groundTransform;
+ groundTransform.setIdentity();
+ groundTransform.setOrigin(btVector3(0, -5.1, 0));
+ groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
+ //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
+ btScalar mass(0.);
+
+ //rigidbody is dynamic if and only if mass is non zero, otherwise static
+ bool isDynamic = (mass != 0.f);
+
+ btVector3 localInertia(0, 0, 0);
+ if (isDynamic)
+ groundShape->calculateLocalInertia(mass, localInertia);
+
+ //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
+ btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
+ btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
+ btRigidBody* body = new btRigidBody(rbInfo);
+ body->setFriction(0.5);
+
+ //add the ground to the dynamics world
+ m_dynamicsWorld->addRigidBody(body,1,1+2);
+ }
+
+ // create volumetric reduced deformable body
+ {
+ std::string file_path("../../../data/reduced_cube/");
+ std::string vtk_file("cube_mesh.vtk");
+ btReducedDeformableBody* rsb = btReducedDeformableBodyHelpers::createReducedDeformableObject(
+ getDeformableDynamicsWorld()->getWorldInfo(),
+ file_path,
+ vtk_file,
+ num_modes,
+ false);
+ getDeformableDynamicsWorld()->addSoftBody(rsb);
+ rsb->getCollisionShape()->setMargin(0.001);
+
+ rsb->setStiffnessScale(100);
+ rsb->setDamping(damping_alpha, damping_beta);
+
+ rsb->scale(btVector3(0.075, 0.075, 0.075));
+ rsb->setTotalMass(1);
+
+ btTransform init_transform;
+ init_transform.setIdentity();
+ init_transform.setOrigin(btVector3(0, 0.1, 0));
+ // init_transform.setRotation(btQuaternion(SIMD_PI / 2.0, 0, SIMD_PI / 2.0));
+ rsb->transform(init_transform);
+
+ // rsb->setRigidVelocity(btVector3(0, 1, 0));
+
+ rsb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
+ rsb->m_cfg.kCHR = 1; // collision hardness with rigid body
+ rsb->m_cfg.kDF = 0;
+ rsb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
+ rsb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
+ rsb->m_sleepingThreshold = 0;
+ btSoftBodyHelpers::generateBoundaryFaces(rsb);
+ }
+
+ // Ctor_RbUpStack();
+
+ getDeformableDynamicsWorld()->setImplicit(false);
+ getDeformableDynamicsWorld()->setLineSearch(false);
+ getDeformableDynamicsWorld()->setUseProjection(false);
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_erp = 0.2;
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_cfm = 0.2;
+ getDeformableDynamicsWorld()->getSolverInfo().m_friction = 1;
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_maxErrorReduction = btScalar(200);
+ getDeformableDynamicsWorld()->getSolverInfo().m_leastSquaresResidualThreshold = 1e-6;
+ getDeformableDynamicsWorld()->getSolverInfo().m_splitImpulse = false;
+ getDeformableDynamicsWorld()->getSolverInfo().m_numIterations = 200;
+ m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
+
+ {
+ SliderParams slider("Moving velocity", &sGripperVerticalVelocity);
+ // slider.m_minVal = -.02;
+ // slider.m_maxVal = .02;
+ slider.m_minVal = -.2;
+ slider.m_maxVal = .2;
+ m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
+ }
+
+ {
+ SliderParams slider("Closing velocity", &sGripperClosingTargetVelocity);
+ slider.m_minVal = -1;
+ slider.m_maxVal = 1;
+ m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
+ }
+
+}
+
+void ReducedMotorGrasp::exitPhysics()
+{
+ //cleanup in the reverse order of creation/initialization
+ removePickingConstraint();
+ //remove the rigidbodies from the dynamics world and delete them
+ int i;
+ for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
+ {
+ btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
+ btRigidBody* body = btRigidBody::upcast(obj);
+ if (body && body->getMotionState())
+ {
+ delete body->getMotionState();
+ }
+ m_dynamicsWorld->removeCollisionObject(obj);
+ delete obj;
+ }
+ // delete forces
+ for (int j = 0; j < m_forces.size(); j++)
+ {
+ btDeformableLagrangianForce* force = m_forces[j];
+ delete force;
+ }
+ m_forces.clear();
+
+ //delete collision shapes
+ for (int j = 0; j < m_collisionShapes.size(); j++)
+ {
+ btCollisionShape* shape = m_collisionShapes[j];
+ delete shape;
+ }
+ m_collisionShapes.clear();
+
+ delete m_dynamicsWorld;
+
+ delete m_solver;
+
+ delete m_broadphase;
+
+ delete m_dispatcher;
+
+ delete m_collisionConfiguration;
+}
+
+btMultiBody* ReducedMotorGrasp::createFeatherstoneMultiBody(btMultiBodyDynamicsWorld* pWorld, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool floating)
+{
+ //init the base
+ btVector3 baseInertiaDiag(0.f, 0.f, 0.f);
+ float baseMass = 55;
+ float linkMass = 55;
+ int numLinks = 2;
+
+ if (baseMass)
+ {
+ btCollisionShape* pTempBox = new btBoxShape(btVector3(baseHalfExtents[0], baseHalfExtents[1], baseHalfExtents[2]));
+ pTempBox->calculateLocalInertia(baseMass, baseInertiaDiag);
+ delete pTempBox;
+ }
+
+ bool canSleep = false;
+ btMultiBody* pMultiBody = new btMultiBody(numLinks, baseMass, baseInertiaDiag, !floating, canSleep);
+
+ btQuaternion baseOriQuat(0.f, 0.f, 0.f, 1.f);
+ pMultiBody->setBasePos(basePosition);
+ pMultiBody->setWorldToBaseRot(baseOriQuat);
+
+ //init the links
+ btVector3 hingeJointAxis(1, 0, 0);
+
+ btVector3 linkInertiaDiag(0.f, 0.f, 0.f);
+
+ btCollisionShape* pTempBox = new btBoxShape(btVector3(linkHalfExtents[0], linkHalfExtents[1], linkHalfExtents[2]));
+ pTempBox->calculateLocalInertia(linkMass, linkInertiaDiag);
+ delete pTempBox;
+
+ //y-axis assumed up
+ btAlignedObjectArray<btVector3> parentComToCurrentCom;
+ parentComToCurrentCom.push_back(btVector3(0, -linkHalfExtents[1] * 2.f, -baseHalfExtents[2] * 2.f));
+ parentComToCurrentCom.push_back(btVector3(0, -linkHalfExtents[1] * 2.f, +baseHalfExtents[2] * 2.f));//par body's COM to cur body's COM offset
+
+
+ btVector3 currentPivotToCurrentCom(0, -linkHalfExtents[1]*2.f, 0); //cur body's COM to cur body's PIV offset
+
+ btAlignedObjectArray<btVector3> parentComToCurrentPivot;
+ parentComToCurrentPivot.push_back(btVector3(parentComToCurrentCom[0] - currentPivotToCurrentCom));
+ parentComToCurrentPivot.push_back(btVector3(parentComToCurrentCom[1] - currentPivotToCurrentCom));//par body's COM to cur body's PIV offset
+
+ //////
+ btScalar q0 = 0.f * SIMD_PI / 180.f;
+ btQuaternion quat0(btVector3(0, 1, 0).normalized(), q0);
+ quat0.normalize();
+ /////
+
+ for (int i = 0; i < numLinks; ++i)
+ {
+ pMultiBody->setupRevolute(i, linkMass, linkInertiaDiag, - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), hingeJointAxis, parentComToCurrentPivot[i], currentPivotToCurrentCom, true);
+ }
+ pMultiBody->finalizeMultiDof();
+ ///
+ pWorld->addMultiBody(pMultiBody);
+ ///
+ return pMultiBody;
+}
+
+void ReducedMotorGrasp::addColliders(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents)
+{
+ btAlignedObjectArray<btQuaternion> world_to_local;
+ world_to_local.resize(pMultiBody->getNumLinks() + 1);
+
+ btAlignedObjectArray<btVector3> local_origin;
+ local_origin.resize(pMultiBody->getNumLinks() + 1);
+ world_to_local[0] = pMultiBody->getWorldToBaseRot();
+ local_origin[0] = pMultiBody->getBasePos();
+
+ {
+ btScalar quat[4] = {-world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w()};
+
+ if (1)
+ {
+ btCollisionShape* box = new btBoxShape(baseHalfExtents);
+ box->setMargin(0.001);
+ btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, -1);
+ col->setCollisionShape(box);
+
+ btTransform tr;
+ tr.setIdentity();
+ tr.setOrigin(local_origin[0]);
+ tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
+ col->setWorldTransform(tr);
+
+ pWorld->addCollisionObject(col, 2, 1 + 2);
+
+ col->setFriction(friction);
+ pMultiBody->setBaseCollider(col);
+ }
+ }
+
+ for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
+ {
+ const int parent = pMultiBody->getParent(i);
+ world_to_local[i + 1] = pMultiBody->getParentToLocalRot(i) * world_to_local[parent + 1];
+ local_origin[i + 1] = local_origin[parent + 1] + (quatRotate(world_to_local[i + 1].inverse(), pMultiBody->getRVector(i)));
+ }
+
+ for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
+ {
+ btVector3 posr = local_origin[i + 1];
+
+ btScalar quat[4] = {-world_to_local[i + 1].x(), -world_to_local[i + 1].y(), -world_to_local[i + 1].z(), world_to_local[i + 1].w()};
+
+ btCollisionShape* box = new btBoxShape(linkHalfExtents);
+ box->setMargin(0.001);
+ btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, i);
+
+ col->setCollisionShape(box);
+ btTransform tr;
+ tr.setIdentity();
+ tr.setOrigin(posr);
+ tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
+ col->setWorldTransform(tr);
+ col->setFriction(friction);
+ pWorld->addCollisionObject(col, 2, 1 + 2);
+
+ pMultiBody->getLink(i).m_collider = col;
+ }
+}
+
+class CommonExampleInterface* ReducedMotorGraspCreateFunc(struct CommonExampleOptions& options)
+{
+ return new ReducedMotorGrasp(options.m_guiHelper);
+}
+
+
diff --git a/examples/ReducedDeformableDemo/ReducedMotorGrasp.h b/examples/ReducedDeformableDemo/ReducedMotorGrasp.h
new file mode 100644
index 000000000..52883ecf1
--- /dev/null
+++ b/examples/ReducedDeformableDemo/ReducedMotorGrasp.h
@@ -0,0 +1,19 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef _REDUCED_MOTOR_GRASP
+#define _REDUCED_MOTOR_GRASP
+
+class CommonExampleInterface* ReducedMotorGraspCreateFunc(struct CommonExampleOptions& options);
+
+#endif //_REDUCED_MOTOR_GRASP
diff --git a/examples/ReducedDeformableDemo/Springboard.cpp b/examples/ReducedDeformableDemo/Springboard.cpp
new file mode 100644
index 000000000..58641365e
--- /dev/null
+++ b/examples/ReducedDeformableDemo/Springboard.cpp
@@ -0,0 +1,264 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "Springboard.h"
+///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
+#include "btBulletDynamicsCommon.h"
+#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.h"
+#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
+#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
+#include "../CommonInterfaces/CommonParameterInterface.h"
+#include <stdio.h> //printf debugging
+
+#include "../CommonInterfaces/CommonDeformableBodyBase.h"
+#include "../Utils/b3ResourcePath.h"
+
+static btScalar damping_alpha = 0.0;
+static btScalar damping_beta = 0.0001;
+static int num_modes = 20;
+
+class Springboard : public CommonDeformableBodyBase
+{
+ btScalar sim_time;
+ bool first_step;
+
+public:
+ Springboard(struct GUIHelperInterface* helper)
+ : CommonDeformableBodyBase(helper)
+ {
+ sim_time = 0;
+ first_step = true;
+ }
+ virtual ~Springboard()
+ {
+ }
+ void initPhysics();
+
+ void exitPhysics();
+
+ // TODO: disable pick force, non-interactive for now.
+ bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) {
+ return false;
+ }
+
+ void resetCamera()
+ {
+ float dist = 10;
+ float pitch = 0;
+ float yaw = 90;
+ float targetPos[3] = {0, 3, 0};
+ m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
+ }
+
+ void Ctor_RbUpStack()
+ {
+ float mass = 2;
+ btCollisionShape* shape = new btBoxShape(btVector3(1, 1, 1));
+ btTransform startTransform;
+ startTransform.setIdentity();
+ startTransform.setOrigin(btVector3(0,8,1));
+ btRigidBody* rb1 = createRigidBody(mass, startTransform, shape);
+ rb1->setActivationState(DISABLE_DEACTIVATION);
+ }
+
+ void stepSimulation(float deltaTime)
+ {
+ float internalTimeStep = 1. / 60.f;
+ m_dynamicsWorld->stepSimulation(deltaTime, 1, internalTimeStep);
+
+ {
+ sim_time += internalTimeStep;
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(getDeformableDynamicsWorld()->getSoftBodyArray()[0]);
+
+ // std::ofstream myfile("fixed_node.txt", std::ios_base::app);
+ // myfile << sim_time << "\t" << rsb->m_nodes[0].m_x[0] - rsb->m_x0[0][0] << "\t"
+ // << rsb->m_nodes[0].m_x[1] - rsb->m_x0[0][1] << "\t"
+ // << rsb->m_nodes[0].m_x[2] - rsb->m_x0[0][2] << "\n";
+ // myfile.close();
+ }
+ }
+
+ virtual void renderScene()
+ {
+ CommonDeformableBodyBase::renderScene();
+ btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
+
+ for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
+ {
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(deformableWorld->getSoftBodyArray()[i]);
+ {
+ btSoftBodyHelpers::DrawFrame(rsb, deformableWorld->getDebugDrawer());
+ btSoftBodyHelpers::Draw(rsb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
+
+ for (int p = 0; p < rsb->m_fixedNodes.size(); ++p)
+ {
+ deformableWorld->getDebugDrawer()->drawSphere(rsb->m_nodes[rsb->m_fixedNodes[p]].m_x, 0.2, btVector3(1, 0, 0));
+ // std::cout << rsb->m_nodes[rsb->m_fixedNodes[p]].m_x[0] << "\t" << rsb->m_nodes[rsb->m_fixedNodes[p]].m_x[1] << "\t" << rsb->m_nodes[rsb->m_fixedNodes[p]].m_x[2] << "\n";
+ }
+ // deformableWorld->getDebugDrawer()->drawSphere(btVector3(0, 0, 0), 0.1, btVector3(1, 1, 1));
+ // deformableWorld->getDebugDrawer()->drawSphere(btVector3(0, 2, 0), 0.1, btVector3(1, 1, 1));
+ // deformableWorld->getDebugDrawer()->drawSphere(btVector3(0, 4, 0), 0.1, btVector3(1, 1, 1));
+ }
+ }
+ }
+};
+
+void Springboard::initPhysics()
+{
+ m_guiHelper->setUpAxis(1);
+
+ ///collision configuration contains default setup for memory, collision setup
+ m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
+
+ ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
+ m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
+
+ m_broadphase = new btDbvtBroadphase();
+ btReducedDeformableBodySolver* reducedSoftBodySolver = new btReducedDeformableBodySolver();
+ btVector3 gravity = btVector3(0, -10, 0);
+ reducedSoftBodySolver->setGravity(gravity);
+
+ btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
+ sol->setDeformableSolver(reducedSoftBodySolver);
+ m_solver = sol;
+
+ m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, reducedSoftBodySolver);
+ m_dynamicsWorld->setGravity(gravity);
+ m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
+
+ // create volumetric reduced deformable body
+ {
+ std::string file_path("../../../data/reduced_beam/");
+ std::string vtk_file("beam_mesh_origin.vtk");
+ btReducedDeformableBody* rsb = btReducedDeformableBodyHelpers::createReducedDeformableObject(
+ getDeformableDynamicsWorld()->getWorldInfo(),
+ file_path,
+ vtk_file,
+ num_modes,
+ false);
+
+ getDeformableDynamicsWorld()->addSoftBody(rsb);
+ rsb->getCollisionShape()->setMargin(0.1);
+
+ btTransform init_transform;
+ init_transform.setIdentity();
+ init_transform.setOrigin(btVector3(0, 4, 0));
+ // init_transform.setRotation(btQuaternion(btVector3(0, 1, 0), SIMD_PI / 2.0));
+ rsb->transform(init_transform);
+
+ rsb->setStiffnessScale(200);
+ rsb->setDamping(damping_alpha, damping_beta);
+
+ // set fixed nodes
+ rsb->setFixedNodes(0);
+ rsb->setFixedNodes(1);
+ rsb->setFixedNodes(2);
+ rsb->setFixedNodes(3);
+
+ rsb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
+ rsb->m_cfg.kCHR = 1; // collision hardness with rigid body
+ rsb->m_cfg.kDF = 0;
+ rsb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
+ rsb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
+ rsb->m_sleepingThreshold = 0;
+ btSoftBodyHelpers::generateBoundaryFaces(rsb);
+
+ // rsb->setVelocity(btVector3(0, -COLLIDING_VELOCITY, 0));
+ // rsb->setRigidVelocity(btVector3(0, 1, 0));
+ // rsb->setRigidAngularVelocity(btVector3(1, 0, 0));
+ }
+ getDeformableDynamicsWorld()->setImplicit(false);
+ getDeformableDynamicsWorld()->setLineSearch(false);
+ getDeformableDynamicsWorld()->setUseProjection(false);
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_erp = 0.3;
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_cfm = 0.2;
+ getDeformableDynamicsWorld()->getSolverInfo().m_deformable_maxErrorReduction = btScalar(200);
+ getDeformableDynamicsWorld()->getSolverInfo().m_leastSquaresResidualThreshold = 1e-3;
+ getDeformableDynamicsWorld()->getSolverInfo().m_splitImpulse = false;
+ getDeformableDynamicsWorld()->getSolverInfo().m_numIterations = 100;
+ // add a few rigid bodies
+ Ctor_RbUpStack();
+
+ // create a static rigid box as the ground
+ {
+ // btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50), btScalar(50), btScalar(50)));
+ btBoxShape* groundShape = createBoxShape(btVector3(btScalar(10), btScalar(2), btScalar(10)));
+ m_collisionShapes.push_back(groundShape);
+
+ btTransform groundTransform;
+ groundTransform.setIdentity();
+ groundTransform.setOrigin(btVector3(0, 0, 0));
+ {
+ btScalar mass(0.);
+ createRigidBody(mass, groundTransform, groundShape, btVector4(0,0,0,0));
+ }
+ }
+
+ m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
+}
+
+void Springboard::exitPhysics()
+{
+ //cleanup in the reverse order of creation/initialization
+ removePickingConstraint();
+ //remove the rigidbodies from the dynamics world and delete them
+ int i;
+ for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
+ {
+ btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
+ btRigidBody* body = btRigidBody::upcast(obj);
+ if (body && body->getMotionState())
+ {
+ delete body->getMotionState();
+ }
+ m_dynamicsWorld->removeCollisionObject(obj);
+ delete obj;
+ }
+ // delete forces
+ for (int j = 0; j < m_forces.size(); j++)
+ {
+ btDeformableLagrangianForce* force = m_forces[j];
+ delete force;
+ }
+ m_forces.clear();
+
+ //delete collision shapes
+ for (int j = 0; j < m_collisionShapes.size(); j++)
+ {
+ btCollisionShape* shape = m_collisionShapes[j];
+ delete shape;
+ }
+ m_collisionShapes.clear();
+
+ delete m_dynamicsWorld;
+
+ delete m_solver;
+
+ delete m_broadphase;
+
+ delete m_dispatcher;
+
+ delete m_collisionConfiguration;
+}
+
+
+
+class CommonExampleInterface* ReducedSpringboardCreateFunc(struct CommonExampleOptions& options)
+{
+ return new Springboard(options.m_guiHelper);
+}
+
+
diff --git a/examples/ReducedDeformableDemo/Springboard.h b/examples/ReducedDeformableDemo/Springboard.h
new file mode 100644
index 000000000..2636d5623
--- /dev/null
+++ b/examples/ReducedDeformableDemo/Springboard.h
@@ -0,0 +1,19 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef _REDUCED_SPRINGBOARD_H
+#define _REDUCED_SPRINGBOARD_H
+
+class CommonExampleInterface* ReducedSpringboardCreateFunc(struct CommonExampleOptions& options);
+
+#endif //_REDUCED_SPRINGBOARD_H
diff --git a/examples/SharedMemory/PhysicsClientC_API.cpp b/examples/SharedMemory/PhysicsClientC_API.cpp
index 75f48e39d..ec697cdbf 100644
--- a/examples/SharedMemory/PhysicsClientC_API.cpp
+++ b/examples/SharedMemory/PhysicsClientC_API.cpp
@@ -1549,6 +1549,22 @@ B3_SHARED_API void b3GetMeshDataSetFlags(b3SharedMemoryCommandHandle commandHand
}
}
+B3_SHARED_API void b3GetMeshDataSimulationMesh(b3SharedMemoryCommandHandle commandHandle)
+{
+ struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
+ b3Assert(command);
+ b3Assert(command->m_type == CMD_REQUEST_MESH_DATA);
+ command->m_updateFlags |= B3_MESH_DATA_SIMULATION_MESH;
+}
+
+B3_SHARED_API void b3MeshDataSimulationMeshVelocity(b3SharedMemoryCommandHandle commandHandle)
+{
+ struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
+ b3Assert(command);
+ b3Assert(command->m_type == CMD_REQUEST_MESH_DATA || command->m_type == CMD_RESET_MESH_DATA);
+ command->m_updateFlags |= B3_MESH_DATA_SIMULATION_MESH_VELOCITY;
+}
+
B3_SHARED_API void b3GetMeshData(b3PhysicsClientHandle physClient, struct b3MeshData* meshData)
{
PhysicsClient* cl = (PhysicsClient*)physClient;
diff --git a/examples/SharedMemory/PhysicsClientC_API.h b/examples/SharedMemory/PhysicsClientC_API.h
index c14feb82f..fb0ac3d7e 100644
--- a/examples/SharedMemory/PhysicsClientC_API.h
+++ b/examples/SharedMemory/PhysicsClientC_API.h
@@ -532,6 +532,8 @@ extern "C"
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRemoveCollisionShapeCommand(b3PhysicsClientHandle physClient, int collisionShapeId);
B3_SHARED_API b3SharedMemoryCommandHandle b3GetMeshDataCommandInit(b3PhysicsClientHandle physClient, int bodyUniqueId, int linkIndex);
+ B3_SHARED_API void b3GetMeshDataSimulationMesh(b3SharedMemoryCommandHandle commandHandle);
+ B3_SHARED_API void b3MeshDataSimulationMeshVelocity(b3SharedMemoryCommandHandle commandHandle);
B3_SHARED_API void b3GetMeshDataSetCollisionShapeIndex(b3SharedMemoryCommandHandle commandHandle, int shapeIndex);
B3_SHARED_API void b3GetMeshDataSetFlags(b3SharedMemoryCommandHandle commandHandle, int flags);
diff --git a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp
index aade5904c..ebbfbdc80 100644
--- a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp
+++ b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp
@@ -120,6 +120,10 @@
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
#include "BulletSoftBody/btDeformableBodySolver.h"
#include "BulletSoftBody/btDeformableMultiBodyConstraintSolver.h"
+
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.h"
+#include "BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.h"
#endif //SKIP_DEFORMABLE_BODY
#include "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h"
@@ -1664,6 +1668,7 @@ struct PhysicsServerCommandProcessorInternalData
btDeformableMousePickingForce* m_mouseForce;
btScalar m_maxPickingForce;
btDeformableBodySolver* m_deformablebodySolver;
+ btReducedDeformableBodySolver* m_reducedSoftBodySolver;
btAlignedObjectArray<btDeformableLagrangianForce*> m_lf;
#endif
@@ -2720,16 +2725,26 @@ void PhysicsServerCommandProcessor::createEmptyDynamicsWorld(int flags)
m_data->m_broadphase = bv;
}
+#ifndef SKIP_DEFORMABLE_BODY
if (flags & RESET_USE_DEFORMABLE_WORLD)
{
-#ifndef SKIP_DEFORMABLE_BODY
+ // deformable
m_data->m_deformablebodySolver = new btDeformableBodySolver();
btDeformableMultiBodyConstraintSolver* solver = new btDeformableMultiBodyConstraintSolver;
m_data->m_solver = solver;
solver->setDeformableSolver(m_data->m_deformablebodySolver);
m_data->m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_data->m_dispatcher, m_data->m_broadphase, solver, m_data->m_collisionConfiguration, m_data->m_deformablebodySolver);
-#endif
}
+ else if (flags & RESET_USE_REDUCED_DEFORMABLE_WORLD)
+ {
+ // reduced deformable
+ m_data->m_reducedSoftBodySolver = new btReducedDeformableBodySolver();
+ btDeformableMultiBodyConstraintSolver* solver = new btDeformableMultiBodyConstraintSolver;
+ m_data->m_solver = solver;
+ solver->setDeformableSolver(m_data->m_reducedSoftBodySolver);
+ m_data->m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_data->m_dispatcher, m_data->m_broadphase, solver, m_data->m_collisionConfiguration, m_data->m_reducedSoftBodySolver);
+ }
+#endif
@@ -2776,7 +2791,14 @@ void PhysicsServerCommandProcessor::createEmptyDynamicsWorld(int flags)
m_data->m_dynamicsWorld->getSolverInfo().m_frictionERP = 0.2; //need to check if there are artifacts with frictionERP
m_data->m_dynamicsWorld->getSolverInfo().m_linearSlop = 0.00001;
m_data->m_dynamicsWorld->getSolverInfo().m_numIterations = 50;
- m_data->m_dynamicsWorld->getSolverInfo().m_minimumSolverBatchSize = 0;
+ if (flags & RESET_USE_REDUCED_DEFORMABLE_WORLD)
+ {
+ m_data->m_dynamicsWorld->getSolverInfo().m_minimumSolverBatchSize = 128;
+ }
+ else
+ {
+ m_data->m_dynamicsWorld->getSolverInfo().m_minimumSolverBatchSize = 0;
+ }
m_data->m_dynamicsWorld->getSolverInfo().m_warmstartingFactor = 0.1;
gDbvtMargin = btScalar(0);
m_data->m_dynamicsWorld->getSolverInfo().m_leastSquaresResidualThreshold = 1e-7;
@@ -3643,6 +3665,11 @@ bool PhysicsServerCommandProcessor::loadUrdf(const char* fileName, const btVecto
return false;
}
}
+ if (!(u2b.getReducedDeformableModel().m_visualFileName.empty()))
+ {
+ bool use_self_collision = false;
+ return processReducedDeformable(u2b.getReducedDeformableModel(), pos, orn, bodyUniqueIdPtr, bufferServerToClient, bufferSizeInBytes, globalScaling, use_self_collision);
+ }
bool ok = processImportedObjects(fileName, bufferServerToClient, bufferSizeInBytes, useMultiBody, flags, u2b);
if (ok)
{
@@ -5524,10 +5551,23 @@ bool PhysicsServerCommandProcessor::processResetMeshDataCommand(const struct Sha
int numVertices = psb->m_nodes.size();
if (clientCmd.m_resetMeshDataArgs.m_numVertices == numVertices)
{
- for (int i = 0; i < numVertices; ++i)
+ if (clientCmd.m_updateFlags & B3_MESH_DATA_SIMULATION_MESH_VELOCITY)
+ {
+ for (int i = 0; i < numVertices; ++i)
+ {
+ btSoftBody::Node& n = psb->m_nodes[i];
+ n.m_v.setValue(vertexUpload[i * 3 + 0], vertexUpload[i * 3 + 1], vertexUpload[i * 3 + 2]);
+ n.m_vn.setValue(vertexUpload[i * 3 + 0], vertexUpload[i * 3 + 1], vertexUpload[i * 3 + 2]);
+ }
+ }
+ else
{
- btSoftBody::Node& n = psb->m_nodes[i];
- n.m_x.setValue(vertexUpload[i*3+0], vertexUpload[i*3+1],vertexUpload[i*3+2]);
+ for (int i = 0; i < numVertices; ++i)
+ {
+ btSoftBody::Node& n = psb->m_nodes[i];
+ n.m_x.setValue(vertexUpload[i * 3 + 0], vertexUpload[i * 3 + 1], vertexUpload[i * 3 + 2]);
+ n.m_q.setValue(vertexUpload[i * 3 + 0], vertexUpload[i * 3 + 1], vertexUpload[i * 3 + 2]);
+ }
}
serverStatusOut.m_type = CMD_RESET_MESH_DATA_COMPLETED;
}
@@ -5614,10 +5654,12 @@ bool PhysicsServerCommandProcessor::processRequestMeshDataCommand(const struct S
}
bool separateRenderMesh = false;
- if ((flags & B3_MESH_DATA_SIMULATION_MESH) == 0)
+ if ((clientCmd.m_updateFlags & B3_MESH_DATA_SIMULATION_MESH) == 0)
{
separateRenderMesh = (psb->m_renderNodes.size() != 0);
}
+ bool requestVelocity = clientCmd.m_updateFlags & B3_MESH_DATA_SIMULATION_MESH_VELOCITY;
+
int numVertices = separateRenderMesh ? psb->m_renderNodes.size() : psb->m_nodes.size();
int maxNumVertices = bufferSizeInBytes / totalBytesPerVertex - 1;
int numVerticesRemaining = numVertices - clientCmd.m_requestMeshDataArgs.m_startingVertex;
@@ -5626,14 +5668,22 @@ bool PhysicsServerCommandProcessor::processRequestMeshDataCommand(const struct S
{
if (separateRenderMesh)
{
-
const btSoftBody::RenderNode& n = psb->m_renderNodes[i + clientCmd.m_requestMeshDataArgs.m_startingVertex];
+ if(requestVelocity){
+ b3Warning("Request mesh velocity not implemented for Render Mesh.");
+ return hasStatus;
+ }
verticesOut[i].setValue(n.m_x.x(), n.m_x.y(), n.m_x.z());
}
else
{
const btSoftBody::Node& n = psb->m_nodes[i + clientCmd.m_requestMeshDataArgs.m_startingVertex];
- verticesOut[i].setValue(n.m_x.x(), n.m_x.y(), n.m_x.z());
+ if(!requestVelocity){
+ verticesOut[i].setValue(n.m_x.x(), n.m_x.y(), n.m_x.z());
+ }
+ else{
+ verticesOut[i].setValue(n.m_v.x(), n.m_v.y(), n.m_v.z());
+ }
}
}
sizeInBytes = verticesCopied * sizeof(btVector3);
@@ -8077,6 +8127,125 @@ bool PhysicsServerCommandProcessor::processRequestActualStateCommand(const struc
return hasStatus;
}
+bool RequestFiltered(const struct SharedMemoryCommand& clientCmd, int& linkIndexA, int& linkIndexB, int& objectIndexA, int& objectIndexB, bool& swap){
+
+ if (clientCmd.m_requestContactPointArguments.m_objectAIndexFilter >= 0)
+ {
+ if (clientCmd.m_requestContactPointArguments.m_objectAIndexFilter == objectIndexA)
+ {
+ swap = false;
+ }
+ else if (clientCmd.m_requestContactPointArguments.m_objectAIndexFilter == objectIndexB)
+ {
+ swap = true;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ if (swap)
+ {
+ std::swap(objectIndexA, objectIndexB);
+ std::swap(linkIndexA, linkIndexB);
+ }
+
+ //apply the second object filter, if the user provides it
+ if (clientCmd.m_requestContactPointArguments.m_objectBIndexFilter >= 0)
+ {
+ if (clientCmd.m_requestContactPointArguments.m_objectBIndexFilter != objectIndexB)
+ {
+ return true;
+ }
+ }
+
+ if (
+ (clientCmd.m_updateFlags & CMD_REQUEST_CONTACT_POINT_HAS_LINK_INDEX_A_FILTER) &&
+ clientCmd.m_requestContactPointArguments.m_linkIndexAIndexFilter != linkIndexA)
+ {
+ return true;
+ }
+
+ if (
+ (clientCmd.m_updateFlags & CMD_REQUEST_CONTACT_POINT_HAS_LINK_INDEX_B_FILTER) &&
+ clientCmd.m_requestContactPointArguments.m_linkIndexBIndexFilter != linkIndexB)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool PhysicsServerCommandProcessor::processRequestDeformableDeformableContactpointHelper(const struct SharedMemoryCommand& clientCmd){
+#ifndef SKIP_DEFORMABLE_BODY
+ btDeformableMultiBodyDynamicsWorld* deformWorld = getDeformableWorld();
+ if (!deformWorld)
+ {
+ return false;
+ }
+ const int max_contacts_per_object = 4;
+ for (int i = deformWorld->getSoftBodyArray().size() - 1; i >= 0; i--)
+ {
+ int num_contacts_reported = 0;
+ btSoftBody* psb = deformWorld->getSoftBodyArray()[i];
+ for (int c = 0; c < psb->m_faceNodeContacts.size(); c++)
+ {
+ const btSoftBody::DeformableFaceNodeContact* contact = &psb->m_faceNodeContacts[c];
+ //apply the filter, if the user provides it
+ int linkIndexA = -1;
+ int linkIndexB = -1;
+ int objectIndexA = psb->getUserIndex2();
+ int objectIndexB = -1;
+ const btSoftBody* bodyB = btSoftBody::upcast(contact->m_colObj);
+ if (bodyB)
+ {
+ objectIndexB = bodyB->getUserIndex2();
+ }
+ bool swap = false;
+ if(RequestFiltered(clientCmd, linkIndexA, linkIndexB, objectIndexA, objectIndexB, swap)==true){
+ continue;
+ }
+ if (++num_contacts_reported > max_contacts_per_object)
+ {
+ break;
+ }
+ //Convert contact info
+ b3ContactPointData pt;
+ btVector3 l = contact->m_node->m_x - BaryEval(contact->m_face->m_n[0]->m_x, contact->m_face->m_n[1]->m_x, contact->m_face->m_n[2]->m_x, contact->m_normal);
+ pt.m_contactDistance = -contact->m_margin + contact->m_normal.dot(l);
+ pt.m_bodyUniqueIdA = objectIndexA;
+ pt.m_bodyUniqueIdB = objectIndexB;
+ pt.m_contactFlags = 0;
+ pt.m_linkIndexA = linkIndexA;
+ pt.m_linkIndexB = linkIndexB;
+ for (int j = 0; j < 3; j++)
+ {
+ if (swap)
+ {
+ pt.m_contactNormalOnBInWS[j] = -contact->m_normal[j];
+ }
+ else
+ {
+ pt.m_contactNormalOnBInWS[j] = contact->m_normal[j];
+ }
+ pt.m_positionOnAInWS[j] = contact->m_node->m_x[j];
+ pt.m_positionOnBInWS[j] = contact->m_node->m_x[j];
+ pt.m_linearFrictionDirection1[j] = 0;
+ pt.m_linearFrictionDirection2[j] = 0;
+ }
+ pt.m_normalForce = 0;
+ pt.m_linearFrictionForce1 = 0;
+ pt.m_linearFrictionForce2 = 0;
+ m_data->m_cachedContactPoints.push_back(pt);
+ }
+ }
+#endif
+ return true;
+}
+
+
+
bool PhysicsServerCommandProcessor::processRequestDeformableContactpointHelper(const struct SharedMemoryCommand& clientCmd)
{
#ifndef SKIP_DEFORMABLE_BODY
@@ -8345,6 +8514,7 @@ bool PhysicsServerCommandProcessor::processRequestContactpointInformationCommand
#ifndef SKIP_DEFORMABLE_BODY
processRequestDeformableContactpointHelper(clientCmd);
+ processRequestDeformableDeformableContactpointHelper(clientCmd);
#endif
break;
}
@@ -9220,6 +9390,10 @@ bool PhysicsServerCommandProcessor::processDeformable(const UrdfDeformable& defo
psb->setGravityFactor(deformable.m_gravFactor);
psb->setCacheBarycenter(deformable.m_cache_barycenter);
psb->initializeFaceTree();
+
+ deformWorld->setImplicit(true);
+ deformWorld->setLineSearch(false);
+ deformWorld->setUseProjection(true);
}
#endif //SKIP_DEFORMABLE_BODY
#ifndef SKIP_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD
@@ -9481,6 +9655,447 @@ bool PhysicsServerCommandProcessor::processDeformable(const UrdfDeformable& defo
return true;
}
+bool PhysicsServerCommandProcessor::processReducedDeformable(const UrdfReducedDeformable& reduced_deformable, const btVector3& pos, const btQuaternion& orn, int* bodyUniqueId, char* bufferServerToClient, int bufferSizeInBytes, btScalar scale, bool useSelfCollision)
+{
+#ifndef SKIP_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD
+ btReducedDeformableBody* rsb = NULL;
+ CommonFileIOInterface* fileIO(m_data->m_pluginManager.getFileIOInterface());
+ char relativeFileName[1024];
+ char pathPrefix[1024];
+ pathPrefix[0] = 0;
+ if (fileIO->findResourcePath(reduced_deformable.m_visualFileName.c_str(), relativeFileName, 1024))
+ {
+ b3FileUtils::extractPath(relativeFileName, pathPrefix, 1024);
+ }
+ const std::string& error_message_prefix = "";
+ std::string out_found_filename, out_found_sim_filename;
+ int out_type(0), out_sim_type(0);
+
+ bool foundFile = UrdfFindMeshFile(fileIO, pathPrefix, relativeFileName, error_message_prefix, &out_found_filename, &out_type);
+ if (!reduced_deformable.m_simFileName.empty())
+ {
+ bool foundSimMesh = UrdfFindMeshFile(fileIO, pathPrefix, reduced_deformable.m_simFileName, error_message_prefix, &out_found_sim_filename, &out_sim_type);
+ }
+ else
+ {
+ out_sim_type = out_type;
+ out_found_sim_filename = out_found_filename;
+ }
+
+ if (out_sim_type == UrdfGeometry::FILE_OBJ)
+ {
+ printf("Obj file is currently unsupported\n");
+ return false;
+ }
+ else if (out_sim_type == UrdfGeometry::FILE_VTK)
+ {
+#ifndef SKIP_DEFORMABLE_BODY
+ btDeformableMultiBodyDynamicsWorld* deformWorld = getDeformableWorld();
+ if (deformWorld)
+ {
+ rsb = btReducedDeformableBodyHelpers::createFromVtkFile(deformWorld->getWorldInfo(), out_found_sim_filename.c_str());
+ if (!rsb)
+ {
+ printf("Load reduced deformable failed\n");
+ return false;
+ }
+
+ // load modes, reduced stiffness matrix
+ rsb->setReducedModes(reduced_deformable.m_numModes, rsb->m_nodes.size());
+ rsb->setStiffnessScale(reduced_deformable.m_stiffnessScale);
+ rsb->setDamping(0, reduced_deformable.m_damping); // damping alpha is set to 0 by default
+ btReducedDeformableBodyHelpers::readReducedDeformableInfoFromFiles(rsb, pathPrefix);
+ // set total mass
+ rsb->setTotalMass(reduced_deformable.m_mass);
+ }
+#endif
+ }
+ b3ImportMeshData meshData;
+
+ if (rsb != NULL)
+ {
+#ifndef SKIP_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD
+ // load render mesh
+ if ((out_found_sim_filename != out_found_filename) || ((out_sim_type == UrdfGeometry::FILE_OBJ)))
+ {
+ // load render mesh
+ if (!m_data->m_useAlternativeDeformableIndexing)
+ {
+
+ float rgbaColor[4] = { 1,1,1,1 };
+
+ if (b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(
+ out_found_filename.c_str(), meshData, fileIO))
+ {
+
+ for (int v = 0; v < meshData.m_gfxShape->m_numvertices; v++)
+ {
+ btSoftBody::RenderNode n;
+ n.m_x.setValue(
+ meshData.m_gfxShape->m_vertices->at(v).xyzw[0],
+ meshData.m_gfxShape->m_vertices->at(v).xyzw[1],
+ meshData.m_gfxShape->m_vertices->at(v).xyzw[2]);
+ n.m_uv1.setValue(meshData.m_gfxShape->m_vertices->at(v).uv[0],
+ meshData.m_gfxShape->m_vertices->at(v).uv[1],
+ 0.);
+ n.m_normal.setValue(meshData.m_gfxShape->m_vertices->at(v).normal[0],
+ meshData.m_gfxShape->m_vertices->at(v).normal[1],
+ meshData.m_gfxShape->m_vertices->at(v).normal[2]);
+ rsb->m_renderNodes.push_back(n);
+ }
+ for (int f = 0; f < meshData.m_gfxShape->m_numIndices; f += 3)
+ {
+ btSoftBody::RenderFace ff;
+ ff.m_n[0] = &rsb->m_renderNodes[meshData.m_gfxShape->m_indices->at(f + 0)];
+ ff.m_n[1] = &rsb->m_renderNodes[meshData.m_gfxShape->m_indices->at(f + 1)];
+ ff.m_n[2] = &rsb->m_renderNodes[meshData.m_gfxShape->m_indices->at(f + 2)];
+ rsb->m_renderFaces.push_back(ff);
+ }
+ }
+ }
+ else
+ {
+ bt_tinyobj::attrib_t attribute;
+ std::vector<bt_tinyobj::shape_t> shapes;
+
+ std::string err = bt_tinyobj::LoadObj(attribute, shapes, out_found_filename.c_str(), pathPrefix, m_data->m_pluginManager.getFileIOInterface());
+
+ for (int s = 0; s < (int)shapes.size(); s++)
+ {
+ bt_tinyobj::shape_t& shape = shapes[s];
+ int faceCount = shape.mesh.indices.size();
+ int vertexCount = attribute.vertices.size() / 3;
+ for (int v = 0; v < vertexCount; v++)
+ {
+ btSoftBody::RenderNode n;
+ n.m_x = btVector3(attribute.vertices[3 * v], attribute.vertices[3 * v + 1], attribute.vertices[3 * v + 2]);
+ rsb->m_renderNodes.push_back(n);
+ }
+ for (int f = 0; f < faceCount; f += 3)
+ {
+ if (f < 0 && f >= int(shape.mesh.indices.size()))
+ {
+ continue;
+ }
+ bt_tinyobj::index_t v_0 = shape.mesh.indices[f];
+ bt_tinyobj::index_t v_1 = shape.mesh.indices[f + 1];
+ bt_tinyobj::index_t v_2 = shape.mesh.indices[f + 2];
+ btSoftBody::RenderFace ff;
+ ff.m_n[0] = &rsb->m_renderNodes[v_0.vertex_index];
+ ff.m_n[1] = &rsb->m_renderNodes[v_1.vertex_index];
+ ff.m_n[2] = &rsb->m_renderNodes[v_2.vertex_index];
+ rsb->m_renderFaces.push_back(ff);
+ }
+ }
+ }
+ if (out_sim_type == UrdfGeometry::FILE_VTK)
+ {
+ btSoftBodyHelpers::interpolateBarycentricWeights(rsb);
+ }
+ else if (out_sim_type == UrdfGeometry::FILE_OBJ)
+ {
+ btSoftBodyHelpers::extrapolateBarycentricWeights(rsb);
+ }
+ }
+ else
+ {
+ rsb->m_renderNodes.resize(0);
+ }
+#endif
+#ifndef SKIP_DEFORMABLE_BODY
+ btDeformableMultiBodyDynamicsWorld* deformWorld = getDeformableWorld();
+ if (deformWorld)
+ {
+ btScalar collision_hardness = 1;
+ rsb->m_cfg.kKHR = collision_hardness;
+ rsb->m_cfg.kCHR = collision_hardness;
+
+ rsb->m_cfg.kDF = reduced_deformable.m_friction;
+ btSoftBody::Material* pm = rsb->appendMaterial();
+ pm->m_flags -= btSoftBody::fMaterial::DebugDraw;
+
+ // turn on the collision flag for deformable
+ // collision between deformable and rigid
+ rsb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
+ /// turn on node contact for rigid body
+ rsb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
+ // turn on face contact for multibodies
+ // rsb->m_cfg.collisions |= btSoftBody::fCollision::SDF_MDF;
+ // collion between deformable and deformable and self-collision
+ // rsb->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
+ rsb->setCollisionFlags(0);
+ rsb->setSelfCollision(useSelfCollision);
+ rsb->initializeFaceTree();
+ }
+#endif //SKIP_DEFORMABLE_BODY
+// #ifndef SKIP_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD
+// btSoftMultiBodyDynamicsWorld* softWorld = getSoftWorld();
+// if (softWorld)
+// {
+// btSoftBody::Material* pm = rsb->appendMaterial();
+// pm->m_kLST = 0.5;
+// pm->m_flags -= btSoftBody::fMaterial::DebugDraw;
+// rsb->generateBendingConstraints(2, pm);
+// rsb->m_cfg.piterations = 20;
+// rsb->m_cfg.kDF = 0.5;
+// //turn on softbody vs softbody collision
+// rsb->m_cfg.collisions |= btSoftBody::fCollision::VF_SS;
+// rsb->randomizeConstraints();
+// rsb->setTotalMass(reduced_deformable.m_mass, true);
+// }
+// #endif //SKIP_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD
+ rsb->scale(btVector3(scale, scale, scale));
+ btTransform init_transform;
+ init_transform.setOrigin(pos);
+ init_transform.setRotation(orn);
+ rsb->transform(init_transform);
+
+ rsb->getCollisionShape()->setMargin(reduced_deformable.m_collisionMargin);
+ rsb->getCollisionShape()->setUserPointer(rsb);
+#ifndef SKIP_DEFORMABLE_BODY
+ if (deformWorld)
+ {
+ deformWorld->addSoftBody(rsb);
+ deformWorld->getSolverInfo().m_deformable_erp = reduced_deformable.m_erp;
+ deformWorld->getSolverInfo().m_deformable_cfm = reduced_deformable.m_cfm;
+ deformWorld->getSolverInfo().m_friction = reduced_deformable.m_friction;
+ deformWorld->getSolverInfo().m_splitImpulse = false;
+ deformWorld->setImplicit(false);
+ deformWorld->setLineSearch(false);
+ deformWorld->setUseProjection(false);
+ }
+ else
+#endif //SKIP_DEFORMABLE_BODY
+ {
+ btSoftMultiBodyDynamicsWorld* softWorld = getSoftWorld();
+ if (softWorld)
+ {
+ softWorld->addSoftBody(rsb);
+ }
+ }
+
+ *bodyUniqueId = m_data->m_bodyHandles.allocHandle();
+ InternalBodyHandle* bodyHandle = m_data->m_bodyHandles.getHandle(*bodyUniqueId);
+ bodyHandle->m_softBody = rsb;
+ rsb->setUserIndex2(*bodyUniqueId);
+
+ b3VisualShapeData visualShape;
+
+ visualShape.m_objectUniqueId = *bodyUniqueId;
+ visualShape.m_linkIndex = -1;
+ visualShape.m_visualGeometryType = URDF_GEOM_MESH;
+ //dimensions just contains the scale
+ visualShape.m_dimensions[0] = 1;
+ visualShape.m_dimensions[1] = 1;
+ visualShape.m_dimensions[2] = 1;
+ //filename
+ strncpy(visualShape.m_meshAssetFileName, relativeFileName, VISUAL_SHAPE_MAX_PATH_LEN);
+ visualShape.m_meshAssetFileName[VISUAL_SHAPE_MAX_PATH_LEN - 1] = 0;
+ //position and orientation
+ visualShape.m_localVisualFrame[0] = 0;
+ visualShape.m_localVisualFrame[1] = 0;
+ visualShape.m_localVisualFrame[2] = 0;
+ visualShape.m_localVisualFrame[3] = 0;
+ visualShape.m_localVisualFrame[4] = 0;
+ visualShape.m_localVisualFrame[5] = 0;
+ visualShape.m_localVisualFrame[6] = 1;
+ //color and ids to be set by the renderer
+ visualShape.m_rgbaColor[0] = 1;
+ visualShape.m_rgbaColor[1] = 1;
+ visualShape.m_rgbaColor[2] = 1;
+ visualShape.m_rgbaColor[3] = 1;
+ visualShape.m_tinyRendererTextureId = -1;
+ visualShape.m_textureUniqueId = -1;
+ visualShape.m_openglTextureId = -1;
+
+ if (meshData.m_gfxShape)
+ {
+ int texUid1 = -1;
+ if (meshData.m_textureHeight > 0 && meshData.m_textureWidth > 0 && meshData.m_textureImage1)
+ {
+ texUid1 = m_data->m_guiHelper->registerTexture(meshData.m_textureImage1, meshData.m_textureWidth, meshData.m_textureHeight);
+ }
+ visualShape.m_openglTextureId = texUid1;
+ int shapeUid1 = m_data->m_guiHelper->registerGraphicsShape(&meshData.m_gfxShape->m_vertices->at(0).xyzw[0], meshData.m_gfxShape->m_numvertices, &meshData.m_gfxShape->m_indices->at(0), meshData.m_gfxShape->m_numIndices, B3_GL_TRIANGLES, texUid1);
+ rsb->getCollisionShape()->setUserIndex(shapeUid1);
+ float position[4] = { 0,0,0,1 };
+ float orientation[4] = { 0,0,0,1 };
+ float color[4] = { 1,1,1,1 };
+ float scaling[4] = { 1,1,1,1 };
+ int instanceUid = m_data->m_guiHelper->registerGraphicsInstance(shapeUid1, position, orientation, color, scaling);
+ rsb->setUserIndex(instanceUid);
+
+ if (m_data->m_enableTinyRenderer)
+ {
+ int texUid2 = m_data->m_pluginManager.getRenderInterface()->registerTexture(meshData.m_textureImage1, meshData.m_textureWidth, meshData.m_textureHeight);
+ visualShape.m_tinyRendererTextureId = texUid2;
+ int linkIndex = -1;
+ int softBodyGraphicsShapeUid = m_data->m_pluginManager.getRenderInterface()->registerShapeAndInstance(
+ visualShape,
+ &meshData.m_gfxShape->m_vertices->at(0).xyzw[0],
+ meshData.m_gfxShape->m_numvertices,
+ &meshData.m_gfxShape->m_indices->at(0),
+ meshData.m_gfxShape->m_numIndices,
+ B3_GL_TRIANGLES,
+ texUid2,
+ rsb->getBroadphaseHandle()->getUid(),
+ *bodyUniqueId,
+ linkIndex);
+
+ rsb->setUserIndex3(softBodyGraphicsShapeUid);
+ }
+ delete meshData.m_gfxShape;
+ meshData.m_gfxShape = 0;
+ }
+ else
+ {
+ //m_data->m_guiHelper->createCollisionShapeGraphicsObject(psb->getCollisionShape());
+
+ btAlignedObjectArray<GLInstanceVertex> gfxVertices;
+ btAlignedObjectArray<int> indices;
+ int strideInBytes = 9 * sizeof(float);
+ gfxVertices.resize(rsb->m_faces.size() * 3);
+ for (int i = 0; i < rsb->m_faces.size(); i++) // Foreach face
+ {
+ for (int k = 0; k < 3; k++) // Foreach vertex on a face
+ {
+ int currentIndex = i * 3 + k;
+ for (int j = 0; j < 3; j++)
+ {
+ gfxVertices[currentIndex].xyzw[j] = rsb->m_faces[i].m_n[k]->m_x[j];
+ }
+ for (int j = 0; j < 3; j++)
+ {
+ gfxVertices[currentIndex].normal[j] = rsb->m_faces[i].m_n[k]->m_n[j];
+ }
+ for (int j = 0; j < 2; j++)
+ {
+ gfxVertices[currentIndex].uv[j] = btFabs(btFabs(10. * rsb->m_faces[i].m_n[k]->m_x[j]));
+ }
+ indices.push_back(currentIndex);
+ }
+ }
+ if (gfxVertices.size() && indices.size())
+ {
+ int red = 173;
+ int green = 199;
+ int blue = 255;
+
+ int texWidth = 256;
+ int texHeight = 256;
+ btAlignedObjectArray<unsigned char> texels;
+ texels.resize(texWidth* texHeight * 3);
+ for (int i = 0; i < texWidth * texHeight * 3; i++)
+ texels[i] = 255;
+ for (int i = 0; i < texWidth; i++)
+ {
+ for (int j = 0; j < texHeight; j++)
+ {
+ int a = i < texWidth / 2 ? 1 : 0;
+ int b = j < texWidth / 2 ? 1 : 0;
+
+ if (a == b)
+ {
+ texels[(i + j * texWidth) * 3 + 0] = red;
+ texels[(i + j * texWidth) * 3 + 1] = green;
+ texels[(i + j * texWidth) * 3 + 2] = blue;
+ }
+ }
+ }
+
+ int texId = m_data->m_guiHelper->registerTexture(&texels[0], texWidth, texHeight);
+ visualShape.m_openglTextureId = texId;
+ int shapeId = m_data->m_guiHelper->registerGraphicsShape(&gfxVertices[0].xyzw[0], gfxVertices.size(), &indices[0], indices.size(), B3_GL_TRIANGLES, texId);
+ b3Assert(shapeId >= 0);
+ rsb->getCollisionShape()->setUserIndex(shapeId);
+ if (m_data->m_enableTinyRenderer)
+ {
+
+ int texUid2 = m_data->m_pluginManager.getRenderInterface()->registerTexture(&texels[0], texWidth, texHeight);
+ visualShape.m_tinyRendererTextureId = texUid2;
+ int linkIndex = -1;
+ int softBodyGraphicsShapeUid = m_data->m_pluginManager.getRenderInterface()->registerShapeAndInstance(
+ visualShape,
+ &gfxVertices[0].xyzw[0], gfxVertices.size(), &indices[0], indices.size(), B3_GL_TRIANGLES, texUid2,
+ rsb->getBroadphaseHandle()->getUid(),
+ *bodyUniqueId,
+ linkIndex);
+ rsb->setUserIndex3(softBodyGraphicsShapeUid);
+ }
+ }
+ }
+
+
+
+ btAlignedObjectArray<btVector3> vertices;
+ btAlignedObjectArray<btVector3> normals;
+ if (rsb->m_renderNodes.size() == 0)
+ {
+ rsb->m_renderNodes.resize(rsb->m_faces.size()*3);
+ vertices.resize(rsb->m_faces.size() * 3);
+ normals.resize(rsb->m_faces.size() * 3);
+
+ for (int i = 0; i < rsb->m_faces.size(); i++) // Foreach face
+ {
+
+ for (int k = 0; k < 3; k++) // Foreach vertex on a face
+ {
+ int currentIndex = i * 3 + k;
+ for (int j = 0; j < 3; j++)
+ {
+ rsb->m_renderNodes[currentIndex].m_x[j] = rsb->m_faces[i].m_n[k]->m_x[j];
+ }
+ for (int j = 0; j < 3; j++)
+ {
+ rsb->m_renderNodes[currentIndex].m_normal[j] = rsb->m_faces[i].m_n[k]->m_n[j];
+ }
+ for (int j = 0; j < 2; j++)
+ {
+ rsb->m_renderNodes[currentIndex].m_uv1[j] = btFabs(10*rsb->m_faces[i].m_n[k]->m_x[j]);
+ }
+ rsb->m_renderNodes[currentIndex].m_uv1[2] = 0;
+ vertices[currentIndex] = rsb->m_faces[i].m_n[k]->m_x;
+ normals[currentIndex] = rsb->m_faces[i].m_n[k]->m_n;
+ }
+ }
+ btSoftBodyHelpers::extrapolateBarycentricWeights(rsb);
+ }
+ else
+ {
+ vertices.resize(rsb->m_renderNodes.size());
+ normals.resize(rsb->m_renderNodes.size());
+ for (int i = 0; i < rsb->m_renderNodes.size(); i++) // Foreach face
+ {
+ vertices[i] = rsb->m_renderNodes[i].m_x;
+ normals[i] = rsb->m_renderNodes[i].m_normal;
+ }
+ }
+ m_data->m_pluginManager.getRenderInterface()->updateShape(rsb->getUserIndex3(), &vertices[0], vertices.size(), &normals[0], normals.size());
+
+ if (!reduced_deformable.m_name.empty())
+ {
+ bodyHandle->m_bodyName = reduced_deformable.m_name;
+ }
+ else
+ {
+ int pos = strlen(relativeFileName) - 1;
+ while (pos >= 0 && relativeFileName[pos] != '/')
+ {
+ pos--;
+ }
+ btAssert(strlen(relativeFileName) - pos - 5 > 0);
+ std::string object_name(std::string(relativeFileName).substr(pos + 1, strlen(relativeFileName) - 5 - pos));
+ bodyHandle->m_bodyName = object_name;
+ }
+ b3Notification notification;
+ notification.m_notificationType = BODY_ADDED;
+ notification.m_bodyArgs.m_bodyUniqueId = *bodyUniqueId;
+ m_data->m_pluginManager.addNotification(notification);
+ }
+#endif
+ return true;
+}
+
bool PhysicsServerCommandProcessor::processLoadSoftBodyCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes)
{
serverStatusOut.m_type = CMD_LOAD_SOFT_BODY_FAILED;
@@ -10714,7 +11329,8 @@ bool PhysicsServerCommandProcessor::processSendPhysicsParametersCommand(const st
btDeformableMultiBodyDynamicsWorld* deformWorld = getDeformableWorld();
if (deformWorld)
{
- deformWorld->getWorldInfo().m_gravity = grav;
+ // deformWorld->getWorldInfo().m_gravity = grav;
+ deformWorld->setGravity(grav);
for (int i = 0; i < m_data->m_lf.size(); ++i)
{
btDeformableLagrangianForce* force = m_data->m_lf[i];
diff --git a/examples/SharedMemory/PhysicsServerCommandProcessor.h b/examples/SharedMemory/PhysicsServerCommandProcessor.h
index ad6c403aa..fb23a1bb9 100644
--- a/examples/SharedMemory/PhysicsServerCommandProcessor.h
+++ b/examples/SharedMemory/PhysicsServerCommandProcessor.h
@@ -46,6 +46,7 @@ protected:
bool processRequestActualStateCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestContactpointInformationCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestDeformableContactpointHelper(const struct SharedMemoryCommand& clientCmd);
+ bool processRequestDeformableDeformableContactpointHelper(const struct SharedMemoryCommand& clientCmd);
bool processRequestBodyInfoCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processLoadSDFCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processCreateMultiBodyCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
@@ -109,6 +110,7 @@ protected:
bool processImportedObjects(const char* fileName, char* bufferServerToClient, int bufferSizeInBytes, bool useMultiBody, int flags, class URDFImporterInterface& u2b);
bool processDeformable(const UrdfDeformable& deformable, const btVector3& pos, const btQuaternion& orn, int* bodyUniqueId, char* bufferServerToClient, int bufferSizeInBytes, btScalar scale, bool useSelfCollision);
+ bool processReducedDeformable(const UrdfReducedDeformable& deformable, const btVector3& pos, const btQuaternion& orn, int* bodyUniqueId, char* bufferServerToClient, int bufferSizeInBytes, btScalar scale, bool useSelfCollision);
bool supportsJointMotor(class btMultiBody* body, int linkIndex);
diff --git a/examples/SharedMemory/PosixSharedMemory.cpp b/examples/SharedMemory/PosixSharedMemory.cpp
index 00bcf7584..dac21eeb4 100644
--- a/examples/SharedMemory/PosixSharedMemory.cpp
+++ b/examples/SharedMemory/PosixSharedMemory.cpp
@@ -8,6 +8,11 @@
#define TEST_SHARED_MEMORY
#endif //_WIN32
+//Shmem not available on target api < 26
+#if defined(__ANDROID_API__) && (__ANDROID_API__ < 26)
+#undef TEST_SHARED_MEMORY
+#endif //__ANDROID__
+
#include <stddef.h>
#ifdef TEST_SHARED_MEMORY
diff --git a/examples/SharedMemory/SharedMemoryPublic.h b/examples/SharedMemory/SharedMemoryPublic.h
index 2649fc44d..7541ddb5a 100644
--- a/examples/SharedMemory/SharedMemoryPublic.h
+++ b/examples/SharedMemory/SharedMemoryPublic.h
@@ -461,12 +461,12 @@ struct b3MeshVertex
double x, y, z, w;
};
-
enum eMeshDataFlags
{
- B3_MESH_DATA_SIMULATION_MESH=1,
- B3_MESH_DATA_SIMULATION_INDICES,
- B3_MESH_DATA_GRAPHICS_INDICES,
+ B3_MESH_DATA_SIMULATION_MESH = 1,
+ B3_MESH_DATA_SIMULATION_INDICES = 2,
+ B3_MESH_DATA_GRAPHICS_INDICES = 4,
+ B3_MESH_DATA_SIMULATION_MESH_VELOCITY = 8,
};
enum eMeshDataEnum
@@ -617,6 +617,7 @@ enum b3ResetSimulationFlags
RESET_USE_DEFORMABLE_WORLD=1,
RESET_USE_DISCRETE_DYNAMICS_WORLD=2,
RESET_USE_SIMPLE_BROADPHASE=4,
+ RESET_USE_REDUCED_DEFORMABLE_WORLD=8,
};
struct b3BodyNotificationArgs
diff --git a/examples/pybullet/examples/reduced_deformable_cube.py b/examples/pybullet/examples/reduced_deformable_cube.py
new file mode 100644
index 000000000..cab91cfdb
--- /dev/null
+++ b/examples/pybullet/examples/reduced_deformable_cube.py
@@ -0,0 +1,27 @@
+import pybullet as p
+from time import sleep
+import pybullet_data
+
+physicsClient = p.connect(p.GUI)
+
+p.setAdditionalSearchPath(pybullet_data.getDataPath())
+
+p.resetSimulation(p.RESET_USE_REDUCED_DEFORMABLE_WORLD)
+p.resetDebugVisualizerCamera(4,-40,-30,[0, 0, 0])
+p.setGravity(0, 0, -10)
+
+tex = p.loadTexture("uvmap.png")
+planeId = p.loadURDF("plane.urdf", [0,0,-2])
+
+boxId = p.loadURDF("cube.urdf", [1,1,5],useMaximalCoordinates = True)
+
+#p.startStateLogging(p.STATE_LOGGING_VIDEO_MP4, "reduced_cube.mp4")
+cube = p.loadURDF("reduced_cube/reduced_cube.urdf", [1,1,1])
+p.changeVisualShape(cube, -1, rgbaColor=[1,1,1,1], textureUniqueId=tex, flags=0)
+p.setPhysicsEngineParameter(sparseSdfVoxelSize=0.25)
+p.setRealTimeSimulation(0)
+
+while p.isConnected():
+ p.stepSimulation()
+ p.getCameraImage(320,200)
+ p.setGravity(0,0,-10)
diff --git a/examples/pybullet/examples/reduced_deformable_torus.py b/examples/pybullet/examples/reduced_deformable_torus.py
new file mode 100644
index 000000000..8f42e0372
--- /dev/null
+++ b/examples/pybullet/examples/reduced_deformable_torus.py
@@ -0,0 +1,32 @@
+import pybullet as p
+from time import sleep
+import pybullet_data
+
+physicsClient = p.connect(p.GUI)
+
+p.setAdditionalSearchPath(pybullet_data.getDataPath())
+
+p.resetSimulation(p.RESET_USE_REDUCED_DEFORMABLE_WORLD)
+p.resetDebugVisualizerCamera(4,-40,-30,[0, 0, 0])
+p.setGravity(0, 0, -10)
+
+tex = p.loadTexture("uvmap.png")
+planeId = p.loadURDF("plane.urdf", [0,0,-2])
+
+box1 = p.loadURDF("cube.urdf", [1,1,3],useMaximalCoordinates = True)
+box2 = p.loadURDF("cube.urdf", [0,3,2],useMaximalCoordinates = True)
+
+# p.startStateLogging(p.STATE_LOGGING_VIDEO_MP4, "reduced_torus.mp4")
+reduced_obj1= p.loadURDF("reduced_torus/reduced_torus.urdf", [1,1,1])
+p.changeVisualShape(reduced_obj1, -1, rgbaColor=[1,1,1,1], textureUniqueId=tex, flags=0)
+
+reduced_obj2 = p.loadURDF("reduced_torus/reduced_torus.urdf", [1,2,1])
+p.changeVisualShape(reduced_obj2, -1, rgbaColor=[1,1,1,1], textureUniqueId=tex, flags=0)
+
+p.setPhysicsEngineParameter(sparseSdfVoxelSize=0.25)
+p.setRealTimeSimulation(0)
+
+while p.isConnected():
+ p.stepSimulation()
+ p.getCameraImage(320,200)
+ p.setGravity(0,0,-10)
diff --git a/examples/pybullet/gym/pybullet_utils/urdfEditor.py b/examples/pybullet/gym/pybullet_utils/urdfEditor.py
index a9d9c5fa1..3b6a9fcbc 100644
--- a/examples/pybullet/gym/pybullet_utils/urdfEditor.py
+++ b/examples/pybullet/gym/pybullet_utils/urdfEditor.py
@@ -64,6 +64,8 @@ class UrdfJoint(object):
self.joint_type = p.JOINT_REVOLUTE
self.joint_lower_limit = 0
self.joint_upper_limit = -1
+ self.joint_max_force = 0
+ self.joint_max_velocity = 0
self.parent_name = "parentName"
self.child_name = "childName"
self.joint_origin_xyz = [1, 2, 3]
@@ -171,6 +173,8 @@ class UrdfEditor(object):
urdfJoint.joint_type = jointInfo[2]
urdfJoint.joint_lower_limit = jointInfo[8]
urdfJoint.joint_upper_limit = jointInfo[9]
+ urdfJoint.joint_max_force = jointInfo[10]
+ urdfJoint.joint_max_velocity = jointInfo[11]
urdfJoint.joint_axis_xyz = jointInfo[13]
orgParentIndex = jointInfo[16]
if (orgParentIndex < 0):
@@ -326,12 +330,14 @@ class UrdfEditor(object):
str = '\t\t<child link=\"{}\"/>\n'.format(urdfJoint.child_name)
file.write(str)
- if urdfJoint.joint_type == p.JOINT_PRISMATIC:
- #todo: handle limits
- lowerLimit = -0.5
- upperLimit = 0.5
- str = '<limit effort="1000.0" lower="{:.{prec}f}" upper="{:.{prec}f}" velocity="0.5"/>'.format(
- lowerLimit, upperLimit, prec=precision)
+ if jointTypeStr == "prismatic" or jointTypeStr == "revolute":
+ lowerLimit = urdfJoint.joint_lower_limit
+ upperLimit = urdfJoint.joint_upper_limit
+ maxForce = urdfJoint.joint_max_force
+ maxVelocity = urdfJoint.joint_max_velocity
+
+ str = '\t\t<limit effort="{:.{prec}f}" lower="{:.{prec}f}" upper="{:.{prec}f}" velocity="{:.{prec}f}"/>\n'.format(
+ maxForce, lowerLimit, upperLimit, maxVelocity, prec=precision)
file.write(str)
file.write("\t\t<dynamics damping=\"1.0\" friction=\"0.0001\"/>\n")
diff --git a/examples/pybullet/pybullet.c b/examples/pybullet/pybullet.c
index 3c5d8f3ae..52589aa59 100644
--- a/examples/pybullet/pybullet.c
+++ b/examples/pybullet/pybullet.c
@@ -13176,6 +13176,7 @@ initpybullet(void)
//PyModule_AddIntConstant(m, "CONSTRAINT_SOLVER_LCP_BLOCK",eConstraintSolverLCP_BLOCK_PGS);
PyModule_AddIntConstant(m, "RESET_USE_DEFORMABLE_WORLD", RESET_USE_DEFORMABLE_WORLD);
+ PyModule_AddIntConstant(m, "RESET_USE_REDUCED_DEFORMABLE_WORLD", RESET_USE_REDUCED_DEFORMABLE_WORLD);
PyModule_AddIntConstant(m, "RESET_USE_DISCRETE_DYNAMICS_WORLD", RESET_USE_DISCRETE_DYNAMICS_WORLD);
PyModule_AddIntConstant(m, "RESET_USE_SIMPLE_BROADPHASE", RESET_USE_SIMPLE_BROADPHASE);
diff --git a/examples/pybullet/tensorflow/humanoid_running.py b/examples/pybullet/tensorflow/humanoid_running.py
index ffd502fa3..aedbb1278 100644
--- a/examples/pybullet/tensorflow/humanoid_running.py
+++ b/examples/pybullet/tensorflow/humanoid_running.py
@@ -1,4 +1,8 @@
-import tf.compat.v1 as tf
+try:
+ import tf.compat.v1 as tf
+except Exception:
+ import tensorflow.compat.v1 as tf
+ tf.disable_eager_execution()
import sys
import numpy as np
import argparse
diff --git a/examples/pybullet/tensorflow/humanoid_running_vr_follow.py b/examples/pybullet/tensorflow/humanoid_running_vr_follow.py
index 2df85cd88..98564c091 100644
--- a/examples/pybullet/tensorflow/humanoid_running_vr_follow.py
+++ b/examples/pybullet/tensorflow/humanoid_running_vr_follow.py
@@ -1,4 +1,8 @@
-import tf.compat.v1 as tf
+try:
+ import tf.compat.v1 as tf
+except Exception:
+ import tensorflow.compat.v1 as tf
+ tf.disable_eager_execution()
import sys
import numpy as np
diff --git a/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.cpp b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.cpp
new file mode 100644
index 000000000..feb30d587
--- /dev/null
+++ b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.cpp
@@ -0,0 +1,792 @@
+#include "btReducedDeformableBody.h"
+#include "../btSoftBodyInternals.h"
+#include "btReducedDeformableBodyHelpers.h"
+#include "LinearMath/btTransformUtil.h"
+#include <iostream>
+#include <fstream>
+
+btReducedDeformableBody::btReducedDeformableBody(btSoftBodyWorldInfo* worldInfo, int node_count, const btVector3* x, const btScalar* m)
+ : btSoftBody(worldInfo, node_count, x, m), m_rigidOnly(false)
+{
+ // reduced deformable
+ m_reducedModel = true;
+ m_nReduced = 0;
+ m_nFull = 0;
+ m_nodeIndexOffset = 0;
+
+ m_transform_lock = false;
+ m_ksScale = 1.0;
+ m_rhoScale = 1.0;
+
+ // rigid motion
+ m_linearVelocity.setZero();
+ m_angularVelocity.setZero();
+ m_internalDeltaLinearVelocity.setZero();
+ m_internalDeltaAngularVelocity.setZero();
+ m_angularVelocityFromReduced.setZero();
+ m_internalDeltaAngularVelocityFromReduced.setZero();
+ m_angularFactor.setValue(1, 1, 1);
+ m_linearFactor.setValue(1, 1, 1);
+ // m_invInertiaLocal.setValue(1, 1, 1);
+ m_invInertiaLocal.setIdentity();
+ m_mass = 0.0;
+ m_inverseMass = 0.0;
+
+ m_linearDamping = 0;
+ m_angularDamping = 0;
+
+ // Rayleigh damping
+ m_dampingAlpha = 0;
+ m_dampingBeta = 0;
+
+ m_rigidTransformWorld.setIdentity();
+}
+
+void btReducedDeformableBody::setReducedModes(int num_modes, int full_size)
+{
+ m_nReduced = num_modes;
+ m_nFull = full_size;
+ m_reducedDofs.resize(m_nReduced, 0);
+ m_reducedDofsBuffer.resize(m_nReduced, 0);
+ m_reducedVelocity.resize(m_nReduced, 0);
+ m_reducedVelocityBuffer.resize(m_nReduced, 0);
+ m_reducedForceElastic.resize(m_nReduced, 0);
+ m_reducedForceDamping.resize(m_nReduced, 0);
+ m_reducedForceExternal.resize(m_nReduced, 0);
+ m_internalDeltaReducedVelocity.resize(m_nReduced, 0);
+ m_nodalMass.resize(full_size, 0);
+ m_localMomentArm.resize(m_nFull);
+}
+
+void btReducedDeformableBody::setMassProps(const tDenseArray& mass_array)
+{
+ btScalar total_mass = 0;
+ btVector3 CoM(0, 0, 0);
+ for (int i = 0; i < m_nFull; ++i)
+ {
+ m_nodalMass[i] = m_rhoScale * mass_array[i];
+ m_nodes[i].m_im = mass_array[i] > 0 ? 1.0 / (m_rhoScale * mass_array[i]) : 0;
+ total_mass += m_rhoScale * mass_array[i];
+
+ CoM += m_nodalMass[i] * m_nodes[i].m_x;
+ }
+ // total rigid body mass
+ m_mass = total_mass;
+ m_inverseMass = total_mass > 0 ? 1.0 / total_mass : 0;
+ // original CoM
+ m_initialCoM = CoM / total_mass;
+}
+
+void btReducedDeformableBody::setInertiaProps()
+{
+ // make sure the initial CoM is at the origin (0,0,0)
+ // for (int i = 0; i < m_nFull; ++i)
+ // {
+ // m_nodes[i].m_x -= m_initialCoM;
+ // }
+ // m_initialCoM.setZero();
+ m_rigidTransformWorld.setOrigin(m_initialCoM);
+ m_interpolationWorldTransform = m_rigidTransformWorld;
+
+ updateLocalInertiaTensorFromNodes();
+
+ // update world inertia tensor
+ btMatrix3x3 rotation;
+ rotation.setIdentity();
+ updateInitialInertiaTensor(rotation);
+ updateInertiaTensor();
+ m_interpolateInvInertiaTensorWorld = m_invInertiaTensorWorld;
+}
+
+void btReducedDeformableBody::setRigidVelocity(const btVector3& v)
+{
+ m_linearVelocity = v;
+}
+
+void btReducedDeformableBody::setRigidAngularVelocity(const btVector3& omega)
+{
+ m_angularVelocity = omega;
+}
+
+void btReducedDeformableBody::setStiffnessScale(const btScalar ks)
+{
+ m_ksScale = ks;
+}
+
+void btReducedDeformableBody::setMassScale(const btScalar rho)
+{
+ m_rhoScale = rho;
+}
+
+void btReducedDeformableBody::setFixedNodes(const int n_node)
+{
+ m_fixedNodes.push_back(n_node);
+ m_nodes[n_node].m_im = 0; // set inverse mass to be zero for the constraint solver.
+}
+
+void btReducedDeformableBody::setDamping(const btScalar alpha, const btScalar beta)
+{
+ m_dampingAlpha = alpha;
+ m_dampingBeta = beta;
+}
+
+void btReducedDeformableBody::internalInitialization()
+{
+ // zeroing
+ endOfTimeStepZeroing();
+ // initialize rest position
+ updateRestNodalPositions();
+ // initialize local nodal moment arm form the CoM
+ updateLocalMomentArm();
+ // initialize projection matrix
+ updateExternalForceProjectMatrix(false);
+}
+
+void btReducedDeformableBody::updateLocalMomentArm()
+{
+ TVStack delta_x;
+ delta_x.resize(m_nFull);
+
+ for (int i = 0; i < m_nFull; ++i)
+ {
+ for (int k = 0; k < 3; ++k)
+ {
+ // compute displacement
+ delta_x[i][k] = 0;
+ for (int j = 0; j < m_nReduced; ++j)
+ {
+ delta_x[i][k] += m_modes[j][3 * i + k] * m_reducedDofs[j];
+ }
+ }
+ // get new moment arm Sq + x0
+ m_localMomentArm[i] = m_x0[i] - m_initialCoM + delta_x[i];
+ }
+}
+
+void btReducedDeformableBody::updateExternalForceProjectMatrix(bool initialized)
+{
+ // if not initialized, need to compute both P_A and Cq
+ // otherwise, only need to udpate Cq
+ if (!initialized)
+ {
+ // resize
+ m_projPA.resize(m_nReduced);
+ m_projCq.resize(m_nReduced);
+
+ m_STP.resize(m_nReduced);
+ m_MrInvSTP.resize(m_nReduced);
+
+ // P_A
+ for (int r = 0; r < m_nReduced; ++r)
+ {
+ m_projPA[r].resize(3 * m_nFull, 0);
+ for (int i = 0; i < m_nFull; ++i)
+ {
+ btMatrix3x3 mass_scaled_i = Diagonal(1) - Diagonal(m_nodalMass[i] / m_mass);
+ btVector3 s_ri(m_modes[r][3 * i], m_modes[r][3 * i + 1], m_modes[r][3 * i + 2]);
+ btVector3 prod_i = mass_scaled_i * s_ri;
+
+ for (int k = 0; k < 3; ++k)
+ m_projPA[r][3 * i + k] = prod_i[k];
+
+ // btScalar ratio = m_nodalMass[i] / m_mass;
+ // m_projPA[r] += btVector3(- m_modes[r][3 * i] * ratio,
+ // - m_modes[r][3 * i + 1] * ratio,
+ // - m_modes[r][3 * i + 2] * ratio);
+ }
+ }
+ }
+
+ // C(q) is updated once per position update
+ for (int r = 0; r < m_nReduced; ++r)
+ {
+ m_projCq[r].resize(3 * m_nFull, 0);
+ for (int i = 0; i < m_nFull; ++i)
+ {
+ btMatrix3x3 r_star = Cross(m_localMomentArm[i]);
+ btVector3 s_ri(m_modes[r][3 * i], m_modes[r][3 * i + 1], m_modes[r][3 * i + 2]);
+ btVector3 prod_i = r_star * m_invInertiaTensorWorld * r_star * s_ri;
+
+ for (int k = 0; k < 3; ++k)
+ m_projCq[r][3 * i + k] = m_nodalMass[i] * prod_i[k];
+
+ // btVector3 si(m_modes[r][3 * i], m_modes[r][3 * i + 1], m_modes[r][3 * i + 2]);
+ // m_projCq[r] += m_nodalMass[i] * si.cross(m_localMomentArm[i]);
+ }
+ }
+}
+
+void btReducedDeformableBody::endOfTimeStepZeroing()
+{
+ for (int i = 0; i < m_nReduced; ++i)
+ {
+ m_reducedForceElastic[i] = 0;
+ m_reducedForceDamping[i] = 0;
+ m_reducedForceExternal[i] = 0;
+ m_internalDeltaReducedVelocity[i] = 0;
+ m_reducedDofsBuffer[i] = m_reducedDofs[i];
+ m_reducedVelocityBuffer[i] = m_reducedVelocity[i];
+ }
+ // std::cout << "zeroed!\n";
+}
+
+void btReducedDeformableBody::applyInternalVelocityChanges()
+{
+ m_linearVelocity += m_internalDeltaLinearVelocity;
+ m_angularVelocity += m_internalDeltaAngularVelocity;
+ m_internalDeltaLinearVelocity.setZero();
+ m_internalDeltaAngularVelocity.setZero();
+ for (int r = 0; r < m_nReduced; ++r)
+ {
+ m_reducedVelocity[r] += m_internalDeltaReducedVelocity[r];
+ m_internalDeltaReducedVelocity[r] = 0;
+ }
+}
+
+void btReducedDeformableBody::predictIntegratedTransform(btScalar dt, btTransform& predictedTransform)
+{
+ btTransformUtil::integrateTransform(m_rigidTransformWorld, m_linearVelocity, m_angularVelocity, dt, predictedTransform);
+}
+
+void btReducedDeformableBody::updateReducedDofs(btScalar solverdt)
+{
+ for (int r = 0; r < m_nReduced; ++r)
+ {
+ m_reducedDofs[r] = m_reducedDofsBuffer[r] + solverdt * m_reducedVelocity[r];
+ }
+}
+
+void btReducedDeformableBody::mapToFullPosition(const btTransform& ref_trans)
+{
+ btVector3 origin = ref_trans.getOrigin();
+ btMatrix3x3 rotation = ref_trans.getBasis();
+
+
+ for (int i = 0; i < m_nFull; ++i)
+ {
+ m_nodes[i].m_x = rotation * m_localMomentArm[i] + origin;
+ m_nodes[i].m_q = m_nodes[i].m_x;
+ }
+}
+
+void btReducedDeformableBody::updateReducedVelocity(btScalar solverdt)
+{
+ // update reduced velocity
+ for (int r = 0; r < m_nReduced; ++r)
+ {
+ // the reduced mass is always identity!
+ btScalar delta_v = 0;
+ delta_v = solverdt * (m_reducedForceElastic[r] + m_reducedForceDamping[r]);
+ // delta_v = solverdt * (m_reducedForceElastic[r] + m_reducedForceDamping[r] + m_reducedForceExternal[r]);
+ m_reducedVelocity[r] = m_reducedVelocityBuffer[r] + delta_v;
+ }
+}
+
+void btReducedDeformableBody::mapToFullVelocity(const btTransform& ref_trans)
+{
+ // compute the reduced contribution to the angular velocity
+ // btVector3 sum_linear(0, 0, 0);
+ // btVector3 sum_angular(0, 0, 0);
+ // m_linearVelocityFromReduced.setZero();
+ // m_angularVelocityFromReduced.setZero();
+ // for (int i = 0; i < m_nFull; ++i)
+ // {
+ // btVector3 r_com = ref_trans.getBasis() * m_localMomentArm[i];
+ // btMatrix3x3 r_star = Cross(r_com);
+
+ // btVector3 v_from_reduced(0, 0, 0);
+ // for (int k = 0; k < 3; ++k)
+ // {
+ // for (int r = 0; r < m_nReduced; ++r)
+ // {
+ // v_from_reduced[k] += m_modes[r][3 * i + k] * m_reducedVelocity[r];
+ // }
+ // }
+
+ // btVector3 delta_linear = m_nodalMass[i] * v_from_reduced;
+ // btVector3 delta_angular = m_nodalMass[i] * (r_star * ref_trans.getBasis() * v_from_reduced);
+ // sum_linear += delta_linear;
+ // sum_angular += delta_angular;
+ // // std::cout << "delta_linear: " << delta_linear[0] << "\t" << delta_linear[1] << "\t" << delta_linear[2] << "\n";
+ // // std::cout << "delta_angular: " << delta_angular[0] << "\t" << delta_angular[1] << "\t" << delta_angular[2] << "\n";
+ // // std::cout << "sum_linear: " << sum_linear[0] << "\t" << sum_linear[1] << "\t" << sum_linear[2] << "\n";
+ // // std::cout << "sum_angular: " << sum_angular[0] << "\t" << sum_angular[1] << "\t" << sum_angular[2] << "\n";
+ // }
+ // m_linearVelocityFromReduced = 1.0 / m_mass * (ref_trans.getBasis() * sum_linear);
+ // m_angularVelocityFromReduced = m_interpolateInvInertiaTensorWorld * sum_angular;
+
+ // m_linearVelocity -= m_linearVelocityFromReduced;
+ // m_angularVelocity -= m_angularVelocityFromReduced;
+
+ for (int i = 0; i < m_nFull; ++i)
+ {
+ m_nodes[i].m_v = computeNodeFullVelocity(ref_trans, i);
+ }
+}
+
+const btVector3 btReducedDeformableBody::computeTotalAngularMomentum() const
+{
+ btVector3 L_rigid = m_invInertiaTensorWorld.inverse() * m_angularVelocity;
+ btVector3 L_reduced(0, 0, 0);
+ btMatrix3x3 omega_prime_star = Cross(m_angularVelocityFromReduced);
+
+ for (int i = 0; i < m_nFull; ++i)
+ {
+ btVector3 r_com = m_rigidTransformWorld.getBasis() * m_localMomentArm[i];
+ btMatrix3x3 r_star = Cross(r_com);
+
+ btVector3 v_from_reduced(0, 0, 0);
+ for (int k = 0; k < 3; ++k)
+ {
+ for (int r = 0; r < m_nReduced; ++r)
+ {
+ v_from_reduced[k] += m_modes[r][3 * i + k] * m_reducedVelocity[r];
+ }
+ }
+
+ L_reduced += m_nodalMass[i] * (r_star * (m_rigidTransformWorld.getBasis() * v_from_reduced - omega_prime_star * r_com));
+ // L_reduced += m_nodalMass[i] * (r_star * (m_rigidTransformWorld.getBasis() * v_from_reduced));
+ }
+ return L_rigid + L_reduced;
+}
+
+const btVector3 btReducedDeformableBody::computeNodeFullVelocity(const btTransform& ref_trans, int n_node) const
+{
+ btVector3 v_from_reduced(0, 0, 0);
+ btVector3 r_com = ref_trans.getBasis() * m_localMomentArm[n_node];
+ // compute velocity contributed by the reduced velocity
+ for (int k = 0; k < 3; ++k)
+ {
+ for (int r = 0; r < m_nReduced; ++r)
+ {
+ v_from_reduced[k] += m_modes[r][3 * n_node + k] * m_reducedVelocity[r];
+ }
+ }
+ // get new velocity
+ btVector3 vel = m_angularVelocity.cross(r_com) +
+ ref_trans.getBasis() * v_from_reduced +
+ m_linearVelocity;
+ return vel;
+}
+
+const btVector3 btReducedDeformableBody::internalComputeNodeDeltaVelocity(const btTransform& ref_trans, int n_node) const
+{
+ btVector3 deltaV_from_reduced(0, 0, 0);
+ btVector3 r_com = ref_trans.getBasis() * m_localMomentArm[n_node];
+
+ // compute velocity contributed by the reduced velocity
+ for (int k = 0; k < 3; ++k)
+ {
+ for (int r = 0; r < m_nReduced; ++r)
+ {
+ deltaV_from_reduced[k] += m_modes[r][3 * n_node + k] * m_internalDeltaReducedVelocity[r];
+ }
+ }
+
+ // get delta velocity
+ btVector3 deltaV = m_internalDeltaAngularVelocity.cross(r_com) +
+ ref_trans.getBasis() * deltaV_from_reduced +
+ m_internalDeltaLinearVelocity;
+ return deltaV;
+}
+
+void btReducedDeformableBody::proceedToTransform(btScalar dt, bool end_of_time_step)
+{
+ btTransformUtil::integrateTransform(m_rigidTransformWorld, m_linearVelocity, m_angularVelocity, dt, m_interpolationWorldTransform);
+ updateInertiaTensor();
+ // m_interpolateInvInertiaTensorWorld = m_interpolationWorldTransform.getBasis().scaled(m_invInertiaLocal) * m_interpolationWorldTransform.getBasis().transpose();
+ m_rigidTransformWorld = m_interpolationWorldTransform;
+ m_invInertiaTensorWorld = m_interpolateInvInertiaTensorWorld;
+}
+
+void btReducedDeformableBody::transformTo(const btTransform& trs)
+{
+ btTransform current_transform = getRigidTransform();
+ btTransform new_transform(trs.getBasis() * current_transform.getBasis().transpose(),
+ trs.getOrigin() - current_transform.getOrigin());
+ transform(new_transform);
+}
+
+void btReducedDeformableBody::transform(const btTransform& trs)
+{
+ m_transform_lock = true;
+
+ // transform mesh
+ {
+ const btScalar margin = getCollisionShape()->getMargin();
+ ATTRIBUTE_ALIGNED16(btDbvtVolume)
+ vol;
+
+ btVector3 CoM = m_rigidTransformWorld.getOrigin();
+ btVector3 translation = trs.getOrigin();
+ btMatrix3x3 rotation = trs.getBasis();
+
+ for (int i = 0; i < m_nodes.size(); ++i)
+ {
+ Node& n = m_nodes[i];
+ n.m_x = rotation * (n.m_x - CoM) + CoM + translation;
+ n.m_q = rotation * (n.m_q - CoM) + CoM + translation;
+ n.m_n = rotation * n.m_n;
+ vol = btDbvtVolume::FromCR(n.m_x, margin);
+
+ m_ndbvt.update(n.m_leaf, vol);
+ }
+ updateNormals();
+ updateBounds();
+ updateConstants();
+ }
+
+ // update modes
+ updateModesByRotation(trs.getBasis());
+
+ // update inertia tensor
+ updateInitialInertiaTensor(trs.getBasis());
+ updateInertiaTensor();
+ m_interpolateInvInertiaTensorWorld = m_invInertiaTensorWorld;
+
+ // update rigid frame (No need to update the rotation. Nodes have already been updated.)
+ m_rigidTransformWorld.setOrigin(m_initialCoM + trs.getOrigin());
+ m_interpolationWorldTransform = m_rigidTransformWorld;
+ m_initialCoM = m_rigidTransformWorld.getOrigin();
+
+ internalInitialization();
+}
+
+void btReducedDeformableBody::scale(const btVector3& scl)
+{
+ // Scaling the mesh after transform is applied is not allowed
+ btAssert(!m_transform_lock);
+
+ // scale the mesh
+ {
+ const btScalar margin = getCollisionShape()->getMargin();
+ ATTRIBUTE_ALIGNED16(btDbvtVolume)
+ vol;
+
+ btVector3 CoM = m_rigidTransformWorld.getOrigin();
+
+ for (int i = 0; i < m_nodes.size(); ++i)
+ {
+ Node& n = m_nodes[i];
+ n.m_x = (n.m_x - CoM) * scl + CoM;
+ n.m_q = (n.m_q - CoM) * scl + CoM;
+ vol = btDbvtVolume::FromCR(n.m_x, margin);
+ m_ndbvt.update(n.m_leaf, vol);
+ }
+ updateNormals();
+ updateBounds();
+ updateConstants();
+ initializeDmInverse();
+ }
+
+ // update inertia tensor
+ updateLocalInertiaTensorFromNodes();
+
+ btMatrix3x3 id;
+ id.setIdentity();
+ updateInitialInertiaTensor(id); // there is no rotation, but the local inertia tensor has changed
+ updateInertiaTensor();
+ m_interpolateInvInertiaTensorWorld = m_invInertiaTensorWorld;
+
+ internalInitialization();
+}
+
+void btReducedDeformableBody::setTotalMass(btScalar mass, bool fromfaces)
+{
+ // Changing the total mass after transform is applied is not allowed
+ btAssert(!m_transform_lock);
+
+ btScalar scale_ratio = mass / m_mass;
+
+ // update nodal mass
+ for (int i = 0; i < m_nFull; ++i)
+ {
+ m_nodalMass[i] *= scale_ratio;
+ }
+ m_mass = mass;
+ m_inverseMass = mass > 0 ? 1.0 / mass : 0;
+
+ // update inertia tensors
+ updateLocalInertiaTensorFromNodes();
+
+ btMatrix3x3 id;
+ id.setIdentity();
+ updateInitialInertiaTensor(id); // there is no rotation, but the local inertia tensor has changed
+ updateInertiaTensor();
+ m_interpolateInvInertiaTensorWorld = m_invInertiaTensorWorld;
+
+ internalInitialization();
+}
+
+void btReducedDeformableBody::updateRestNodalPositions()
+{
+ // update reset nodal position
+ m_x0.resize(m_nFull);
+ for (int i = 0; i < m_nFull; ++i)
+ {
+ m_x0[i] = m_nodes[i].m_x;
+ }
+}
+
+// reference notes:
+// https://ocw.mit.edu/courses/aeronautics-and-astronautics/16-07-dynamics-fall-2009/lecture-notes/MIT16_07F09_Lec26.pdf
+void btReducedDeformableBody::updateLocalInertiaTensorFromNodes()
+{
+ btMatrix3x3 inertia_tensor;
+ inertia_tensor.setZero();
+
+ for (int p = 0; p < m_nFull; ++p)
+ {
+ btMatrix3x3 particle_inertia;
+ particle_inertia.setZero();
+
+ btVector3 r = m_nodes[p].m_x - m_initialCoM;
+
+ particle_inertia[0][0] = m_nodalMass[p] * (r[1] * r[1] + r[2] * r[2]);
+ particle_inertia[1][1] = m_nodalMass[p] * (r[0] * r[0] + r[2] * r[2]);
+ particle_inertia[2][2] = m_nodalMass[p] * (r[0] * r[0] + r[1] * r[1]);
+
+ particle_inertia[0][1] = - m_nodalMass[p] * (r[0] * r[1]);
+ particle_inertia[0][2] = - m_nodalMass[p] * (r[0] * r[2]);
+ particle_inertia[1][2] = - m_nodalMass[p] * (r[1] * r[2]);
+
+ particle_inertia[1][0] = particle_inertia[0][1];
+ particle_inertia[2][0] = particle_inertia[0][2];
+ particle_inertia[2][1] = particle_inertia[1][2];
+
+ inertia_tensor += particle_inertia;
+ }
+ m_invInertiaLocal = inertia_tensor.inverse();
+}
+
+void btReducedDeformableBody::updateInitialInertiaTensor(const btMatrix3x3& rotation)
+{
+ // m_invInertiaTensorWorldInitial = rotation.scaled(m_invInertiaLocal) * rotation.transpose();
+ m_invInertiaTensorWorldInitial = rotation * m_invInertiaLocal * rotation.transpose();
+}
+
+void btReducedDeformableBody::updateModesByRotation(const btMatrix3x3& rotation)
+{
+ for (int r = 0; r < m_nReduced; ++r)
+ {
+ for (int i = 0; i < m_nFull; ++i)
+ {
+ btVector3 nodal_disp(m_modes[r][3 * i], m_modes[r][3 * i + 1], m_modes[r][3 * i + 2]);
+ nodal_disp = rotation * nodal_disp;
+
+ for (int k = 0; k < 3; ++k)
+ {
+ m_modes[r][3 * i + k] = nodal_disp[k];
+ }
+ }
+ }
+}
+
+void btReducedDeformableBody::updateInertiaTensor()
+{
+ m_invInertiaTensorWorld = m_rigidTransformWorld.getBasis() * m_invInertiaTensorWorldInitial * m_rigidTransformWorld.getBasis().transpose();
+}
+
+void btReducedDeformableBody::applyDamping(btScalar timeStep)
+{
+ m_linearVelocity *= btScalar(1) - m_linearDamping;
+ m_angularDamping *= btScalar(1) - m_angularDamping;
+}
+
+void btReducedDeformableBody::applyCentralImpulse(const btVector3& impulse)
+{
+ m_linearVelocity += impulse * m_linearFactor * m_inverseMass;
+ #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
+ clampVelocity(m_linearVelocity);
+ #endif
+}
+
+void btReducedDeformableBody::applyTorqueImpulse(const btVector3& torque)
+{
+ m_angularVelocity += m_interpolateInvInertiaTensorWorld * torque * m_angularFactor;
+ #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
+ clampVelocity(m_angularVelocity);
+ #endif
+}
+
+void btReducedDeformableBody::internalApplyRigidImpulse(const btVector3& impulse, const btVector3& rel_pos)
+{
+ if (m_inverseMass == btScalar(0.))
+ {
+ std::cout << "something went wrong...probably didn't initialize?\n";
+ btAssert(false);
+ }
+ // delta linear velocity
+ m_internalDeltaLinearVelocity += impulse * m_linearFactor * m_inverseMass;
+ // delta angular velocity
+ btVector3 torque = rel_pos.cross(impulse * m_linearFactor);
+ m_internalDeltaAngularVelocity += m_interpolateInvInertiaTensorWorld * torque * m_angularFactor;
+}
+
+btVector3 btReducedDeformableBody::getRelativePos(int n_node)
+{
+ btMatrix3x3 rotation = m_interpolationWorldTransform.getBasis();
+ btVector3 ri = rotation * m_localMomentArm[n_node];
+ return ri;
+}
+
+btMatrix3x3 btReducedDeformableBody::getImpulseFactor(int n_node)
+{
+ // relative position
+ btMatrix3x3 rotation = m_interpolationWorldTransform.getBasis();
+ btVector3 ri = rotation * m_localMomentArm[n_node];
+ btMatrix3x3 ri_skew = Cross(ri);
+
+ // calculate impulse factor
+ // rigid part
+ btScalar inv_mass = m_nodalMass[n_node] > btScalar(0) ? btScalar(1) / m_mass : btScalar(0);
+ btMatrix3x3 K1 = Diagonal(inv_mass);
+ K1 -= ri_skew * m_interpolateInvInertiaTensorWorld * ri_skew;
+
+ // reduced deformable part
+ btMatrix3x3 SA;
+ SA.setZero();
+ for (int i = 0; i < 3; ++i)
+ {
+ for (int j = 0; j < 3; ++j)
+ {
+ for (int r = 0; r < m_nReduced; ++r)
+ {
+ SA[i][j] += m_modes[r][3 * n_node + i] * (m_projPA[r][3 * n_node + j] + m_projCq[r][3 * n_node + j]);
+ }
+ }
+ }
+ btMatrix3x3 RSARinv = rotation * SA * rotation.transpose();
+
+
+ TVStack omega_helper; // Sum_i m_i r*_i R S_i
+ omega_helper.resize(m_nReduced);
+ for (int r = 0; r < m_nReduced; ++r)
+ {
+ omega_helper[r].setZero();
+ for (int i = 0; i < m_nFull; ++i)
+ {
+ btMatrix3x3 mi_rstar_i = rotation * Cross(m_localMomentArm[i]) * m_nodalMass[i];
+ btVector3 s_ri(m_modes[r][3 * i], m_modes[r][3 * i + 1], m_modes[r][3 * i + 2]);
+ omega_helper[r] += mi_rstar_i * rotation * s_ri;
+ }
+ }
+
+ btMatrix3x3 sum_multiply_A;
+ sum_multiply_A.setZero();
+ for (int i = 0; i < 3; ++i)
+ {
+ for (int j = 0; j < 3; ++j)
+ {
+ for (int r = 0; r < m_nReduced; ++r)
+ {
+ sum_multiply_A[i][j] += omega_helper[r][i] * (m_projPA[r][3 * n_node + j] + m_projCq[r][3 * n_node + j]);
+ }
+ }
+ }
+
+ btMatrix3x3 K2 = RSARinv + ri_skew * m_interpolateInvInertiaTensorWorld * sum_multiply_A * rotation.transpose();
+
+ return m_rigidOnly ? K1 : K1 + K2;
+}
+
+void btReducedDeformableBody::internalApplyFullSpaceImpulse(const btVector3& impulse, const btVector3& rel_pos, int n_node, btScalar dt)
+{
+ if (!m_rigidOnly)
+ {
+ // apply impulse force
+ applyFullSpaceNodalForce(impulse / dt, n_node);
+
+ // update delta damping force
+ tDenseArray reduced_vel_tmp;
+ reduced_vel_tmp.resize(m_nReduced);
+ for (int r = 0; r < m_nReduced; ++r)
+ {
+ reduced_vel_tmp[r] = m_reducedVelocity[r] + m_internalDeltaReducedVelocity[r];
+ }
+ applyReducedDampingForce(reduced_vel_tmp);
+ // applyReducedDampingForce(m_internalDeltaReducedVelocity);
+
+ // delta reduced velocity
+ for (int r = 0; r < m_nReduced; ++r)
+ {
+ // The reduced mass is always identity!
+ m_internalDeltaReducedVelocity[r] += dt * (m_reducedForceDamping[r] + m_reducedForceExternal[r]);
+ }
+ }
+
+ internalApplyRigidImpulse(impulse, rel_pos);
+}
+
+void btReducedDeformableBody::applyFullSpaceNodalForce(const btVector3& f_ext, int n_node)
+{
+ // f_local = R^-1 * f_ext //TODO: interpoalted transfrom
+ // btVector3 f_local = m_rigidTransformWorld.getBasis().transpose() * f_ext;
+ btVector3 f_local = m_interpolationWorldTransform.getBasis().transpose() * f_ext;
+
+ // f_ext_r = [S^T * P]_{n_node} * f_local
+ tDenseArray f_ext_r;
+ f_ext_r.resize(m_nReduced, 0);
+ for (int r = 0; r < m_nReduced; ++r)
+ {
+ m_reducedForceExternal[r] = 0;
+ for (int k = 0; k < 3; ++k)
+ {
+ f_ext_r[r] += (m_projPA[r][3 * n_node + k] + m_projCq[r][3 * n_node + k]) * f_local[k];
+ }
+
+ m_reducedForceExternal[r] += f_ext_r[r];
+ }
+}
+
+void btReducedDeformableBody::applyRigidGravity(const btVector3& gravity, btScalar dt)
+{
+ // update rigid frame velocity
+ m_linearVelocity += dt * gravity;
+}
+
+void btReducedDeformableBody::applyReducedElasticForce(const tDenseArray& reduce_dofs)
+{
+ for (int r = 0; r < m_nReduced; ++r)
+ {
+ m_reducedForceElastic[r] = - m_ksScale * m_Kr[r] * reduce_dofs[r];
+ }
+}
+
+void btReducedDeformableBody::applyReducedDampingForce(const tDenseArray& reduce_vel)
+{
+ for (int r = 0; r < m_nReduced; ++r)
+ {
+ m_reducedForceDamping[r] = - m_dampingBeta * m_ksScale * m_Kr[r] * reduce_vel[r];
+ }
+}
+
+btScalar btReducedDeformableBody::getTotalMass() const
+{
+ return m_mass;
+}
+
+btTransform& btReducedDeformableBody::getRigidTransform()
+{
+ return m_rigidTransformWorld;
+}
+
+const btVector3& btReducedDeformableBody::getLinearVelocity() const
+{
+ return m_linearVelocity;
+}
+
+const btVector3& btReducedDeformableBody::getAngularVelocity() const
+{
+ return m_angularVelocity;
+}
+
+void btReducedDeformableBody::disableReducedModes(const bool rigid_only)
+{
+ m_rigidOnly = rigid_only;
+}
+
+bool btReducedDeformableBody::isReducedModesOFF() const
+{
+ return m_rigidOnly;
+} \ No newline at end of file
diff --git a/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h
new file mode 100644
index 000000000..8968fb0cb
--- /dev/null
+++ b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBody.h
@@ -0,0 +1,257 @@
+#ifndef BT_REDUCED_SOFT_BODY_H
+#define BT_REDUCED_SOFT_BODY_H
+
+#include "../btSoftBody.h"
+#include "LinearMath/btAlignedObjectArray.h"
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btMatrix3x3.h"
+#include "LinearMath/btTransform.h"
+
+// Reduced deformable body is a simplified deformable object embedded in a rigid frame.
+class btReducedDeformableBody : public btSoftBody
+{
+ public:
+ //
+ // Typedefs
+ //
+ typedef btAlignedObjectArray<btVector3> TVStack;
+ // typedef btAlignedObjectArray<btMatrix3x3> tBlockDiagMatrix;
+ typedef btAlignedObjectArray<btScalar> tDenseArray;
+ typedef btAlignedObjectArray<btAlignedObjectArray<btScalar> > tDenseMatrix;
+
+ private:
+ // flag to turn off the reduced modes
+ bool m_rigidOnly;
+
+ // Flags for transform. Once transform is applied, users cannot scale the mesh or change its total mass.
+ bool m_transform_lock;
+
+ // scaling factors
+ btScalar m_rhoScale; // mass density scale
+ btScalar m_ksScale; // stiffness scale
+
+ // projection matrix
+ tDenseMatrix m_projPA; // Eqn. 4.11 from Rahul Sheth's thesis
+ tDenseMatrix m_projCq;
+ tDenseArray m_STP;
+ tDenseArray m_MrInvSTP;
+
+ TVStack m_localMomentArm; // Sq + x0
+
+ btVector3 m_internalDeltaLinearVelocity;
+ btVector3 m_internalDeltaAngularVelocity;
+ tDenseArray m_internalDeltaReducedVelocity;
+
+ btVector3 m_linearVelocityFromReduced; // contribution to the linear velocity from reduced velocity
+ btVector3 m_angularVelocityFromReduced; // contribution to the angular velocity from reduced velocity
+ btVector3 m_internalDeltaAngularVelocityFromReduced;
+
+ protected:
+ // rigid frame
+ btScalar m_mass; // total mass of the rigid frame
+ btScalar m_inverseMass; // inverse of the total mass of the rigid frame
+ btVector3 m_linearVelocity;
+ btVector3 m_angularVelocity;
+ btScalar m_linearDamping; // linear damping coefficient
+ btScalar m_angularDamping; // angular damping coefficient
+ btVector3 m_linearFactor;
+ btVector3 m_angularFactor;
+ // btVector3 m_invInertiaLocal;
+ btMatrix3x3 m_invInertiaLocal;
+ btTransform m_rigidTransformWorld;
+ btMatrix3x3 m_invInertiaTensorWorldInitial;
+ btMatrix3x3 m_invInertiaTensorWorld;
+ btMatrix3x3 m_interpolateInvInertiaTensorWorld;
+ btVector3 m_initialCoM; // initial center of mass (original of the m_rigidTransformWorld)
+
+ // damping
+ btScalar m_dampingAlpha;
+ btScalar m_dampingBeta;
+
+ public:
+ //
+ // Fields
+ //
+
+ // reduced space
+ int m_nReduced;
+ int m_nFull;
+ tDenseMatrix m_modes; // modes of the reduced deformable model. Each inner array is a mode, outer array size = n_modes
+ tDenseArray m_reducedDofs; // Reduced degree of freedom
+ tDenseArray m_reducedDofsBuffer; // Reduced degree of freedom at t^n
+ tDenseArray m_reducedVelocity; // Reduced velocity array
+ tDenseArray m_reducedVelocityBuffer; // Reduced velocity array at t^n
+ tDenseArray m_reducedForceExternal; // reduced external force
+ tDenseArray m_reducedForceElastic; // reduced internal elastic force
+ tDenseArray m_reducedForceDamping; // reduced internal damping force
+ tDenseArray m_eigenvalues; // eigenvalues of the reduce deformable model
+ tDenseArray m_Kr; // reduced stiffness matrix
+
+ // full space
+ TVStack m_x0; // Rest position
+ tDenseArray m_nodalMass; // Mass on each node
+ btAlignedObjectArray<int> m_fixedNodes; // index of the fixed nodes
+ int m_nodeIndexOffset; // offset of the node index needed for contact solver when there are multiple reduced deformable body in the world.
+
+ // contacts
+ btAlignedObjectArray<int> m_contactNodesList;
+
+ //
+ // Api
+ //
+ btReducedDeformableBody(btSoftBodyWorldInfo* worldInfo, int node_count, const btVector3* x, const btScalar* m);
+
+ ~btReducedDeformableBody() {}
+
+ //
+ // initializing helpers
+ //
+ void internalInitialization();
+
+ void setReducedModes(int num_modes, int full_size);
+
+ void setMassProps(const tDenseArray& mass_array);
+
+ void setInertiaProps();
+
+ void setRigidVelocity(const btVector3& v);
+
+ void setRigidAngularVelocity(const btVector3& omega);
+
+ void setStiffnessScale(const btScalar ks);
+
+ void setMassScale(const btScalar rho);
+
+ void setFixedNodes(const int n_node);
+
+ void setDamping(const btScalar alpha, const btScalar beta);
+
+ void disableReducedModes(const bool rigid_only);
+
+ virtual void setTotalMass(btScalar mass, bool fromfaces = false);
+
+ //
+ // various internal updates
+ //
+ virtual void transformTo(const btTransform& trs);
+ virtual void transform(const btTransform& trs);
+ // caution:
+ // need to use scale before using transform, because the scale is performed in the local frame
+ // (i.e., may have some rotation already, but the m_rigidTransformWorld doesn't have this info)
+ virtual void scale(const btVector3& scl);
+
+ private:
+ void updateRestNodalPositions();
+
+ void updateInitialInertiaTensor(const btMatrix3x3& rotation);
+
+ void updateLocalInertiaTensorFromNodes();
+
+ void updateInertiaTensor();
+
+ void updateModesByRotation(const btMatrix3x3& rotation);
+
+ public:
+ void updateLocalMomentArm();
+
+ void predictIntegratedTransform(btScalar dt, btTransform& predictedTransform);
+
+ // update the external force projection matrix
+ void updateExternalForceProjectMatrix(bool initialized);
+
+ void endOfTimeStepZeroing();
+
+ void applyInternalVelocityChanges();
+
+ //
+ // position and velocity update related
+ //
+
+ // compute reduced degree of freedoms
+ void updateReducedDofs(btScalar solverdt);
+
+ // compute reduced velocity update (for explicit time stepping)
+ void updateReducedVelocity(btScalar solverdt);
+
+ // map to full degree of freedoms
+ void mapToFullPosition(const btTransform& ref_trans);
+
+ // compute full space velocity from the reduced velocity
+ void mapToFullVelocity(const btTransform& ref_trans);
+
+ // compute total angular momentum
+ const btVector3 computeTotalAngularMomentum() const;
+
+ // get a single node's full space velocity from the reduced velocity
+ const btVector3 computeNodeFullVelocity(const btTransform& ref_trans, int n_node) const;
+
+ // get a single node's all delta velocity
+ const btVector3 internalComputeNodeDeltaVelocity(const btTransform& ref_trans, int n_node) const;
+
+ //
+ // rigid motion related
+ //
+ void applyDamping(btScalar timeStep);
+
+ void applyCentralImpulse(const btVector3& impulse);
+
+ void applyTorqueImpulse(const btVector3& torque);
+
+ void proceedToTransform(btScalar dt, bool end_of_time_step);
+
+ //
+ // force related
+ //
+
+ // apply impulse to the rigid frame
+ void internalApplyRigidImpulse(const btVector3& impulse, const btVector3& rel_pos);
+
+ // apply impulse to nodes in the full space
+ void internalApplyFullSpaceImpulse(const btVector3& impulse, const btVector3& rel_pos, int n_node, btScalar dt);
+
+ // apply nodal external force in the full space
+ void applyFullSpaceNodalForce(const btVector3& f_ext, int n_node);
+
+ // apply gravity to the rigid frame
+ void applyRigidGravity(const btVector3& gravity, btScalar dt);
+
+ // apply reduced elastic force
+ void applyReducedElasticForce(const tDenseArray& reduce_dofs);
+
+ // apply reduced damping force
+ void applyReducedDampingForce(const tDenseArray& reduce_vel);
+
+ // calculate the impulse factor
+ virtual btMatrix3x3 getImpulseFactor(int n_node);
+
+ // get relative position from a node to the CoM of the rigid frame
+ btVector3 getRelativePos(int n_node);
+
+ //
+ // accessors
+ //
+ bool isReducedModesOFF() const;
+ btScalar getTotalMass() const;
+ btTransform& getRigidTransform();
+ const btVector3& getLinearVelocity() const;
+ const btVector3& getAngularVelocity() const;
+
+ #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
+ void clampVelocity(btVector3& v) const {
+ v.setX(
+ fmax(-BT_CLAMP_VELOCITY_TO,
+ fmin(BT_CLAMP_VELOCITY_TO, v.getX()))
+ );
+ v.setY(
+ fmax(-BT_CLAMP_VELOCITY_TO,
+ fmin(BT_CLAMP_VELOCITY_TO, v.getY()))
+ );
+ v.setZ(
+ fmax(-BT_CLAMP_VELOCITY_TO,
+ fmin(BT_CLAMP_VELOCITY_TO, v.getZ()))
+ );
+ }
+ #endif
+};
+
+#endif // BT_REDUCED_SOFT_BODY_H \ No newline at end of file
diff --git a/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.cpp b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.cpp
new file mode 100644
index 000000000..d7e4cc2b8
--- /dev/null
+++ b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.cpp
@@ -0,0 +1,215 @@
+#include "btReducedDeformableBodyHelpers.h"
+#include "../btSoftBodyHelpers.h"
+#include <iostream>
+#include <string>
+#include <sstream>
+
+btReducedDeformableBody* btReducedDeformableBodyHelpers::createReducedDeformableObject(btSoftBodyWorldInfo& worldInfo, const std::string& file_path, const std::string& vtk_file, const int num_modes, bool rigid_only) {
+ std::string filename = file_path + vtk_file;
+ btReducedDeformableBody* rsb = btReducedDeformableBodyHelpers::createFromVtkFile(worldInfo, filename.c_str());
+
+ rsb->setReducedModes(num_modes, rsb->m_nodes.size());
+ btReducedDeformableBodyHelpers::readReducedDeformableInfoFromFiles(rsb, file_path.c_str());
+
+ rsb->disableReducedModes(rigid_only);
+
+ return rsb;
+}
+
+btReducedDeformableBody* btReducedDeformableBodyHelpers::createFromVtkFile(btSoftBodyWorldInfo& worldInfo, const char* vtk_file)
+{
+ std::ifstream fs;
+ fs.open(vtk_file);
+ btAssert(fs);
+
+ typedef btAlignedObjectArray<int> Index;
+ std::string line;
+ btAlignedObjectArray<btVector3> X;
+ btVector3 position;
+ btAlignedObjectArray<Index> indices;
+ bool reading_points = false;
+ bool reading_tets = false;
+ size_t n_points = 0;
+ size_t n_tets = 0;
+ size_t x_count = 0;
+ size_t indices_count = 0;
+ while (std::getline(fs, line))
+ {
+ std::stringstream ss(line);
+ if (line.size() == (size_t)(0))
+ {
+ }
+ else if (line.substr(0, 6) == "POINTS")
+ {
+ reading_points = true;
+ reading_tets = false;
+ ss.ignore(128, ' '); // ignore "POINTS"
+ ss >> n_points;
+ X.resize(n_points);
+ }
+ else if (line.substr(0, 5) == "CELLS")
+ {
+ reading_points = false;
+ reading_tets = true;
+ ss.ignore(128, ' '); // ignore "CELLS"
+ ss >> n_tets;
+ indices.resize(n_tets);
+ }
+ else if (line.substr(0, 10) == "CELL_TYPES")
+ {
+ reading_points = false;
+ reading_tets = false;
+ }
+ else if (reading_points)
+ {
+ btScalar p;
+ ss >> p;
+ position.setX(p);
+ ss >> p;
+ position.setY(p);
+ ss >> p;
+ position.setZ(p);
+ //printf("v %f %f %f\n", position.getX(), position.getY(), position.getZ());
+ X[x_count++] = position;
+ }
+ else if (reading_tets)
+ {
+ int d;
+ ss >> d;
+ if (d != 4)
+ {
+ printf("Load deformable failed: Only Tetrahedra are supported in VTK file.\n");
+ fs.close();
+ return 0;
+ }
+ ss.ignore(128, ' '); // ignore "4"
+ Index tet;
+ tet.resize(4);
+ for (size_t i = 0; i < 4; i++)
+ {
+ ss >> tet[i];
+ //printf("%d ", tet[i]);
+ }
+ //printf("\n");
+ indices[indices_count++] = tet;
+ }
+ }
+ btReducedDeformableBody* rsb = new btReducedDeformableBody(&worldInfo, n_points, &X[0], 0);
+
+ for (int i = 0; i < n_tets; ++i)
+ {
+ const Index& ni = indices[i];
+ rsb->appendTetra(ni[0], ni[1], ni[2], ni[3]);
+ {
+ rsb->appendLink(ni[0], ni[1], 0, true);
+ rsb->appendLink(ni[1], ni[2], 0, true);
+ rsb->appendLink(ni[2], ni[0], 0, true);
+ rsb->appendLink(ni[0], ni[3], 0, true);
+ rsb->appendLink(ni[1], ni[3], 0, true);
+ rsb->appendLink(ni[2], ni[3], 0, true);
+ }
+ }
+
+ btSoftBodyHelpers::generateBoundaryFaces(rsb);
+ rsb->initializeDmInverse();
+ rsb->m_tetraScratches.resize(rsb->m_tetras.size());
+ rsb->m_tetraScratchesTn.resize(rsb->m_tetras.size());
+ printf("Nodes: %u\r\n", rsb->m_nodes.size());
+ printf("Links: %u\r\n", rsb->m_links.size());
+ printf("Faces: %u\r\n", rsb->m_faces.size());
+ printf("Tetras: %u\r\n", rsb->m_tetras.size());
+
+ fs.close();
+
+ return rsb;
+}
+
+void btReducedDeformableBodyHelpers::readReducedDeformableInfoFromFiles(btReducedDeformableBody* rsb, const char* file_path)
+{
+ // read in eigenmodes, stiffness and mass matrices
+ std::string eigenvalues_file = std::string(file_path) + "eigenvalues.bin";
+ btReducedDeformableBodyHelpers::readBinaryVec(rsb->m_eigenvalues, rsb->m_nReduced, eigenvalues_file.c_str());
+
+ std::string Kr_file = std::string(file_path) + "K_r_diag_mat.bin";
+ btReducedDeformableBodyHelpers::readBinaryVec(rsb->m_Kr, rsb->m_nReduced, Kr_file.c_str());
+
+ // std::string Mr_file = std::string(file_path) + "M_r_diag_mat.bin";
+ // btReducedDeformableBodyHelpers::readBinaryVec(rsb->m_Mr, rsb->m_nReduced, Mr_file.c_str());
+
+ std::string modes_file = std::string(file_path) + "modes.bin";
+ btReducedDeformableBodyHelpers::readBinaryMat(rsb->m_modes, rsb->m_nReduced, 3 * rsb->m_nFull, modes_file.c_str());
+
+ // read in full nodal mass
+ std::string M_file = std::string(file_path) + "M_diag_mat.bin";
+ btAlignedObjectArray<btScalar> mass_array;
+ btReducedDeformableBodyHelpers::readBinaryVec(mass_array, rsb->m_nFull, M_file.c_str());
+ rsb->setMassProps(mass_array);
+
+ // calculate the inertia tensor in the local frame
+ rsb->setInertiaProps();
+
+ // other internal initialization
+ rsb->internalInitialization();
+}
+
+// read in a vector from the binary file
+void btReducedDeformableBodyHelpers::readBinaryVec(btReducedDeformableBody::tDenseArray& vec,
+ const unsigned int n_size, // #entries read
+ const char* file)
+{
+ std::ifstream f_in(file, std::ios::in | std::ios::binary);
+ // first get size
+ unsigned int size;
+ f_in.read((char*)&size, sizeof(uint32_t));
+ btAssert(size >= n_size); // make sure the #requested mode is smaller than the #available modes
+
+ // read data
+ vec.resize(n_size);
+ double temp;
+ for (unsigned int i = 0; i < n_size; ++i)
+ {
+ f_in.read((char*)&temp, sizeof(double));
+ vec[i] = btScalar(temp);
+ }
+ f_in.close();
+}
+
+// read in a matrix from the binary file
+void btReducedDeformableBodyHelpers::readBinaryMat(btReducedDeformableBody::tDenseMatrix& mat,
+ const unsigned int n_modes, // #modes, outer array size
+ const unsigned int n_full, // inner array size
+ const char* file)
+{
+ std::ifstream f_in(file, std::ios::in | std::ios::binary);
+ // first get size
+ unsigned int v_size;
+ f_in.read((char*)&v_size, sizeof(uint32_t));
+ btAssert(v_size >= n_modes * n_full); // make sure the #requested mode is smaller than the #available modes
+
+ // read data
+ mat.resize(n_modes);
+ for (int i = 0; i < n_modes; ++i)
+ {
+ for (int j = 0; j < n_full; ++j)
+ {
+ double temp;
+ f_in.read((char*)&temp, sizeof(double));
+
+ if (mat[i].size() != n_modes)
+ mat[i].resize(n_full);
+ mat[i][j] = btScalar(temp);
+ }
+ }
+ f_in.close();
+}
+
+void btReducedDeformableBodyHelpers::calculateLocalInertia(btVector3& inertia, const btScalar mass, const btVector3& half_extents, const btVector3& margin)
+{
+ btScalar lx = btScalar(2.) * (half_extents[0] + margin[0]);
+ btScalar ly = btScalar(2.) * (half_extents[1] + margin[1]);
+ btScalar lz = btScalar(2.) * (half_extents[2] + margin[2]);
+
+ inertia.setValue(mass / (btScalar(12.0)) * (ly * ly + lz * lz),
+ mass / (btScalar(12.0)) * (lx * lx + lz * lz),
+ mass / (btScalar(12.0)) * (lx * lx + ly * ly));
+}
diff --git a/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.h b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.h
new file mode 100644
index 000000000..2b259a931
--- /dev/null
+++ b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodyHelpers.h
@@ -0,0 +1,25 @@
+#ifndef BT_REDUCED_SOFT_BODY_HELPERS_H
+#define BT_REDUCED_SOFT_BODY_HELPERS_H
+
+#include "btReducedDeformableBody.h"
+#include <string>
+
+struct btReducedDeformableBodyHelpers
+{
+ // create a reduced deformable object
+ static btReducedDeformableBody* createReducedDeformableObject(btSoftBodyWorldInfo& worldInfo, const std::string& file_path, const std::string& vtk_file, const int num_modes, bool rigid_only);
+ // read in geometry info from Vtk file
+ static btReducedDeformableBody* createFromVtkFile(btSoftBodyWorldInfo& worldInfo, const char* vtk_file);
+ // read in all reduced files
+ static void readReducedDeformableInfoFromFiles(btReducedDeformableBody* rsb, const char* file_path);
+ // read in a binary vector
+ static void readBinaryVec(btReducedDeformableBody::tDenseArray& vec, const unsigned int n_size, const char* file);
+ // read in a binary matrix
+ static void readBinaryMat(btReducedDeformableBody::tDenseMatrix& mat, const unsigned int n_modes, const unsigned int n_full, const char* file);
+
+ // calculate the local inertia tensor for a box shape reduced deformable object
+ static void calculateLocalInertia(btVector3& inertia, const btScalar mass, const btVector3& half_extents, const btVector3& margin);
+};
+
+
+#endif // BT_REDUCED_SOFT_BODY_HELPERS_H \ No newline at end of file
diff --git a/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.cpp b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.cpp
new file mode 100644
index 000000000..1418cc247
--- /dev/null
+++ b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.cpp
@@ -0,0 +1,325 @@
+#include "btReducedDeformableBodySolver.h"
+#include "btReducedDeformableBody.h"
+
+btReducedDeformableBodySolver::btReducedDeformableBodySolver()
+{
+ m_ascendOrder = true;
+ m_reducedSolver = true;
+ m_dampingAlpha = 0;
+ m_dampingBeta = 0;
+ m_gravity = btVector3(0, 0, 0);
+}
+
+void btReducedDeformableBodySolver::setGravity(const btVector3& gravity)
+{
+ m_gravity = gravity;
+}
+
+void btReducedDeformableBodySolver::reinitialize(const btAlignedObjectArray<btSoftBody*>& bodies, btScalar dt)
+{
+ m_softBodies.copyFromArray(bodies);
+ bool nodeUpdated = updateNodes();
+
+ if (nodeUpdated)
+ {
+ m_dv.resize(m_numNodes, btVector3(0, 0, 0));
+ m_ddv.resize(m_numNodes, btVector3(0, 0, 0));
+ m_residual.resize(m_numNodes, btVector3(0, 0, 0));
+ m_backupVelocity.resize(m_numNodes, btVector3(0, 0, 0));
+ }
+
+ // need to setZero here as resize only set value for newly allocated items
+ for (int i = 0; i < m_numNodes; ++i)
+ {
+ m_dv[i].setZero();
+ m_ddv[i].setZero();
+ m_residual[i].setZero();
+ }
+
+ if (dt > 0)
+ {
+ m_dt = dt;
+ }
+ m_objective->reinitialize(nodeUpdated, dt);
+
+ int N = bodies.size();
+ if (nodeUpdated)
+ {
+ m_staticConstraints.resize(N);
+ m_nodeRigidConstraints.resize(N);
+ // m_faceRigidConstraints.resize(N);
+ }
+ for (int i = 0; i < N; ++i)
+ {
+ m_staticConstraints[i].clear();
+ m_nodeRigidConstraints[i].clear();
+ // m_faceRigidConstraints[i].clear();
+ }
+
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(m_softBodies[i]);
+ rsb->m_contactNodesList.clear();
+ }
+
+ // set node index offsets
+ int sum = 0;
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(m_softBodies[i]);
+ rsb->m_nodeIndexOffset = sum;
+ sum += rsb->m_nodes.size();
+ }
+
+ btDeformableBodySolver::updateSoftBodies();
+}
+
+void btReducedDeformableBodySolver::predictMotion(btScalar solverdt)
+{
+ applyExplicitForce(solverdt);
+
+ // predict new mesh location
+ predictReduceDeformableMotion(solverdt);
+
+ //TODO: check if there is anything missed from btDeformableBodySolver::predictDeformableMotion
+}
+
+void btReducedDeformableBodySolver::predictReduceDeformableMotion(btScalar solverdt)
+{
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(m_softBodies[i]);
+ if (!rsb->isActive())
+ {
+ continue;
+ }
+
+ // clear contacts variables
+ rsb->m_nodeRigidContacts.resize(0);
+ rsb->m_faceRigidContacts.resize(0);
+ rsb->m_faceNodeContacts.resize(0);
+
+ // calculate inverse mass matrix for all nodes
+ for (int j = 0; j < rsb->m_nodes.size(); ++j)
+ {
+ if (rsb->m_nodes[j].m_im > 0)
+ {
+ rsb->m_nodes[j].m_effectiveMass_inv = rsb->m_nodes[j].m_effectiveMass.inverse();
+ }
+ }
+
+ // rigid motion: t, R at time^*
+ rsb->predictIntegratedTransform(solverdt, rsb->getInterpolationWorldTransform());
+
+ // update reduced dofs at time^*
+ // rsb->updateReducedDofs(solverdt);
+
+ // update local moment arm at time^*
+ // rsb->updateLocalMomentArm();
+ // rsb->updateExternalForceProjectMatrix(true);
+
+ // predict full space velocity at time^* (needed for constraints)
+ rsb->mapToFullVelocity(rsb->getInterpolationWorldTransform());
+
+ // update full space nodal position at time^*
+ rsb->mapToFullPosition(rsb->getInterpolationWorldTransform());
+
+ // update bounding box
+ rsb->updateBounds();
+
+ // update tree
+ rsb->updateNodeTree(true, true);
+ if (!rsb->m_fdbvt.empty())
+ {
+ rsb->updateFaceTree(true, true);
+ }
+ }
+}
+
+void btReducedDeformableBodySolver::applyExplicitForce(btScalar solverdt)
+{
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(m_softBodies[i]);
+
+ // apply gravity to the rigid frame, get m_linearVelocity at time^*
+ rsb->applyRigidGravity(m_gravity, solverdt);
+
+ if (!rsb->isReducedModesOFF())
+ {
+ // add internal force (elastic force & damping force)
+ rsb->applyReducedElasticForce(rsb->m_reducedDofsBuffer);
+ rsb->applyReducedDampingForce(rsb->m_reducedVelocityBuffer);
+
+ // get reduced velocity at time^*
+ rsb->updateReducedVelocity(solverdt);
+ }
+
+ // apply damping (no need at this point)
+ // rsb->applyDamping(solverdt);
+ }
+}
+
+void btReducedDeformableBodySolver::applyTransforms(btScalar timeStep)
+{
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(m_softBodies[i]);
+
+ // rigid motion
+ rsb->proceedToTransform(timeStep, true);
+
+ if (!rsb->isReducedModesOFF())
+ {
+ // update reduced dofs for time^n+1
+ rsb->updateReducedDofs(timeStep);
+
+ // update local moment arm for time^n+1
+ rsb->updateLocalMomentArm();
+ rsb->updateExternalForceProjectMatrix(true);
+ }
+
+ // update mesh nodal positions for time^n+1
+ rsb->mapToFullPosition(rsb->getRigidTransform());
+
+ // update mesh nodal velocity
+ rsb->mapToFullVelocity(rsb->getRigidTransform());
+
+ // end of time step clean up and update
+ rsb->endOfTimeStepZeroing();
+
+ // update the rendering mesh
+ rsb->interpolateRenderMesh();
+ }
+}
+
+void btReducedDeformableBodySolver::setConstraints(const btContactSolverInfo& infoGlobal)
+{
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(m_softBodies[i]);
+ if (!rsb->isActive())
+ {
+ continue;
+ }
+
+ // set fixed constraints
+ for (int j = 0; j < rsb->m_fixedNodes.size(); ++j)
+ {
+ int i_node = rsb->m_fixedNodes[j];
+ if (rsb->m_nodes[i_node].m_im == 0)
+ {
+ for (int k = 0; k < 3; ++k)
+ {
+ btVector3 dir(0, 0, 0);
+ dir[k] = 1;
+ btReducedDeformableStaticConstraint static_constraint(rsb, &rsb->m_nodes[i_node], rsb->getRelativePos(i_node), rsb->m_x0[i_node], dir, infoGlobal, m_dt);
+ m_staticConstraints[i].push_back(static_constraint);
+ }
+ }
+ }
+ btAssert(rsb->m_fixedNodes.size() * 3 == m_staticConstraints[i].size());
+
+ // set Deformable Node vs. Rigid constraint
+ for (int j = 0; j < rsb->m_nodeRigidContacts.size(); ++j)
+ {
+ const btSoftBody::DeformableNodeRigidContact& contact = rsb->m_nodeRigidContacts[j];
+ // skip fixed points
+ if (contact.m_node->m_im == 0)
+ {
+ continue;
+ }
+ btReducedDeformableNodeRigidContactConstraint constraint(rsb, contact, infoGlobal, m_dt);
+ m_nodeRigidConstraints[i].push_back(constraint);
+ rsb->m_contactNodesList.push_back(contact.m_node->index - rsb->m_nodeIndexOffset);
+ }
+ // std::cout << "contact node list size: " << rsb->m_contactNodesList.size() << "\n";
+ // std::cout << "#contact nodes: " << m_nodeRigidConstraints[i].size() << "\n";
+
+ }
+}
+
+btScalar btReducedDeformableBodySolver::solveContactConstraints(btCollisionObject** deformableBodies, int numDeformableBodies, const btContactSolverInfo& infoGlobal)
+{
+ btScalar residualSquare = 0;
+
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btAlignedObjectArray<int> m_orderNonContactConstraintPool;
+ btAlignedObjectArray<int> m_orderContactConstraintPool;
+
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(m_softBodies[i]);
+
+ // shuffle the order of applying constraint
+ m_orderNonContactConstraintPool.resize(m_staticConstraints[i].size());
+ m_orderContactConstraintPool.resize(m_nodeRigidConstraints[i].size());
+ if (infoGlobal.m_solverMode & SOLVER_RANDMIZE_ORDER)
+ {
+ // fixed constraint order
+ for (int j = 0; j < m_staticConstraints[i].size(); ++j)
+ {
+ m_orderNonContactConstraintPool[j] = m_ascendOrder ? j : m_staticConstraints[i].size() - 1 - j;
+ }
+ // contact constraint order
+ for (int j = 0; j < m_nodeRigidConstraints[i].size(); ++j)
+ {
+ m_orderContactConstraintPool[j] = m_ascendOrder ? j : m_nodeRigidConstraints[i].size() - 1 - j;
+ }
+
+ m_ascendOrder = m_ascendOrder ? false : true;
+ }
+ else
+ {
+ for (int j = 0; j < m_staticConstraints[i].size(); ++j)
+ {
+ m_orderNonContactConstraintPool[j] = j;
+ }
+ // contact constraint order
+ for (int j = 0; j < m_nodeRigidConstraints[i].size(); ++j)
+ {
+ m_orderContactConstraintPool[j] = j;
+ }
+ }
+
+ // handle fixed constraint
+ for (int k = 0; k < m_staticConstraints[i].size(); ++k)
+ {
+ btReducedDeformableStaticConstraint& constraint = m_staticConstraints[i][m_orderNonContactConstraintPool[k]];
+ btScalar localResidualSquare = constraint.solveConstraint(infoGlobal);
+ residualSquare = btMax(residualSquare, localResidualSquare);
+ }
+
+ // handle contact constraint
+
+ // node vs rigid contact
+ // std::cout << "!!#contact_nodes: " << m_nodeRigidConstraints[i].size() << '\n';
+ for (int k = 0; k < m_nodeRigidConstraints[i].size(); ++k)
+ {
+ btReducedDeformableNodeRigidContactConstraint& constraint = m_nodeRigidConstraints[i][m_orderContactConstraintPool[k]];
+ btScalar localResidualSquare = constraint.solveConstraint(infoGlobal);
+ residualSquare = btMax(residualSquare, localResidualSquare);
+ }
+
+ // face vs rigid contact
+ // for (int k = 0; k < m_faceRigidConstraints[i].size(); ++k)
+ // {
+ // btReducedDeformableFaceRigidContactConstraint& constraint = m_faceRigidConstraints[i][k];
+ // btScalar localResidualSquare = constraint.solveConstraint(infoGlobal);
+ // residualSquare = btMax(residualSquare, localResidualSquare);
+ // }
+ }
+
+
+ return residualSquare;
+}
+
+void btReducedDeformableBodySolver::deformableBodyInternalWriteBack()
+{
+ // reduced deformable update
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btReducedDeformableBody* rsb = static_cast<btReducedDeformableBody*>(m_softBodies[i]);
+ rsb->applyInternalVelocityChanges();
+ }
+ m_ascendOrder = true;
+} \ No newline at end of file
diff --git a/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.h b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.h
new file mode 100644
index 000000000..04c171f31
--- /dev/null
+++ b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableBodySolver.h
@@ -0,0 +1,61 @@
+#ifndef BT_REDUCED_DEFORMABLE_BODY_DYNAMICS_WORLD_H
+#define BT_REDUCED_DEFORMABLE_BODY_DYNAMICS_WORLD_H
+
+#include "BulletSoftBody/btDeformableBodySolver.h"
+#include "btReducedDeformableContactConstraint.h"
+
+class btReducedDeformableBody;
+
+class btReducedDeformableBodySolver : public btDeformableBodySolver
+{
+ protected:
+ bool m_ascendOrder;
+ btScalar m_dampingAlpha;
+ btScalar m_dampingBeta;
+
+ btVector3 m_gravity;
+
+ void predictReduceDeformableMotion(btScalar solverdt);
+
+ void applyExplicitForce(btScalar solverdt);
+
+ public:
+ btAlignedObjectArray<btAlignedObjectArray<btReducedDeformableStaticConstraint> > m_staticConstraints;
+ btAlignedObjectArray<btAlignedObjectArray<btReducedDeformableNodeRigidContactConstraint> > m_nodeRigidConstraints;
+ btAlignedObjectArray<btAlignedObjectArray<btReducedDeformableFaceRigidContactConstraint> > m_faceRigidConstraints;
+
+ btReducedDeformableBodySolver();
+ ~btReducedDeformableBodySolver() {}
+
+ virtual void setGravity(const btVector3& gravity);
+
+ virtual SolverTypes getSolverType() const
+ {
+ return REDUCED_DEFORMABLE_SOLVER;
+ }
+
+ // resize/clear data structures
+ virtual void reinitialize(const btAlignedObjectArray<btSoftBody*>& bodies, btScalar dt);
+
+ virtual void predictMotion(btScalar solverdt);
+
+ virtual void applyTransforms(btScalar timeStep);
+
+ // set up contact constraints
+ virtual void setConstraints(const btContactSolverInfo& infoGlobal);
+
+ // solve all constraints (fixed and contact)
+ virtual btScalar solveContactConstraints(btCollisionObject** deformableBodies, int numDeformableBodies, const btContactSolverInfo& infoGlobal);
+
+ // apply all the delta velocities
+ virtual void deformableBodyInternalWriteBack();
+
+ // virtual void setProjection() {}
+
+ // virtual void setLagrangeMultiplier() {}
+
+ // virtual void setupDeformableSolve(bool implicit);
+
+};
+
+#endif // BT_REDUCED_DEFORMABLE_BODY_DYNAMICS_WORLD_H \ No newline at end of file
diff --git a/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableContactConstraint.cpp b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableContactConstraint.cpp
new file mode 100644
index 000000000..3c78d2d22
--- /dev/null
+++ b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableContactConstraint.cpp
@@ -0,0 +1,579 @@
+#include "btReducedDeformableContactConstraint.h"
+#include <iostream>
+
+// ================= static constraints ===================
+btReducedDeformableStaticConstraint::btReducedDeformableStaticConstraint(
+ btReducedDeformableBody* rsb,
+ btSoftBody::Node* node,
+ const btVector3& ri,
+ const btVector3& x0,
+ const btVector3& dir,
+ const btContactSolverInfo& infoGlobal,
+ btScalar dt)
+ : m_rsb(rsb), m_ri(ri), m_targetPos(x0), m_impulseDirection(dir), m_dt(dt), btDeformableStaticConstraint(node, infoGlobal)
+{
+ m_erp = 0.2;
+ m_appliedImpulse = 0;
+
+ // get impulse factor
+ m_impulseFactorMatrix = rsb->getImpulseFactor(m_node->index);
+ m_impulseFactor = (m_impulseFactorMatrix * m_impulseDirection).dot(m_impulseDirection);
+
+ btScalar vel_error = btDot(-m_node->m_v, m_impulseDirection);
+ btScalar pos_error = btDot(m_targetPos - m_node->m_x, m_impulseDirection);
+
+ m_rhs = (vel_error + m_erp * pos_error / m_dt) / m_impulseFactor;
+}
+
+btScalar btReducedDeformableStaticConstraint::solveConstraint(const btContactSolverInfo& infoGlobal)
+{
+ // target velocity of fixed constraint is 0
+ btVector3 deltaVa = getDeltaVa();
+ btScalar deltaV_rel = btDot(deltaVa, m_impulseDirection);
+ btScalar deltaImpulse = m_rhs - deltaV_rel / m_impulseFactor;
+ m_appliedImpulse = m_appliedImpulse + deltaImpulse;
+
+ btVector3 impulse = deltaImpulse * m_impulseDirection;
+ applyImpulse(impulse);
+
+ // calculate residual
+ btScalar residualSquare = m_impulseFactor * deltaImpulse;
+ residualSquare *= residualSquare;
+
+ return residualSquare;
+}
+
+// this calls reduced deformable body's internalApplyFullSpaceImpulse
+void btReducedDeformableStaticConstraint::applyImpulse(const btVector3& impulse)
+{
+ // apply full space impulse
+ m_rsb->internalApplyFullSpaceImpulse(impulse, m_ri, m_node->index, m_dt);
+}
+
+btVector3 btReducedDeformableStaticConstraint::getDeltaVa() const
+{
+ return m_rsb->internalComputeNodeDeltaVelocity(m_rsb->getInterpolationWorldTransform(), m_node->index);
+}
+
+// ================= base contact constraints ===================
+btReducedDeformableRigidContactConstraint::btReducedDeformableRigidContactConstraint(
+ btReducedDeformableBody* rsb,
+ const btSoftBody::DeformableRigidContact& c,
+ const btContactSolverInfo& infoGlobal,
+ btScalar dt)
+ : m_rsb(rsb), m_dt(dt), btDeformableRigidContactConstraint(c, infoGlobal)
+{
+ m_nodeQueryIndex = 0;
+ m_appliedNormalImpulse = 0;
+ m_appliedTangentImpulse = 0;
+ m_rhs = 0;
+ m_rhs_tangent = 0;
+ m_cfm = infoGlobal.m_deformable_cfm;
+ m_cfm_friction = 0;
+ m_erp = infoGlobal.m_deformable_erp;
+ m_erp_friction = infoGlobal.m_deformable_erp;
+ m_friction = infoGlobal.m_friction;
+
+ m_collideStatic = m_contact->m_cti.m_colObj->isStaticObject();
+ m_collideMultibody = (m_contact->m_cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK);
+}
+
+void btReducedDeformableRigidContactConstraint::setSolverBody(const int bodyId, btSolverBody& solver_body)
+{
+ if (!m_collideMultibody)
+ {
+ m_solverBodyId = bodyId;
+ m_solverBody = &solver_body;
+ m_linearComponentNormal = -m_contactNormalA * m_solverBody->internalGetInvMass();
+ btVector3 torqueAxis = -m_relPosA.cross(m_contactNormalA);
+ m_angularComponentNormal = m_solverBody->m_originalBody->getInvInertiaTensorWorld() * torqueAxis;
+
+ m_linearComponentTangent = m_contactTangent * m_solverBody->internalGetInvMass();
+ btVector3 torqueAxisTangent = m_relPosA.cross(m_contactTangent);
+ m_angularComponentTangent = m_solverBody->m_originalBody->getInvInertiaTensorWorld() * torqueAxisTangent;
+ }
+}
+
+btVector3 btReducedDeformableRigidContactConstraint::getVa() const
+{
+ btVector3 Va(0, 0, 0);
+ if (!m_collideStatic)
+ {
+ Va = btDeformableRigidContactConstraint::getVa();
+ }
+ return Va;
+}
+
+btScalar btReducedDeformableRigidContactConstraint::solveConstraint(const btContactSolverInfo& infoGlobal)
+{
+ // btVector3 Va = getVa();
+ // btVector3 deltaVa = Va - m_bufferVelocityA;
+ // if (!m_collideStatic)
+ // {
+ // std::cout << "moving collision!!!\n";
+ // std::cout << "relPosA: " << m_relPosA[0] << "\t" << m_relPosA[1] << "\t" << m_relPosA[2] << "\n";
+ // std::cout << "moving rigid linear_vel: " << m_solverBody->m_originalBody->getLinearVelocity()[0] << '\t'
+ // << m_solverBody->m_originalBody->getLinearVelocity()[1] << '\t'
+ // << m_solverBody->m_originalBody->getLinearVelocity()[2] << '\n';
+ // }
+ btVector3 deltaVa = getDeltaVa();
+ btVector3 deltaVb = getDeltaVb();
+
+ // if (!m_collideStatic)
+ // {
+ // std::cout << "deltaVa: " << deltaVa[0] << '\t' << deltaVa[1] << '\t' << deltaVa[2] << '\n';
+ // std::cout << "deltaVb: " << deltaVb[0] << '\t' << deltaVb[1] << '\t' << deltaVb[2] << '\n';
+ // }
+
+ // get delta relative velocity and magnitude (i.e., how much impulse has been applied?)
+ btVector3 deltaV_rel = deltaVa - deltaVb;
+ btScalar deltaV_rel_normal = -btDot(deltaV_rel, m_contactNormalA);
+
+ // if (!m_collideStatic)
+ // {
+ // std::cout << "deltaV_rel: " << deltaV_rel[0] << '\t' << deltaV_rel[1] << '\t' << deltaV_rel[2] << "\n";
+ // std::cout << "deltaV_rel_normal: " << deltaV_rel_normal << "\n";
+ // std::cout << "normal_A: " << m_contactNormalA[0] << '\t' << m_contactNormalA[1] << '\t' << m_contactNormalA[2] << '\n';
+ // }
+
+ // get the normal impulse to be applied
+ btScalar deltaImpulse = m_rhs - m_appliedNormalImpulse * m_cfm - deltaV_rel_normal / m_normalImpulseFactor;
+ // if (!m_collideStatic)
+ // {
+ // std::cout << "m_rhs: " << m_rhs << '\t' << "m_appliedNormalImpulse: " << m_appliedNormalImpulse << "\n";
+ // std::cout << "m_normalImpulseFactor: " << m_normalImpulseFactor << '\n';
+ // }
+
+ {
+ // cumulative impulse that has been applied
+ btScalar sum = m_appliedNormalImpulse + deltaImpulse;
+ // if the cumulative impulse is pushing the object into the rigid body, set it zero
+ if (sum < 0)
+ {
+ deltaImpulse = -m_appliedNormalImpulse;
+ m_appliedNormalImpulse = 0;
+ }
+ else
+ {
+ m_appliedNormalImpulse = sum;
+ }
+ }
+
+ // if (!m_collideStatic)
+ // {
+ // std::cout << "m_appliedNormalImpulse: " << m_appliedNormalImpulse << '\n';
+ // std::cout << "deltaImpulse: " << deltaImpulse << '\n';
+ // }
+
+ // residual is the nodal normal velocity change in current iteration
+ btScalar residualSquare = deltaImpulse * m_normalImpulseFactor; // get residual
+ residualSquare *= residualSquare;
+
+
+ // apply Coulomb friction (based on delta velocity, |dv_t| = |dv_n * friction|)
+ btScalar deltaImpulse_tangent = 0;
+ btScalar deltaImpulse_tangent2 = 0;
+ {
+ // calculate how much impulse is needed
+ // btScalar deltaV_rel_tangent = btDot(deltaV_rel, m_contactTangent);
+ // btScalar impulse_changed = deltaV_rel_tangent * m_tangentImpulseFactorInv;
+ // deltaImpulse_tangent = m_rhs_tangent - impulse_changed;
+
+ // btScalar sum = m_appliedTangentImpulse + deltaImpulse_tangent;
+ btScalar lower_limit = - m_appliedNormalImpulse * m_friction;
+ btScalar upper_limit = m_appliedNormalImpulse * m_friction;
+ // if (sum > upper_limit)
+ // {
+ // deltaImpulse_tangent = upper_limit - m_appliedTangentImpulse;
+ // m_appliedTangentImpulse = upper_limit;
+ // }
+ // else if (sum < lower_limit)
+ // {
+ // deltaImpulse_tangent = lower_limit - m_appliedTangentImpulse;
+ // m_appliedTangentImpulse = lower_limit;
+ // }
+ // else
+ // {
+ // m_appliedTangentImpulse = sum;
+ // }
+ //
+ calculateTangentialImpulse(deltaImpulse_tangent, m_appliedTangentImpulse, m_rhs_tangent,
+ m_tangentImpulseFactorInv, m_contactTangent, lower_limit, upper_limit, deltaV_rel);
+
+ if (m_collideMultibody)
+ {
+ calculateTangentialImpulse(deltaImpulse_tangent2, m_appliedTangentImpulse2, m_rhs_tangent2,
+ m_tangentImpulseFactorInv2, m_contactTangent2, lower_limit, upper_limit, deltaV_rel);
+ }
+
+
+ if (!m_collideStatic)
+ {
+ // std::cout << "m_contactTangent: " << m_contactTangent[0] << "\t" << m_contactTangent[1] << "\t" << m_contactTangent[2] << "\n";
+ // std::cout << "deltaV_rel_tangent: " << deltaV_rel_tangent << '\n';
+ // std::cout << "deltaImpulseTangent: " << deltaImpulse_tangent << '\n';
+ // std::cout << "m_appliedTangentImpulse: " << m_appliedTangentImpulse << '\n';
+ }
+ }
+
+ // get the total impulse vector
+ btVector3 impulse_normal = deltaImpulse * m_contactNormalA;
+ btVector3 impulse_tangent = deltaImpulse_tangent * (-m_contactTangent);
+ btVector3 impulse_tangent2 = deltaImpulse_tangent2 * (-m_contactTangent2);
+ btVector3 impulse = impulse_normal + impulse_tangent + impulse_tangent2;
+
+ applyImpulse(impulse);
+
+ // apply impulse to the rigid/multibodies involved and change their velocities
+ if (!m_collideStatic)
+ {
+ // std::cout << "linear_component: " << m_linearComponentNormal[0] << '\t'
+ // << m_linearComponentNormal[1] << '\t'
+ // << m_linearComponentNormal[2] << '\n';
+ // std::cout << "angular_component: " << m_angularComponentNormal[0] << '\t'
+ // << m_angularComponentNormal[1] << '\t'
+ // << m_angularComponentNormal[2] << '\n';
+
+ if (!m_collideMultibody) // collision with rigid body
+ {
+ // std::cout << "rigid impulse applied!!\n";
+ // std::cout << "delta Linear: " << m_solverBody->getDeltaLinearVelocity()[0] << '\t'
+ // << m_solverBody->getDeltaLinearVelocity()[1] << '\t'
+ // << m_solverBody->getDeltaLinearVelocity()[2] << '\n';
+ // std::cout << "delta Angular: " << m_solverBody->getDeltaAngularVelocity()[0] << '\t'
+ // << m_solverBody->getDeltaAngularVelocity()[1] << '\t'
+ // << m_solverBody->getDeltaAngularVelocity()[2] << '\n';
+
+ m_solverBody->internalApplyImpulse(m_linearComponentNormal, m_angularComponentNormal, deltaImpulse);
+ m_solverBody->internalApplyImpulse(m_linearComponentTangent, m_angularComponentTangent, deltaImpulse_tangent);
+
+ // std::cout << "after\n";
+ // std::cout << "rigid impulse applied!!\n";
+ // std::cout << "delta Linear: " << m_solverBody->getDeltaLinearVelocity()[0] << '\t'
+ // << m_solverBody->getDeltaLinearVelocity()[1] << '\t'
+ // << m_solverBody->getDeltaLinearVelocity()[2] << '\n';
+ // std::cout << "delta Angular: " << m_solverBody->getDeltaAngularVelocity()[0] << '\t'
+ // << m_solverBody->getDeltaAngularVelocity()[1] << '\t'
+ // << m_solverBody->getDeltaAngularVelocity()[2] << '\n';
+ }
+ else // collision with multibody
+ {
+ btMultiBodyLinkCollider* multibodyLinkCol = 0;
+ multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(m_contact->m_cti.m_colObj);
+ if (multibodyLinkCol)
+ {
+ const btScalar* deltaV_normal = &m_contact->jacobianData_normal.m_deltaVelocitiesUnitImpulse[0];
+ // apply normal component of the impulse
+ multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof2(deltaV_normal, -deltaImpulse);
+
+ // const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6;
+ // std::cout << "deltaV_normal: ";
+ // for (int i = 0; i < ndof; ++i)
+ // {
+ // std::cout << i << "\t" << deltaV_normal[i] << '\n';
+ // }
+
+ if (impulse_tangent.norm() > SIMD_EPSILON)
+ {
+ // apply tangential component of the impulse
+ const btScalar* deltaV_t1 = &m_contact->jacobianData_t1.m_deltaVelocitiesUnitImpulse[0];
+ multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof2(deltaV_t1, deltaImpulse_tangent);
+ const btScalar* deltaV_t2 = &m_contact->jacobianData_t2.m_deltaVelocitiesUnitImpulse[0];
+ multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof2(deltaV_t2, deltaImpulse_tangent2);
+ }
+ }
+ }
+ }
+ return residualSquare;
+}
+
+void btReducedDeformableRigidContactConstraint::calculateTangentialImpulse(btScalar& deltaImpulse_tangent,
+ btScalar& appliedImpulse,
+ const btScalar rhs_tangent,
+ const btScalar tangentImpulseFactorInv,
+ const btVector3& tangent,
+ const btScalar lower_limit,
+ const btScalar upper_limit,
+ const btVector3& deltaV_rel)
+{
+ btScalar deltaV_rel_tangent = btDot(deltaV_rel, tangent);
+ btScalar impulse_changed = deltaV_rel_tangent * tangentImpulseFactorInv;
+ deltaImpulse_tangent = rhs_tangent - m_cfm_friction * appliedImpulse - impulse_changed;
+
+ btScalar sum = appliedImpulse + deltaImpulse_tangent;
+ if (sum > upper_limit)
+ {
+ deltaImpulse_tangent = upper_limit - appliedImpulse;
+ appliedImpulse = upper_limit;
+ }
+ else if (sum < lower_limit)
+ {
+ deltaImpulse_tangent = lower_limit - appliedImpulse;
+ appliedImpulse = lower_limit;
+ }
+ else
+ {
+ appliedImpulse = sum;
+ }
+}
+
+// ================= node vs rigid constraints ===================
+btReducedDeformableNodeRigidContactConstraint::btReducedDeformableNodeRigidContactConstraint(
+ btReducedDeformableBody* rsb,
+ const btSoftBody::DeformableNodeRigidContact& contact,
+ const btContactSolverInfo& infoGlobal,
+ btScalar dt)
+ : m_node(contact.m_node), btReducedDeformableRigidContactConstraint(rsb, contact, infoGlobal, dt)
+{
+ m_contactNormalA = contact.m_cti.m_normal;
+ m_contactNormalB = -contact.m_cti.m_normal;
+
+ if (contact.m_node->index < rsb->m_nodes.size())
+ {
+ m_nodeQueryIndex = contact.m_node->index;
+ }
+ else
+ {
+ m_nodeQueryIndex = m_node->index - rsb->m_nodeIndexOffset;
+ }
+
+ if (m_contact->m_cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY)
+ {
+ m_relPosA = contact.m_c1;
+ }
+ else
+ {
+ m_relPosA = btVector3(0,0,0);
+ }
+ m_relPosB = m_node->m_x - m_rsb->getRigidTransform().getOrigin();
+
+ if (m_collideStatic) // colliding with static object, only consider reduced deformable body's impulse factor
+ {
+ m_impulseFactor = m_rsb->getImpulseFactor(m_nodeQueryIndex);
+ }
+ else // colliding with dynamic object, consider both reduced deformable and rigid body's impulse factors
+ {
+ m_impulseFactor = m_rsb->getImpulseFactor(m_nodeQueryIndex) + contact.m_c0;
+ }
+
+ m_normalImpulseFactor = (m_impulseFactor * m_contactNormalA).dot(m_contactNormalA);
+ m_tangentImpulseFactor = 0;
+
+ warmStarting();
+}
+
+void btReducedDeformableNodeRigidContactConstraint::warmStarting()
+{
+ btVector3 va = getVa();
+ btVector3 vb = getVb();
+ m_bufferVelocityA = va;
+ m_bufferVelocityB = vb;
+
+ // we define the (+) direction of errors to be the outward surface normal of the rigid object
+ btVector3 v_rel = vb - va;
+ // get tangent direction of the relative velocity
+ btVector3 v_tangent = v_rel - v_rel.dot(m_contactNormalA) * m_contactNormalA;
+ if (v_tangent.norm() < SIMD_EPSILON)
+ {
+ m_contactTangent = btVector3(0, 0, 0);
+ // tangent impulse factor
+ m_tangentImpulseFactor = 0;
+ m_tangentImpulseFactorInv = 0;
+ }
+ else
+ {
+ if (!m_collideMultibody)
+ {
+ m_contactTangent = v_tangent.normalized();
+ m_contactTangent2.setZero();
+ // tangent impulse factor 1
+ m_tangentImpulseFactor = (m_impulseFactor * m_contactTangent).dot(m_contactTangent);
+ m_tangentImpulseFactorInv = btScalar(1) / m_tangentImpulseFactor;
+ // tangent impulse factor 2
+ m_tangentImpulseFactor2 = 0;
+ m_tangentImpulseFactorInv2 = 0;
+ }
+ else // multibody requires 2 contact directions
+ {
+ m_contactTangent = m_contact->t1;
+ m_contactTangent2 = m_contact->t2;
+
+ // tangent impulse factor 1
+ m_tangentImpulseFactor = (m_impulseFactor * m_contactTangent).dot(m_contactTangent);
+ m_tangentImpulseFactorInv = btScalar(1) / m_tangentImpulseFactor;
+ // tangent impulse factor 2
+ m_tangentImpulseFactor2 = (m_impulseFactor * m_contactTangent2).dot(m_contactTangent2);
+ m_tangentImpulseFactorInv2 = btScalar(1) / m_tangentImpulseFactor2;
+ }
+ }
+
+
+ // initial guess for normal impulse
+ {
+ btScalar velocity_error = btDot(v_rel, m_contactNormalA); // magnitude of relative velocity
+ btScalar position_error = 0;
+ if (m_penetration > 0)
+ {
+ velocity_error += m_penetration / m_dt;
+ }
+ else
+ {
+ // add penetration correction vel
+ position_error = m_penetration * m_erp / m_dt;
+ }
+ // get the initial estimate of impulse magnitude to be applied
+ m_rhs = -(velocity_error + position_error) / m_normalImpulseFactor;
+ }
+
+ // initial guess for tangential impulse
+ {
+ btScalar velocity_error = btDot(v_rel, m_contactTangent);
+ m_rhs_tangent = velocity_error * m_tangentImpulseFactorInv;
+
+ if (m_collideMultibody)
+ {
+ btScalar velocity_error2 = btDot(v_rel, m_contactTangent2);
+ m_rhs_tangent2 = velocity_error2 * m_tangentImpulseFactorInv2;
+ }
+ }
+
+ // warm starting
+ // applyImpulse(m_rhs * m_contactNormalA);
+ // if (!m_collideStatic)
+ // {
+ // const btSoftBody::sCti& cti = m_contact->m_cti;
+ // if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY)
+ // {
+ // m_solverBody->internalApplyImpulse(m_linearComponentNormal, m_angularComponentNormal, -m_rhs);
+ // }
+ // }
+}
+
+btVector3 btReducedDeformableNodeRigidContactConstraint::getVb() const
+{
+ return m_node->m_v;
+}
+
+btVector3 btReducedDeformableNodeRigidContactConstraint::getDeltaVa() const
+{
+ btVector3 deltaVa(0, 0, 0);
+ if (!m_collideStatic)
+ {
+ if (!m_collideMultibody) // for rigid body
+ {
+ deltaVa = m_solverBody->internalGetDeltaLinearVelocity() + m_solverBody->internalGetDeltaAngularVelocity().cross(m_relPosA);
+ }
+ else // for multibody
+ {
+ btMultiBodyLinkCollider* multibodyLinkCol = 0;
+ multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(m_contact->m_cti.m_colObj);
+ if (multibodyLinkCol)
+ {
+ const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6;
+ const btScalar* J_n = &m_contact->jacobianData_normal.m_jacobians[0];
+ const btScalar* J_t1 = &m_contact->jacobianData_t1.m_jacobians[0];
+ const btScalar* J_t2 = &m_contact->jacobianData_t2.m_jacobians[0];
+ const btScalar* local_dv = multibodyLinkCol->m_multiBody->getDeltaVelocityVector();
+ // add in the normal component of the va
+ btScalar vel = 0;
+ for (int k = 0; k < ndof; ++k)
+ {
+ vel += local_dv[k] * J_n[k];
+ }
+ deltaVa = m_contact->m_cti.m_normal * vel;
+
+ // add in the tangential components of the va
+ vel = 0;
+ for (int k = 0; k < ndof; ++k)
+ {
+ vel += local_dv[k] * J_t1[k];
+ }
+ deltaVa += m_contact->t1 * vel;
+
+ vel = 0;
+ for (int k = 0; k < ndof; ++k)
+ {
+ vel += local_dv[k] * J_t2[k];
+ }
+ deltaVa += m_contact->t2 * vel;
+ }
+ }
+ }
+ return deltaVa;
+}
+
+btVector3 btReducedDeformableNodeRigidContactConstraint::getDeltaVb() const
+{
+ // std::cout << "node: " << m_node->index << '\n';
+ return m_rsb->internalComputeNodeDeltaVelocity(m_rsb->getInterpolationWorldTransform(), m_nodeQueryIndex);
+}
+
+btVector3 btReducedDeformableNodeRigidContactConstraint::getSplitVb() const
+{
+ return m_node->m_splitv;
+}
+
+btVector3 btReducedDeformableNodeRigidContactConstraint::getDv(const btSoftBody::Node* node) const
+{
+ return m_total_normal_dv + m_total_tangent_dv;
+}
+
+void btReducedDeformableNodeRigidContactConstraint::applyImpulse(const btVector3& impulse)
+{
+ m_rsb->internalApplyFullSpaceImpulse(impulse, m_relPosB, m_nodeQueryIndex, m_dt);
+ // m_rsb->applyFullSpaceImpulse(impulse, m_relPosB, m_node->index, m_dt);
+ // m_rsb->mapToFullVelocity(m_rsb->getInterpolationWorldTransform());
+ // if (!m_collideStatic)
+ // {
+ // // std::cout << "impulse applied: " << impulse[0] << '\t' << impulse[1] << '\t' << impulse[2] << '\n';
+ // // std::cout << "node: " << m_node->index << " vel: " << m_node->m_v[0] << '\t' << m_node->m_v[1] << '\t' << m_node->m_v[2] << '\n';
+ // btVector3 v_after = getDeltaVb() + m_node->m_v;
+ // // std::cout << "vel after: " << v_after[0] << '\t' << v_after[1] << '\t' << v_after[2] << '\n';
+ // }
+ // std::cout << "node: " << m_node->index << " pos: " << m_node->m_x[0] << '\t' << m_node->m_x[1] << '\t' << m_node->m_x[2] << '\n';
+}
+
+// ================= face vs rigid constraints ===================
+btReducedDeformableFaceRigidContactConstraint::btReducedDeformableFaceRigidContactConstraint(
+ btReducedDeformableBody* rsb,
+ const btSoftBody::DeformableFaceRigidContact& contact,
+ const btContactSolverInfo& infoGlobal,
+ btScalar dt,
+ bool useStrainLimiting)
+ : m_face(contact.m_face), m_useStrainLimiting(useStrainLimiting), btReducedDeformableRigidContactConstraint(rsb, contact, infoGlobal, dt)
+{}
+
+btVector3 btReducedDeformableFaceRigidContactConstraint::getVb() const
+{
+ const btSoftBody::DeformableFaceRigidContact* contact = getContact();
+ btVector3 vb = m_face->m_n[0]->m_v * contact->m_bary[0] + m_face->m_n[1]->m_v * contact->m_bary[1] + m_face->m_n[2]->m_v * contact->m_bary[2];
+ return vb;
+}
+
+btVector3 btReducedDeformableFaceRigidContactConstraint::getSplitVb() const
+{
+ const btSoftBody::DeformableFaceRigidContact* contact = getContact();
+ btVector3 vb = (m_face->m_n[0]->m_splitv) * contact->m_bary[0] + (m_face->m_n[1]->m_splitv) * contact->m_bary[1] + (m_face->m_n[2]->m_splitv) * contact->m_bary[2];
+ return vb;
+}
+
+btVector3 btReducedDeformableFaceRigidContactConstraint::getDv(const btSoftBody::Node* node) const
+{
+ btVector3 face_dv = m_total_normal_dv + m_total_tangent_dv;
+ const btSoftBody::DeformableFaceRigidContact* contact = getContact();
+ if (m_face->m_n[0] == node)
+ {
+ return face_dv * contact->m_weights[0];
+ }
+ if (m_face->m_n[1] == node)
+ {
+ return face_dv * contact->m_weights[1];
+ }
+ btAssert(node == m_face->m_n[2]);
+ return face_dv * contact->m_weights[2];
+}
+
+void btReducedDeformableFaceRigidContactConstraint::applyImpulse(const btVector3& impulse)
+{
+ //
+} \ No newline at end of file
diff --git a/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableContactConstraint.h b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableContactConstraint.h
new file mode 100644
index 000000000..10d0938c5
--- /dev/null
+++ b/src/BulletSoftBody/BulletReducedDeformableBody/btReducedDeformableContactConstraint.h
@@ -0,0 +1,194 @@
+#include "../btDeformableContactConstraint.h"
+#include "btReducedDeformableBody.h"
+
+// ================= static constraints ===================
+class btReducedDeformableStaticConstraint : public btDeformableStaticConstraint
+{
+ public:
+ btReducedDeformableBody* m_rsb;
+ btScalar m_dt;
+ btVector3 m_ri;
+ btVector3 m_targetPos;
+ btVector3 m_impulseDirection;
+ btMatrix3x3 m_impulseFactorMatrix;
+ btScalar m_impulseFactor;
+ btScalar m_rhs;
+ btScalar m_appliedImpulse;
+ btScalar m_erp;
+
+ btReducedDeformableStaticConstraint(btReducedDeformableBody* rsb,
+ btSoftBody::Node* node,
+ const btVector3& ri,
+ const btVector3& x0,
+ const btVector3& dir,
+ const btContactSolverInfo& infoGlobal,
+ btScalar dt);
+ // btReducedDeformableStaticConstraint(const btReducedDeformableStaticConstraint& other);
+ btReducedDeformableStaticConstraint() {}
+ virtual ~btReducedDeformableStaticConstraint() {}
+
+ virtual btScalar solveConstraint(const btContactSolverInfo& infoGlobal);
+
+ // this calls reduced deformable body's applyFullSpaceImpulse
+ virtual void applyImpulse(const btVector3& impulse);
+
+ btVector3 getDeltaVa() const;
+
+ // virtual void applySplitImpulse(const btVector3& impulse) {}
+};
+
+// ================= base contact constraints ===================
+class btReducedDeformableRigidContactConstraint : public btDeformableRigidContactConstraint
+{
+ public:
+ bool m_collideStatic; // flag for collision with static object
+ bool m_collideMultibody; // flag for collision with multibody
+
+ int m_nodeQueryIndex;
+ int m_solverBodyId; // for debugging
+
+ btReducedDeformableBody* m_rsb;
+ btSolverBody* m_solverBody;
+ btScalar m_dt;
+
+ btScalar m_appliedNormalImpulse;
+ btScalar m_appliedTangentImpulse;
+ btScalar m_appliedTangentImpulse2;
+ btScalar m_normalImpulseFactor;
+ btScalar m_tangentImpulseFactor;
+ btScalar m_tangentImpulseFactor2;
+ btScalar m_tangentImpulseFactorInv;
+ btScalar m_tangentImpulseFactorInv2;
+ btScalar m_rhs;
+ btScalar m_rhs_tangent;
+ btScalar m_rhs_tangent2;
+
+ btScalar m_cfm;
+ btScalar m_cfm_friction;
+ btScalar m_erp;
+ btScalar m_erp_friction;
+ btScalar m_friction;
+
+ btVector3 m_contactNormalA; // surface normal for rigid body (opposite direction as impulse)
+ btVector3 m_contactNormalB; // surface normal for reduced deformable body (opposite direction as impulse)
+ btVector3 m_contactTangent; // tangential direction of the relative velocity
+ btVector3 m_contactTangent2; // 2nd tangential direction of the relative velocity
+ btVector3 m_relPosA; // relative position of the contact point for A (rigid)
+ btVector3 m_relPosB; // relative position of the contact point for B
+ btMatrix3x3 m_impulseFactor; // total impulse matrix
+
+ btVector3 m_bufferVelocityA; // velocity at the beginning of the iteration
+ btVector3 m_bufferVelocityB;
+ btVector3 m_linearComponentNormal; // linear components for the solver body
+ btVector3 m_angularComponentNormal; // angular components for the solver body
+ // since 2nd contact direction only applies to multibody, these components will never be used
+ btVector3 m_linearComponentTangent;
+ btVector3 m_angularComponentTangent;
+
+ btReducedDeformableRigidContactConstraint(btReducedDeformableBody* rsb,
+ const btSoftBody::DeformableRigidContact& c,
+ const btContactSolverInfo& infoGlobal,
+ btScalar dt);
+ // btReducedDeformableRigidContactConstraint(const btReducedDeformableRigidContactConstraint& other);
+ btReducedDeformableRigidContactConstraint() {}
+ virtual ~btReducedDeformableRigidContactConstraint() {}
+
+ void setSolverBody(const int bodyId, btSolverBody& solver_body);
+
+ virtual void warmStarting() {}
+
+ virtual btScalar solveConstraint(const btContactSolverInfo& infoGlobal);
+
+ void calculateTangentialImpulse(btScalar& deltaImpulse_tangent,
+ btScalar& appliedImpulse,
+ const btScalar rhs_tangent,
+ const btScalar tangentImpulseFactorInv,
+ const btVector3& tangent,
+ const btScalar lower_limit,
+ const btScalar upper_limit,
+ const btVector3& deltaV_rel);
+
+ virtual void applyImpulse(const btVector3& impulse) {}
+
+ virtual void applySplitImpulse(const btVector3& impulse) {} // TODO: may need later
+
+ virtual btVector3 getVa() const;
+ virtual btVector3 getDeltaVa() const = 0;
+ virtual btVector3 getDeltaVb() const = 0;
+};
+
+// ================= node vs rigid constraints ===================
+class btReducedDeformableNodeRigidContactConstraint : public btReducedDeformableRigidContactConstraint
+{
+ public:
+ btSoftBody::Node* m_node;
+
+ btReducedDeformableNodeRigidContactConstraint(btReducedDeformableBody* rsb,
+ const btSoftBody::DeformableNodeRigidContact& contact,
+ const btContactSolverInfo& infoGlobal,
+ btScalar dt);
+ // btReducedDeformableNodeRigidContactConstraint(const btReducedDeformableNodeRigidContactConstraint& other);
+ btReducedDeformableNodeRigidContactConstraint() {}
+ virtual ~btReducedDeformableNodeRigidContactConstraint() {}
+
+ virtual void warmStarting();
+
+ // get the velocity of the deformable node in contact
+ virtual btVector3 getVb() const;
+
+ // get the velocity change of the rigid body
+ virtual btVector3 getDeltaVa() const;
+
+ // get velocity change of the node in contat
+ virtual btVector3 getDeltaVb() const;
+
+ // get the split impulse velocity of the deformable face at the contact point
+ virtual btVector3 getSplitVb() const;
+
+ // get the velocity change of the input soft body node in the constraint
+ virtual btVector3 getDv(const btSoftBody::Node*) const;
+
+ // cast the contact to the desired type
+ const btSoftBody::DeformableNodeRigidContact* getContact() const
+ {
+ return static_cast<const btSoftBody::DeformableNodeRigidContact*>(m_contact);
+ }
+
+ // this calls reduced deformable body's applyFullSpaceImpulse
+ virtual void applyImpulse(const btVector3& impulse);
+};
+
+// ================= face vs rigid constraints ===================
+class btReducedDeformableFaceRigidContactConstraint : public btReducedDeformableRigidContactConstraint
+{
+ public:
+ btSoftBody::Face* m_face;
+ bool m_useStrainLimiting;
+
+ btReducedDeformableFaceRigidContactConstraint(btReducedDeformableBody* rsb,
+ const btSoftBody::DeformableFaceRigidContact& contact,
+ const btContactSolverInfo& infoGlobal,
+ btScalar dt,
+ bool useStrainLimiting);
+ // btReducedDeformableFaceRigidContactConstraint(const btReducedDeformableFaceRigidContactConstraint& other);
+ btReducedDeformableFaceRigidContactConstraint() {}
+ virtual ~btReducedDeformableFaceRigidContactConstraint() {}
+
+ // get the velocity of the deformable face at the contact point
+ virtual btVector3 getVb() const;
+
+ // get the split impulse velocity of the deformable face at the contact point
+ virtual btVector3 getSplitVb() const;
+
+ // get the velocity change of the input soft body node in the constraint
+ virtual btVector3 getDv(const btSoftBody::Node*) const;
+
+ // cast the contact to the desired type
+ const btSoftBody::DeformableFaceRigidContact* getContact() const
+ {
+ return static_cast<const btSoftBody::DeformableFaceRigidContact*>(m_contact);
+ }
+
+ // this calls reduced deformable body's applyFullSpaceImpulse
+ virtual void applyImpulse(const btVector3& impulse);
+}; \ No newline at end of file
diff --git a/src/BulletSoftBody/CMakeLists.txt b/src/BulletSoftBody/CMakeLists.txt
index 945276801..c12eef5fe 100644
--- a/src/BulletSoftBody/CMakeLists.txt
+++ b/src/BulletSoftBody/CMakeLists.txt
@@ -24,6 +24,11 @@ SET(BulletSoftBody_SRCS
btDeformableMultiBodyDynamicsWorld.cpp
btDeformableContactConstraint.cpp
poly34.cpp
+
+ BulletReducedDeformableBody/btReducedDeformableBody.cpp
+ BulletReducedDeformableBody/btReducedDeformableBodyHelpers.cpp
+ BulletReducedDeformableBody/btReducedDeformableBodySolver.cpp
+ BulletReducedDeformableBody/btReducedDeformableContactConstraint.cpp
)
@@ -63,6 +68,11 @@ SET(BulletSoftBody_HDRS
poly34.h
btSoftBodySolverVertexBuffer.h
+
+ BulletReducedDeformableBody/btReducedDeformableBody.h
+ BulletReducedDeformableBody/btReducedDeformableBodyHelpers.h
+ BulletReducedDeformableBody/btReducedDeformableBodySolver.h
+ BulletReducedDeformableBody/btReducedDeformableContactConstraint.h
)
diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h
index eb05b9f01..60b6fe388 100644
--- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h
+++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h
@@ -25,12 +25,18 @@
#include "btDeformableNeoHookeanForce.h"
#include "btDeformableContactProjection.h"
#include "btPreconditioner.h"
-#include "btDeformableMultiBodyDynamicsWorld.h"
+// #include "btDeformableMultiBodyDynamicsWorld.h"
#include "LinearMath/btQuickprof.h"
class btDeformableBackwardEulerObjective
{
public:
+ enum _
+ {
+ Mass_preconditioner,
+ KKT_preconditioner
+ };
+
typedef btAlignedObjectArray<btVector3> TVStack;
btScalar m_dt;
btAlignedObjectArray<btDeformableLagrangianForce*> m_lf;
diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp
index 699c6bcad..4e9df5f83 100644
--- a/src/BulletSoftBody/btDeformableBodySolver.cpp
+++ b/src/BulletSoftBody/btDeformableBodySolver.cpp
@@ -23,6 +23,7 @@ btDeformableBodySolver::btDeformableBodySolver()
: m_numNodes(0), m_cg(kMaxConjugateGradientIterations), m_cr(kMaxConjugateGradientIterations), m_maxNewtonIterations(1), m_newtonTolerance(1e-4), m_lineSearch(false), m_useProjection(false)
{
m_objective = new btDeformableBackwardEulerObjective(m_softBodies, m_backupVelocity);
+ m_reducedSolver = false;
}
btDeformableBodySolver::~btDeformableBodySolver()
@@ -401,7 +402,7 @@ void btDeformableBodySolver::predictMotion(btScalar solverdt)
}
}
}
- m_objective->applyExplicitForce(m_residual);
+ applyExplicitForce();
for (int i = 0; i < m_softBodies.size(); ++i)
{
btSoftBody* psb = m_softBodies[i];
@@ -411,6 +412,7 @@ void btDeformableBodySolver::predictMotion(btScalar solverdt)
psb->m_nodeRigidContacts.resize(0);
psb->m_faceRigidContacts.resize(0);
psb->m_faceNodeContacts.resize(0);
+ psb->m_faceNodeContactsCCD.resize(0);
// predict motion for collision detection
predictDeformableMotion(psb, solverdt);
}
@@ -503,3 +505,89 @@ void btDeformableBodySolver::setLineSearch(bool lineSearch)
{
m_lineSearch = lineSearch;
}
+
+void btDeformableBodySolver::applyExplicitForce()
+{
+ m_objective->applyExplicitForce(m_residual);
+}
+
+void btDeformableBodySolver::applyTransforms(btScalar timeStep)
+{
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btSoftBody* psb = m_softBodies[i];
+ for (int j = 0; j < psb->m_nodes.size(); ++j)
+ {
+ btSoftBody::Node& node = psb->m_nodes[j];
+ btScalar maxDisplacement = psb->getWorldInfo()->m_maxDisplacement;
+ btScalar clampDeltaV = maxDisplacement / timeStep;
+ for (int c = 0; c < 3; c++)
+ {
+ if (node.m_v[c] > clampDeltaV)
+ {
+ node.m_v[c] = clampDeltaV;
+ }
+ if (node.m_v[c] < -clampDeltaV)
+ {
+ node.m_v[c] = -clampDeltaV;
+ }
+ }
+ node.m_x = node.m_x + timeStep * (node.m_v + node.m_splitv);
+ node.m_q = node.m_x;
+ node.m_vn = node.m_v;
+ }
+ // enforce anchor constraints
+ for (int j = 0; j < psb->m_deformableAnchors.size(); ++j)
+ {
+ btSoftBody::DeformableNodeRigidAnchor& a = psb->m_deformableAnchors[j];
+ btSoftBody::Node* n = a.m_node;
+ n->m_x = a.m_cti.m_colObj->getWorldTransform() * a.m_local;
+
+ // update multibody anchor info
+ if (a.m_cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK)
+ {
+ btMultiBodyLinkCollider* multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(a.m_cti.m_colObj);
+ if (multibodyLinkCol)
+ {
+ btVector3 nrm;
+ const btCollisionShape* shp = multibodyLinkCol->getCollisionShape();
+ const btTransform& wtr = multibodyLinkCol->getWorldTransform();
+ psb->m_worldInfo->m_sparsesdf.Evaluate(
+ wtr.invXform(n->m_x),
+ shp,
+ nrm,
+ 0);
+ a.m_cti.m_normal = wtr.getBasis() * nrm;
+ btVector3 normal = a.m_cti.m_normal;
+ btVector3 t1 = generateUnitOrthogonalVector(normal);
+ btVector3 t2 = btCross(normal, t1);
+ btMultiBodyJacobianData jacobianData_normal, jacobianData_t1, jacobianData_t2;
+ findJacobian(multibodyLinkCol, jacobianData_normal, a.m_node->m_x, normal);
+ findJacobian(multibodyLinkCol, jacobianData_t1, a.m_node->m_x, t1);
+ findJacobian(multibodyLinkCol, jacobianData_t2, a.m_node->m_x, t2);
+
+ btScalar* J_n = &jacobianData_normal.m_jacobians[0];
+ btScalar* J_t1 = &jacobianData_t1.m_jacobians[0];
+ btScalar* J_t2 = &jacobianData_t2.m_jacobians[0];
+
+ btScalar* u_n = &jacobianData_normal.m_deltaVelocitiesUnitImpulse[0];
+ btScalar* u_t1 = &jacobianData_t1.m_deltaVelocitiesUnitImpulse[0];
+ btScalar* u_t2 = &jacobianData_t2.m_deltaVelocitiesUnitImpulse[0];
+
+ btMatrix3x3 rot(normal.getX(), normal.getY(), normal.getZ(),
+ t1.getX(), t1.getY(), t1.getZ(),
+ t2.getX(), t2.getY(), t2.getZ()); // world frame to local frame
+ const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6;
+ btMatrix3x3 local_impulse_matrix = (Diagonal(n->m_im) + OuterProduct(J_n, J_t1, J_t2, u_n, u_t1, u_t2, ndof)).inverse();
+ a.m_c0 = rot.transpose() * local_impulse_matrix * rot;
+ a.jacobianData_normal = jacobianData_normal;
+ a.jacobianData_t1 = jacobianData_t1;
+ a.jacobianData_t2 = jacobianData_t2;
+ a.t1 = t1;
+ a.t2 = t2;
+ }
+ }
+ }
+ psb->interpolateRenderMesh();
+ }
+} \ No newline at end of file
diff --git a/src/BulletSoftBody/btDeformableBodySolver.h b/src/BulletSoftBody/btDeformableBodySolver.h
index ae674d6e8..68354f199 100644
--- a/src/BulletSoftBody/btDeformableBodySolver.h
+++ b/src/BulletSoftBody/btDeformableBodySolver.h
@@ -24,8 +24,8 @@
#include "btConjugateResidual.h"
#include "btConjugateGradient.h"
struct btCollisionObjectWrapper;
-class btDeformableBackwardEulerObjective;
-class btDeformableMultiBodyDynamicsWorld;
+// class btDeformableBackwardEulerObjective;
+// class btDeformableMultiBodyDynamicsWorld;
class btDeformableBodySolver : public btSoftBodySolver
{
@@ -46,6 +46,7 @@ protected:
int m_maxNewtonIterations; // max number of newton iterations
btScalar m_newtonTolerance; // stop newton iterations if f(x) < m_newtonTolerance
bool m_lineSearch; // If true, use newton's method with line search under implicit scheme
+ bool m_reducedSolver; // flag for reduced soft body solver
public:
// handles data related to objective function
btDeformableBackwardEulerObjective* m_objective;
@@ -68,11 +69,18 @@ public:
// solve the momentum equation
virtual void solveDeformableConstraints(btScalar solverdt);
+ // set gravity (get from deformable world)
+ virtual void setGravity(const btVector3& gravity)
+ {
+ // for full deformable object, we don't store gravity in the solver
+ // this function is overriden in the reduced deformable object
+ }
+
// resize/clear data structures
- void reinitialize(const btAlignedObjectArray<btSoftBody*>& softBodies, btScalar dt);
+ virtual void reinitialize(const btAlignedObjectArray<btSoftBody*>& softBodies, btScalar dt);
// set up contact constraints
- void setConstraints(const btContactSolverInfo& infoGlobal);
+ virtual void setConstraints(const btContactSolverInfo& infoGlobal);
// add in elastic forces and gravity to obtain v_{n+1}^* and calls predictDeformableMotion
virtual void predictMotion(btScalar solverdt);
@@ -85,7 +93,7 @@ public:
void backupVelocity();
// set m_dv and m_backupVelocity to desired value to prepare for momentum solve
- void setupDeformableSolve(bool implicit);
+ virtual void setupDeformableSolve(bool implicit);
// set the current velocity to that backed up in m_backupVelocity
void revertVelocity();
@@ -150,6 +158,62 @@ public:
// used in line search
btScalar kineticEnergy();
+ // add explicit force to the velocity in the objective class
+ virtual void applyExplicitForce();
+
+ // execute position/velocity update and apply anchor constraints in the integrateTransforms from the Dynamics world
+ virtual void applyTransforms(btScalar timeStep);
+
+ virtual void setStrainLimiting(bool opt)
+ {
+ m_objective->m_projection.m_useStrainLimiting = opt;
+ }
+
+ virtual void setPreconditioner(int opt)
+ {
+ switch (opt)
+ {
+ case btDeformableBackwardEulerObjective::Mass_preconditioner:
+ m_objective->m_preconditioner = m_objective->m_massPreconditioner;
+ break;
+
+ case btDeformableBackwardEulerObjective::KKT_preconditioner:
+ m_objective->m_preconditioner = m_objective->m_KKTPreconditioner;
+ break;
+
+ default:
+ btAssert(false);
+ break;
+ }
+ }
+
+ virtual btAlignedObjectArray<btDeformableLagrangianForce*>* getLagrangianForceArray()
+ {
+ return &(m_objective->m_lf);
+ }
+
+ virtual const btAlignedObjectArray<btSoftBody::Node*>* getIndices()
+ {
+ return m_objective->getIndices();
+ }
+
+ virtual void setProjection()
+ {
+ m_objective->m_projection.setProjection();
+ }
+
+ virtual void setLagrangeMultiplier()
+ {
+ m_objective->m_projection.setLagrangeMultiplier();
+ }
+
+ virtual bool isReducedSolver()
+ {
+ return m_reducedSolver;
+ }
+
+ virtual void deformableBodyInternalWriteBack() {}
+
// unused functions
virtual void optimize(btAlignedObjectArray<btSoftBody*>& softBodies, bool forceUpdate = false) {}
virtual void solveConstraints(btScalar dt) {}
diff --git a/src/BulletSoftBody/btDeformableMultiBodyConstraintSolver.cpp b/src/BulletSoftBody/btDeformableMultiBodyConstraintSolver.cpp
index 631fd5fbe..2a0e5ec34 100644
--- a/src/BulletSoftBody/btDeformableMultiBodyConstraintSolver.cpp
+++ b/src/BulletSoftBody/btDeformableMultiBodyConstraintSolver.cpp
@@ -14,11 +14,16 @@
*/
#include "btDeformableMultiBodyConstraintSolver.h"
+#include "BulletReducedDeformableBody/btReducedDeformableBodySolver.h"
#include <iostream>
+#include <thread>
// override the iterations method to include deformable/multibody contact
btScalar btDeformableMultiBodyConstraintSolver::solveDeformableGroupIterations(btCollisionObject** bodies, int numBodies, btCollisionObject** deformableBodies, int numDeformableBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer)
{
{
+ // pair deformable body with solver body
+ pairDeformableAndSolverBody(bodies, numBodies, numDeformableBodies, infoGlobal);
+
///this is a special step to resolve penetrations (just for contacts)
solveGroupCacheFriendlySplitImpulseIterations(bodies, numBodies, deformableBodies, numDeformableBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer);
@@ -37,6 +42,10 @@ btScalar btDeformableMultiBodyConstraintSolver::solveDeformableGroupIterations(b
// solver body velocity <- rigid body velocity
writeToSolverBody(bodies, numBodies, infoGlobal);
+
+ // std::cout << "------------Iteration " << iteration << "------------\n";
+ // std::cout << "m_leastSquaresResidual: " << m_leastSquaresResidual << "\n";
+
if (m_leastSquaresResidual <= infoGlobal.m_leastSquaresResidualThreshold || (iteration >= (maxIterations - 1)))
{
#ifdef VERBOSE_RESIDUAL_PRINTF
@@ -51,6 +60,9 @@ btScalar btDeformableMultiBodyConstraintSolver::solveDeformableGroupIterations(b
m_analyticsData.m_numBodies = numBodies;
m_analyticsData.m_numContactManifolds = numManifolds;
m_analyticsData.m_remainingLeastSquaresResidual = m_leastSquaresResidual;
+
+ m_deformableSolver->deformableBodyInternalWriteBack();
+ // std::cout << "[===================Next Step===================]\n";
break;
}
}
@@ -78,6 +90,12 @@ void btDeformableMultiBodyConstraintSolver::solveDeformableBodyGroup(btCollision
void btDeformableMultiBodyConstraintSolver::writeToSolverBody(btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal)
{
+ // reduced soft body solver directly modifies the solver body
+ if (m_deformableSolver->isReducedSolver())
+ {
+ return;
+ }
+
for (int i = 0; i < numBodies; i++)
{
int bodyId = getOrInitSolverBody(*bodies[i], infoGlobal.m_timeStep);
@@ -94,6 +112,12 @@ void btDeformableMultiBodyConstraintSolver::writeToSolverBody(btCollisionObject*
void btDeformableMultiBodyConstraintSolver::solverBodyWriteBack(const btContactSolverInfo& infoGlobal)
{
+ // reduced soft body solver directly modifies the solver body
+ if (m_deformableSolver->isReducedSolver())
+ {
+ return;
+ }
+
for (int i = 0; i < m_tmpSolverBodyPool.size(); i++)
{
btRigidBody* body = m_tmpSolverBodyPool[i].m_originalBody;
@@ -105,6 +129,53 @@ void btDeformableMultiBodyConstraintSolver::solverBodyWriteBack(const btContactS
}
}
+
+void btDeformableMultiBodyConstraintSolver::pairDeformableAndSolverBody(btCollisionObject** bodies, int numBodies, int numDeformableBodies, const btContactSolverInfo& infoGlobal)
+{
+ if (!m_deformableSolver->isReducedSolver())
+ {
+ return;
+ }
+
+ btReducedDeformableBodySolver* solver = static_cast<btReducedDeformableBodySolver*>(m_deformableSolver);
+
+ for (int i = 0; i < numDeformableBodies; ++i)
+ {
+ for (int k = 0; k < solver->m_nodeRigidConstraints[i].size(); ++k)
+ {
+ btReducedDeformableNodeRigidContactConstraint& constraint = solver->m_nodeRigidConstraints[i][k];
+
+ if (!constraint.m_contact->m_cti.m_colObj->isStaticObject())
+ {
+ btCollisionObject& col_obj = const_cast<btCollisionObject&>(*constraint.m_contact->m_cti.m_colObj);
+
+ // object index in the solver body pool
+ int bodyId = getOrInitSolverBody(col_obj, infoGlobal.m_timeStep);
+
+ const btRigidBody* body = btRigidBody::upcast(bodies[bodyId]);
+ if (body && body->getInvMass())
+ {
+ // std::cout << "Node: " << constraint.m_node->index << ", body: " << bodyId << "\n";
+ btSolverBody& solverBody = m_tmpSolverBodyPool[bodyId];
+ constraint.setSolverBody(bodyId, solverBody);
+ }
+ }
+ }
+
+ // for (int j = 0; j < numBodies; j++)
+ // {
+ // int bodyId = getOrInitSolverBody(*bodies[j], infoGlobal.m_timeStep);
+
+ // btRigidBody* body = btRigidBody::upcast(bodies[j]);
+ // if (body && body->getInvMass())
+ // {
+ // btSolverBody& solverBody = m_tmpSolverBodyPool[bodyId];
+ // m_deformableSolver->pairConstraintWithSolverBody(i, bodyId, solverBody);
+ // }
+ // }
+ }
+}
+
void btDeformableMultiBodyConstraintSolver::solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies, int numBodies, btCollisionObject** deformableBodies, int numDeformableBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer)
{
BT_PROFILE("solveGroupCacheFriendlySplitImpulseIterations");
diff --git a/src/BulletSoftBody/btDeformableMultiBodyConstraintSolver.h b/src/BulletSoftBody/btDeformableMultiBodyConstraintSolver.h
index 94aabce83..28733fa49 100644
--- a/src/BulletSoftBody/btDeformableMultiBodyConstraintSolver.h
+++ b/src/BulletSoftBody/btDeformableMultiBodyConstraintSolver.h
@@ -43,6 +43,9 @@ protected:
// write the velocity of the underlying rigid body to the the the solver body
void writeToSolverBody(btCollisionObject * *bodies, int numBodies, const btContactSolverInfo& infoGlobal);
+ // let each deformable body knows which solver body is in constact
+ void pairDeformableAndSolverBody(btCollisionObject** bodies, int numBodies, int numDeformableBodies, const btContactSolverInfo& infoGlobal);
+
virtual void solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject * *bodies, int numBodies, btCollisionObject** deformableBodies, int numDeformableBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
virtual btScalar solveDeformableGroupIterations(btCollisionObject * *bodies, int numBodies, btCollisionObject** deformableBodies, int numDeformableBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
diff --git a/src/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp
index 983e622b5..030cbaf90 100644
--- a/src/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp
+++ b/src/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp
@@ -94,7 +94,7 @@ void btDeformableMultiBodyDynamicsWorld::internalSingleStepSimulation(btScalar t
beforeSolverCallbacks(timeStep);
- ///solve contact constraints and then deformable bodies momemtum equation
+ // ///solve contact constraints and then deformable bodies momemtum equation
solveConstraints(timeStep);
afterSolverCallbacks(timeStep);
@@ -201,7 +201,7 @@ void btDeformableMultiBodyDynamicsWorld::performGeometricCollisions(btScalar tim
if (psb->isActive())
{
// clear contact points in the previous iteration
- psb->m_faceNodeContacts.clear();
+ psb->m_faceNodeContactsCCD.clear();
// update m_q and normals for CCD calculation
for (int j = 0; j < psb->m_nodes.size(); ++j)
@@ -237,7 +237,8 @@ void btDeformableMultiBodyDynamicsWorld::performGeometricCollisions(btScalar tim
btSoftBody* psb = m_softBodies[i];
if (psb->isActive())
{
- penetration_count += psb->m_faceNodeContacts.size();
+ penetration_count += psb->m_faceNodeContactsCCD.size();
+ ;
}
}
if (penetration_count == 0)
@@ -297,83 +298,7 @@ void btDeformableMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep)
BT_PROFILE("integrateTransforms");
positionCorrection(timeStep);
btMultiBodyDynamicsWorld::integrateTransforms(timeStep);
- for (int i = 0; i < m_softBodies.size(); ++i)
- {
- btSoftBody* psb = m_softBodies[i];
- for (int j = 0; j < psb->m_nodes.size(); ++j)
- {
- btSoftBody::Node& node = psb->m_nodes[j];
- btScalar maxDisplacement = psb->getWorldInfo()->m_maxDisplacement;
- btScalar clampDeltaV = maxDisplacement / timeStep;
- for (int c = 0; c < 3; c++)
- {
- if (node.m_v[c] > clampDeltaV)
- {
- node.m_v[c] = clampDeltaV;
- }
- if (node.m_v[c] < -clampDeltaV)
- {
- node.m_v[c] = -clampDeltaV;
- }
- }
- node.m_x = node.m_x + timeStep * (node.m_v + node.m_splitv);
- node.m_q = node.m_x;
- node.m_vn = node.m_v;
- }
- // enforce anchor constraints
- for (int j = 0; j < psb->m_deformableAnchors.size(); ++j)
- {
- btSoftBody::DeformableNodeRigidAnchor& a = psb->m_deformableAnchors[j];
- btSoftBody::Node* n = a.m_node;
- n->m_x = a.m_cti.m_colObj->getWorldTransform() * a.m_local;
-
- // update multibody anchor info
- if (a.m_cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK)
- {
- btMultiBodyLinkCollider* multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(a.m_cti.m_colObj);
- if (multibodyLinkCol)
- {
- btVector3 nrm;
- const btCollisionShape* shp = multibodyLinkCol->getCollisionShape();
- const btTransform& wtr = multibodyLinkCol->getWorldTransform();
- psb->m_worldInfo->m_sparsesdf.Evaluate(
- wtr.invXform(n->m_x),
- shp,
- nrm,
- 0);
- a.m_cti.m_normal = wtr.getBasis() * nrm;
- btVector3 normal = a.m_cti.m_normal;
- btVector3 t1 = generateUnitOrthogonalVector(normal);
- btVector3 t2 = btCross(normal, t1);
- btMultiBodyJacobianData jacobianData_normal, jacobianData_t1, jacobianData_t2;
- findJacobian(multibodyLinkCol, jacobianData_normal, a.m_node->m_x, normal);
- findJacobian(multibodyLinkCol, jacobianData_t1, a.m_node->m_x, t1);
- findJacobian(multibodyLinkCol, jacobianData_t2, a.m_node->m_x, t2);
-
- btScalar* J_n = &jacobianData_normal.m_jacobians[0];
- btScalar* J_t1 = &jacobianData_t1.m_jacobians[0];
- btScalar* J_t2 = &jacobianData_t2.m_jacobians[0];
-
- btScalar* u_n = &jacobianData_normal.m_deltaVelocitiesUnitImpulse[0];
- btScalar* u_t1 = &jacobianData_t1.m_deltaVelocitiesUnitImpulse[0];
- btScalar* u_t2 = &jacobianData_t2.m_deltaVelocitiesUnitImpulse[0];
-
- btMatrix3x3 rot(normal.getX(), normal.getY(), normal.getZ(),
- t1.getX(), t1.getY(), t1.getZ(),
- t2.getX(), t2.getY(), t2.getZ()); // world frame to local frame
- const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6;
- btMatrix3x3 local_impulse_matrix = (Diagonal(n->m_im) + OuterProduct(J_n, J_t1, J_t2, u_n, u_t1, u_t2, ndof)).inverse();
- a.m_c0 = rot.transpose() * local_impulse_matrix * rot;
- a.jacobianData_normal = jacobianData_normal;
- a.jacobianData_t1 = jacobianData_t1;
- a.jacobianData_t2 = jacobianData_t2;
- a.t1 = t1;
- a.t2 = t2;
- }
- }
- }
- psb->interpolateRenderMesh();
- }
+ m_deformableBodySolver->applyTransforms(timeStep);
}
void btDeformableMultiBodyDynamicsWorld::solveConstraints(btScalar timeStep)
@@ -390,9 +315,9 @@ void btDeformableMultiBodyDynamicsWorld::solveConstraints(btScalar timeStep)
// set up the directions in which the velocity does not change in the momentum solve
if (m_useProjection)
- m_deformableBodySolver->m_objective->m_projection.setProjection();
+ m_deformableBodySolver->setProjection();
else
- m_deformableBodySolver->m_objective->m_projection.setLagrangeMultiplier();
+ m_deformableBodySolver->setLagrangeMultiplier();
// for explicit scheme, m_backupVelocity = v_{n+1}^*
// for implicit scheme, m_backupVelocity = v_n
@@ -518,6 +443,12 @@ void btDeformableMultiBodyDynamicsWorld::predictUnconstraintMotion(btScalar time
m_deformableBodySolver->predictMotion(timeStep);
}
+void btDeformableMultiBodyDynamicsWorld::setGravity(const btVector3& gravity)
+{
+ btDiscreteDynamicsWorld::setGravity(gravity);
+ m_deformableBodySolver->setGravity(gravity);
+}
+
void btDeformableMultiBodyDynamicsWorld::reinitialize(btScalar timeStep)
{
m_internalTime += timeStep;
@@ -532,14 +463,14 @@ void btDeformableMultiBodyDynamicsWorld::reinitialize(btScalar timeStep)
if (m_useProjection)
{
m_deformableBodySolver->m_useProjection = true;
- m_deformableBodySolver->m_objective->m_projection.m_useStrainLimiting = true;
- m_deformableBodySolver->m_objective->m_preconditioner = m_deformableBodySolver->m_objective->m_massPreconditioner;
+ m_deformableBodySolver->setStrainLimiting(true);
+ m_deformableBodySolver->setPreconditioner(btDeformableBackwardEulerObjective::Mass_preconditioner);
}
else
{
m_deformableBodySolver->m_useProjection = false;
- m_deformableBodySolver->m_objective->m_projection.m_useStrainLimiting = false;
- m_deformableBodySolver->m_objective->m_preconditioner = m_deformableBodySolver->m_objective->m_KKTPreconditioner;
+ m_deformableBodySolver->setStrainLimiting(false);
+ m_deformableBodySolver->setPreconditioner(btDeformableBackwardEulerObjective::KKT_preconditioner);
}
}
@@ -681,7 +612,7 @@ void btDeformableMultiBodyDynamicsWorld::afterSolverCallbacks(btScalar timeStep)
void btDeformableMultiBodyDynamicsWorld::addForce(btSoftBody* psb, btDeformableLagrangianForce* force)
{
- btAlignedObjectArray<btDeformableLagrangianForce*>& forces = m_deformableBodySolver->m_objective->m_lf;
+ btAlignedObjectArray<btDeformableLagrangianForce*>& forces = *m_deformableBodySolver->getLagrangianForceArray();
bool added = false;
for (int i = 0; i < forces.size(); ++i)
{
@@ -695,14 +626,14 @@ void btDeformableMultiBodyDynamicsWorld::addForce(btSoftBody* psb, btDeformableL
if (!added)
{
force->addSoftBody(psb);
- force->setIndices(m_deformableBodySolver->m_objective->getIndices());
+ force->setIndices(m_deformableBodySolver->getIndices());
forces.push_back(force);
}
}
void btDeformableMultiBodyDynamicsWorld::removeForce(btSoftBody* psb, btDeformableLagrangianForce* force)
{
- btAlignedObjectArray<btDeformableLagrangianForce*>& forces = m_deformableBodySolver->m_objective->m_lf;
+ btAlignedObjectArray<btDeformableLagrangianForce*>& forces = *m_deformableBodySolver->getLagrangianForceArray();
int removed_index = -1;
for (int i = 0; i < forces.size(); ++i)
{
@@ -720,7 +651,7 @@ void btDeformableMultiBodyDynamicsWorld::removeForce(btSoftBody* psb, btDeformab
void btDeformableMultiBodyDynamicsWorld::removeSoftBodyForce(btSoftBody* psb)
{
- btAlignedObjectArray<btDeformableLagrangianForce*>& forces = m_deformableBodySolver->m_objective->m_lf;
+ btAlignedObjectArray<btDeformableLagrangianForce*>& forces = *m_deformableBodySolver->getLagrangianForceArray();
for (int i = 0; i < forces.size(); ++i)
{
forces[i]->removeSoftBody(psb);
diff --git a/src/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h b/src/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h
index 4b7069aac..5971ecd9a 100644
--- a/src/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h
+++ b/src/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h
@@ -19,7 +19,7 @@
#include "btSoftMultiBodyDynamicsWorld.h"
#include "btDeformableLagrangianForce.h"
#include "btDeformableMassSpringForce.h"
-#include "btDeformableBodySolver.h"
+// #include "btDeformableBodySolver.h"
#include "btDeformableMultiBodyConstraintSolver.h"
#include "btSoftBodyHelpers.h"
#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h"
@@ -121,6 +121,8 @@ public:
return m_sbi;
}
+ virtual void setGravity(const btVector3& gravity);
+
void reinitialize(btScalar timeStep);
void applyRigidBodyGravity(btScalar timeStep);
diff --git a/src/BulletSoftBody/btSoftBody.cpp b/src/BulletSoftBody/btSoftBody.cpp
index c6226a008..933f3edc5 100644
--- a/src/BulletSoftBody/btSoftBody.cpp
+++ b/src/BulletSoftBody/btSoftBody.cpp
@@ -231,6 +231,9 @@ void btSoftBody::initDefaults()
m_gravityFactor = 1;
m_cacheBarycenter = false;
m_fdbvnt = 0;
+
+ // reduced flag
+ m_reducedModel = false;
}
//
@@ -1483,6 +1486,21 @@ void btSoftBody::randomizeConstraints()
#undef NEXTRAND
}
+void btSoftBody::updateState(const btAlignedObjectArray<btVector3>& q, const btAlignedObjectArray<btVector3>& v)
+{
+ int node_count = m_nodes.size();
+ btAssert(node_count == q.size());
+ btAssert(node_count == v.size());
+ for (int i = 0; i < node_count; i++)
+ {
+ Node& n = m_nodes[i];
+ n.m_x = q[i];
+ n.m_q = q[i];
+ n.m_v = v[i];
+ n.m_vn = v[i];
+ }
+}
+
//
void btSoftBody::releaseCluster(int index)
{
@@ -2821,7 +2839,7 @@ bool btSoftBody::checkDeformableFaceContact(const btCollisionObjectWrapper* colO
btScalar dst;
btGjkEpaSolver2::sResults results;
-// #define USE_QUADRATURE 1
+ // #define USE_QUADRATURE 1
// use collision quadrature point
#ifdef USE_QUADRATURE
diff --git a/src/BulletSoftBody/btSoftBody.h b/src/BulletSoftBody/btSoftBody.h
index d5b01faf3..f91640acb 100644
--- a/src/BulletSoftBody/btSoftBody.h
+++ b/src/BulletSoftBody/btSoftBody.h
@@ -298,7 +298,7 @@ public:
};
struct RenderFace
{
- RenderNode* m_n[3]; // Node pointers
+ RenderNode* m_n[3]; // Node pointers
};
/* Face */
@@ -407,6 +407,7 @@ public:
btScalar m_friction; // Friction
btScalar m_imf; // inverse mass of the face at contact point
btScalar m_c0; // scale of the impulse matrix;
+ const btCollisionObject* m_colObj; // Collision object to collide with.
};
/* SContact */
@@ -786,7 +787,7 @@ public:
typedef btAlignedObjectArray<Cluster*> tClusterArray;
typedef btAlignedObjectArray<Note> tNoteArray;
typedef btAlignedObjectArray<Node> tNodeArray;
- typedef btAlignedObjectArray< RenderNode> tRenderNodeArray;
+ typedef btAlignedObjectArray<RenderNode> tRenderNodeArray;
typedef btAlignedObjectArray<btDbvtNode*> tLeafArray;
typedef btAlignedObjectArray<Link> tLinkArray;
typedef btAlignedObjectArray<Face> tFaceArray;
@@ -798,6 +799,7 @@ public:
typedef btAlignedObjectArray<Material*> tMaterialArray;
typedef btAlignedObjectArray<Joint*> tJointArray;
typedef btAlignedObjectArray<btSoftBody*> tSoftBodyArray;
+ typedef btAlignedObjectArray<btAlignedObjectArray<btScalar> > tDenseMatrix;
//
// Fields
@@ -813,7 +815,7 @@ public:
tRenderNodeArray m_renderNodes; // Render Nodes
tLinkArray m_links; // Links
tFaceArray m_faces; // Faces
- tRenderFaceArray m_renderFaces; // Faces
+ tRenderFaceArray m_renderFaces; // Faces
tTetraArray m_tetras; // Tetras
btAlignedObjectArray<TetraScratch> m_tetraScratches;
btAlignedObjectArray<TetraScratch> m_tetraScratchesTn;
@@ -823,6 +825,7 @@ public:
btAlignedObjectArray<DeformableNodeRigidContact> m_nodeRigidContacts;
btAlignedObjectArray<DeformableFaceNodeContact> m_faceNodeContacts;
btAlignedObjectArray<DeformableFaceRigidContact> m_faceRigidContacts;
+ btAlignedObjectArray<DeformableFaceNodeContact> m_faceNodeContactsCCD;
tSContactArray m_scontacts; // Soft contacts
tJointArray m_joints; // Joints
tMaterialArray m_materials; // Materials
@@ -855,6 +858,8 @@ public:
btScalar m_restLengthScale;
+ bool m_reducedModel; // Reduced deformable model flag
+
//
// Api
//
@@ -1001,15 +1006,15 @@ public:
/* Get best fit rigid transform */
btTransform getRigidTransform();
/* Transform to given pose */
- void transformTo(const btTransform& trs);
+ virtual void transformTo(const btTransform& trs);
/* Transform */
- void transform(const btTransform& trs);
+ virtual void transform(const btTransform& trs);
/* Translate */
- void translate(const btVector3& trs);
+ virtual void translate(const btVector3& trs);
/* Rotate */
- void rotate(const btQuaternion& rot);
+ virtual void rotate(const btQuaternion& rot);
/* Scale */
- void scale(const btVector3& scl);
+ virtual void scale(const btVector3& scl);
/* Get link resting lengths scale */
btScalar getRestLengthScale();
/* Scale resting length of all springs */
@@ -1051,6 +1056,9 @@ public:
Material* mat = 0);
/* Randomize constraints to reduce solver bias */
void randomizeConstraints();
+
+ void updateState(const btAlignedObjectArray<btVector3>& qs, const btAlignedObjectArray<btVector3>& vs);
+
/* Release clusters */
void releaseCluster(int index);
void releaseClusters();
@@ -1096,6 +1104,13 @@ public:
void setZeroVelocity();
bool wantsSleeping();
+ virtual btMatrix3x3 getImpulseFactor(int n_node)
+ {
+ btMatrix3x3 tmp;
+ tmp.setIdentity();
+ return tmp;
+ }
+
//
// Functionality to deal with new accelerated solvers.
//
diff --git a/src/BulletSoftBody/btSoftBodyHelpers.cpp b/src/BulletSoftBody/btSoftBodyHelpers.cpp
index e464c4668..35eb22ec1 100644
--- a/src/BulletSoftBody/btSoftBodyHelpers.cpp
+++ b/src/BulletSoftBody/btSoftBodyHelpers.cpp
@@ -18,6 +18,7 @@ subject to the following restrictions:
#include <stdio.h>
#include <string>
#include <iostream>
+#include <iomanip>
#include <sstream>
#include <string.h>
#include <algorithm>
@@ -1487,6 +1488,168 @@ void btSoftBodyHelpers::writeObj(const char* filename, const btSoftBody* psb)
fs.close();
}
+static inline bool isSpace(const char c)
+{
+ return (c == ' ') || (c == '\t');
+}
+static inline bool isNewLine(const char c)
+{
+ return (c == '\r') || (c == '\n') || (c == '\0');
+}
+static inline float parseFloat(const char*& token)
+{
+ token += strspn(token, " \t");
+ float f = (float)atof(token);
+ token += strcspn(token, " \t\r");
+ return f;
+}
+static inline void parseFloat3(
+ float& x, float& y, float& z,
+ const char*& token)
+{
+ x = parseFloat(token);
+ y = parseFloat(token);
+ z = parseFloat(token);
+}
+
+void btSoftBodyHelpers::writeState(const char* file, const btSoftBody* psb)
+{
+ std::ofstream fs;
+ fs.open(file);
+ btAssert(fs);
+ fs << std::scientific << std::setprecision(16);
+
+ // Only write out for trimesh, directly write out all the nodes and faces.xs
+ for (int i = 0; i < psb->m_nodes.size(); ++i)
+ {
+ fs << "q";
+ for (int d = 0; d < 3; d++)
+ {
+ fs << " " << psb->m_nodes[i].m_q[d];
+ }
+ fs << "\n";
+ }
+
+ for (int i = 0; i < psb->m_nodes.size(); ++i)
+ {
+ fs << "v";
+ for (int d = 0; d < 3; d++)
+ {
+ fs << " " << psb->m_nodes[i].m_v[d];
+ }
+ fs << "\n";
+ }
+ fs.close();
+}
+
+std::string btSoftBodyHelpers::loadDeformableState(btAlignedObjectArray<btVector3>& qs, btAlignedObjectArray<btVector3>& vs, const char* filename, CommonFileIOInterface* fileIO)
+{
+ {
+ qs.clear();
+ vs.clear();
+ std::string tmp = filename;
+ std::stringstream err;
+#ifdef USE_STREAM
+ std::ifstream ifs(filename);
+ if (!ifs)
+ {
+ err << "Cannot open file [" << filename << "]" << std::endl;
+ return err.str();
+ }
+#else
+ int fileHandle = fileIO->fileOpen(filename, "r");
+ if (fileHandle < 0)
+ {
+ err << "Cannot open file [" << filename << "]" << std::endl;
+ return err.str();
+ }
+#endif
+
+ std::string name;
+
+ int maxchars = 8192; // Alloc enough size.
+ std::vector<char> buf(maxchars); // Alloc enough size.
+ std::string linebuf;
+ linebuf.reserve(maxchars);
+
+#ifdef USE_STREAM
+ while (ifs.peek() != -1)
+#else
+ char* line = 0;
+ do
+#endif
+ {
+ linebuf.resize(0);
+#ifdef USE_STREAM
+ safeGetline(ifs, linebuf);
+#else
+ char tmpBuf[1024];
+ line = fileIO->readLine(fileHandle, tmpBuf, 1024);
+ if (line)
+ {
+ linebuf = line;
+ }
+#endif
+ // Trim newline '\r\n' or '\r'
+ if (linebuf.size() > 0)
+ {
+ if (linebuf[linebuf.size() - 1] == '\n') linebuf.erase(linebuf.size() - 1);
+ }
+ if (linebuf.size() > 0)
+ {
+ if (linebuf[linebuf.size() - 1] == '\n') linebuf.erase(linebuf.size() - 1);
+ }
+
+ // Skip if empty line.
+ if (linebuf.empty())
+ {
+ continue;
+ }
+
+ // Skip leading space.
+ const char* token = linebuf.c_str();
+ token += strspn(token, " \t");
+
+ btAssert(token);
+ if (token[0] == '\0') continue; // empty line
+
+ if (token[0] == '#') continue; // comment line
+
+ // q
+ if (token[0] == 'q' && isSpace((token[1])))
+ {
+ token += 2;
+ float x, y, z;
+ parseFloat3(x, y, z, token);
+ qs.push_back(btVector3(x, y, z));
+ continue;
+ }
+
+ // v
+ if (token[0] == 'v' && isSpace((token[1])))
+ {
+ token += 3;
+ float x, y, z;
+ parseFloat3(x, y, z, token);
+ vs.push_back(btVector3(x, y, z));
+ continue;
+ }
+
+ // Ignore unknown command.
+ }
+#ifndef USE_STREAM
+ while (line)
+ ;
+#endif
+
+ if (fileHandle >= 0)
+ {
+ fileIO->fileClose(fileHandle);
+ }
+ return err.str();
+ }
+}
+
void btSoftBodyHelpers::duplicateFaces(const char* filename, const btSoftBody* psb)
{
std::ifstream fs_read;
diff --git a/src/BulletSoftBody/btSoftBodyHelpers.h b/src/BulletSoftBody/btSoftBodyHelpers.h
index b292d90d1..d1fdf0450 100644
--- a/src/BulletSoftBody/btSoftBodyHelpers.h
+++ b/src/BulletSoftBody/btSoftBodyHelpers.h
@@ -17,6 +17,7 @@ subject to the following restrictions:
#define BT_SOFT_BODY_HELPERS_H
#include "btSoftBody.h"
+#include "../../examples/CommonInterfaces/CommonFileIOInterface.h"
#include <fstream>
#include <string>
//
@@ -146,6 +147,10 @@ struct btSoftBodyHelpers
static void writeObj(const char* file, const btSoftBody* psb);
+ static void writeState(const char* file, const btSoftBody* psb);
+
+ static std::string loadDeformableState(btAlignedObjectArray<btVector3>& qs, btAlignedObjectArray<btVector3>& vs, const char* filename, CommonFileIOInterface* fileIO);
+
static void getBarycentricWeights(const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, const btVector3& p, btVector4& bary);
static void getBarycentricWeights(const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& p, btVector4& bary);
diff --git a/src/BulletSoftBody/btSoftBodyInternals.h b/src/BulletSoftBody/btSoftBodyInternals.h
index e52b1c875..137258675 100644
--- a/src/BulletSoftBody/btSoftBodyInternals.h
+++ b/src/BulletSoftBody/btSoftBodyInternals.h
@@ -1691,12 +1691,19 @@ struct btSoftColliders
if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY)
{
const btTransform& wtr = m_rigidBody ? m_rigidBody->getWorldTransform() : m_colObj1Wrap->getCollisionObject()->getWorldTransform();
- static const btMatrix3x3 iwiStatic(0, 0, 0, 0, 0, 0, 0, 0, 0);
- const btMatrix3x3& iwi = m_rigidBody ? m_rigidBody->getInvInertiaTensorWorld() : iwiStatic;
const btVector3 ra = n.m_x - wtr.getOrigin();
- c.m_c0 = ImpulseMatrix(1, n.m_effectiveMass_inv, imb, iwi, ra);
- // c.m_c0 = ImpulseMatrix(1, ima, imb, iwi, ra);
+ static const btMatrix3x3 iwiStatic(0, 0, 0, 0, 0, 0, 0, 0, 0);
+ const btMatrix3x3& iwi = m_rigidBody ? m_rigidBody->getInvInertiaTensorWorld() : iwiStatic;
+ if (psb->m_reducedModel)
+ {
+ c.m_c0 = MassMatrix(imb, iwi, ra); //impulse factor K of the rigid body only (not the inverse)
+ }
+ else
+ {
+ c.m_c0 = ImpulseMatrix(1, n.m_effectiveMass_inv, imb, iwi, ra);
+ // c.m_c0 = ImpulseMatrix(1, ima, imb, iwi, ra);
+ }
c.m_c1 = ra;
}
else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK)
@@ -1724,7 +1731,16 @@ struct btSoftColliders
t1.getX(), t1.getY(), t1.getZ(),
t2.getX(), t2.getY(), t2.getZ()); // world frame to local frame
const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6;
- btMatrix3x3 local_impulse_matrix = (n.m_effectiveMass_inv + OuterProduct(J_n, J_t1, J_t2, u_n, u_t1, u_t2, ndof)).inverse();
+
+ btMatrix3x3 local_impulse_matrix;
+ if (psb->m_reducedModel)
+ {
+ local_impulse_matrix = OuterProduct(J_n, J_t1, J_t2, u_n, u_t1, u_t2, ndof);
+ }
+ else
+ {
+ local_impulse_matrix = (n.m_effectiveMass_inv + OuterProduct(J_n, J_t1, J_t2, u_n, u_t1, u_t2, ndof)).inverse();
+ }
c.m_c0 = rot.transpose() * local_impulse_matrix * rot;
c.jacobianData_normal = jacobianData_normal;
c.jacobianData_t1 = jacobianData_t1;
@@ -1944,6 +1960,7 @@ struct btSoftColliders
c.m_weights = btVector3(0, 0, 0);
c.m_imf = 0;
c.m_c0 = 0;
+ c.m_colObj = psb[1];
psb[0]->m_faceNodeContacts.push_back(c);
}
}
@@ -2019,6 +2036,7 @@ struct btSoftColliders
c.m_weights = btVector3(0, 0, 0);
c.m_imf = 0;
c.m_c0 = 0;
+ c.m_colObj = psb[1];
psb[0]->m_faceNodeContacts.push_back(c);
}
}
@@ -2050,7 +2068,8 @@ struct btSoftColliders
c.m_margin = mrg;
c.m_imf = 0;
c.m_c0 = 0;
- psb[0]->m_faceNodeContacts.push_back(c);
+ c.m_colObj = psb[1];
+ psb[0]->m_faceNodeContactsCCD.push_back(c);
}
}
void Process(const btDbvntNode* lface1,
@@ -2114,7 +2133,8 @@ struct btSoftColliders
c.m_margin = mrg;
c.m_imf = 0;
c.m_c0 = 0;
- psb[0]->m_faceNodeContacts.push_back(c);
+ c.m_colObj = psb[1];
+ psb[0]->m_faceNodeContactsCCD.push_back(c);
}
}
}
diff --git a/src/BulletSoftBody/btSoftBodySolvers.h b/src/BulletSoftBody/btSoftBodySolvers.h
index cdd069849..7eafc6c31 100644
--- a/src/BulletSoftBody/btSoftBodySolvers.h
+++ b/src/BulletSoftBody/btSoftBodySolvers.h
@@ -36,7 +36,8 @@ public:
CL_SIMD_SOLVER,
DX_SOLVER,
DX_SIMD_SOLVER,
- DEFORMABLE_SOLVER
+ DEFORMABLE_SOLVER,
+ REDUCED_DEFORMABLE_SOLVER
};
protected: